Skip to content

Commit

Permalink
fix: speedup cancellation
Browse files Browse the repository at this point in the history
fixes #7305
  • Loading branch information
shanejonas committed Mar 12, 2021
1 parent 90bfaf6 commit f696205
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 272 deletions.
4 changes: 2 additions & 2 deletions app/scripts/controllers/transactions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ export default class TransactionController extends EventEmitter {
* @param {string} [customGasPrice] - the hex value to use for the cancel transaction
* @returns {txMeta}
*/
async createCancelTransaction(originalTxId, customGasPrice) {
async createCancelTransaction(originalTxId, customGasPrice, customGasLimit) {
const originalTxMeta = this.txStateManager.getTx(originalTxId);
const { txParams } = originalTxMeta;
const { gasPrice: lastGasPrice, from, nonce } = txParams;
Expand All @@ -398,7 +398,7 @@ export default class TransactionController extends EventEmitter {
from,
to: from,
nonce,
gas: '0x5208',
gas: customGasLimit || '0x5208',
value: '0x0',
gasPrice: newGasPrice,
},
Expand Down
3 changes: 2 additions & 1 deletion app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -1858,10 +1858,11 @@ export default class MetamaskController extends EventEmitter {
* @param {string} [customGasPrice] - the hex value to use for the cancel transaction
* @returns {Object} MetaMask state
*/
async createCancelTransaction(originalTxId, customGasPrice) {
async createCancelTransaction(originalTxId, customGasPrice, customGasLimit) {
await this.txController.createCancelTransaction(
originalTxId,
customGasPrice,
customGasLimit,
);
const state = await this.getState();
return state;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const mapStateToProps = (state, ownProps) => {
const { currentNetworkTxList, send } = state.metamask;
const { modalState: { props: modalProps } = {} } = state.appState.modal || {};
const { txData = {} } = modalProps || {};
const { transaction = {} } = ownProps;
const { transaction = {}, onSubmit } = ownProps;
const selectedTransaction = currentNetworkTxList.find(
({ id }) => id === (transaction.id || txData.id),
);
Expand All @@ -77,7 +77,8 @@ const mapStateToProps = (state, ownProps) => {
value: sendToken ? '0x0' : send.amount,
};

const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = txParams;
const { gasPrice: currentGasPrice, gas: currentGasLimit } = txParams;
const value = ownProps.transaction?.txParams?.value || txParams.value;
const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice;
const customModalGasLimitInHex =
getCustomGasLimit(state) || currentGasLimit || '0x5208';
Expand Down Expand Up @@ -175,6 +176,7 @@ const mapStateToProps = (state, ownProps) => {
tokenBalance: getTokenBalance(state),
conversionRate,
value,
onSubmit,
};
};

Expand Down Expand Up @@ -253,6 +255,12 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
...otherDispatchProps,
...ownProps,
onSubmit: (gasLimit, gasPrice) => {
if (ownProps.onSubmit) {
dispatchHideSidebar();
dispatchCancelAndClose();
ownProps.onSubmit(gasLimit, gasPrice);
return;
}
if (isConfirm) {
const updatedTx = {
...transaction,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import assert from 'assert';
import proxyquire from 'proxyquire';
import sinon from 'sinon';
import { TRANSACTION_STATUSES } from '../../../../../../../shared/constants/transaction';

let mapStateToProps;
let mapDispatchToProps;
let mergeProps;

Expand All @@ -25,8 +23,7 @@ const sendActionSpies = {

proxyquire('../gas-modal-page-container.container.js', {
'react-redux': {
connect: (ms, md, mp) => {
mapStateToProps = ms;
connect: (_, md, mp) => {
mapDispatchToProps = md;
mergeProps = mp;
return () => ({});
Expand All @@ -48,225 +45,6 @@ proxyquire('../gas-modal-page-container.container.js', {
});

describe('gas-modal-page-container container', function () {
describe('mapStateToProps()', function () {
it('should map the correct properties to props', function () {
const baseMockState = {
appState: {
modal: {
modalState: {
props: {
hideBasic: true,
txData: {
id: 34,
},
},
},
},
},
metamask: {
send: {
gasLimit: '16',
gasPrice: '32',
amount: '64',
maxModeOn: false,
},
currentCurrency: 'abc',
conversionRate: 50,
usdConversionRate: 123,
preferences: {
showFiatInTestnets: false,
},
provider: {
type: 'mainnet',
chainId: '0x1',
},
currentNetworkTxList: [
{
id: 34,
txParams: {
gas: '0x1600000',
gasPrice: '0x3200000',
value: '0x640000000000000',
},
},
],
},
gas: {
basicEstimates: {
blockTime: 12,
safeLow: 2,
},
customData: {
limit: 'aaaaaaaa',
price: 'ffffffff',
},
priceAndTimeEstimates: [
{ gasprice: 3, expectedTime: 31 },
{ gasprice: 4, expectedTime: 62 },
{ gasprice: 5, expectedTime: 93 },
{ gasprice: 6, expectedTime: 124 },
],
},
confirmTransaction: {
txData: {
txParams: {
gas: '0x1600000',
gasPrice: '0x3200000',
value: '0x640000000000000',
},
},
},
};
const baseExpectedResult = {
balance: '0x0',
isConfirm: true,
customGasPrice: 4.294967295,
customGasLimit: 2863311530,
newTotalFiat: '637.41',
conversionRate: 50,
customModalGasLimitInHex: 'aaaaaaaa',
customModalGasPriceInHex: 'ffffffff',
customPriceIsExcessive: false,
customGasTotal: 'aaaaaaa955555556',
customPriceIsSafe: true,
gasPriceButtonGroupProps: {
buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4',
defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff',
gasButtonInfo: 'mockRenderableBasicEstimateData:4',
},
hideBasic: true,
infoRowProps: {
originalTotalFiat: '637.41',
originalTotalEth: '12.748189 ETH',
newTotalFiat: '637.41',
newTotalEth: '12.748189 ETH',
sendAmount: '0.45036 ETH',
transactionFee: '12.297829 ETH',
},
insufficientBalance: true,
isSpeedUp: false,
isRetry: false,
txId: 34,
isMainnet: true,
maxModeOn: false,
sendToken: null,
tokenBalance: '0x0',
transaction: {
id: 34,
},
value: '0x640000000000000',
};
const baseMockOwnProps = { transaction: { id: 34 } };
const tests = [
{
mockState: baseMockState,
expectedResult: baseExpectedResult,
mockOwnProps: baseMockOwnProps,
},
{
mockState: {
...baseMockState,
metamask: {
...baseMockState.metamask,
balance: '0xfffffffffffffffffffff',
},
},
expectedResult: {
...baseExpectedResult,
balance: '0xfffffffffffffffffffff',
insufficientBalance: false,
},
mockOwnProps: baseMockOwnProps,
},
{
mockState: baseMockState,
mockOwnProps: {
...baseMockOwnProps,
transaction: { id: 34, status: TRANSACTION_STATUSES.SUBMITTED },
},
expectedResult: {
...baseExpectedResult,
isSpeedUp: true,
transaction: { id: 34 },
},
},
{
mockState: {
...baseMockState,
metamask: {
...baseMockState.metamask,
preferences: {
...baseMockState.metamask.preferences,
showFiatInTestnets: false,
},
provider: {
...baseMockState.metamask.provider,
type: 'rinkeby',
chainId: '0x4',
},
},
},
mockOwnProps: baseMockOwnProps,
expectedResult: {
...baseExpectedResult,
infoRowProps: {
...baseExpectedResult.infoRowProps,
newTotalFiat: '',
},
isMainnet: false,
},
},
{
mockState: {
...baseMockState,
metamask: {
...baseMockState.metamask,
preferences: {
...baseMockState.metamask.preferences,
showFiatInTestnets: true,
},
provider: {
...baseMockState.metamask.provider,
type: 'rinkeby',
chainId: '0x4',
},
},
},
mockOwnProps: baseMockOwnProps,
expectedResult: {
...baseExpectedResult,
isMainnet: false,
},
},
{
mockState: {
...baseMockState,
metamask: {
...baseMockState.metamask,
preferences: {
...baseMockState.metamask.preferences,
showFiatInTestnets: true,
},
provider: {
...baseMockState.metamask.provider,
type: 'mainnet',
chainId: '0x1',
},
},
},
mockOwnProps: baseMockOwnProps,
expectedResult: baseExpectedResult,
},
];

let result;
tests.forEach(({ mockState, mockOwnProps, expectedResult }) => {
result = mapStateToProps(mockState, mockOwnProps);
assert.deepStrictEqual(result, expectedResult);
});
});
});

describe('mapDispatchToProps()', function () {
let dispatchSpy;
let mapDispatchToPropsObject;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,55 +1,53 @@
import { connect } from 'react-redux';
import { compose } from 'redux';
import { multiplyCurrencies } from '../../../../helpers/utils/conversion-util';
import withModalProps from '../../../../helpers/higher-order-components/with-modal-props';
import { showModal, createCancelTransaction } from '../../../../store/actions';
import { getHexGasTotal } from '../../../../helpers/utils/confirm-tx.util';
import { addHexPrefix } from '../../../../../../app/scripts/lib/util';
import CancelTransaction from './cancel-transaction.component';

const mapStateToProps = (state, ownProps) => {
const { metamask } = state;
const { transactionId, originalGasPrice } = ownProps;
const {
transactionId,
originalGasPrice,
newGasFee,
defaultNewGasPrice,
gasLimit,
} = ownProps;
const { currentNetworkTxList } = metamask;
const transaction = currentNetworkTxList.find(
({ id }) => id === transactionId,
);
const transactionStatus = transaction ? transaction.status : '';

const defaultNewGasPrice = addHexPrefix(
multiplyCurrencies(originalGasPrice, 1.1, {
toNumericBase: 'hex',
multiplicandBase: 16,
multiplierBase: 10,
}),
);

const newGasFee = getHexGasTotal({
gasPrice: defaultNewGasPrice,
gasLimit: '0x5208',
});

return {
transactionId,
transactionStatus,
originalGasPrice,
defaultNewGasPrice,
newGasFee,
gasLimit,
};
};

const mapDispatchToProps = (dispatch) => {
return {
createCancelTransaction: (txId, customGasPrice) => {
return dispatch(createCancelTransaction(txId, customGasPrice));
createCancelTransaction: (txId, customGasPrice, customGasLimit) => {
return dispatch(
createCancelTransaction(txId, customGasPrice, customGasLimit),
);
},
showTransactionConfirmedModal: () =>
dispatch(showModal({ name: 'TRANSACTION_CONFIRMED' })),
};
};

const mergeProps = (stateProps, dispatchProps, ownProps) => {
const { transactionId, defaultNewGasPrice, ...restStateProps } = stateProps;
const {
transactionId,
defaultNewGasPrice,
gasLimit,
...restStateProps
} = stateProps;
// eslint-disable-next-line no-shadow
const { createCancelTransaction, ...restDispatchProps } = dispatchProps;

Expand All @@ -58,7 +56,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
...restDispatchProps,
...ownProps,
createCancelTransaction: () =>
createCancelTransaction(transactionId, defaultNewGasPrice),
createCancelTransaction(transactionId, defaultNewGasPrice, gasLimit),
};
};

Expand Down
Loading

0 comments on commit f696205

Please sign in to comment.