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

Shared wallets in incomplete state should not undergo restoration #3676

Merged

Conversation

paweljakubas
Copy link
Contributor

@paweljakubas paweljakubas commented Jan 4, 2023

Issue Number

ADP-2432

Description

  • I have made sure Incomplete shared wallet invokes createNonRestoringWalletWorker.
  • When Incomplete -> Ready transition then the private key and meta from incomplete wallet is read.
  • The incomplete wallet is deleted and active wallet is created. The wallet starts restoring.
  • Wallet takes meta and private key from incomplete wallet.

The solution making db exchange between workers (non-restoring and restoring) did not work properly. hence the above solution.

@paweljakubas paweljakubas self-assigned this Jan 4, 2023
@paweljakubas paweljakubas force-pushed the paweljakubas/adp-2432/shared-wallets-pending-should-not-restore branch from 104a2d3 to a00485d Compare January 10, 2023 15:14
@paweljakubas paweljakubas marked this pull request as ready for review January 10, 2023 15:18
@jonathanknowles jonathanknowles force-pushed the paweljakubas/adp-2432/shared-wallets-pending-should-not-restore branch from 894456a to c6d9676 Compare January 11, 2023 07:14
@jonathanknowles jonathanknowles force-pushed the paweljakubas/adp-2432/shared-wallets-pending-should-not-restore branch from 5ff2ae6 to 5a01f20 Compare January 11, 2023 07:25
```patch
- createNonrestoringWalletWorker
+ createNonRestoringWalletWorker
```
Copy link
Member

@jonathanknowles jonathanknowles left a comment

Choose a reason for hiding this comment

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

Hi @paweljakubas

Thanks for making this PR!

I've given it a brief look (though still need to look further).

I have one question about the use of terminology:

When you say "no meta", are you referring to a case where the database has no metadata for a given wallet?

