2021-05-17 19:44:47 +02:00
|
|
|
import { cloneDeep } from 'lodash';
|
2022-09-14 16:55:31 +02:00
|
|
|
import { CHAIN_IDS } from '../../../shared/constants/network';
|
2021-05-17 19:44:47 +02:00
|
|
|
import {
|
2023-01-18 15:47:29 +01:00
|
|
|
TransactionType,
|
|
|
|
TransactionStatus,
|
2021-05-17 19:44:47 +02:00
|
|
|
} from '../../../shared/constants/transaction';
|
|
|
|
import migration59 from './059';
|
|
|
|
|
2023-01-18 15:47:29 +01:00
|
|
|
const SENT_ETHER = 'sentEther'; // a legacy transaction type replaced now by TransactionType.simpleSend
|
2021-09-15 23:54:51 +02:00
|
|
|
|
2021-05-17 19:44:47 +02:00
|
|
|
const ERRONEOUS_TRANSACTION_STATE = {
|
|
|
|
0: {
|
2023-01-18 15:47:29 +01:00
|
|
|
type: TransactionType.cancel,
|
2021-05-17 19:44:47 +02:00
|
|
|
id: 0,
|
2022-09-14 16:55:31 +02:00
|
|
|
chainId: CHAIN_IDS.MAINNET,
|
2021-05-17 19:44:47 +02:00
|
|
|
txParams: {
|
|
|
|
nonce: '0x0',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
1: {
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
id: 1,
|
2022-09-14 16:55:31 +02:00
|
|
|
chainId: CHAIN_IDS.MAINNET,
|
2021-05-17 19:44:47 +02:00
|
|
|
txParams: {
|
|
|
|
nonce: '0x1',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
2: {
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
id: 2,
|
2022-09-29 05:26:01 +02:00
|
|
|
chainId: '0x2a',
|
2021-05-17 19:44:47 +02:00
|
|
|
txParams: {
|
|
|
|
nonce: '0x2',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
3: {
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
id: 3,
|
2022-09-29 05:26:01 +02:00
|
|
|
chainId: '0x4',
|
2021-05-17 19:44:47 +02:00
|
|
|
txParams: {
|
|
|
|
nonce: '0x3',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
4: {
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
id: 4,
|
2022-09-29 05:26:01 +02:00
|
|
|
chainId: '0x4',
|
2021-05-17 19:44:47 +02:00
|
|
|
txParams: {
|
|
|
|
nonce: '0x4',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
5: {
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
id: 5,
|
2022-09-14 16:55:31 +02:00
|
|
|
chainId: CHAIN_IDS.MAINNET,
|
2021-05-17 19:44:47 +02:00
|
|
|
txParams: {
|
|
|
|
nonce: '0x5',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
6: {
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
id: 6,
|
2022-09-29 05:26:01 +02:00
|
|
|
chainId: '0x2a',
|
2021-05-17 19:44:47 +02:00
|
|
|
txParams: {
|
|
|
|
nonce: '0x6',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
7: {
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
id: 7,
|
2022-09-29 05:26:01 +02:00
|
|
|
chainId: '0x4',
|
2021-05-17 19:44:47 +02:00
|
|
|
txParams: {
|
|
|
|
nonce: '0x7',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
8: {
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
id: 8,
|
2022-09-29 05:26:01 +02:00
|
|
|
chainId: '0x4',
|
2021-05-17 19:44:47 +02:00
|
|
|
txParams: {
|
|
|
|
nonce: '0x8',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
9: {
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
id: 9,
|
2022-09-29 05:26:01 +02:00
|
|
|
chainId: '0x4',
|
2023-01-18 15:47:29 +01:00
|
|
|
status: TransactionStatus.unapproved,
|
2021-05-17 19:44:47 +02:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const ERRONEOUS_TRANSACTION_STATE_RETRY = {
|
|
|
|
...ERRONEOUS_TRANSACTION_STATE,
|
|
|
|
0: {
|
|
|
|
...ERRONEOUS_TRANSACTION_STATE[0],
|
2023-01-18 15:47:29 +01:00
|
|
|
type: TransactionType.retry,
|
2021-05-17 19:44:47 +02:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const ERRONEOUS_TRANSACTION_STATE_MIXED = {
|
|
|
|
...ERRONEOUS_TRANSACTION_STATE,
|
|
|
|
10: {
|
2023-01-18 15:47:29 +01:00
|
|
|
type: TransactionType.retry,
|
2021-05-17 19:44:47 +02:00
|
|
|
id: 10,
|
2022-09-14 16:55:31 +02:00
|
|
|
chainId: CHAIN_IDS.MAINNET,
|
2021-05-17 19:44:47 +02:00
|
|
|
txParams: {
|
|
|
|
nonce: '0xa',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
11: {
|
2023-01-18 15:47:29 +01:00
|
|
|
type: TransactionType.retry,
|
2021-05-17 19:44:47 +02:00
|
|
|
id: 11,
|
2022-09-14 16:55:31 +02:00
|
|
|
chainId: CHAIN_IDS.MAINNET,
|
2021-05-17 19:44:47 +02:00
|
|
|
txParams: {
|
|
|
|
nonce: '0xb',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-09-22 17:15:40 +02:00
|
|
|
describe('migration #59', () => {
|
|
|
|
it('should update the version metadata', async () => {
|
2021-05-17 19:44:47 +02:00
|
|
|
const oldStorage = {
|
|
|
|
meta: {
|
|
|
|
version: 58,
|
|
|
|
},
|
|
|
|
data: {},
|
|
|
|
};
|
|
|
|
|
|
|
|
const newStorage = await migration59.migrate(oldStorage);
|
2021-09-21 18:28:13 +02:00
|
|
|
expect(newStorage.meta).toStrictEqual({
|
2021-05-17 19:44:47 +02:00
|
|
|
version: 59,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-09-22 17:15:40 +02:00
|
|
|
it('should drop orphaned cancel transactions', async () => {
|
2021-05-17 19:44:47 +02:00
|
|
|
const oldStorage = {
|
|
|
|
meta: {},
|
|
|
|
data: {
|
|
|
|
TransactionController: {
|
|
|
|
transactions: ERRONEOUS_TRANSACTION_STATE,
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const newStorage = await migration59.migrate(oldStorage);
|
|
|
|
const EXPECTED = cloneDeep(ERRONEOUS_TRANSACTION_STATE);
|
|
|
|
delete EXPECTED['0'];
|
2021-09-21 18:28:13 +02:00
|
|
|
expect(newStorage.data).toStrictEqual({
|
2021-05-17 19:44:47 +02:00
|
|
|
TransactionController: {
|
|
|
|
transactions: EXPECTED,
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-09-22 17:15:40 +02:00
|
|
|
it('should drop orphaned cancel transactions even if a nonce exists on another network that is confirmed', async () => {
|
2021-05-17 19:44:47 +02:00
|
|
|
const oldStorage = {
|
|
|
|
meta: {},
|
|
|
|
data: {
|
|
|
|
TransactionController: {
|
|
|
|
transactions: {
|
|
|
|
...ERRONEOUS_TRANSACTION_STATE,
|
|
|
|
11: {
|
|
|
|
...ERRONEOUS_TRANSACTION_STATE['0'],
|
|
|
|
id: 11,
|
2022-09-14 16:55:31 +02:00
|
|
|
chainId: CHAIN_IDS.GOERLI,
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const newStorage = await migration59.migrate(oldStorage);
|
|
|
|
const EXPECTED = cloneDeep(
|
|
|
|
oldStorage.data.TransactionController.transactions,
|
|
|
|
);
|
|
|
|
delete EXPECTED['0'];
|
2021-09-21 18:28:13 +02:00
|
|
|
expect(newStorage.data).toStrictEqual({
|
2021-05-17 19:44:47 +02:00
|
|
|
TransactionController: {
|
|
|
|
transactions: EXPECTED,
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-09-22 17:15:40 +02:00
|
|
|
it('should not drop cancel transactions with matching non cancel or retry in same network and nonce', async () => {
|
2021-05-17 19:44:47 +02:00
|
|
|
const oldStorage = {
|
|
|
|
meta: {},
|
|
|
|
data: {
|
|
|
|
TransactionController: {
|
|
|
|
transactions: {
|
|
|
|
...ERRONEOUS_TRANSACTION_STATE,
|
|
|
|
11: {
|
|
|
|
...ERRONEOUS_TRANSACTION_STATE['0'],
|
|
|
|
id: 11,
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const newStorage = await migration59.migrate(oldStorage);
|
2021-09-21 18:28:13 +02:00
|
|
|
expect(newStorage.data).toStrictEqual({
|
2021-05-17 19:44:47 +02:00
|
|
|
TransactionController: {
|
|
|
|
transactions: oldStorage.data.TransactionController.transactions,
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-09-22 17:15:40 +02:00
|
|
|
it('should drop orphaned retry transactions', async () => {
|
2021-05-17 19:44:47 +02:00
|
|
|
const oldStorage = {
|
|
|
|
meta: {},
|
|
|
|
data: {
|
|
|
|
TransactionController: {
|
|
|
|
transactions: ERRONEOUS_TRANSACTION_STATE_RETRY,
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const newStorage = await migration59.migrate(oldStorage);
|
|
|
|
const EXPECTED = cloneDeep(ERRONEOUS_TRANSACTION_STATE_RETRY);
|
|
|
|
delete EXPECTED['0'];
|
2021-09-21 18:28:13 +02:00
|
|
|
expect(newStorage.data).toStrictEqual({
|
2021-05-17 19:44:47 +02:00
|
|
|
TransactionController: {
|
|
|
|
transactions: EXPECTED,
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-09-22 17:15:40 +02:00
|
|
|
it('should drop orphaned retry transactions even if a nonce exists on another network that is confirmed', async () => {
|
2021-05-17 19:44:47 +02:00
|
|
|
const oldStorage = {
|
|
|
|
meta: {},
|
|
|
|
data: {
|
|
|
|
TransactionController: {
|
|
|
|
transactions: {
|
|
|
|
...ERRONEOUS_TRANSACTION_STATE_RETRY,
|
|
|
|
11: {
|
|
|
|
...ERRONEOUS_TRANSACTION_STATE_RETRY['0'],
|
|
|
|
id: 11,
|
2022-09-14 16:55:31 +02:00
|
|
|
chainId: CHAIN_IDS.GOERLI,
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const newStorage = await migration59.migrate(oldStorage);
|
|
|
|
const EXPECTED = cloneDeep(
|
|
|
|
oldStorage.data.TransactionController.transactions,
|
|
|
|
);
|
|
|
|
delete EXPECTED['0'];
|
2021-09-21 18:28:13 +02:00
|
|
|
expect(newStorage.data).toStrictEqual({
|
2021-05-17 19:44:47 +02:00
|
|
|
TransactionController: {
|
|
|
|
transactions: EXPECTED,
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-09-22 17:15:40 +02:00
|
|
|
it('should not drop retry transactions with matching non cancel or retry in same network and nonce', async () => {
|
2021-05-17 19:44:47 +02:00
|
|
|
const oldStorage = {
|
|
|
|
meta: {},
|
|
|
|
data: {
|
|
|
|
TransactionController: {
|
|
|
|
transactions: {
|
|
|
|
...ERRONEOUS_TRANSACTION_STATE_RETRY,
|
|
|
|
11: {
|
|
|
|
...ERRONEOUS_TRANSACTION_STATE_RETRY['0'],
|
|
|
|
id: 11,
|
2021-09-15 23:54:51 +02:00
|
|
|
type: SENT_ETHER,
|
2021-05-17 19:44:47 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const newStorage = await migration59.migrate(oldStorage);
|
2021-09-21 18:28:13 +02:00
|
|
|
expect(newStorage.data).toStrictEqual({
|
2021-05-17 19:44:47 +02:00
|
|
|
TransactionController: {
|
|
|
|
transactions: oldStorage.data.TransactionController.transactions,
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-09-22 17:15:40 +02:00
|
|
|
it('should drop all orphaned retry and cancel transactions', async () => {
|
2021-05-17 19:44:47 +02:00
|
|
|
const oldStorage = {
|
|
|
|
meta: {},
|
|
|
|
data: {
|
|
|
|
TransactionController: {
|
|
|
|
transactions: ERRONEOUS_TRANSACTION_STATE_MIXED,
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const newStorage = await migration59.migrate(oldStorage);
|
|
|
|
// The following ERRONEOUS_TRANSACTION_STATE object only has one orphan in it
|
|
|
|
// so using it as the base for our expected output automatically removes a few
|
|
|
|
// transactions we expect to be missing.
|
|
|
|
const EXPECTED = cloneDeep(ERRONEOUS_TRANSACTION_STATE);
|
|
|
|
delete EXPECTED['0'];
|
2021-09-21 18:28:13 +02:00
|
|
|
expect(newStorage.data).toStrictEqual({
|
2021-05-17 19:44:47 +02:00
|
|
|
TransactionController: {
|
|
|
|
transactions: EXPECTED,
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-09-22 17:15:40 +02:00
|
|
|
it('should do nothing if transactions state does not exist', async () => {
|
2021-05-17 19:44:47 +02:00
|
|
|
const oldStorage = {
|
|
|
|
meta: {},
|
|
|
|
data: {
|
|
|
|
TransactionController: {
|
|
|
|
bar: 'baz',
|
|
|
|
},
|
|
|
|
IncomingTransactionsController: {
|
|
|
|
foo: 'baz',
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const newStorage = await migration59.migrate(oldStorage);
|
2021-09-21 18:28:13 +02:00
|
|
|
expect(oldStorage.data).toStrictEqual(newStorage.data);
|
2021-05-17 19:44:47 +02:00
|
|
|
});
|
|
|
|
|
2021-09-22 17:15:40 +02:00
|
|
|
it('should do nothing if transactions state is empty', async () => {
|
2021-05-17 19:44:47 +02:00
|
|
|
const oldStorage = {
|
|
|
|
meta: {},
|
|
|
|
data: {
|
|
|
|
TransactionController: {
|
|
|
|
transactions: {},
|
|
|
|
bar: 'baz',
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const newStorage = await migration59.migrate(oldStorage);
|
2021-09-21 18:28:13 +02:00
|
|
|
expect(oldStorage.data).toStrictEqual(newStorage.data);
|
2021-05-17 19:44:47 +02:00
|
|
|
});
|
|
|
|
|
2021-09-22 17:15:40 +02:00
|
|
|
it('should do nothing if transactions state is not an object', async () => {
|
2021-05-17 19:44:47 +02:00
|
|
|
const oldStorage = {
|
|
|
|
meta: {},
|
|
|
|
data: {
|
|
|
|
TransactionController: {
|
|
|
|
transactions: [],
|
|
|
|
bar: 'baz',
|
|
|
|
},
|
|
|
|
foo: 'bar',
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const newStorage = await migration59.migrate(oldStorage);
|
2021-09-21 18:28:13 +02:00
|
|
|
expect(oldStorage.data).toStrictEqual(newStorage.data);
|
2021-05-17 19:44:47 +02:00
|
|
|
});
|
|
|
|
|
2021-09-22 17:15:40 +02:00
|
|
|
it('should do nothing if state is empty', async () => {
|
2021-05-17 19:44:47 +02:00
|
|
|
const oldStorage = {
|
|
|
|
meta: {},
|
|
|
|
data: {},
|
|
|
|
};
|
|
|
|
|
|
|
|
const newStorage = await migration59.migrate(oldStorage);
|
2021-09-21 18:28:13 +02:00
|
|
|
expect(oldStorage.data).toStrictEqual(newStorage.data);
|
2021-05-17 19:44:47 +02:00
|
|
|
});
|
|
|
|
});
|