mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-25 11:28:51 +01:00
fix issues relating to race conditions where draftTx does not exist (#15420)
* fix issues relating to race conditions where draftTx does not exist * add another fail safe for inflight initializations
This commit is contained in:
parent
fb191c865b
commit
f425e482e4
@ -603,7 +603,7 @@ export const initializeSendState = createAsyncThunk(
|
|||||||
// For instance, in the actions.js file we dispatch this action anytime the
|
// For instance, in the actions.js file we dispatch this action anytime the
|
||||||
// chain changes.
|
// chain changes.
|
||||||
if (!draftTransaction) {
|
if (!draftTransaction) {
|
||||||
thunkApi.rejectWithValue(
|
return thunkApi.rejectWithValue(
|
||||||
'draftTransaction not found, possibly not on send flow',
|
'draftTransaction not found, possibly not on send flow',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -678,6 +678,20 @@ export const initializeSendState = createAsyncThunk(
|
|||||||
// We have to keep the gas slice in sync with the send slice state
|
// We have to keep the gas slice in sync with the send slice state
|
||||||
// so that it'll be initialized correctly if the gas modal is opened.
|
// so that it'll be initialized correctly if the gas modal is opened.
|
||||||
await thunkApi.dispatch(setCustomGasLimit(gasLimit));
|
await thunkApi.dispatch(setCustomGasLimit(gasLimit));
|
||||||
|
|
||||||
|
// There may be a case where the send has been canceled by the user while
|
||||||
|
// the gas estimate is being computed. So we check again to make sure that
|
||||||
|
// a currentTransactionUUID exists and matches the previous tx.
|
||||||
|
const newState = thunkApi.getState();
|
||||||
|
if (
|
||||||
|
newState.send.currentTransactionUUID !== sendState.currentTransactionUUID
|
||||||
|
) {
|
||||||
|
return thunkApi.rejectWithValue(
|
||||||
|
`draftTransaction changed during initialization.
|
||||||
|
A new initializeSendState action must be dispatched.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
account,
|
account,
|
||||||
chainId: getCurrentChainId(state),
|
chainId: getCurrentChainId(state),
|
||||||
@ -1396,28 +1410,30 @@ const slice = createSlice({
|
|||||||
validateSendState: (state) => {
|
validateSendState: (state) => {
|
||||||
const draftTransaction =
|
const draftTransaction =
|
||||||
state.draftTransactions[state.currentTransactionUUID];
|
state.draftTransactions[state.currentTransactionUUID];
|
||||||
switch (true) {
|
if (draftTransaction) {
|
||||||
case Boolean(draftTransaction.amount.error):
|
switch (true) {
|
||||||
case Boolean(draftTransaction.gas.error):
|
case Boolean(draftTransaction.amount.error):
|
||||||
case Boolean(draftTransaction.asset.error):
|
case Boolean(draftTransaction.gas.error):
|
||||||
case draftTransaction.asset.type === ASSET_TYPES.TOKEN &&
|
case Boolean(draftTransaction.asset.error):
|
||||||
draftTransaction.asset.details === null:
|
case draftTransaction.asset.type === ASSET_TYPES.TOKEN &&
|
||||||
case state.stage === SEND_STAGES.ADD_RECIPIENT:
|
draftTransaction.asset.details === null:
|
||||||
case state.stage === SEND_STAGES.INACTIVE:
|
case state.stage === SEND_STAGES.ADD_RECIPIENT:
|
||||||
case state.gasEstimateIsLoading:
|
case state.stage === SEND_STAGES.INACTIVE:
|
||||||
case new BigNumber(draftTransaction.gas.gasLimit, 16).lessThan(
|
case state.gasEstimateIsLoading:
|
||||||
new BigNumber(state.gasLimitMinimum),
|
case new BigNumber(draftTransaction.gas.gasLimit, 16).lessThan(
|
||||||
):
|
new BigNumber(state.gasLimitMinimum),
|
||||||
draftTransaction.status = SEND_STATUSES.INVALID;
|
):
|
||||||
break;
|
draftTransaction.status = SEND_STATUSES.INVALID;
|
||||||
case draftTransaction.recipient.warning === 'loading':
|
break;
|
||||||
case draftTransaction.recipient.warning ===
|
case draftTransaction.recipient.warning === 'loading':
|
||||||
KNOWN_RECIPIENT_ADDRESS_WARNING &&
|
case draftTransaction.recipient.warning ===
|
||||||
draftTransaction.recipient.recipientWarningAcknowledged === false:
|
KNOWN_RECIPIENT_ADDRESS_WARNING &&
|
||||||
draftTransaction.status = SEND_STATUSES.INVALID;
|
draftTransaction.recipient.recipientWarningAcknowledged === false:
|
||||||
break;
|
draftTransaction.status = SEND_STATUSES.INVALID;
|
||||||
default:
|
break;
|
||||||
draftTransaction.status = SEND_STATUSES.VALID;
|
default:
|
||||||
|
draftTransaction.status = SEND_STATUSES.VALID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1512,26 +1528,28 @@ const slice = createSlice({
|
|||||||
state.selectedAccount.balance = action.payload.account.balance;
|
state.selectedAccount.balance = action.payload.account.balance;
|
||||||
const draftTransaction =
|
const draftTransaction =
|
||||||
state.draftTransactions[state.currentTransactionUUID];
|
state.draftTransactions[state.currentTransactionUUID];
|
||||||
draftTransaction.gas.gasLimit = action.payload.gasLimit;
|
if (draftTransaction) {
|
||||||
|
draftTransaction.gas.gasLimit = action.payload.gasLimit;
|
||||||
|
draftTransaction.gas.gasTotal = action.payload.gasTotal;
|
||||||
|
if (action.payload.chainHasChanged) {
|
||||||
|
// If the state was reinitialized as a result of the user changing
|
||||||
|
// the network from the network dropdown, then the selected asset is
|
||||||
|
// no longer valid and should be set to the native asset for the
|
||||||
|
// network.
|
||||||
|
draftTransaction.asset.type = ASSET_TYPES.NATIVE;
|
||||||
|
draftTransaction.asset.balance =
|
||||||
|
draftTransaction.fromAccount?.balance ??
|
||||||
|
state.selectedAccount.balance;
|
||||||
|
draftTransaction.asset.details = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
slice.caseReducers.updateGasFeeEstimates(state, {
|
slice.caseReducers.updateGasFeeEstimates(state, {
|
||||||
payload: {
|
payload: {
|
||||||
gasFeeEstimates: action.payload.gasFeeEstimates,
|
gasFeeEstimates: action.payload.gasFeeEstimates,
|
||||||
gasEstimateType: action.payload.gasEstimateType,
|
gasEstimateType: action.payload.gasEstimateType,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
draftTransaction.gas.gasTotal = action.payload.gasTotal;
|
|
||||||
state.gasEstimatePollToken = action.payload.gasEstimatePollToken;
|
state.gasEstimatePollToken = action.payload.gasEstimatePollToken;
|
||||||
if (action.payload.chainHasChanged) {
|
|
||||||
// If the state was reinitialized as a result of the user changing
|
|
||||||
// the network from the network dropdown, then the selected asset is
|
|
||||||
// no longer valid and should be set to the native asset for the
|
|
||||||
// network.
|
|
||||||
draftTransaction.asset.type = ASSET_TYPES.NATIVE;
|
|
||||||
draftTransaction.asset.balance =
|
|
||||||
draftTransaction.fromAccount?.balance ??
|
|
||||||
state.selectedAccount.balance;
|
|
||||||
draftTransaction.asset.details = null;
|
|
||||||
}
|
|
||||||
if (action.payload.gasEstimatePollToken) {
|
if (action.payload.gasEstimatePollToken) {
|
||||||
state.gasEstimateIsLoading = false;
|
state.gasEstimateIsLoading = false;
|
||||||
}
|
}
|
||||||
@ -2641,7 +2659,11 @@ export function isSendStateInitialized(state) {
|
|||||||
* @type {Selector<boolean>}
|
* @type {Selector<boolean>}
|
||||||
*/
|
*/
|
||||||
export function isSendFormInvalid(state) {
|
export function isSendFormInvalid(state) {
|
||||||
return getCurrentDraftTransaction(state).status === SEND_STATUSES.INVALID;
|
const draftTransaction = getCurrentDraftTransaction(state);
|
||||||
|
if (!draftTransaction) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return draftTransaction.status === SEND_STATUSES.INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user