@@ -769,6 +769,11 @@ instance IsServerError ErrDerivePublicKey where
instance IsServerError ErrAddCosignerKey where
toServerError = \case
ErrAddCosignerKeyNoSuchWallet e -> toServerError e
ErrAddCosignerKeyNoMeta ->
apiError err503 NoMeta $ mconcat
[ "No meta of wallet was found in database during migration"
Copy link
Member

Choose a reason for hiding this comment

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

@paweljakubas

When you refer to "no meta of wallet", do you mean "no wallet metadata"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes

This commit makes it clearer that it was not possible to find the
**metadata** for a particular wallet.

In this particular context, the term "meta" is arguably a bit hard to
understand, unless the reader happens to be familiar with the internals
of cardano wallet.
This commit revises the error messages relating to
`WalletMetadataNotFound`, for readability and flow.
@paweljakubas paweljakubas changed the title Shared wallets pending should not restore Shared wallets in pending state should not restore Jan 11, 2023
Copy link
Contributor

@piotr-iohk piotr-iohk left a comment

Choose a reason for hiding this comment

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

I have played a bit and it seems to work as expected. Also e2e tests pass on the branch.

I think that we could have some integration tests:

  • producing the introduced WalletMetadataNotFound if that is possible
  • creating a shared wallet, funding it, then deleting it and creating again "in steps", i.e. create + patch and making sure the balance is as expected.

apiError err503 WalletMetadataNotFound $ T.unwords
[ "It was not possible to find any metadata for the given"
, "wallet within the database. This could be because the"
, "wallet has yet to become active after being in the pending"
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
, "wallet has yet to become active after being in the pending"
, "wallet has yet to become active after being in the incomplete"

Copy link
Contributor

Choose a reason for hiding this comment

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

Q: what are circumstances for this error to occur? Is it possible to produce the test that incurs this error?

Copy link
Contributor Author

@paweljakubas paweljakubas Jan 11, 2023

Choose a reason for hiding this comment

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

if something wrong with db ie. when during being in incomplete db is erased

withWorkerCtx ctx wid liftE liftE $ \wrk -> do
liftHandler $ W.updateCosigner wrk wid (liftKey accXPub) cosigner cred
wal' <- fst <$> getWallet ctx (mkSharedWallet @_ @s @k) (ApiT wid)
-- we switch on restoring only after pending -> active transition
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
-- we switch on restoring only after pending -> active transition
-- we switch on restoring only after incomplete -> active transition

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

wallet within the database.

May occur when a shared wallet has not yet become active after being in
the pending state.
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
the pending state.
the incomplete state.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@jonathanknowles jonathanknowles changed the title Shared wallets in pending state should not restore Shared wallets in pending state should not undergo restoration Jan 11, 2023
@Anviking
Copy link
Member

bors r-

restarting

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Jan 12, 2023

Canceled.

@Anviking
Copy link
Member

bors r+

iohk-bors bot added a commit that referenced this pull request Jan 12, 2023
3609: [ADP-2391] implement model API for submissions store r=Anviking a=paolino




- [x] implement model API operations for submissions store

### Comments

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

### Issue Number

ADP-2391

<!-- 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. -->


3676: Shared wallets in incomplete state should not undergo restoration r=Anviking a=paweljakubas

### Issue Number

ADP-2432

### Description

- [x] I have made sure `Incomplete` shared wallet invokes  `createNonRestoringWalletWorker`.
- [x] When `Incomplete -> Ready` transition then the private key and meta from incomplete wallet is read.
- [x] The incomplete wallet is deleted and active wallet is created. The wallet starts restoring. 
- [x] Wallet takes meta and private key from incomplete wallet.

The solution making db exchange between workers (non-restoring and restoring) did not work properly. hence the above solution.

3680: Shared wallets user guide - creating a wallet and spending r=piotr-iohk a=piotr-iohk

- [x] Shared wallets user guide - creating a wallet and spending (fc5615f) 

### Comments

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

### Issue Number

ADP-2457


3684: Make sure there is collateral on the wallet before e2e plutus tests r=Anviking a=piotr-iohk

- [x] Make sure there is collateral on the wallet before e2e plutus tests (925cc09) 

### Comments

Sometimes wallets turn out to have no pure ADA utxo and plutus tests fail. This is to make sure there are always some pure ADA utxos.

#maintenance

### Issue Number

n/a


Co-authored-by: paolo veronelli <paolo.veronelli@gmail.com>
Co-authored-by: Pawel Jakubas <pawel.jakubas@iohk.io>
Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
Co-authored-by: Piotr Stachyra <piotr.stachyra@iohk.io>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Jan 12, 2023

Build failed (retrying...):

iohk-bors bot added a commit that referenced this pull request Jan 12, 2023
3676: Shared wallets in incomplete state should not undergo restoration r=Anviking a=paweljakubas

### Issue Number

ADP-2432

### Description

- [x] I have made sure `Incomplete` shared wallet invokes  `createNonRestoringWalletWorker`.
- [x] When `Incomplete -> Ready` transition then the private key and meta from incomplete wallet is read.
- [x] The incomplete wallet is deleted and active wallet is created. The wallet starts restoring. 
- [x] Wallet takes meta and private key from incomplete wallet.

The solution making db exchange between workers (non-restoring and restoring) did not work properly. hence the above solution.

3680: Shared wallets user guide - creating a wallet and spending r=piotr-iohk a=piotr-iohk

- [x] Shared wallets user guide - creating a wallet and spending (fc5615f) 

### Comments

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

### Issue Number

ADP-2457


Co-authored-by: Pawel Jakubas <pawel.jakubas@iohk.io>
Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
Co-authored-by: Piotr Stachyra <piotr.stachyra@iohk.io>
@Anviking
Copy link
Member

bors r-

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Jan 12, 2023

Canceled.

@Anviking
Copy link
Member

bors r+

iohk-bors bot added a commit that referenced this pull request Jan 12, 2023
3609: [ADP-2391] implement model API for submissions store r=Anviking a=paolino




- [x] implement model API operations for submissions store

### Comments

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

### Issue Number

ADP-2391

<!-- 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. -->


3676: Shared wallets in incomplete state should not undergo restoration r=Anviking a=paweljakubas

### Issue Number

ADP-2432

### Description

- [x] I have made sure `Incomplete` shared wallet invokes  `createNonRestoringWalletWorker`.
- [x] When `Incomplete -> Ready` transition then the private key and meta from incomplete wallet is read.
- [x] The incomplete wallet is deleted and active wallet is created. The wallet starts restoring. 
- [x] Wallet takes meta and private key from incomplete wallet.

The solution making db exchange between workers (non-restoring and restoring) did not work properly. hence the above solution.

3680: Shared wallets user guide - creating a wallet and spending r=Anviking a=piotr-iohk

- [x] Shared wallets user guide - creating a wallet and spending (fc5615f) 

### Comments

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

### Issue Number

ADP-2457


3684: Make sure there is collateral on the wallet before e2e plutus tests r=Anviking a=piotr-iohk

- [x] Make sure there is collateral on the wallet before e2e plutus tests (925cc09) 

### Comments

Sometimes wallets turn out to have no pure ADA utxo and plutus tests fail. This is to make sure there are always some pure ADA utxos.

#maintenance

### Issue Number

n/a


Co-authored-by: paolo veronelli <paolo.veronelli@gmail.com>
Co-authored-by: Pawel Jakubas <pawel.jakubas@iohk.io>
Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
Co-authored-by: Piotr Stachyra <piotr.stachyra@iohk.io>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Jan 12, 2023

Build failed (retrying...):

iohk-bors bot added a commit that referenced this pull request Jan 12, 2023
3676: Shared wallets in incomplete state should not undergo restoration r=Anviking a=paweljakubas

### Issue Number

ADP-2432

### Description

- [x] I have made sure `Incomplete` shared wallet invokes  `createNonRestoringWalletWorker`.
- [x] When `Incomplete -> Ready` transition then the private key and meta from incomplete wallet is read.
- [x] The incomplete wallet is deleted and active wallet is created. The wallet starts restoring. 
- [x] Wallet takes meta and private key from incomplete wallet.

The solution making db exchange between workers (non-restoring and restoring) did not work properly. hence the above solution.

3680: Shared wallets user guide - creating a wallet and spending r=Anviking a=piotr-iohk

- [x] Shared wallets user guide - creating a wallet and spending (fc5615f) 

### Comments

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

### Issue Number

ADP-2457


Co-authored-by: Pawel Jakubas <pawel.jakubas@iohk.io>
Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
Co-authored-by: Piotr Stachyra <piotr.stachyra@iohk.io>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Jan 12, 2023

This PR was included in a batch that successfully built, but then failed to merge into master. It will not be retried.

Additional information:

@Anviking
Copy link
Member

bors r+

iohk-bors bot added a commit that referenced this pull request Jan 12, 2023
3676: Shared wallets in incomplete state should not undergo restoration r=Anviking a=paweljakubas

### Issue Number

ADP-2432

### Description

- [x] I have made sure `Incomplete` shared wallet invokes  `createNonRestoringWalletWorker`.
- [x] When `Incomplete -> Ready` transition then the private key and meta from incomplete wallet is read.
- [x] The incomplete wallet is deleted and active wallet is created. The wallet starts restoring. 
- [x] Wallet takes meta and private key from incomplete wallet.

The solution making db exchange between workers (non-restoring and restoring) did not work properly. hence the above solution.

3680: Shared wallets user guide - creating a wallet and spending r=Anviking a=piotr-iohk

- [x] Shared wallets user guide - creating a wallet and spending (fc5615f) 

### Comments

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

### Issue Number

ADP-2457


Co-authored-by: Pawel Jakubas <pawel.jakubas@iohk.io>
Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
Co-authored-by: Piotr Stachyra <piotr.stachyra@iohk.io>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Jan 12, 2023

Build failed (retrying...):

iohk-bors bot added a commit that referenced this pull request Jan 12, 2023
3676: Shared wallets in incomplete state should not undergo restoration r=Anviking a=paweljakubas

### Issue Number

ADP-2432

### Description

- [x] I have made sure `Incomplete` shared wallet invokes  `createNonRestoringWalletWorker`.
- [x] When `Incomplete -> Ready` transition then the private key and meta from incomplete wallet is read.
- [x] The incomplete wallet is deleted and active wallet is created. The wallet starts restoring. 
- [x] Wallet takes meta and private key from incomplete wallet.

The solution making db exchange between workers (non-restoring and restoring) did not work properly. hence the above solution.

Co-authored-by: Pawel Jakubas <pawel.jakubas@iohk.io>
Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Jan 12, 2023

Build failed:

@Anviking
Copy link
Member

bors r+

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Jan 12, 2023

Build succeeded:

@iohk-bors iohk-bors bot merged commit 24b188a into master Jan 12, 2023
@iohk-bors iohk-bors bot deleted the paweljakubas/adp-2432/shared-wallets-pending-should-not-restore branch January 12, 2023 22:04
WilliamKingNoel-Bot pushed a commit that referenced this pull request Jan 12, 2023
… undergo restoration r=Anviking a=paweljakubas ### Issue Number ADP-2432
 
 ### Description
 
 - [x] I have made sure `Incomplete` shared wallet invokes `createNonRestoringWalletWorker`.
 - [x] When `Incomplete -> Ready` transition then the private key and meta from incomplete wallet is read.
 - [x] The incomplete wallet is deleted and active wallet is created. The wallet starts restoring. 
 - [x] Wallet takes meta and private key from incomplete wallet.
 
 The solution making db exchange between workers (non-restoring and restoring) did not work properly. hence the above solution. Co-authored-by: Pawel Jakubas <pawel.jakubas@iohk.io> Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io> Source commit: 24b188a
iohk-bors bot added a commit that referenced this pull request Jan 16, 2023
3689: Use `decodeErrorInfo` in shared wallet integration tests r=jonathanknowles a=jonathanknowles

## Issue Number

Follow-on from review of #3676.

## Summary

This PR removes a small number of **error string comparisons** from our integration tests, replacing them with equality checks on the API error types themselves.

This allows us to remove redundant duplicated error strings from the `Framework.TestData` module, which need to be manually kept in sync with (virtually the same) definitions in the `Cardano.Wallet.Api.Http.Server.Error` module.

## Notes

This PR doesn't convert all integration tests to use this style: it's just meant as a demonstration of the overall method. Additionally, many error strings are created through string interpolation. To convert all of our integration tests to use pattern matching on API error types, we'd need to create richer error types similar to that used for the `UtxoTooSmall` error, and remove the use of string interpolation.

Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
WilliamKingNoel-Bot pushed a commit that referenced this pull request Jan 16, 2023
…ation tests r=jonathanknowles a=jonathanknowles ## Issue Number Follow-on from review of #3676.
 
 ## Summary
 
 This PR removes a small number of **error string comparisons** from our integration tests, replacing them with equality checks on the API error types themselves.
 
 This allows us to remove redundant duplicated error strings from the `Framework.TestData` module, which need to be manually kept in sync with (virtually the same) definitions in the `Cardano.Wallet.Api.Http.Server.Error` module.
 
 ## Notes
 
 This PR doesn't convert all integration tests to use this style: it's just meant as a demonstration of the overall method. Additionally, many error strings are created through string interpolation. To convert all of our integration tests to use pattern matching on API error types, we'd need to create richer error types similar to that used for the `UtxoTooSmall` error, and remove the use of string interpolation. Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io> Source commit: eba2723
iohk-bors bot added a commit that referenced this pull request Jan 17, 2023
3693: Machine-readable shared wallet API errors. r=jonathanknowles a=jonathanknowles

## Issue Number

Follow-on from review of #3676.

## Summary

This PR removes an **interpolated string equality check** from our API integration test suite, and replaces it an equality check that uses **`decodeErrorInfo`** in conjunction with an **API error record**:

```patch
lib/wallet/integration/src/Test/Integration/Scenario/API/Shared/Wallets.hs
 
-     expectErrorMessage (errMsg403NoSuchCosigner (toText Payment) 7) rPatch5
+     decodeErrorInfo rPatch5 `shouldBe` SharedWalletNoSuchCosigner
+         ApiErrorSharedWalletNoSuchCosigner
+             { cosignerIndex = ApiCosignerIndex 7
+             , credentialType = ApiCredentialType Payment
+             }
```
```patch
lib/wallet/integration/src/Test/Integration/Framework/TestData.hs
 
- errMsg403NoSuchCosigner :: Text -> Int -> String
- errMsg403NoSuchCosigner cred cosigner = unwords
-     [ "It looks like you've tried to add a cosigner key to a"
-     , "shared wallet's"
-     , unpack cred
-     , "template for a non-existing cosigner index:"
-     , show cosigner
-     ]
```
The above definition of `errMsg403NoCosigner` (now removed) was essentially a **duplicate** of an identical interpolated string in `Http.Server.Error`:

https://github.com/input-output-hk/cardano-wallet/blob/1263e6ed8c486f31ed75219b59a8e5fc6af577de/lib/wallet/api/http/Cardano/Wallet/Api/Http/Server/Error.hs#L801-L807

## Advantages

1. If we make any breaking changes to the API error type, the compiler will warn us to update the test suite.
2. Someone browsing the integration tests can easily jump to the definition of the error type, or to the definitions of any of the constructors used.
3. We no longer need to manually keep two copies of an interpolated string function in sync with one another.

## Method

To achieve this, we introduce the following structured error type:
```haskell
data ApiErrorSharedWalletNoSuchCosigner = ApiErrorSharedWalletNoSuchCosigner
    { cosignerIndex
        :: !ApiCosignerIndex
    , credentialType
        :: !ApiCredentialType
    }
    deriving (Data, Eq, Generic, Show, Typeable)
    deriving (FromJSON, ToJSON)
        via DefaultRecord ApiErrorSharedWalletNoSuchCosigner
    deriving anyclass NFData
```
And add it as a parameter to the relevant constructor of ApiErrorInfo:
```patch
lib/wallet/api/http/Cardano/Wallet/Api/Types/Error.hs

  data ApiErrorInfo
      = ...
      | ...
-     | SharedWalletNoSuchCosigner
+     | SharedWalletNoSuchCosigner !ApiErrorSharedWalletNoSuchCosigner
      | ...
```
When errors of this type are encoded as JSON, this results in objects of the following format:
```json
{ "code": "shared_wallet_no_such_cosigner"
, "info":
  { "cosigner_index": 182
  , "credential_type": "delegation"
  }
, "message": "It looks like you've..."
}
```

## Future Work

This PR serves as a demonstration of this technique, and only converts one particular error type. We could use this method to remove all duplicate interpolated error messages from our API integration test suite.

Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
iohk-bors bot added a commit that referenced this pull request Jan 17, 2023
3693: Machine-readable shared wallet API errors. r=jonathanknowles a=jonathanknowles

## Issue Number

Follow-on from review of #3676.

## Summary

This PR removes an **interpolated string equality check** from our API integration test suite, and replaces it an equality check that uses **`decodeErrorInfo`** in conjunction with an **API error record**:

```patch
lib/wallet/integration/src/Test/Integration/Scenario/API/Shared/Wallets.hs
 
-     expectErrorMessage (errMsg403NoSuchCosigner (toText Payment) 7) rPatch5
+     decodeErrorInfo rPatch5 `shouldBe` SharedWalletNoSuchCosigner
+         ApiErrorSharedWalletNoSuchCosigner
+             { cosignerIndex = ApiCosignerIndex 7
+             , credentialType = ApiCredentialType Payment
+             }
```
```patch
lib/wallet/integration/src/Test/Integration/Framework/TestData.hs
 
- errMsg403NoSuchCosigner :: Text -> Int -> String
- errMsg403NoSuchCosigner cred cosigner = unwords
-     [ "It looks like you've tried to add a cosigner key to a"
-     , "shared wallet's"
-     , unpack cred
-     , "template for a non-existing cosigner index:"
-     , show cosigner
-     ]
```
The above definition of `errMsg403NoCosigner` (now removed) was essentially a **duplicate** of an identical interpolated string in `Http.Server.Error`:

https://github.com/input-output-hk/cardano-wallet/blob/1263e6ed8c486f31ed75219b59a8e5fc6af577de/lib/wallet/api/http/Cardano/Wallet/Api/Http/Server/Error.hs#L801-L807

## Advantages

1. If we make any breaking changes to the API error type, the compiler will warn us to update the test suite.
2. Someone browsing the integration tests can easily jump to the definition of the error type, or to the definitions of any of the constructors used.
3. We no longer need to manually keep two copies of an interpolated string function in sync with one another.

## Method

To achieve this, we introduce the following structured error type:
```haskell
data ApiErrorSharedWalletNoSuchCosigner = ApiErrorSharedWalletNoSuchCosigner
    { cosignerIndex
        :: !ApiCosignerIndex
    , credentialType
        :: !ApiCredentialType
    }
    deriving (Data, Eq, Generic, Show, Typeable)
    deriving (FromJSON, ToJSON)
        via DefaultRecord ApiErrorSharedWalletNoSuchCosigner
    deriving anyclass NFData
```
And add it as a parameter to the relevant constructor of ApiErrorInfo:
```patch
lib/wallet/api/http/Cardano/Wallet/Api/Types/Error.hs

  data ApiErrorInfo
      = ...
      | ...
-     | SharedWalletNoSuchCosigner
+     | SharedWalletNoSuchCosigner !ApiErrorSharedWalletNoSuchCosigner
      | ...
```
When errors of this type are encoded as JSON, this results in objects of the following format:
```json
{ "code": "shared_wallet_no_such_cosigner"
, "info":
  { "cosigner_index": 182
  , "credential_type": "delegation"
  }
, "message": "It looks like you've..."
}
```

## Future Work

This PR serves as a demonstration of this technique, and only converts one particular error type. We could use this method to remove all duplicate interpolated error messages from our API integration test suite.

Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io>
WilliamKingNoel-Bot pushed a commit that referenced this pull request Jan 17, 2023
…jonathanknowles a=jonathanknowles ## Issue Number Follow-on from review of #3676.
 
 ## Summary
 
 This PR removes an **interpolated string equality check** from our API integration test suite, and replaces it an equality check that uses **`decodeErrorInfo`** in conjunction with an **API error record**:
 
 ```patch
 lib/wallet/integration/src/Test/Integration/Scenario/API/Shared/Wallets.hs
 
 - expectErrorMessage (errMsg403NoSuchCosigner (toText Payment) 7) rPatch5
 + decodeErrorInfo rPatch5 `shouldBe` SharedWalletNoSuchCosigner
 + ApiErrorSharedWalletNoSuchCosigner
 + { cosignerIndex = ApiCosignerIndex 7
 + , credentialType = ApiCredentialType Payment
 + }
 ```
 ```patch
 lib/wallet/integration/src/Test/Integration/Framework/TestData.hs
 
 - errMsg403NoSuchCosigner :: Text -> Int -> String
 - errMsg403NoSuchCosigner cred cosigner = unwords
 - [ "It looks like you've tried to add a cosigner key to a"
 - , "shared wallet's"
 - , unpack cred
 - , "template for a non-existing cosigner index:"
 - , show cosigner
 - ]
 ```
 The above definition of `errMsg403NoCosigner` (now removed) was essentially a **duplicate** of an identical interpolated string in `Http.Server.Error`:
 
 https://github.com/input-output-hk/cardano-wallet/blob/1263e6ed8c486f31ed75219b59a8e5fc6af577de/lib/wallet/api/http/Cardano/Wallet/Api/Http/Server/Error.hs#L801-L807
 
 ## Advantages
 
 1. If we make any breaking changes to the API error type, the compiler will warn us to update the test suite.
 2. Someone browsing the integration tests can easily jump to the definition of the error type, or to the definitions of any of the constructors used.
 3. We no longer need to manually keep two copies of an interpolated string function in sync with one another.
 
 ## Method
 
 To achieve this, we introduce the following structured error type:
 ```haskell
 data ApiErrorSharedWalletNoSuchCosigner = ApiErrorSharedWalletNoSuchCosigner
 { cosignerIndex
 :: !ApiCosignerIndex
 , credentialType
 :: !ApiCredentialType
 }
 deriving (Data, Eq, Generic, Show, Typeable)
 deriving (FromJSON, ToJSON)
 via DefaultRecord ApiErrorSharedWalletNoSuchCosigner
 deriving anyclass NFData
 ```
 And add it as a parameter to the relevant constructor of ApiErrorInfo:
 ```patch
 lib/wallet/api/http/Cardano/Wallet/Api/Types/Error.hs
 
 data ApiErrorInfo
 = ...
 | ...
 - | SharedWalletNoSuchCosigner
 + | SharedWalletNoSuchCosigner !ApiErrorSharedWalletNoSuchCosigner
 | ...
 ```
 When errors of this type are encoded as JSON, this results in objects of the following format:
 ```json
 { "code": "shared_wallet_no_such_cosigner"
 , "info":
 { "cosigner_index": 182
 , "credential_type": "delegation"
 }
 , "message": "It looks like you've..."
 }
 ```
 
 ## Future Work
 
 This PR serves as a demonstration of this technique, and only converts one particular error type. We could use this method to remove all duplicate interpolated error messages from our API integration test suite. Co-authored-by: Jonathan Knowles <jonathan.knowles@iohk.io> Source commit: 76fdaf9
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