1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 18:00:18 +01:00

Ensure transaction activity log supports EIP-1559 (#11794)

* Ensure transaction activity log supports EIP-1559

* unit test fix

* Add estimated base fee to swaps txMeta

* fix lint and tests

* Improve activity log copy
This commit is contained in:
Dan J Miller 2021-08-06 19:48:53 -02:30 committed by Dan Miller
parent 9566cd09c0
commit de388a7b1c
10 changed files with 103 additions and 19 deletions

View File

@ -2499,7 +2499,7 @@
"message": "transaction"
},
"transactionCancelAttempted": {
"message": "Transaction cancel attempted with gas fee of $1 at $2"
"message": "Transaction cancel attempted with estimated gas fee of $1 at $2"
},
"transactionCancelSuccess": {
"message": "Transaction successfully cancelled at $2"
@ -2557,10 +2557,10 @@
"message": "Total Gas Fee"
},
"transactionResubmitted": {
"message": "Transaction resubmitted with gas fee increased to $1 at $2"
"message": "Transaction resubmitted with estimated gas fee increased to $1 at $2"
},
"transactionSubmitted": {
"message": "Transaction submitted with gas fee of $1 at $2."
"message": "Transaction submitted with estimated gas fee of $1 at $2."
},
"transactionUpdated": {
"message": "Transaction updated at $2."

View File

@ -693,7 +693,11 @@ export default class TransactionController extends EventEmitter {
* params instead of allowing this method to generate them
* @returns {txMeta}
*/
async createCancelTransaction(originalTxId, customGasSettings) {
async createCancelTransaction(
originalTxId,
customGasSettings,
{ estimatedBaseFee } = {},
) {
const originalTxMeta = this.txStateManager.getTransaction(originalTxId);
const { txParams } = originalTxMeta;
const { from, nonce } = txParams;
@ -723,6 +727,10 @@ export default class TransactionController extends EventEmitter {
type: TRANSACTION_TYPES.CANCEL,
});
if (estimatedBaseFee) {
newTxMeta.estimatedBaseFee = estimatedBaseFee;
}
this.addTransaction(newTxMeta);
await this.approveTransaction(newTxMeta.id);
return newTxMeta;
@ -738,7 +746,11 @@ export default class TransactionController extends EventEmitter {
* params instead of allowing this method to generate them
* @returns {txMeta}
*/
async createSpeedUpTransaction(originalTxId, customGasSettings) {
async createSpeedUpTransaction(
originalTxId,
customGasSettings,
{ estimatedBaseFee } = {},
) {
const originalTxMeta = this.txStateManager.getTransaction(originalTxId);
const { txParams } = originalTxMeta;
@ -758,6 +770,10 @@ export default class TransactionController extends EventEmitter {
type: TRANSACTION_TYPES.RETRY,
});
if (estimatedBaseFee) {
newTxMeta.estimatedBaseFee = estimatedBaseFee;
}
this.addTransaction(newTxMeta);
await this.approveTransaction(newTxMeta.id);
return newTxMeta;

View File

@ -2099,10 +2099,15 @@ export default class MetamaskController extends EventEmitter {
* instead of allowing this method to generate them
* @returns {Object} MetaMask state
*/
async createCancelTransaction(originalTxId, customGasSettings) {
async createCancelTransaction(
originalTxId,
customGasSettings,
newTxMetaProps,
) {
await this.txController.createCancelTransaction(
originalTxId,
customGasSettings,
newTxMetaProps,
);
const state = await this.getState();
return state;
@ -2119,10 +2124,15 @@ export default class MetamaskController extends EventEmitter {
* instead of allowing this method to generate them
* @returns {Object} MetaMask state
*/
async createSpeedUpTransaction(originalTxId, customGasSettings) {
async createSpeedUpTransaction(
originalTxId,
customGasSettings,
newTxMetaProps,
) {
await this.txController.createSpeedUpTransaction(
originalTxId,
customGasSettings,
newTxMetaProps,
);
const state = await this.getState();
return state;

View File

@ -90,6 +90,7 @@ export default function EditGasPopover({
onManualChange,
balanceError,
estimatesUnavailableWarning,
estimatedBaseFee,
} = useGasFeeInputs(defaultEstimateToUse, transaction, minimumGasLimit, mode);
/**
@ -139,10 +140,18 @@ export default function EditGasPopover({
switch (mode) {
case EDIT_GAS_MODES.CANCEL:
dispatch(createCancelTransaction(transaction.id, newGasSettings));
dispatch(
createCancelTransaction(transaction.id, newGasSettings, {
estimatedBaseFee,
}),
);
break;
case EDIT_GAS_MODES.SPEED_UP:
dispatch(createSpeedUpTransaction(transaction.id, newGasSettings));
dispatch(
createSpeedUpTransaction(transaction.id, newGasSettings, {
estimatedBaseFee,
}),
);
break;
case EDIT_GAS_MODES.MODIFY_IN_PLACE:
dispatch(updateTransaction(updatedTxMeta));
@ -170,6 +179,7 @@ export default function EditGasPopover({
maxPriorityFeePerGas,
networkAndAccountSupport1559,
estimateToUse,
estimatedBaseFee,
]);
let title = t('editGasTitle');

View File

@ -1,5 +1,6 @@
import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction';
import { getHexGasTotal } from '../../../helpers/utils/confirm-tx.util';
import { sumHexes } from '../../../helpers/utils/transactions.util';
import {
// event constants
@ -22,6 +23,7 @@ import {
const STATUS_PATH = '/status';
const GAS_PRICE_PATH = '/txParams/gasPrice';
const GAS_LIMIT_PATH = '/txParams/gas';
const ESTIMATE_BASE_FEE_PATH = '/estimatedBaseFee';
// op constants
const REPLACE_OP = 'replace';
@ -53,11 +55,20 @@ export function getActivities(transaction, isFirstTransaction = false) {
metamaskNetworkId,
hash,
history = [],
txParams: { gas: paramsGasLimit, gasPrice: paramsGasPrice },
xReceipt: { status } = {},
txParams: {
gas: paramsGasLimit,
gasPrice: paramsGasPrice,
maxPriorityFeePerGas: paramsMaxPriorityFeePerGas,
},
txReceipt: { status } = {},
type,
estimatedBaseFee: paramsEstimatedBaseFee,
} = transaction;
const paramsEip1559Price =
paramsEstimatedBaseFee &&
paramsMaxPriorityFeePerGas &&
sumHexes(paramsEstimatedBaseFee, paramsMaxPriorityFeePerGas);
let cachedGasLimit = '0x0';
let cachedGasPrice = '0x0';
@ -66,13 +77,19 @@ export function getActivities(transaction, isFirstTransaction = false) {
if (index === 0 && !Array.isArray(base) && base.txParams) {
const {
time: timestamp,
txParams: { value, gas = '0x0', gasPrice = '0x0' } = {},
estimatedBaseFee,
txParams: { value, gas = '0x0', gasPrice, maxPriorityFeePerGas } = {},
} = base;
const eip1559Price =
estimatedBaseFee &&
maxPriorityFeePerGas &&
sumHexes(estimatedBaseFee, maxPriorityFeePerGas);
// The cached gas limit and gas price are used to display the gas fee in the activity log. We
// need to cache these values because the status update history events don't provide us with
// the latest gas limit and gas price.
cachedGasLimit = gas;
cachedGasPrice = gasPrice;
cachedGasPrice = eip1559Price || gasPrice || '0x0';
if (isFirstTransaction) {
return acc.concat({
@ -95,14 +112,16 @@ export function getActivities(transaction, isFirstTransaction = false) {
// timestamp, the first sub-entry in a history entry should.
const timestamp = entryTimestamp || (base[0] && base[0].timestamp);
if (path in eventPathsHash && op === REPLACE_OP) {
const isAddBaseFee = path === ESTIMATE_BASE_FEE_PATH && op === 'add';
if ((path in eventPathsHash && op === REPLACE_OP) || isAddBaseFee) {
switch (path) {
case STATUS_PATH: {
const gasFee =
cachedGasLimit === '0x0' && cachedGasPrice === '0x0'
? getHexGasTotal({
gasLimit: paramsGasLimit,
gasPrice: paramsGasPrice,
gasPrice: paramsEip1559Price || paramsGasPrice,
})
: getHexGasTotal({
gasLimit: cachedGasLimit,
@ -144,7 +163,8 @@ export function getActivities(transaction, isFirstTransaction = false) {
// previously submitted event. These events happen when the gas limit and gas price is
// changed at the confirm screen.
case GAS_PRICE_PATH:
case GAS_LIMIT_PATH: {
case GAS_LIMIT_PATH:
case ESTIMATE_BASE_FEE_PATH: {
const lastEvent = events[events.length - 1] || {};
const { lastEventKey } = lastEvent;
@ -152,6 +172,12 @@ export function getActivities(transaction, isFirstTransaction = false) {
cachedGasLimit = value;
} else if (path === GAS_PRICE_PATH) {
cachedGasPrice = value;
} else if (path === ESTIMATE_BASE_FEE_PATH) {
cachedGasPrice = paramsEip1559Price || base?.txParams?.gasPrice;
lastEvent.value = getHexGasTotal({
gasLimit: paramsGasLimit,
gasPrice: cachedGasPrice,
});
}
if (

View File

@ -674,19 +674,21 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => {
let maxFeePerGas;
let maxPriorityFeePerGas;
let baseAndPriorityFeePerGas;
let decEstimatedBaseFee;
if (networkAndAccountSupports1559) {
const {
high: { suggestedMaxFeePerGas, suggestedMaxPriorityFeePerGas },
estimatedBaseFee = '0',
} = getGasFeeEstimates(state);
decEstimatedBaseFee = decGWEIToHexWEI(estimatedBaseFee);
maxFeePerGas =
customMaxFeePerGas || decGWEIToHexWEI(suggestedMaxFeePerGas);
maxPriorityFeePerGas =
customMaxPriorityFeePerGas ||
decGWEIToHexWEI(suggestedMaxPriorityFeePerGas);
baseAndPriorityFeePerGas = addHexes(
decGWEIToHexWEI(estimatedBaseFee),
decEstimatedBaseFee,
maxPriorityFeePerGas,
);
}
@ -816,6 +818,7 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => {
updateTransaction(
{
...approveTxMeta,
estimatedBaseFee: decEstimatedBaseFee,
type: TRANSACTION_TYPES.SWAP_APPROVAL,
sourceTokenSymbol: sourceTokenInfo.symbol,
},
@ -855,6 +858,7 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => {
updateTransaction(
{
...tradeTxMeta,
estimatedBaseFee: decEstimatedBaseFee,
sourceTokenSymbol: sourceTokenInfo.symbol,
destinationTokenSymbol: destinationTokenInfo.symbol,
type: TRANSACTION_TYPES.SWAP,

View File

@ -544,5 +544,6 @@ export function useGasFeeInputs(
},
balanceError,
estimatesUnavailableWarning,
estimatedBaseFee: gasSettings.baseFeePerGas,
};
}

View File

@ -111,6 +111,7 @@ export default class ConfirmTransactionBase extends Component {
useNativeCurrencyAsPrimaryCurrency: PropTypes.bool,
maxFeePerGas: PropTypes.string,
maxPriorityFeePerGas: PropTypes.string,
baseFeePerGas: PropTypes.string,
};
state = {
@ -612,6 +613,7 @@ export default class ConfirmTransactionBase extends Component {
updateCustomNonce,
maxFeePerGas,
maxPriorityFeePerGas,
baseFeePerGas,
} = this.props;
const { submitting } = this.state;
@ -619,6 +621,10 @@ export default class ConfirmTransactionBase extends Component {
return;
}
if (baseFeePerGas) {
txData.estimatedBaseFee = baseFeePerGas;
}
if (maxFeePerGas) {
txData.txParams = {
...txData.txParams,

View File

@ -200,6 +200,7 @@ const mapStateToProps = (state, ownProps) => {
useNativeCurrencyAsPrimaryCurrency,
maxFeePerGas: gasEstimationObject.maxFeePerGas,
maxPriorityFeePerGas: gasEstimationObject.maxPriorityFeePerGas,
baseFeePerGas: gasEstimationObject.baseFeePerGas,
};
};

View File

@ -1340,7 +1340,11 @@ export function clearPendingTokens() {
};
}
export function createCancelTransaction(txId, customGasSettings) {
export function createCancelTransaction(
txId,
customGasSettings,
newTxMetaProps,
) {
log.debug('background.cancelTransaction');
let newTxId;
@ -1349,6 +1353,7 @@ export function createCancelTransaction(txId, customGasSettings) {
background.createCancelTransaction(
txId,
customGasSettings,
newTxMetaProps,
(err, newState) => {
if (err) {
dispatch(displayWarning(err.message));
@ -1368,7 +1373,11 @@ export function createCancelTransaction(txId, customGasSettings) {
};
}
export function createSpeedUpTransaction(txId, customGasSettings) {
export function createSpeedUpTransaction(
txId,
customGasSettings,
newTxMetaProps,
) {
log.debug('background.createSpeedUpTransaction');
let newTx;
@ -1377,6 +1386,7 @@ export function createSpeedUpTransaction(txId, customGasSettings) {
background.createSpeedUpTransaction(
txId,
customGasSettings,
newTxMetaProps,
(err, newState) => {
if (err) {
dispatch(displayWarning(err.message));