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

[DDW-575] Handle 'transaction is too big' transaction error #1308

Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Changelog

### Features

- Implemented a handle for the 'transaction is too big' transaction error ([PR 1308](https://github.com/input-output-hk/daedalus/pull/1308))
- Structured the Daedalus logs in the same format as the Cardano logs, which follows the structured logging specification ([PR 1299](https://github.com/input-output-hk/daedalus/pull/1299))
- Implemented an extra explanation line in the Create Paper Wallet Certificate dialog ([PR 1309](https://github.com/input-output-hk/daedalus/pull/1309))
- Improve performance of rendering huge lists of transactions and addresses ([PR 1276](https://github.com/input-output-hk/daedalus/pull/1276), [PR 1303](https://github.com/input-output-hk/daedalus/pull/1303), [PR 1305](https://github.com/input-output-hk/daedalus/pull/1305), ([PR 1306](https://github.com/input-output-hk/daedalus/pull/1306)))
Expand Down
9 changes: 8 additions & 1 deletion source/renderer/app/api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ import {
NotEnoughFundsForTransactionFeesError,
NotEnoughFundsForTransactionError,
NotEnoughMoneyToSendError,
RedeemAdaError
RedeemAdaError,
TooBigTransactionError,
} from './transactions/errors';
import type { FaultInjectionIpcRequest } from '../../../common/types/cardano-node.types';

Expand Down Expand Up @@ -390,6 +391,9 @@ export default class AdaApi {
if (error.message === 'CannotCreateAddress') {
throw new IncorrectSpendingPasswordError();
}
if (error.message === 'TooBigTransaction') {
throw new TooBigTransactionError();
}
throw new GenericApiError();
}
};
Expand Down Expand Up @@ -455,6 +459,9 @@ export default class AdaApi {
throw new NotEnoughFundsForTransactionError();
}
}
if (error.message === 'TooBigTransaction') {
thedanheller marked this conversation as resolved.
Show resolved Hide resolved
throw new TooBigTransactionError();
}
throw new GenericApiError();
}
};
Expand Down
41 changes: 35 additions & 6 deletions source/renderer/app/api/transactions/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const messages = defineMessages({
},
notAllowedToSendMoneyToRedeemAddressError: {
id: 'api.errors.NotAllowedToSendMoneyToRedeemAddressError',
defaultMessage: '!!!It is not allowed to send money to Ada redemption address.',
description: '"It is not allowed to send money to Ada redemption address." error message.'
defaultMessage: '!!!It is not allowed to send money to ada redemption address.',
description: '"It is not allowed to send money to ada redemption address." error message.'
},
notEnoughMoneyToSendError: {
id: 'api.errors.NotEnoughMoneyToSendError',
Expand All @@ -29,19 +29,35 @@ const messages = defineMessages({
},
notEnoughFundsForTransactionFeesError: {
id: 'api.errors.NotEnoughFundsForTransactionFeesError',
defaultMessage: '!!!Not enough Ada for fees. Try sending a smaller amount.',
description: '"Not enough Ada for fees. Try sending a smaller amount." error message'
defaultMessage: '!!!Not enough ada for fees. Try sending a smaller amount.',
description: '"Not enough ada for fees. Try sending a smaller amount." error message'
},
notEnoughFundsForTransactionError: {
id: 'api.errors.NotEnoughFundsForTransactionError',
defaultMessage: '!!!Not enough Ada. Try sending a smaller amount.',
description: '"Not enough Ada. Try sending a smaller amount." error message'
defaultMessage: '!!!Not enough ada . Try sending a smaller amount.',
description: '"Not enough ada . Try sending a smaller amount." error message'
},
canNotCalculateTransactionFeesError: {
id: 'api.errors.CanNotCalculateTransactionFeesError',
defaultMessage: '!!!Cannot calculate fees while there are pending transactions.',
description: '"Cannot calculate fees while there are pending transactions." error message'
},
tooBigTransactionError: {
id: 'api.errors.TooBigTransactionError',
defaultMessage: '!!!Amount too big due to wallet fragmentation.',
description: '"Amount too big due to wallet fragmentation" error message.'
},
tooBigTransactionErrorLinkLabel: {
id: 'api.errors.TooBigTransactionErrorLinkLabel',
defaultMessage: '!!!Learn more.',
description: '"Amount too big due to wallet fragmentation" error link label.'
},
tooBigTransactionErrorLinkURL: {
id: 'api.errors.TooBigTransactionErrorLinkURL',
defaultMessage: '!!!https://iohk.zendesk.com/hc/en-us/articles/360017733353',
description: '"Amount too big due to wallet fragmentation" error link URL.'
},

});

export class NotAllowedToSendMoneyToSameAddressError extends LocalizableError {
Expand Down Expand Up @@ -115,3 +131,16 @@ export class CanNotCalculateTransactionFeesError extends LocalizableError {
});
}
}

export class TooBigTransactionError extends LocalizableError {
constructor() {
super({
id: messages.tooBigTransactionError.id,
defaultMessage: messages.tooBigTransactionError.defaultMessage,
values: {
linkLabel: messages.tooBigTransactionErrorLinkLabel,
linkURL: messages.tooBigTransactionErrorLinkURL,
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import LocalizableError from '../../i18n/LocalizableError';
import styles from './WalletSendConfirmationDialog.scss';
import { FORM_VALIDATION_DEBOUNCE_WAIT } from '../../config/timingConfig';
import { submitOnEnter } from '../../utils/form';
import { FormattedHTMLMessageWithLink } from '../widgets/FormattedHTMLMessageWithLink';

export const messages = defineMessages({
dialogTitle: {
Expand Down Expand Up @@ -73,6 +74,7 @@ type Props = {
onSubmit: Function,
amountToNaturalUnits: (amountWithFractions: string) => string,
onCancel: Function,
onExternalLinkClick: Function,
isSubmitting: boolean,
error: ?LocalizableError,
currencyUnit: string,
Expand Down Expand Up @@ -138,7 +140,8 @@ export default class WalletSendConfirmationDialog extends Component<Props> {
transactionFee,
isSubmitting,
error,
currencyUnit
currencyUnit,
onExternalLinkClick
} = this.props;

const confirmButtonClasses = classnames([
Expand All @@ -160,6 +163,19 @@ export default class WalletSendConfirmationDialog extends Component<Props> {
},
];

let errorElement = null;
if (error) {
const errorHasLink = !!error.values.linkLabel;
errorElement = errorHasLink
? (
<FormattedHTMLMessageWithLink
message={error}
onExternalLinkClick={onExternalLinkClick}
/>
)
: this.context.intl.formatMessage(error);
}

return (
<Dialog
title={intl.formatMessage(messages.dialogTitle)}
Expand Down Expand Up @@ -214,7 +230,7 @@ export default class WalletSendConfirmationDialog extends Component<Props> {
) : null}
</div>

{error ? <p className={styles.error}>{intl.formatMessage(error)}</p> : null}
{errorElement ? <p className={styles.error}>{errorElement}</p> : null}

</Dialog>
);
Expand Down
19 changes: 16 additions & 3 deletions source/renderer/app/components/wallet/WalletSendForm.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @flow
import React, { Component } from 'react';
import type { Node } from 'react';
import { observer } from 'mobx-react';
import classnames from 'classnames';
import { Button } from 'react-polymorph/lib/components/Button';
Expand All @@ -20,6 +21,7 @@ import WalletSendConfirmationDialog from './WalletSendConfirmationDialog';
import WalletSendConfirmationDialogContainer from '../../containers/wallet/dialogs/WalletSendConfirmationDialogContainer';
import { formattedAmountToBigNumber, formattedAmountToNaturalUnits, formattedAmountToLovelace } from '../../utils/formatters';
import { FORM_VALIDATION_DEBOUNCE_WAIT } from '../../config/timingConfig';
import { FormattedHTMLMessageWithLink } from '../widgets/FormattedHTMLMessageWithLink';

export const messages = defineMessages({
titleLabel: {
Expand Down Expand Up @@ -100,13 +102,14 @@ type Props = {
addressValidator: Function,
openDialogAction: Function,
isDialogOpen: Function,
onExternalLinkClick?: Function,
isRestoreActive: boolean,
};

type State = {
isTransactionFeeCalculated: boolean,
transactionFee: BigNumber,
transactionFeeError: ?string,
transactionFeeError: ?string | ?Node,
};

@observer
Expand Down Expand Up @@ -216,7 +219,7 @@ export default class WalletSendForm extends Component<Props, State> {
const { intl } = this.context;
const {
currencyUnit, currencyMaxIntegerDigits, currencyMaxFractionalDigits,
isDialogOpen, isRestoreActive,
isDialogOpen, isRestoreActive, onExternalLinkClick
} = this.props;
const { isTransactionFeeCalculated, transactionFee, transactionFeeError } = this.state;
const amountField = form.$('amount');
Expand Down Expand Up @@ -305,6 +308,7 @@ export default class WalletSendForm extends Component<Props, State> {
transactionFee={fees}
amountToNaturalUnits={formattedAmountToNaturalUnits}
currencyUnit={currencyUnit}
onExternalLinkClick={onExternalLinkClick}
/>
) : null}

Expand Down Expand Up @@ -335,12 +339,21 @@ export default class WalletSendForm extends Component<Props, State> {
});
}
} catch (error) {
const errorHasLink = !!error.values.linkLabel;
const transactionFeeError = errorHasLink
? (
<FormattedHTMLMessageWithLink
message={error}
onExternalLinkClick={this.props.onExternalLinkClick}
/>
)
: this.context.intl.formatMessage(error);
if (this._isMounted) {
this._isCalculatingFee = false;
this.setState({
isTransactionFeeCalculated: false,
transactionFee: new BigNumber(0),
transactionFeeError: this.context.intl.formatMessage(error),
transactionFeeError,
});
}
}
Expand Down
7 changes: 7 additions & 0 deletions source/renderer/app/components/wallet/WalletSendForm.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
}
}


.syncingTransactionsText {
color: var(--theme-transactions-list-group-date-color);
font-family: var(--font-regular);
Expand All @@ -28,6 +29,12 @@
.receiverInput {
position: relative;
margin-bottom: 20px;

:global {
.SimpleFormField_error a {
color: var(--rp-formfield-error-text-color, rgba(222, 50, 38, 0.5));
}
}
}

.adaLabel {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,41 +36,28 @@ const messages = defineMessages({
},
instructionsRegular: {
id: 'wallet.redeem.dialog.instructions.regular',
defaultMessage: `!!!<p>To redeem your Ada, upload your certificate or copy and paste your redemption code from the certificate.
Below is an example of a redemption key. Your key will look similar:</p>
<p><strong>B_GQOAffMBeRIn6vh1hJmeOT3ViS_TmaT4XAHAfDVH0=</strong></p>
<p>If you upload a PDF file with your certificate, a redemption code will be automatically extracted.</p>
<p>If you upload an <strong>encrypted certificate</strong>, you will need to provide a <strong>{adaRedemptionPassphraseLength} word mnemonic
passphrase</strong> to decrypt your certificate and your redemption code will be automatically extracted.</p>`,
description: 'Detailed instructions for redeeming Ada from the regular vending',
defaultMessage: '!!!<p>To redeem your ada, upload your certificate or copy and paste your redemption code from the certificate. Below is an example of a redemption key. Your key will look similar:</p><p><strong>B_GQOAffMBeRIn6vh1hJmeOT3ViS_TmaT4XAHAfDVH0=</strong></p><p>If you upload a PDF file with your certificate, a redemption code will be automatically extracted.</p><p>If you upload an <strong>encrypted certificate</strong>, you will need to provide a <strong>{adaRedemptionPassphraseLength} word mnemonic passphrase</strong> to decrypt your certificate and your redemption code will be automatically extracted.</p>',
description: 'Detailed instructions for redeeming ada from the regular vending',
},
instructionsForceVended: {
id: 'wallet.redeem.dialog.instructions.forceVended',
defaultMessage: `!!!<p>To redeem your Ada, upload your certificate or copy and paste your redemption code from the certificate.
Below is an example of a redemption key. Your key will look similar:</p><p><strong>B_GQOAffMBeRIn6vh1hJmeOT3ViS_TmaT4XAHAfDVH0=</strong></p>
<p>If you upload a PDF file with your certificate, the redemption code will be automatically extracted.</p>
<p>If you upload an <strong>encrypted certificate</strong>, you will need to provide <strong>your email address, Ada passcode and Ada amount</strong>
to decrypt your certificate and your redemption code will be automatically extracted.</p>`,
description: 'Detailed instructions for redeeming Ada from the force vending',
defaultMessage: '!!!<p>To redeem your ada, upload your certificate or copy and paste your redemption code from the certificate. Below is an example of a redemption key. Your key will look similar:</p><p><strong>B_GQOAffMBeRIn6vh1hJmeOT3ViS_TmaT4XAHAfDVH0=</strong></p><p>If you upload a PDF file with your certificate, the redemption code will be automatically extracted.</p><p>If you upload an <strong>encrypted certificate</strong>, you will need to provide <strong>your email address, ada passcode and ada amount<strong> to decrypt your certificate and your redemption code will be automatically extracted.</p>',
description: 'Detailed instructions for redeeming ada from the force vending',
},
instructionsRecoveryRegular: {
id: 'wallet.redeem.dialog.instructions.recoveryRegular',
defaultMessage: `!!!<p>To redeem your Ada using the regularly vended certificate from the recovery service, please upload your encrypted certificate and enter a {adaRedemptionPassphraseLength}-word mnemonic passphrase.</p>
>After you upload your <strong>encrypted certificate</strong> and enter your <strong>{adaRedemptionPassphraseLength}-word mnemonic passphrase</strong>, your redemption key will be automatically extracted and you will be able to redeem your Ada to the selected wallet.</p>`,
description: 'Detailed instructions for redeeming Ada from the regular vending via Recovery service',
defaultMessage: '!!!<p>To redeem your ada using the regularly vended certificate from the recovery service, please upload your encrypted certificate and enter a {adaRedemptionPassphraseLength}-word mnemonic passphrase.</p><p>After you upload your <strong>encrypted certificate</strong> and enter your <strong>{adaRedemptionPassphraseLength}-word mnemonic passphrase</strong>, your redemption key will be automatically extracted and you will be able to redeem your ada to the selected wallet.</p>',
description: 'Detailed instructions for redeeming ada from the regular vending via Recovery service',
},
instructionsRecoveryForceVended: {
id: 'wallet.redeem.dialog.instructions.recoveryForceVended',
defaultMessage: `!!!<p>To redeem your Ada using the force vended certificate from the recovery service, please upload your encrypted certificate and enter the decryption key. Your decryption key should look like this:</p>
><strong>qXQWDxI3JrlFRtC4SeQjeGzLbVXWBomYPbNO1Vfm1T4=</strong></p>
>After you upload your <strong>encrypted certificate</strong> and enter your <strong>decryption key</strong>, your redemption key will be automatically extracted and you will be able to redeem your Ada to the selected wallet.</p>`,
description: 'Detailed instructions for redeeming Ada from the force vending via Recovery service',
defaultMessage: '!!!<p>To redeem your ada using the force vended certificate from the recovery service, please upload your encrypted certificate and enter the decryption key. Your decryption key should look like this:</p><p><strong>qXQWDxI3JrlFRtC4SeQjeGzLbVXWBomYPbNO1Vfm1T4=</strong></p><p>After you upload your <strong>encrypted certificate</strong> and enter your <strong>decryption key</strong>, your redemption key will be automatically extracted and you will be able to redeem your ada to the selected wallet.</p>',
description: 'Detailed instructions for redeeming ada from the force vending via Recovery service',
},
instructionsPaperVended: {
id: 'wallet.redeem.dialog.instructions.paperVended',
defaultMessage: `!!!<p>To redeem your Ada, enter your shielded vending key from the certificate, choose a wallet
where Ada should be redeemed and enter {adaRedemptionPassphraseLength} word mnemonic passphrase.</p>`,
description: 'Detailed instructions for redeeming Ada from the paper vending',
defaultMessage: '!!!<p>To redeem your ada, enter your shielded vending key from the certificate, choose a wallet where ada should be redeemed and enter {adaRedemptionPassphraseLength} word mnemonic passphrase.</p>',
description: 'Detailed instructions for redeeming ada from the paper vending',
},
certificateLabel: {
id: 'wallet.redeem.dialog.certificateLabel',
Expand All @@ -85,12 +72,12 @@ where Ada should be redeemed and enter {adaRedemptionPassphraseLength} word mnem
walletSelectLabel: {
id: 'wallet.redeem.dialog.walletSelectLabel',
defaultMessage: '!!!Choose Wallet',
description: 'Label for the wallet select field on Ada redemption form'
description: 'Label for the wallet select field on ada redemption form'
},
passphraseLabel: {
id: 'wallet.redeem.dialog.passphraseLabel',
defaultMessage: '!!!Passphrase to Decrypt the Ada Voucher Certificate',
description: 'Label for the passphrase to decrypt Ada voucher certificate input'
defaultMessage: '!!!Passphrase to Decrypt the ada Voucher Certificate',
description: 'Label for the passphrase to decrypt ada voucher certificate input'
},
passphraseHint: {
id: 'wallet.redeem.dialog.passphraseHint',
Expand Down Expand Up @@ -150,7 +137,7 @@ where Ada should be redeemed and enter {adaRedemptionPassphraseLength} word mnem
submitLabel: {
id: 'wallet.redeem.dialog.submitLabel',
defaultMessage: '!!!Redeem your money',
description: 'Label for the "Ada redemption" dialog submit button.'
description: 'Label for the "Redeem your money" dialog submit button.'
},
emailLabel: {
id: 'wallet.redeem.dialog.emailLabel',
Expand All @@ -169,8 +156,8 @@ where Ada should be redeemed and enter {adaRedemptionPassphraseLength} word mnem
},
adaPasscodeHint: {
id: 'wallet.redeem.dialog.adaPasscodeHint',
defaultMessage: '!!!Enter your Ada passcode',
description: 'Hint for the Ada passcode input field.'
defaultMessage: '!!!Enter your ada passcode',
description: 'Hint for the ada passcode input field.'
},
adaAmountLabel: {
id: 'wallet.redeem.dialog.adaAmountLabel',
Expand All @@ -179,8 +166,8 @@ where Ada should be redeemed and enter {adaRedemptionPassphraseLength} word mnem
},
adaAmountHint: {
id: 'wallet.redeem.dialog.adaAmountHint',
defaultMessage: '!!!Enter your Ada amount',
description: 'Hint for the Ada amount input field.'
defaultMessage: '!!!Enter your ada amount',
description: 'Hint for the ada amount input field.'
},
spendingPasswordPlaceholder: {
id: 'wallet.redeem.dialog.spendingPasswordPlaceholder',
Expand Down
Loading