@rosen-bridge/tx-pot 1.0.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +8 -8
- package/dist/db/entities/transactionEntity.d.ts +15 -0
- package/dist/db/entities/{TransactionEntity.d.ts.map → transactionEntity.d.ts.map} +1 -1
- package/dist/db/entities/transactionEntity.js +81 -0
- package/dist/db/migrations/index.d.ts +3 -3
- package/dist/db/migrations/index.js +3 -3
- package/dist/db/migrations/postgres/1706350644686-migration.d.ts +4 -4
- package/dist/db/migrations/postgres/1706350644686-migration.d.ts.map +1 -1
- package/dist/db/migrations/postgres/1706350644686-migration.js +8 -8
- package/dist/db/migrations/sqlite/1706007154531-migration.d.ts +4 -4
- package/dist/db/migrations/sqlite/1706007154531-migration.d.ts.map +1 -1
- package/dist/db/migrations/sqlite/1706007154531-migration.js +8 -8
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/network/abstractPotChainManager.d.ts +36 -0
- package/dist/network/{AbstractPotChainManager.d.ts.map → abstractPotChainManager.d.ts.map} +1 -1
- package/dist/network/{AbstractPotChainManager.js → abstractPotChainManager.js} +3 -2
- package/dist/transaction/txPot.d.ts +212 -0
- package/dist/transaction/txPot.d.ts.map +1 -0
- package/dist/transaction/{TxPot.js → txPot.js} +2 -2
- package/dist/transaction/types.d.ts +21 -24
- package/dist/transaction/types.d.ts.map +1 -1
- package/dist/transaction/types.js +13 -13
- package/dist/transaction/utils.d.ts +2 -4
- package/dist/transaction/utils.d.ts.map +1 -1
- package/dist/transaction/utils.js +48 -43
- package/package.json +25 -21
- package/.eslintignore +0 -1
- package/dist/db/entities/TransactionEntity.d.ts +0 -15
- package/dist/db/entities/TransactionEntity.js +0 -125
- package/dist/network/AbstractPotChainManager.d.ts +0 -39
- package/dist/transaction/TxPot.d.ts +0 -284
- package/dist/transaction/TxPot.d.ts.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/lib/db/entities/TransactionEntity.ts +0 -44
- package/lib/db/migrations/index.ts +0 -7
- package/lib/db/migrations/postgres/1706350644686-migration.ts +0 -31
- package/lib/db/migrations/sqlite/1706007154531-migration.ts +0 -31
- package/lib/index.ts +0 -5
- package/lib/network/AbstractPotChainManager.ts +0 -44
- package/lib/transaction/TxPot.ts +0 -728
- package/lib/transaction/types.ts +0 -46
- package/lib/transaction/utils.ts +0 -59
- package/tests/.gitkeep +0 -0
- package/tests/db/dataSource.mock.ts +0 -18
- package/tests/network/TestPotChainManager.ts +0 -23
- package/tests/transaction/TestTxPot.ts +0 -32
- package/tests/transaction/TxPot.spec.ts +0 -1881
- package/tests/transaction/testData.ts +0 -84
- package/tsconfig.build.json +0 -8
- package/tsconfig.build.tsbuildinfo +0 -1
- package/tsconfig.json +0 -9
- package/vitest.config.ts +0 -13
|
@@ -1,1881 +0,0 @@
|
|
|
1
|
-
import { Repository } from 'typeorm';
|
|
2
|
-
import { mockDataSource } from '../db/dataSource.mock';
|
|
3
|
-
import {
|
|
4
|
-
CallbackFunction,
|
|
5
|
-
TransactionEntity,
|
|
6
|
-
TransactionStatus,
|
|
7
|
-
ValidatorFunction,
|
|
8
|
-
} from '../../lib';
|
|
9
|
-
import { TestTxPot } from './TestTxPot';
|
|
10
|
-
import * as testData from './testData';
|
|
11
|
-
import { TestPotChainManager } from '../network/TestPotChainManager';
|
|
12
|
-
|
|
13
|
-
describe('TxPot', () => {
|
|
14
|
-
let txRepository: Repository<TransactionEntity>;
|
|
15
|
-
let txPot: TestTxPot;
|
|
16
|
-
|
|
17
|
-
beforeAll(() => {
|
|
18
|
-
vi.useFakeTimers();
|
|
19
|
-
vi.setSystemTime(new Date(testData.currentTimeStamp));
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
beforeEach(async () => {
|
|
23
|
-
// init TxPot
|
|
24
|
-
const dataSource = await mockDataSource();
|
|
25
|
-
txPot = TestTxPot.setup(dataSource);
|
|
26
|
-
txRepository = dataSource.getRepository(TransactionEntity);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
afterAll(() => {
|
|
30
|
-
vi.useRealTimers();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
describe('unregisterValidator', () => {
|
|
34
|
-
/**
|
|
35
|
-
* @target TxPot.unregisterValidator should remove registered validator successfully
|
|
36
|
-
* @dependencies
|
|
37
|
-
* @scenario
|
|
38
|
-
* - register a validator function
|
|
39
|
-
* - run test
|
|
40
|
-
* - check registered validators
|
|
41
|
-
* @expected
|
|
42
|
-
* - there should be no validator
|
|
43
|
-
*/
|
|
44
|
-
it('should remove registered validator successfully', async () => {
|
|
45
|
-
const mockedValidator = async (tx: TransactionEntity) => true;
|
|
46
|
-
txPot.registerValidator('chain', 'txType', 'id', mockedValidator);
|
|
47
|
-
|
|
48
|
-
txPot.unregisterValidator('chain', 'txType', 'id');
|
|
49
|
-
|
|
50
|
-
const validatorsMap: Map<
|
|
51
|
-
string,
|
|
52
|
-
Map<string, Map<string, ValidatorFunction>>
|
|
53
|
-
> = (txPot as any).validators;
|
|
54
|
-
expect(validatorsMap.get('chain')?.get('txType')?.size).toEqual(0);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe('unregisterSubmitValidator', () => {
|
|
59
|
-
/**
|
|
60
|
-
* @target TxPot.unregisterSubmitValidator should remove registered submit validator successfully
|
|
61
|
-
* @dependencies
|
|
62
|
-
* @scenario
|
|
63
|
-
* - register a validator function
|
|
64
|
-
* - run test
|
|
65
|
-
* - check registered submit validators
|
|
66
|
-
* @expected
|
|
67
|
-
* - there should be no validator
|
|
68
|
-
*/
|
|
69
|
-
it('should remove registered submit validator successfully', async () => {
|
|
70
|
-
const mockedValidator = async (tx: TransactionEntity) => true;
|
|
71
|
-
txPot.registerSubmitValidator('chain', 'id', mockedValidator);
|
|
72
|
-
|
|
73
|
-
txPot.unregisterSubmitValidator('chain', 'id');
|
|
74
|
-
|
|
75
|
-
const validatorsMap: Map<string, Map<string, ValidatorFunction>> = (
|
|
76
|
-
txPot as any
|
|
77
|
-
).submissionAllowance;
|
|
78
|
-
expect(validatorsMap.get('chain')?.size).toEqual(0);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe('unregisterCallback', () => {
|
|
83
|
-
/**
|
|
84
|
-
* @target TxPot.unregisterCallback should remove registered submit validator successfully
|
|
85
|
-
* @dependencies
|
|
86
|
-
* @scenario
|
|
87
|
-
* - register a validator function
|
|
88
|
-
* - run test
|
|
89
|
-
* - check registered submit validators
|
|
90
|
-
* @expected
|
|
91
|
-
* - there should be no validator
|
|
92
|
-
*/
|
|
93
|
-
it('should remove registered submit validator successfully', async () => {
|
|
94
|
-
const mockedCallback = vi.fn();
|
|
95
|
-
txPot.registerCallback(
|
|
96
|
-
'txType',
|
|
97
|
-
TransactionStatus.SIGNED,
|
|
98
|
-
'id',
|
|
99
|
-
mockedCallback
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
txPot.unregisterCallback('txType', TransactionStatus.SIGNED, 'id');
|
|
103
|
-
|
|
104
|
-
const callbacksMap: Map<
|
|
105
|
-
string,
|
|
106
|
-
Map<TransactionStatus, Map<string, CallbackFunction>>
|
|
107
|
-
> = (txPot as any).txTypeCallbacks;
|
|
108
|
-
expect(
|
|
109
|
-
callbacksMap.get('txType')?.get(TransactionStatus.SIGNED)?.size
|
|
110
|
-
).toEqual(0);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
describe('setTransactionAsInvalid', () => {
|
|
115
|
-
/**
|
|
116
|
-
* @target TxPot.setTransactionAsInvalid should update status when enough blocks is passed
|
|
117
|
-
* @dependencies
|
|
118
|
-
* - Date
|
|
119
|
-
* - database
|
|
120
|
-
* @scenario
|
|
121
|
-
* - insert tx
|
|
122
|
-
* - mock PotChainManager and register to TxPot
|
|
123
|
-
* - mock `getHeight`
|
|
124
|
-
* - mock `getTxRequiredConfirmation` to return -1
|
|
125
|
-
* - run test
|
|
126
|
-
* - check db records
|
|
127
|
-
* @expected
|
|
128
|
-
* - columns of the tx should be updated
|
|
129
|
-
* - status should be updated to invalid
|
|
130
|
-
* - lastStatusUpdate should be updated to currentTimeStamp in seconds
|
|
131
|
-
*/
|
|
132
|
-
it('should update status when enough blocks is passed', async () => {
|
|
133
|
-
// insert tx
|
|
134
|
-
await txRepository.insert(testData.tx1);
|
|
135
|
-
|
|
136
|
-
// mock PotChainManager and register to TxPot
|
|
137
|
-
const mockedManager = new TestPotChainManager();
|
|
138
|
-
txPot.registerChain(testData.tx1.chain, mockedManager);
|
|
139
|
-
// mock `getHeight`
|
|
140
|
-
const requiredConfirmation = 5;
|
|
141
|
-
const currentHeight = testData.tx1.lastCheck + requiredConfirmation;
|
|
142
|
-
vi.spyOn(mockedManager, 'getHeight').mockResolvedValue(currentHeight);
|
|
143
|
-
// mock `getTxRequiredConfirmation`
|
|
144
|
-
vi.spyOn(mockedManager, 'getTxRequiredConfirmation').mockReturnValue(
|
|
145
|
-
requiredConfirmation
|
|
146
|
-
);
|
|
147
|
-
|
|
148
|
-
// run test
|
|
149
|
-
await txPot.callSetTransactionAsInvalid(testData.tx1);
|
|
150
|
-
|
|
151
|
-
// check db records
|
|
152
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
153
|
-
tx.txId,
|
|
154
|
-
tx.status,
|
|
155
|
-
tx.lastStatusUpdate,
|
|
156
|
-
]);
|
|
157
|
-
expect(txs).toEqual([
|
|
158
|
-
[
|
|
159
|
-
testData.tx1.txId,
|
|
160
|
-
TransactionStatus.INVALID,
|
|
161
|
-
String(testData.currentTimeStampAsSeconds),
|
|
162
|
-
],
|
|
163
|
-
]);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* @target TxPot.setTransactionAsInvalid should NOT update when enough blocks is NOT passed
|
|
168
|
-
* @dependencies
|
|
169
|
-
* - Date
|
|
170
|
-
* - database
|
|
171
|
-
* @scenario
|
|
172
|
-
* - insert tx
|
|
173
|
-
* - mock PotChainManager and register to TxPot
|
|
174
|
-
* - mock `getHeight`
|
|
175
|
-
* - mock `getTxRequiredConfirmation` to return -1
|
|
176
|
-
* - run test
|
|
177
|
-
* - check db records
|
|
178
|
-
* @expected
|
|
179
|
-
* - columns of the tx should remain unchanged
|
|
180
|
-
*/
|
|
181
|
-
it('should NOT update when enough blocks is NOT passed', async () => {
|
|
182
|
-
// insert tx
|
|
183
|
-
await txRepository.insert(testData.tx1);
|
|
184
|
-
|
|
185
|
-
// mock PotChainManager and register to TxPot
|
|
186
|
-
const mockedManager = new TestPotChainManager();
|
|
187
|
-
txPot.registerChain(testData.tx1.chain, mockedManager);
|
|
188
|
-
// mock `getHeight`
|
|
189
|
-
const requiredConfirmation = 5;
|
|
190
|
-
const currentHeight = testData.tx1.lastCheck + requiredConfirmation - 1;
|
|
191
|
-
vi.spyOn(mockedManager, 'getHeight').mockResolvedValue(currentHeight);
|
|
192
|
-
// mock `getTxRequiredConfirmation`
|
|
193
|
-
vi.spyOn(mockedManager, 'getTxRequiredConfirmation').mockReturnValue(
|
|
194
|
-
requiredConfirmation
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
// run test
|
|
198
|
-
await txPot.callSetTransactionAsInvalid(testData.tx1);
|
|
199
|
-
|
|
200
|
-
// check db records
|
|
201
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
202
|
-
tx.txId,
|
|
203
|
-
tx.status,
|
|
204
|
-
tx.lastStatusUpdate,
|
|
205
|
-
]);
|
|
206
|
-
expect(txs).toEqual([
|
|
207
|
-
[testData.tx1.txId, testData.tx1.status, testData.tx1.lastStatusUpdate],
|
|
208
|
-
]);
|
|
209
|
-
});
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
describe('validateTx', () => {
|
|
213
|
-
/**
|
|
214
|
-
* @target TxPot.validateTx should return true when no validator function is set
|
|
215
|
-
* @dependencies
|
|
216
|
-
* @scenario
|
|
217
|
-
* - run test
|
|
218
|
-
* - check returned value
|
|
219
|
-
* @expected
|
|
220
|
-
* - should return true
|
|
221
|
-
*/
|
|
222
|
-
it('should return true when no validator function is set', async () => {
|
|
223
|
-
const res = await txPot.callValidateTx(testData.tx1);
|
|
224
|
-
expect(res).toEqual(true);
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* @target TxPot.validateTx should return true when tx is valid
|
|
229
|
-
* @dependencies
|
|
230
|
-
* @scenario
|
|
231
|
-
* - register a validator function to return true
|
|
232
|
-
* - run test
|
|
233
|
-
* - check returned value
|
|
234
|
-
* @expected
|
|
235
|
-
* - should return true
|
|
236
|
-
*/
|
|
237
|
-
it('should return true when tx is valid', async () => {
|
|
238
|
-
const mockedValidator = async (tx: TransactionEntity) => true;
|
|
239
|
-
txPot.registerValidator(
|
|
240
|
-
testData.tx1.chain,
|
|
241
|
-
testData.tx1.txType,
|
|
242
|
-
'id',
|
|
243
|
-
mockedValidator
|
|
244
|
-
);
|
|
245
|
-
|
|
246
|
-
const res = await txPot.callValidateTx(testData.tx1);
|
|
247
|
-
expect(res).toEqual(true);
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* @target TxPot.validateTx should return false and set tx as invalid
|
|
252
|
-
* @dependencies
|
|
253
|
-
* - database
|
|
254
|
-
* @scenario
|
|
255
|
-
* - insert tx into db
|
|
256
|
-
* - register a validator function to return false
|
|
257
|
-
* - mock TxPot.setTransactionAsInvalid
|
|
258
|
-
* - run test
|
|
259
|
-
* - check returned value
|
|
260
|
-
* - check if function got called
|
|
261
|
-
* @expected
|
|
262
|
-
* - should return false
|
|
263
|
-
* - `setTransactionAsInvalid` should got called
|
|
264
|
-
*/
|
|
265
|
-
it('should return false and set tx as invalid', async () => {
|
|
266
|
-
await txRepository.insert(testData.tx1);
|
|
267
|
-
|
|
268
|
-
const mockedValidator = async (tx: TransactionEntity) => false;
|
|
269
|
-
txPot.registerValidator(
|
|
270
|
-
testData.tx1.chain,
|
|
271
|
-
testData.tx1.txType,
|
|
272
|
-
'id',
|
|
273
|
-
mockedValidator
|
|
274
|
-
);
|
|
275
|
-
|
|
276
|
-
const mockedSetTransactionAsInvalid = vi.fn();
|
|
277
|
-
vi.spyOn(txPot as any, 'setTransactionAsInvalid').mockImplementation(
|
|
278
|
-
mockedSetTransactionAsInvalid
|
|
279
|
-
);
|
|
280
|
-
|
|
281
|
-
const res = await txPot.callValidateTx(testData.tx1);
|
|
282
|
-
expect(res).toEqual(false);
|
|
283
|
-
expect(mockedSetTransactionAsInvalid).toHaveBeenCalled();
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* @target TxPot.validateTx should return false and set tx as invalid
|
|
288
|
-
* when at least one validator returns false
|
|
289
|
-
* @dependencies
|
|
290
|
-
* - database
|
|
291
|
-
* @scenario
|
|
292
|
-
* - insert tx into db
|
|
293
|
-
* - register 3 validator functions (1st and 3rd ones returns true, 2nd one returns false)
|
|
294
|
-
* - mock TxPot.setTransactionAsInvalid
|
|
295
|
-
* - run test
|
|
296
|
-
* - check returned value
|
|
297
|
-
* - check if function got called
|
|
298
|
-
* @expected
|
|
299
|
-
* - should return false
|
|
300
|
-
* - `setTransactionAsInvalid` should got called
|
|
301
|
-
*/
|
|
302
|
-
it('should return false and set tx as invalid when at least one validator returns false', async () => {
|
|
303
|
-
await txRepository.insert(testData.tx1);
|
|
304
|
-
|
|
305
|
-
const mockedValidators = [
|
|
306
|
-
{ id: 'validator-1', validator: async (tx: TransactionEntity) => true },
|
|
307
|
-
{
|
|
308
|
-
id: 'validator-2',
|
|
309
|
-
validator: async (tx: TransactionEntity) => false,
|
|
310
|
-
},
|
|
311
|
-
{ id: 'validator-3', validator: async (tx: TransactionEntity) => true },
|
|
312
|
-
];
|
|
313
|
-
mockedValidators.forEach((mockedValidator) =>
|
|
314
|
-
txPot.registerValidator(
|
|
315
|
-
testData.tx1.chain,
|
|
316
|
-
testData.tx1.txType,
|
|
317
|
-
mockedValidator.id,
|
|
318
|
-
mockedValidator.validator
|
|
319
|
-
)
|
|
320
|
-
);
|
|
321
|
-
|
|
322
|
-
const mockedSetTransactionAsInvalid = vi.fn();
|
|
323
|
-
vi.spyOn(txPot as any, 'setTransactionAsInvalid').mockImplementation(
|
|
324
|
-
mockedSetTransactionAsInvalid
|
|
325
|
-
);
|
|
326
|
-
|
|
327
|
-
const res = await txPot.callValidateTx(testData.tx1);
|
|
328
|
-
expect(res).toEqual(false);
|
|
329
|
-
expect(mockedSetTransactionAsInvalid).toHaveBeenCalled();
|
|
330
|
-
});
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
describe('setTxStatus', () => {
|
|
334
|
-
/**
|
|
335
|
-
* @target TxPot.setTxStatus should update status and lastStatusUpdate successfully
|
|
336
|
-
* @dependencies
|
|
337
|
-
* - Date
|
|
338
|
-
* - database
|
|
339
|
-
* @scenario
|
|
340
|
-
* - insert 2 txs
|
|
341
|
-
* - register a callback function
|
|
342
|
-
* - run test
|
|
343
|
-
* - check db records
|
|
344
|
-
* @expected
|
|
345
|
-
* - columns of target tx should be updated as expected
|
|
346
|
-
* - status should be updated to new status
|
|
347
|
-
* - lastStatusUpdate should be updated to currentTimeStamp in seconds
|
|
348
|
-
* - columns of other txs should remain unchanged
|
|
349
|
-
*/
|
|
350
|
-
it('should update status and lastStatusUpdate successfully', async () => {
|
|
351
|
-
await txRepository.insert(testData.tx1);
|
|
352
|
-
await txRepository.insert(testData.tx5);
|
|
353
|
-
|
|
354
|
-
const newStatus = TransactionStatus.IN_SIGN;
|
|
355
|
-
await txPot.callSetTxStatus(testData.tx1, newStatus);
|
|
356
|
-
|
|
357
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
358
|
-
tx.txId,
|
|
359
|
-
tx.status,
|
|
360
|
-
tx.lastStatusUpdate,
|
|
361
|
-
]);
|
|
362
|
-
expect(txs).toEqual([
|
|
363
|
-
[
|
|
364
|
-
testData.tx1.txId,
|
|
365
|
-
newStatus,
|
|
366
|
-
String(testData.currentTimeStampAsSeconds),
|
|
367
|
-
],
|
|
368
|
-
[testData.tx5.txId, testData.tx5.status, testData.tx5.lastStatusUpdate],
|
|
369
|
-
]);
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* @target TxPot.setTxStatus should also call tx status callback if is provided
|
|
374
|
-
* @dependencies
|
|
375
|
-
* - Date
|
|
376
|
-
* - database
|
|
377
|
-
* @scenario
|
|
378
|
-
* - insert 2 txs
|
|
379
|
-
* - register a callback function for new status
|
|
380
|
-
* - run test
|
|
381
|
-
* - check db records
|
|
382
|
-
* - check if function got called
|
|
383
|
-
* @expected
|
|
384
|
-
* - columns of target tx should be updated as expected
|
|
385
|
-
* - status should be updated to new status
|
|
386
|
-
* - lastStatusUpdate should be updated to currentTimeStamp in seconds
|
|
387
|
-
* - columns of other txs should remain unchanged
|
|
388
|
-
* - mocked callback should got called
|
|
389
|
-
*/
|
|
390
|
-
it('should also call tx status callback if is provided', async () => {
|
|
391
|
-
// insert 2 txs
|
|
392
|
-
await txRepository.insert(testData.tx1);
|
|
393
|
-
await txRepository.insert(testData.tx5);
|
|
394
|
-
|
|
395
|
-
// register a callback function
|
|
396
|
-
const newStatus = TransactionStatus.IN_SIGN;
|
|
397
|
-
const mockedCallback = vi.fn();
|
|
398
|
-
mockedCallback.mockResolvedValue(undefined);
|
|
399
|
-
txPot.registerCallback(
|
|
400
|
-
testData.tx1.txType,
|
|
401
|
-
newStatus,
|
|
402
|
-
'id',
|
|
403
|
-
mockedCallback
|
|
404
|
-
);
|
|
405
|
-
|
|
406
|
-
// run test
|
|
407
|
-
await txPot.callSetTxStatus(testData.tx1, newStatus);
|
|
408
|
-
|
|
409
|
-
// check db records
|
|
410
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
411
|
-
tx.txId,
|
|
412
|
-
tx.status,
|
|
413
|
-
tx.lastStatusUpdate,
|
|
414
|
-
]);
|
|
415
|
-
expect(txs).toEqual([
|
|
416
|
-
[
|
|
417
|
-
testData.tx1.txId,
|
|
418
|
-
newStatus,
|
|
419
|
-
String(testData.currentTimeStampAsSeconds),
|
|
420
|
-
],
|
|
421
|
-
[testData.tx5.txId, testData.tx5.status, testData.tx5.lastStatusUpdate],
|
|
422
|
-
]);
|
|
423
|
-
|
|
424
|
-
// check if function got called
|
|
425
|
-
expect(mockedCallback).toHaveBeenCalled();
|
|
426
|
-
});
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
describe('processSignedTx', () => {
|
|
430
|
-
/**
|
|
431
|
-
* @target TxPot.processSignedTx should submit the tx and update the status
|
|
432
|
-
* @dependencies
|
|
433
|
-
* - database
|
|
434
|
-
* @scenario
|
|
435
|
-
* - insert tx with signed status
|
|
436
|
-
* - mock PotChainManager and register to TxPot
|
|
437
|
-
* - mock `submitTransaction`
|
|
438
|
-
* - run test (call `update`)
|
|
439
|
-
* - check if function got called
|
|
440
|
-
* - check db records
|
|
441
|
-
* @expected
|
|
442
|
-
* - `submitTransaction` should got called
|
|
443
|
-
* - columns of the tx should be updated
|
|
444
|
-
* - status should be updated to sent
|
|
445
|
-
* - lastStatusUpdate should be updated to currentTimeStamp in seconds
|
|
446
|
-
*/
|
|
447
|
-
it('should submit the tx and update the status', async () => {
|
|
448
|
-
// insert tx with signed status
|
|
449
|
-
await txRepository.insert(testData.tx4);
|
|
450
|
-
|
|
451
|
-
// mock PotChainManager and register to TxPot
|
|
452
|
-
const mockedManager = new TestPotChainManager();
|
|
453
|
-
txPot.registerChain(testData.tx4.chain, mockedManager);
|
|
454
|
-
// mock `submitTransaction`
|
|
455
|
-
const mockedSubmitTransaction = vi.fn();
|
|
456
|
-
mockedSubmitTransaction.mockResolvedValue(undefined);
|
|
457
|
-
vi.spyOn(mockedManager, 'submitTransaction').mockImplementation(
|
|
458
|
-
mockedSubmitTransaction
|
|
459
|
-
);
|
|
460
|
-
|
|
461
|
-
// run test
|
|
462
|
-
await txPot.update();
|
|
463
|
-
|
|
464
|
-
// check if function got called
|
|
465
|
-
expect(mockedSubmitTransaction).toHaveBeenCalled();
|
|
466
|
-
|
|
467
|
-
// check db records
|
|
468
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
469
|
-
tx.txId,
|
|
470
|
-
tx.status,
|
|
471
|
-
tx.lastStatusUpdate,
|
|
472
|
-
]);
|
|
473
|
-
expect(txs).toEqual([
|
|
474
|
-
[
|
|
475
|
-
testData.tx4.txId,
|
|
476
|
-
TransactionStatus.SENT,
|
|
477
|
-
String(testData.currentTimeStampAsSeconds),
|
|
478
|
-
],
|
|
479
|
-
]);
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
/**
|
|
483
|
-
* @target TxPot.processSignedTx should update the status regardless of submit response
|
|
484
|
-
* @dependencies
|
|
485
|
-
* - database
|
|
486
|
-
* @scenario
|
|
487
|
-
* - insert tx with signed status
|
|
488
|
-
* - mock PotChainManager and register to TxPot
|
|
489
|
-
* - mock `submitTransaction` to throw error
|
|
490
|
-
* - register submit validator function
|
|
491
|
-
* - run test (call `update`)
|
|
492
|
-
* - check if function got called
|
|
493
|
-
* - check db records
|
|
494
|
-
* @expected
|
|
495
|
-
* - `submitTransaction` should got called
|
|
496
|
-
* - columns of the tx should be updated
|
|
497
|
-
* - status should be updated to sent
|
|
498
|
-
* - lastStatusUpdate should be updated to currentTimeStamp in seconds
|
|
499
|
-
*/
|
|
500
|
-
it('should update the status regardless of submit response', async () => {
|
|
501
|
-
// insert tx with signed status
|
|
502
|
-
await txRepository.insert(testData.tx4);
|
|
503
|
-
|
|
504
|
-
// mock PotChainManager and register to TxPot
|
|
505
|
-
const mockedManager = new TestPotChainManager();
|
|
506
|
-
txPot.registerChain(testData.tx4.chain, mockedManager);
|
|
507
|
-
// mock `submitTransaction`
|
|
508
|
-
const mockedSubmitTransaction = vi.fn();
|
|
509
|
-
mockedSubmitTransaction.mockRejectedValue(
|
|
510
|
-
Error(`TestError: submit failed`)
|
|
511
|
-
);
|
|
512
|
-
vi.spyOn(mockedManager, 'submitTransaction').mockImplementation(
|
|
513
|
-
mockedSubmitTransaction
|
|
514
|
-
);
|
|
515
|
-
|
|
516
|
-
// register submit validator function
|
|
517
|
-
txPot.registerSubmitValidator(
|
|
518
|
-
testData.tx1.chain,
|
|
519
|
-
'validator-1',
|
|
520
|
-
async (tx: TransactionEntity) => true
|
|
521
|
-
);
|
|
522
|
-
|
|
523
|
-
// run test
|
|
524
|
-
await txPot.update();
|
|
525
|
-
|
|
526
|
-
// check if function got called
|
|
527
|
-
expect(mockedSubmitTransaction).toHaveBeenCalled();
|
|
528
|
-
|
|
529
|
-
// check db records
|
|
530
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
531
|
-
tx.txId,
|
|
532
|
-
tx.status,
|
|
533
|
-
tx.lastStatusUpdate,
|
|
534
|
-
]);
|
|
535
|
-
expect(txs).toEqual([
|
|
536
|
-
[
|
|
537
|
-
testData.tx4.txId,
|
|
538
|
-
TransactionStatus.SENT,
|
|
539
|
-
String(testData.currentTimeStampAsSeconds),
|
|
540
|
-
],
|
|
541
|
-
]);
|
|
542
|
-
});
|
|
543
|
-
|
|
544
|
-
/**
|
|
545
|
-
* @target TxPot.processSignedTx should not submit the tx nor update the status
|
|
546
|
-
* when at least one submit validator does not allow submission
|
|
547
|
-
* @dependencies
|
|
548
|
-
* - database
|
|
549
|
-
* @scenario
|
|
550
|
-
* - insert tx with signed status
|
|
551
|
-
* - mock PotChainManager and register to TxPot
|
|
552
|
-
* - mock `submitTransaction`
|
|
553
|
-
* - register 3 submit validator functions
|
|
554
|
-
* - 1st and 3rd ones returns true
|
|
555
|
-
* - 2nd one returns false
|
|
556
|
-
* - run test (call `update`)
|
|
557
|
-
* - check if function got called
|
|
558
|
-
* - check db records
|
|
559
|
-
* @expected
|
|
560
|
-
* - `submitTransaction` should NOT got called
|
|
561
|
-
* - columns of the tx should remain unchanged
|
|
562
|
-
*/
|
|
563
|
-
it('should not submit the tx nor update the status when at least one submit validator does not allow submission', async () => {
|
|
564
|
-
// insert tx with signed status
|
|
565
|
-
await txRepository.insert(testData.tx4);
|
|
566
|
-
|
|
567
|
-
// mock PotChainManager and register to TxPot
|
|
568
|
-
const mockedManager = new TestPotChainManager();
|
|
569
|
-
txPot.registerChain(testData.tx4.chain, mockedManager);
|
|
570
|
-
// mock `submitTransaction`
|
|
571
|
-
const mockedSubmitTransaction = vi.fn();
|
|
572
|
-
mockedSubmitTransaction.mockResolvedValue(undefined);
|
|
573
|
-
vi.spyOn(mockedManager, 'submitTransaction').mockImplementation(
|
|
574
|
-
mockedSubmitTransaction
|
|
575
|
-
);
|
|
576
|
-
|
|
577
|
-
// register 3 submit validator functions
|
|
578
|
-
const mockedValidators = [
|
|
579
|
-
{ id: 'validator-1', validator: async (tx: TransactionEntity) => true },
|
|
580
|
-
{
|
|
581
|
-
id: 'validator-2',
|
|
582
|
-
validator: async (tx: TransactionEntity) => false,
|
|
583
|
-
},
|
|
584
|
-
{ id: 'validator-3', validator: async (tx: TransactionEntity) => true },
|
|
585
|
-
];
|
|
586
|
-
mockedValidators.forEach((mockedValidator) =>
|
|
587
|
-
txPot.registerSubmitValidator(
|
|
588
|
-
testData.tx1.chain,
|
|
589
|
-
mockedValidator.id,
|
|
590
|
-
mockedValidator.validator
|
|
591
|
-
)
|
|
592
|
-
);
|
|
593
|
-
|
|
594
|
-
// run test
|
|
595
|
-
await txPot.update();
|
|
596
|
-
|
|
597
|
-
// check if function got called
|
|
598
|
-
expect(mockedSubmitTransaction).not.toHaveBeenCalled();
|
|
599
|
-
|
|
600
|
-
// check db records
|
|
601
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
602
|
-
tx.txId,
|
|
603
|
-
tx.status,
|
|
604
|
-
tx.lastStatusUpdate,
|
|
605
|
-
]);
|
|
606
|
-
expect(txs).toEqual([
|
|
607
|
-
[testData.tx4.txId, testData.tx4.status, testData.tx4.lastStatusUpdate],
|
|
608
|
-
]);
|
|
609
|
-
});
|
|
610
|
-
});
|
|
611
|
-
|
|
612
|
-
describe('processesSentTx', () => {
|
|
613
|
-
/**
|
|
614
|
-
* @target TxPot.processesSentTx should update tx status to completed when
|
|
615
|
-
* transaction is confirmed enough
|
|
616
|
-
* @dependencies
|
|
617
|
-
* - Date
|
|
618
|
-
* - database
|
|
619
|
-
* @scenario
|
|
620
|
-
* - insert tx with sent status
|
|
621
|
-
* - mock PotChainManager and register to TxPot
|
|
622
|
-
* - mock `getTxConfirmation`
|
|
623
|
-
* - mock `getTxRequiredConfirmation`
|
|
624
|
-
* - run test (call `update`)
|
|
625
|
-
* - check db records
|
|
626
|
-
* @expected
|
|
627
|
-
* - columns of the tx should be updated
|
|
628
|
-
* - status should be updated to completed
|
|
629
|
-
* - lastStatusUpdate should be updated to currentTimeStamp in seconds
|
|
630
|
-
*/
|
|
631
|
-
it('should update tx status to completed when transaction is confirmed enough', async () => {
|
|
632
|
-
// insert tx with sent status
|
|
633
|
-
await txRepository.insert(testData.tx6);
|
|
634
|
-
|
|
635
|
-
// mock PotChainManager and register to TxPot
|
|
636
|
-
const mockedManager = new TestPotChainManager();
|
|
637
|
-
txPot.registerChain(testData.tx6.chain, mockedManager);
|
|
638
|
-
// mock `getTxConfirmation`
|
|
639
|
-
vi.spyOn(mockedManager, 'getTxConfirmation').mockResolvedValue(5);
|
|
640
|
-
// mock `getTxRequiredConfirmation`
|
|
641
|
-
vi.spyOn(mockedManager, 'getTxRequiredConfirmation').mockReturnValue(5);
|
|
642
|
-
|
|
643
|
-
// run test
|
|
644
|
-
await txPot.update();
|
|
645
|
-
|
|
646
|
-
// check db records
|
|
647
|
-
const txs = (await txRepository.find()).flatMap((tx) => [
|
|
648
|
-
tx.txId,
|
|
649
|
-
tx.status,
|
|
650
|
-
tx.lastStatusUpdate,
|
|
651
|
-
]);
|
|
652
|
-
expect(txs).toEqual([
|
|
653
|
-
testData.tx6.txId,
|
|
654
|
-
TransactionStatus.COMPLETED,
|
|
655
|
-
String(testData.currentTimeStampAsSeconds),
|
|
656
|
-
]);
|
|
657
|
-
});
|
|
658
|
-
|
|
659
|
-
/**
|
|
660
|
-
* @target TxPot.processesSentTx should only update tx lastCheck when transaction
|
|
661
|
-
* is NOT confirmed enough
|
|
662
|
-
* @dependencies
|
|
663
|
-
* - database
|
|
664
|
-
* @scenario
|
|
665
|
-
* - insert tx with sent status
|
|
666
|
-
* - mock PotChainManager and register to TxPot
|
|
667
|
-
* - mock `getTxConfirmation`
|
|
668
|
-
* - mock `getTxRequiredConfirmation`
|
|
669
|
-
* - mock `getHeight`
|
|
670
|
-
* - run test (call `update`)
|
|
671
|
-
* - check db records
|
|
672
|
-
* @expected
|
|
673
|
-
* - columns of the tx should be as expected
|
|
674
|
-
* - lastCheck should be updated to current height
|
|
675
|
-
* - status and lastStatusUpdate should remain unchanged
|
|
676
|
-
*/
|
|
677
|
-
it('should only update tx lastCheck when transaction is NOT confirmed enough', async () => {
|
|
678
|
-
// insert tx with sent status
|
|
679
|
-
await txRepository.insert(testData.tx6);
|
|
680
|
-
|
|
681
|
-
// mock PotChainManager and register to TxPot
|
|
682
|
-
const mockedManager = new TestPotChainManager();
|
|
683
|
-
txPot.registerChain(testData.tx6.chain, mockedManager);
|
|
684
|
-
// mock `getTxConfirmation`
|
|
685
|
-
vi.spyOn(mockedManager, 'getTxConfirmation').mockResolvedValue(5);
|
|
686
|
-
// mock `getTxRequiredConfirmation`
|
|
687
|
-
vi.spyOn(mockedManager, 'getTxRequiredConfirmation').mockReturnValue(10);
|
|
688
|
-
// mock `getHeight`
|
|
689
|
-
const mockedHeight = 100110;
|
|
690
|
-
vi.spyOn(mockedManager, 'getHeight').mockResolvedValue(mockedHeight);
|
|
691
|
-
|
|
692
|
-
// run test
|
|
693
|
-
await txPot.update();
|
|
694
|
-
|
|
695
|
-
// check db records
|
|
696
|
-
const txs = (await txRepository.find()).flatMap((tx) => [
|
|
697
|
-
tx.txId,
|
|
698
|
-
tx.status,
|
|
699
|
-
tx.lastCheck,
|
|
700
|
-
tx.lastStatusUpdate,
|
|
701
|
-
]);
|
|
702
|
-
expect(txs).toEqual([
|
|
703
|
-
testData.tx6.txId,
|
|
704
|
-
testData.tx6.status,
|
|
705
|
-
mockedHeight,
|
|
706
|
-
testData.tx6.lastStatusUpdate,
|
|
707
|
-
]);
|
|
708
|
-
});
|
|
709
|
-
|
|
710
|
-
/**
|
|
711
|
-
* @target TxPot.processesSentTx should update tx lastCheck when transaction
|
|
712
|
-
* is found in mempool
|
|
713
|
-
* @dependencies
|
|
714
|
-
* - database
|
|
715
|
-
* @scenario
|
|
716
|
-
* - insert tx with sent status
|
|
717
|
-
* - mock PotChainManager and register to TxPot
|
|
718
|
-
* - mock `getTxConfirmation`
|
|
719
|
-
* - mock `getTxRequiredConfirmation` to return -1
|
|
720
|
-
* - mock `isTxInMempool` to return true
|
|
721
|
-
* - mock `getHeight`
|
|
722
|
-
* - run test (call `update`)
|
|
723
|
-
* - check db records
|
|
724
|
-
* @expected
|
|
725
|
-
* - columns of the tx should be as expected
|
|
726
|
-
* - lastCheck should be updated to current height
|
|
727
|
-
* - status and lastStatusUpdate should remain unchanged
|
|
728
|
-
*/
|
|
729
|
-
it('should update tx lastCheck when transaction is found in mempool', async () => {
|
|
730
|
-
// insert tx with sent status
|
|
731
|
-
await txRepository.insert(testData.tx6);
|
|
732
|
-
|
|
733
|
-
// mock PotChainManager and register to TxPot
|
|
734
|
-
const mockedManager = new TestPotChainManager();
|
|
735
|
-
txPot.registerChain(testData.tx6.chain, mockedManager);
|
|
736
|
-
// mock `getTxConfirmation`
|
|
737
|
-
vi.spyOn(mockedManager, 'getTxConfirmation').mockResolvedValue(-1);
|
|
738
|
-
// mock `getTxRequiredConfirmation`
|
|
739
|
-
vi.spyOn(mockedManager, 'getTxRequiredConfirmation').mockReturnValue(10);
|
|
740
|
-
// mock `isTxInMempool`
|
|
741
|
-
vi.spyOn(mockedManager, 'isTxInMempool').mockResolvedValue(true);
|
|
742
|
-
// mock `getHeight`
|
|
743
|
-
const mockedHeight = 100110;
|
|
744
|
-
vi.spyOn(mockedManager, 'getHeight').mockResolvedValue(mockedHeight);
|
|
745
|
-
|
|
746
|
-
// run test
|
|
747
|
-
await txPot.update();
|
|
748
|
-
|
|
749
|
-
// check db records
|
|
750
|
-
const txs = (await txRepository.find()).flatMap((tx) => [
|
|
751
|
-
tx.txId,
|
|
752
|
-
tx.status,
|
|
753
|
-
tx.lastCheck,
|
|
754
|
-
tx.lastStatusUpdate,
|
|
755
|
-
]);
|
|
756
|
-
expect(txs).toEqual([
|
|
757
|
-
testData.tx6.txId,
|
|
758
|
-
testData.tx6.status,
|
|
759
|
-
mockedHeight,
|
|
760
|
-
testData.tx6.lastStatusUpdate,
|
|
761
|
-
]);
|
|
762
|
-
});
|
|
763
|
-
|
|
764
|
-
/**
|
|
765
|
-
* @target TxPot.processesSentTx should resubmit if tx is not found but still valid
|
|
766
|
-
* @dependencies
|
|
767
|
-
* - database
|
|
768
|
-
* @scenario
|
|
769
|
-
* - insert tx with sent status
|
|
770
|
-
* - mock PotChainManager and register to TxPot
|
|
771
|
-
* - mock `getTxConfirmation`
|
|
772
|
-
* - mock `getTxRequiredConfirmation` to return -1
|
|
773
|
-
* - mock `isTxInMempool` to return false
|
|
774
|
-
* - mock `isTxValid` to return true
|
|
775
|
-
* - mock `submitTransaction`
|
|
776
|
-
* - run test (call `update`)
|
|
777
|
-
* - check if function got called
|
|
778
|
-
* @expected
|
|
779
|
-
* - `submitTransaction` should got called
|
|
780
|
-
*/
|
|
781
|
-
it('should resubmit if tx is not found but still valid', async () => {
|
|
782
|
-
// insert tx with sent status
|
|
783
|
-
await txRepository.insert(testData.tx6);
|
|
784
|
-
|
|
785
|
-
// mock PotChainManager and register to TxPot
|
|
786
|
-
const mockedManager = new TestPotChainManager();
|
|
787
|
-
txPot.registerChain(testData.tx6.chain, mockedManager);
|
|
788
|
-
// mock `getTxConfirmation`
|
|
789
|
-
vi.spyOn(mockedManager, 'getTxConfirmation').mockResolvedValue(-1);
|
|
790
|
-
// mock `getTxRequiredConfirmation`
|
|
791
|
-
vi.spyOn(mockedManager, 'getTxRequiredConfirmation').mockReturnValue(10);
|
|
792
|
-
// mock `isTxInMempool`
|
|
793
|
-
vi.spyOn(mockedManager, 'isTxInMempool').mockResolvedValue(false);
|
|
794
|
-
// mock `isTxValid`
|
|
795
|
-
vi.spyOn(mockedManager, 'isTxValid').mockResolvedValue(true);
|
|
796
|
-
// mock `submitTransaction`
|
|
797
|
-
const mockedSubmitTransaction = vi.fn();
|
|
798
|
-
mockedSubmitTransaction.mockResolvedValue(undefined);
|
|
799
|
-
vi.spyOn(mockedManager, 'submitTransaction').mockImplementation(
|
|
800
|
-
mockedSubmitTransaction
|
|
801
|
-
);
|
|
802
|
-
|
|
803
|
-
// run test
|
|
804
|
-
await txPot.update();
|
|
805
|
-
|
|
806
|
-
// check if function got called
|
|
807
|
-
expect(mockedSubmitTransaction).toHaveBeenCalled();
|
|
808
|
-
});
|
|
809
|
-
|
|
810
|
-
/**
|
|
811
|
-
* @target TxPot.processesSentTx should not resubmit if submit validator does not allow
|
|
812
|
-
* @dependencies
|
|
813
|
-
* - database
|
|
814
|
-
* @scenario
|
|
815
|
-
* - insert tx with sent status
|
|
816
|
-
* - mock PotChainManager and register to TxPot
|
|
817
|
-
* - mock `getTxConfirmation`
|
|
818
|
-
* - mock `getTxRequiredConfirmation` to return -1
|
|
819
|
-
* - mock `isTxInMempool` to return false
|
|
820
|
-
* - mock `isTxValid` to return true
|
|
821
|
-
* - mock `submitTransaction`
|
|
822
|
-
* - register a submit validator function to return false
|
|
823
|
-
* - run test (call `update`)
|
|
824
|
-
* - check if function got called
|
|
825
|
-
* @expected
|
|
826
|
-
* - `submitTransaction` should NOT got called
|
|
827
|
-
*/
|
|
828
|
-
it('should not resubmit if submit validator does not allow', async () => {
|
|
829
|
-
// insert tx with sent status
|
|
830
|
-
await txRepository.insert(testData.tx6);
|
|
831
|
-
|
|
832
|
-
// mock PotChainManager and register to TxPot
|
|
833
|
-
const mockedManager = new TestPotChainManager();
|
|
834
|
-
txPot.registerChain(testData.tx6.chain, mockedManager);
|
|
835
|
-
// mock `getTxConfirmation`
|
|
836
|
-
vi.spyOn(mockedManager, 'getTxConfirmation').mockResolvedValue(-1);
|
|
837
|
-
// mock `getTxRequiredConfirmation`
|
|
838
|
-
vi.spyOn(mockedManager, 'getTxRequiredConfirmation').mockReturnValue(10);
|
|
839
|
-
// mock `isTxInMempool`
|
|
840
|
-
vi.spyOn(mockedManager, 'isTxInMempool').mockResolvedValue(false);
|
|
841
|
-
// mock `isTxValid`
|
|
842
|
-
vi.spyOn(mockedManager, 'isTxValid').mockResolvedValue(true);
|
|
843
|
-
// mock `submitTransaction`
|
|
844
|
-
const mockedSubmitTransaction = vi.fn();
|
|
845
|
-
mockedSubmitTransaction.mockResolvedValue(undefined);
|
|
846
|
-
vi.spyOn(mockedManager, 'submitTransaction').mockImplementation(
|
|
847
|
-
mockedSubmitTransaction
|
|
848
|
-
);
|
|
849
|
-
|
|
850
|
-
// register a submit validator function to return false
|
|
851
|
-
txPot.registerSubmitValidator(
|
|
852
|
-
testData.tx6.chain,
|
|
853
|
-
'validator-2',
|
|
854
|
-
async (tx: TransactionEntity) => false
|
|
855
|
-
);
|
|
856
|
-
|
|
857
|
-
// run test
|
|
858
|
-
await txPot.update();
|
|
859
|
-
|
|
860
|
-
// check if function got called
|
|
861
|
-
expect(mockedSubmitTransaction).not.toHaveBeenCalled();
|
|
862
|
-
});
|
|
863
|
-
|
|
864
|
-
/**
|
|
865
|
-
* @target TxPot.processesSentTx should set transaction as invalid if tx is not valid anymore
|
|
866
|
-
* @dependencies
|
|
867
|
-
* - database
|
|
868
|
-
* @scenario
|
|
869
|
-
* - insert tx with sent status
|
|
870
|
-
* - mock PotChainManager and register to TxPot
|
|
871
|
-
* - mock `getTxConfirmation`
|
|
872
|
-
* - mock `getTxRequiredConfirmation` to return -1
|
|
873
|
-
* - mock `isTxInMempool` to return false
|
|
874
|
-
* - mock `isTxValid` to return false
|
|
875
|
-
* - mock `getHeight`
|
|
876
|
-
* - mock TxPot.setTransactionAsInvalid
|
|
877
|
-
* - run test (call `update`)
|
|
878
|
-
* - check if function got called
|
|
879
|
-
* @expected
|
|
880
|
-
* - `setTransactionAsInvalid` should got called
|
|
881
|
-
*/
|
|
882
|
-
it('should set transaction as invalid if tx is not valid anymore', async () => {
|
|
883
|
-
// insert tx with sent status
|
|
884
|
-
await txRepository.insert(testData.tx6);
|
|
885
|
-
|
|
886
|
-
// mock PotChainManager and register to TxPot
|
|
887
|
-
const mockedManager = new TestPotChainManager();
|
|
888
|
-
txPot.registerChain(testData.tx6.chain, mockedManager);
|
|
889
|
-
// mock `getTxConfirmation`
|
|
890
|
-
vi.spyOn(mockedManager, 'getTxConfirmation').mockResolvedValue(-1);
|
|
891
|
-
// mock `getTxRequiredConfirmation`
|
|
892
|
-
vi.spyOn(mockedManager, 'getTxRequiredConfirmation').mockReturnValue(10);
|
|
893
|
-
// mock `isTxInMempool`
|
|
894
|
-
vi.spyOn(mockedManager, 'isTxInMempool').mockResolvedValue(false);
|
|
895
|
-
// mock `isTxValid`
|
|
896
|
-
vi.spyOn(mockedManager, 'isTxValid').mockResolvedValue(false);
|
|
897
|
-
|
|
898
|
-
// mock TxPot.setTransactionAsInvalid
|
|
899
|
-
const mockedSetTransactionAsInvalid = vi.fn();
|
|
900
|
-
vi.spyOn(txPot as any, 'setTransactionAsInvalid').mockImplementation(
|
|
901
|
-
mockedSetTransactionAsInvalid
|
|
902
|
-
);
|
|
903
|
-
|
|
904
|
-
// run test
|
|
905
|
-
await txPot.update();
|
|
906
|
-
|
|
907
|
-
// check if function got called
|
|
908
|
-
expect(mockedSetTransactionAsInvalid).toHaveBeenCalled();
|
|
909
|
-
});
|
|
910
|
-
|
|
911
|
-
/**
|
|
912
|
-
* @target TxPot.processesSentTx should set transaction as invalid when registered
|
|
913
|
-
* validator recognizes the tx as invalid
|
|
914
|
-
* @dependencies
|
|
915
|
-
* - database
|
|
916
|
-
* @scenario
|
|
917
|
-
* - insert tx with sent status
|
|
918
|
-
* - register a validator function to return false
|
|
919
|
-
* - mock PotChainManager and register to TxPot
|
|
920
|
-
* - mock `getTxConfirmation`
|
|
921
|
-
* - mock `getTxRequiredConfirmation` to return -1
|
|
922
|
-
* - mock `isTxInMempool` to return false
|
|
923
|
-
* - mock `isTxValid` to return true
|
|
924
|
-
* - mock `getHeight`
|
|
925
|
-
* - mock TxPot.setTransactionAsInvalid
|
|
926
|
-
* - run test (call `update`)
|
|
927
|
-
* - check if function got called
|
|
928
|
-
* @expected
|
|
929
|
-
* - `setTransactionAsInvalid` should got called
|
|
930
|
-
*/
|
|
931
|
-
it('should set transaction as invalid when registered validator recognizes the tx as invalid', async () => {
|
|
932
|
-
// insert tx with sent status
|
|
933
|
-
await txRepository.insert(testData.tx6);
|
|
934
|
-
|
|
935
|
-
// register a validator function
|
|
936
|
-
const mockedValidator = async (tx: TransactionEntity) => false;
|
|
937
|
-
txPot.registerValidator(
|
|
938
|
-
testData.tx6.chain,
|
|
939
|
-
testData.tx6.txType,
|
|
940
|
-
'id',
|
|
941
|
-
mockedValidator
|
|
942
|
-
);
|
|
943
|
-
|
|
944
|
-
// mock PotChainManager and register to TxPot
|
|
945
|
-
const mockedManager = new TestPotChainManager();
|
|
946
|
-
txPot.registerChain(testData.tx6.chain, mockedManager);
|
|
947
|
-
// mock `getTxConfirmation`
|
|
948
|
-
vi.spyOn(mockedManager, 'getTxConfirmation').mockResolvedValue(-1);
|
|
949
|
-
// mock `getTxRequiredConfirmation`
|
|
950
|
-
vi.spyOn(mockedManager, 'getTxRequiredConfirmation').mockReturnValue(10);
|
|
951
|
-
// mock `isTxInMempool`
|
|
952
|
-
vi.spyOn(mockedManager, 'isTxInMempool').mockResolvedValue(false);
|
|
953
|
-
// mock `isTxValid`
|
|
954
|
-
vi.spyOn(mockedManager, 'isTxValid').mockResolvedValue(true);
|
|
955
|
-
|
|
956
|
-
// mock TxPot.setTransactionAsInvalid
|
|
957
|
-
const mockedSetTransactionAsInvalid = vi.fn();
|
|
958
|
-
vi.spyOn(txPot as any, 'setTransactionAsInvalid').mockImplementation(
|
|
959
|
-
mockedSetTransactionAsInvalid
|
|
960
|
-
);
|
|
961
|
-
|
|
962
|
-
// run test
|
|
963
|
-
await txPot.update();
|
|
964
|
-
|
|
965
|
-
// check if function got called
|
|
966
|
-
expect(mockedSetTransactionAsInvalid).toHaveBeenCalled();
|
|
967
|
-
});
|
|
968
|
-
});
|
|
969
|
-
|
|
970
|
-
describe('getTxsByStatus', () => {
|
|
971
|
-
/**
|
|
972
|
-
* @target TxPot.getTxsByStatus should return txs filtered by status
|
|
973
|
-
* @dependencies
|
|
974
|
-
* - database
|
|
975
|
-
* @scenario
|
|
976
|
-
* - insert 3 txs with different status
|
|
977
|
-
* - run test
|
|
978
|
-
* - check returned value
|
|
979
|
-
* @expected
|
|
980
|
-
* - should return 2 filtered txs
|
|
981
|
-
*/
|
|
982
|
-
it('should return txs filtered by status', async () => {
|
|
983
|
-
await txRepository.insert(testData.tx1); // different status
|
|
984
|
-
await txRepository.insert(testData.tx3);
|
|
985
|
-
await txRepository.insert(testData.tx5);
|
|
986
|
-
|
|
987
|
-
const txs = await txPot.getTxsByStatus(
|
|
988
|
-
testData.tx3.status as TransactionStatus
|
|
989
|
-
);
|
|
990
|
-
expect(txs.length).toEqual(2);
|
|
991
|
-
expect(txs[0].txId).toEqual(testData.tx3.txId);
|
|
992
|
-
expect(txs[1].txId).toEqual(testData.tx5.txId);
|
|
993
|
-
});
|
|
994
|
-
|
|
995
|
-
/**
|
|
996
|
-
* @target TxPot.getTxsByStatus should only return valid txs when
|
|
997
|
-
* validate key is passed
|
|
998
|
-
* @dependencies
|
|
999
|
-
* - database
|
|
1000
|
-
* @scenario
|
|
1001
|
-
* - insert 2 txs with same status
|
|
1002
|
-
* - register a validator function
|
|
1003
|
-
* - should return true for first tx
|
|
1004
|
-
* - should return false for second tx
|
|
1005
|
-
* - mock TxPot.setTransactionAsInvalid
|
|
1006
|
-
* - run test
|
|
1007
|
-
* - check returned value
|
|
1008
|
-
* @expected
|
|
1009
|
-
* - should return the valid tx
|
|
1010
|
-
*/
|
|
1011
|
-
it('should only return valid txs when validate key is passed', async () => {
|
|
1012
|
-
// insert 2 txs with same status
|
|
1013
|
-
await txRepository.insert(testData.tx3);
|
|
1014
|
-
await txRepository.insert(testData.tx5);
|
|
1015
|
-
|
|
1016
|
-
// register a validator function
|
|
1017
|
-
const mockedValidator = async (tx: TransactionEntity) => {
|
|
1018
|
-
if (tx.txId === testData.tx3.txId) return true;
|
|
1019
|
-
return false;
|
|
1020
|
-
};
|
|
1021
|
-
txPot.registerValidator(
|
|
1022
|
-
testData.tx3.chain,
|
|
1023
|
-
testData.tx3.txType,
|
|
1024
|
-
'tx3-validator',
|
|
1025
|
-
mockedValidator
|
|
1026
|
-
);
|
|
1027
|
-
txPot.registerValidator(
|
|
1028
|
-
testData.tx5.chain,
|
|
1029
|
-
testData.tx5.txType,
|
|
1030
|
-
'tx5-validator',
|
|
1031
|
-
mockedValidator
|
|
1032
|
-
);
|
|
1033
|
-
|
|
1034
|
-
// mock TxPot.setTransactionAsInvalid
|
|
1035
|
-
vi.spyOn(txPot as any, 'setTransactionAsInvalid').mockResolvedValue(
|
|
1036
|
-
undefined
|
|
1037
|
-
);
|
|
1038
|
-
|
|
1039
|
-
// run test
|
|
1040
|
-
const txs = await txPot.getTxsByStatus(
|
|
1041
|
-
testData.tx3.status as TransactionStatus,
|
|
1042
|
-
true
|
|
1043
|
-
);
|
|
1044
|
-
expect(txs.length).toEqual(1);
|
|
1045
|
-
expect(txs[0].txId).toEqual(testData.tx3.txId);
|
|
1046
|
-
});
|
|
1047
|
-
});
|
|
1048
|
-
|
|
1049
|
-
describe('addTx', () => {
|
|
1050
|
-
/**
|
|
1051
|
-
* @target TxPot.addTx should insert new tx successfully
|
|
1052
|
-
* @dependencies
|
|
1053
|
-
* - Date
|
|
1054
|
-
* - database
|
|
1055
|
-
* @scenario
|
|
1056
|
-
* - run test
|
|
1057
|
-
* - check db records
|
|
1058
|
-
* @expected
|
|
1059
|
-
* - new tx should be inserted
|
|
1060
|
-
*/
|
|
1061
|
-
it('should insert new tx successfully', async () => {
|
|
1062
|
-
await txPot.addTx(
|
|
1063
|
-
testData.tx1.txId,
|
|
1064
|
-
testData.tx1.chain,
|
|
1065
|
-
testData.tx1.txType,
|
|
1066
|
-
testData.tx1.requiredSign,
|
|
1067
|
-
testData.tx1.serializedTx,
|
|
1068
|
-
testData.tx1.status as TransactionStatus,
|
|
1069
|
-
testData.tx1.lastCheck
|
|
1070
|
-
);
|
|
1071
|
-
|
|
1072
|
-
const txs = await txRepository.find();
|
|
1073
|
-
expect(txs.length).toEqual(1);
|
|
1074
|
-
expect(txs[0]).toEqual({
|
|
1075
|
-
...testData.tx1,
|
|
1076
|
-
lastStatusUpdate: String(testData.currentTimeStampAsSeconds),
|
|
1077
|
-
extra: null,
|
|
1078
|
-
extra2: null,
|
|
1079
|
-
});
|
|
1080
|
-
});
|
|
1081
|
-
|
|
1082
|
-
/**
|
|
1083
|
-
* @target TxPot.addTx should insert new tx with extra fields successfully
|
|
1084
|
-
* @dependencies
|
|
1085
|
-
* - Date
|
|
1086
|
-
* - database
|
|
1087
|
-
* @scenario
|
|
1088
|
-
* - run test
|
|
1089
|
-
* - check db records
|
|
1090
|
-
* @expected
|
|
1091
|
-
* - new tx should be inserted
|
|
1092
|
-
*/
|
|
1093
|
-
it('should insert new tx with extra fields successfully', async () => {
|
|
1094
|
-
await txPot.addTx(
|
|
1095
|
-
testData.tx3.txId,
|
|
1096
|
-
testData.tx3.chain,
|
|
1097
|
-
testData.tx3.txType,
|
|
1098
|
-
testData.tx3.requiredSign,
|
|
1099
|
-
testData.tx3.serializedTx,
|
|
1100
|
-
testData.tx3.status as TransactionStatus,
|
|
1101
|
-
testData.tx3.lastCheck,
|
|
1102
|
-
testData.tx3.extra,
|
|
1103
|
-
testData.tx3.extra2
|
|
1104
|
-
);
|
|
1105
|
-
|
|
1106
|
-
const txs = await txRepository.find();
|
|
1107
|
-
expect(txs.length).toEqual(1);
|
|
1108
|
-
expect(txs[0]).toEqual({
|
|
1109
|
-
...testData.tx3,
|
|
1110
|
-
failedInSign: false,
|
|
1111
|
-
signFailedCount: 0,
|
|
1112
|
-
lastStatusUpdate: String(testData.currentTimeStampAsSeconds),
|
|
1113
|
-
extra: testData.tx3.extra,
|
|
1114
|
-
extra2: null,
|
|
1115
|
-
});
|
|
1116
|
-
});
|
|
1117
|
-
});
|
|
1118
|
-
|
|
1119
|
-
describe('setTxStatusById', () => {
|
|
1120
|
-
/**
|
|
1121
|
-
* @target TxPot.setTxStatusById should throw error when tx is not found
|
|
1122
|
-
* @dependencies
|
|
1123
|
-
* - Date
|
|
1124
|
-
* - database
|
|
1125
|
-
* @scenario
|
|
1126
|
-
* - run test & expect exception thrown
|
|
1127
|
-
* @expected
|
|
1128
|
-
* - it should throw Error
|
|
1129
|
-
*/
|
|
1130
|
-
it('should throw error when tx is not found', async () => {
|
|
1131
|
-
await expect(async () => {
|
|
1132
|
-
await txPot.setTxStatusById(
|
|
1133
|
-
testData.tx1.txId,
|
|
1134
|
-
testData.tx1.chain,
|
|
1135
|
-
TransactionStatus.IN_SIGN
|
|
1136
|
-
);
|
|
1137
|
-
}).rejects.toThrow(Error);
|
|
1138
|
-
});
|
|
1139
|
-
|
|
1140
|
-
/**
|
|
1141
|
-
* @target TxPot.setTxStatusById should update status and lastStatusUpdate successfully
|
|
1142
|
-
* @dependencies
|
|
1143
|
-
* - Date
|
|
1144
|
-
* - database
|
|
1145
|
-
* @scenario
|
|
1146
|
-
* - insert 2 txs
|
|
1147
|
-
* - run test
|
|
1148
|
-
* - check db records
|
|
1149
|
-
* @expected
|
|
1150
|
-
* - columns of target tx should be updated
|
|
1151
|
-
* - status should be updated to new status
|
|
1152
|
-
* - lastStatusUpdate should be updated to currentTimeStamp in seconds
|
|
1153
|
-
* - columns of other txs should remain unchanged
|
|
1154
|
-
*/
|
|
1155
|
-
it('should update status and lastStatusUpdate successfully', async () => {
|
|
1156
|
-
await txRepository.insert(testData.tx1);
|
|
1157
|
-
await txRepository.insert(testData.tx2);
|
|
1158
|
-
|
|
1159
|
-
const newStatus = TransactionStatus.IN_SIGN;
|
|
1160
|
-
await txPot.setTxStatusById(
|
|
1161
|
-
testData.tx1.txId,
|
|
1162
|
-
testData.tx1.chain,
|
|
1163
|
-
newStatus
|
|
1164
|
-
);
|
|
1165
|
-
|
|
1166
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
1167
|
-
tx.txId,
|
|
1168
|
-
tx.status,
|
|
1169
|
-
tx.lastStatusUpdate,
|
|
1170
|
-
]);
|
|
1171
|
-
expect(txs).toEqual([
|
|
1172
|
-
[
|
|
1173
|
-
testData.tx1.txId,
|
|
1174
|
-
newStatus,
|
|
1175
|
-
String(testData.currentTimeStampAsSeconds),
|
|
1176
|
-
],
|
|
1177
|
-
[testData.tx2.txId, testData.tx2.status, testData.tx2.lastStatusUpdate],
|
|
1178
|
-
]);
|
|
1179
|
-
});
|
|
1180
|
-
});
|
|
1181
|
-
|
|
1182
|
-
describe('setTxAsSignFailed', () => {
|
|
1183
|
-
/**
|
|
1184
|
-
* @target TxPot.setTxAsSignFailed should set tx as sign-failed and update required fields successfully
|
|
1185
|
-
* @dependencies
|
|
1186
|
-
* - Date
|
|
1187
|
-
* - database
|
|
1188
|
-
* @scenario
|
|
1189
|
-
* - insert 2 txs
|
|
1190
|
-
* - run test
|
|
1191
|
-
* - check db records
|
|
1192
|
-
* @expected
|
|
1193
|
-
* - columns of target tx should be updated as expected
|
|
1194
|
-
* - status should be sign-failed
|
|
1195
|
-
* - lastStatusUpdate should be updated to currentTimeStamp in seconds
|
|
1196
|
-
* - failedInSign should be true
|
|
1197
|
-
* - signFailedCount should be incremented
|
|
1198
|
-
* - columns of other txs should remain unchanged
|
|
1199
|
-
*/
|
|
1200
|
-
it('should set tx as sign-failed and update required fields successfully', async () => {
|
|
1201
|
-
await txRepository.insert(testData.tx3);
|
|
1202
|
-
await txRepository.insert(testData.tx5);
|
|
1203
|
-
|
|
1204
|
-
await txPot.setTxAsSignFailed(testData.tx5.txId, testData.tx5.chain);
|
|
1205
|
-
|
|
1206
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
1207
|
-
tx.txId,
|
|
1208
|
-
tx.status,
|
|
1209
|
-
tx.lastStatusUpdate,
|
|
1210
|
-
tx.failedInSign,
|
|
1211
|
-
tx.signFailedCount,
|
|
1212
|
-
]);
|
|
1213
|
-
expect(txs).toEqual([
|
|
1214
|
-
[
|
|
1215
|
-
testData.tx3.txId,
|
|
1216
|
-
testData.tx3.status,
|
|
1217
|
-
testData.tx3.lastStatusUpdate,
|
|
1218
|
-
testData.tx3.failedInSign,
|
|
1219
|
-
testData.tx3.signFailedCount,
|
|
1220
|
-
],
|
|
1221
|
-
[
|
|
1222
|
-
testData.tx5.txId,
|
|
1223
|
-
TransactionStatus.SIGN_FAILED,
|
|
1224
|
-
String(testData.currentTimeStampAsSeconds),
|
|
1225
|
-
true,
|
|
1226
|
-
testData.tx5.signFailedCount + 1,
|
|
1227
|
-
],
|
|
1228
|
-
]);
|
|
1229
|
-
});
|
|
1230
|
-
});
|
|
1231
|
-
|
|
1232
|
-
describe('setTxAsSigned', () => {
|
|
1233
|
-
/**
|
|
1234
|
-
* @target TxPot.setTxAsSigned should set tx as signed and update required fields successfully
|
|
1235
|
-
* @dependencies
|
|
1236
|
-
* - Date
|
|
1237
|
-
* - database
|
|
1238
|
-
* @scenario
|
|
1239
|
-
* - insert 2 txs
|
|
1240
|
-
* - run test
|
|
1241
|
-
* - check db records
|
|
1242
|
-
* @expected
|
|
1243
|
-
* - columns of target tx should be updated as expected
|
|
1244
|
-
* - status should be signed
|
|
1245
|
-
* - lastCheck should be updated to currentHeight
|
|
1246
|
-
* - lastStatusUpdate should be updated to currentTimeStamp in seconds
|
|
1247
|
-
* - serializedTx should be updated
|
|
1248
|
-
* - columns of other txs should remain unchanged
|
|
1249
|
-
*/
|
|
1250
|
-
it('should set tx as signed and update required fields successfully', async () => {
|
|
1251
|
-
await txRepository.insert(testData.tx3);
|
|
1252
|
-
await txRepository.insert(testData.tx5);
|
|
1253
|
-
|
|
1254
|
-
const currentHeight = testData.tx3.lastCheck + 10;
|
|
1255
|
-
const serializedSignedTx = 'serialized-signed-tx';
|
|
1256
|
-
await txPot.setTxAsSigned(
|
|
1257
|
-
testData.tx3.txId,
|
|
1258
|
-
testData.tx3.chain,
|
|
1259
|
-
serializedSignedTx,
|
|
1260
|
-
currentHeight
|
|
1261
|
-
);
|
|
1262
|
-
|
|
1263
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
1264
|
-
tx.txId,
|
|
1265
|
-
tx.status,
|
|
1266
|
-
tx.lastCheck,
|
|
1267
|
-
tx.lastStatusUpdate,
|
|
1268
|
-
tx.serializedTx,
|
|
1269
|
-
]);
|
|
1270
|
-
expect(txs).toEqual([
|
|
1271
|
-
[
|
|
1272
|
-
testData.tx3.txId,
|
|
1273
|
-
TransactionStatus.SIGNED,
|
|
1274
|
-
currentHeight,
|
|
1275
|
-
String(testData.currentTimeStampAsSeconds),
|
|
1276
|
-
serializedSignedTx,
|
|
1277
|
-
],
|
|
1278
|
-
[
|
|
1279
|
-
testData.tx5.txId,
|
|
1280
|
-
testData.tx5.status,
|
|
1281
|
-
testData.tx5.lastCheck,
|
|
1282
|
-
testData.tx5.lastStatusUpdate,
|
|
1283
|
-
testData.tx5.serializedTx,
|
|
1284
|
-
],
|
|
1285
|
-
]);
|
|
1286
|
-
});
|
|
1287
|
-
|
|
1288
|
-
/**
|
|
1289
|
-
* @target TxPot.setTxAsSigned should also update extra fields if are provided
|
|
1290
|
-
* @dependencies
|
|
1291
|
-
* - Date
|
|
1292
|
-
* - database
|
|
1293
|
-
* @scenario
|
|
1294
|
-
* - insert 2 txs
|
|
1295
|
-
* - run test
|
|
1296
|
-
* - check db records
|
|
1297
|
-
* @expected
|
|
1298
|
-
* - columns of target tx should be updated as expected
|
|
1299
|
-
* - status should be signed
|
|
1300
|
-
* - lastCheck should be updated to currentHeight
|
|
1301
|
-
* - lastStatusUpdate should be updated to currentTimeStamp in seconds
|
|
1302
|
-
* - serializedTx should be updated
|
|
1303
|
-
* - extra should be updated
|
|
1304
|
-
* - extra2 should be updated
|
|
1305
|
-
* - columns of other txs should remain unchanged
|
|
1306
|
-
*/
|
|
1307
|
-
it('should also update extra fields if are provided', async () => {
|
|
1308
|
-
await txRepository.insert(testData.tx3);
|
|
1309
|
-
await txRepository.insert(testData.tx5);
|
|
1310
|
-
|
|
1311
|
-
const currentHeight = testData.tx3.lastCheck + 10;
|
|
1312
|
-
const serializedSignedTx = 'serialized-signed-tx';
|
|
1313
|
-
const updatedExtra = 'updated-extra';
|
|
1314
|
-
const updatedExtra2 = 'updated-extra-2';
|
|
1315
|
-
await txPot.setTxAsSigned(
|
|
1316
|
-
testData.tx3.txId,
|
|
1317
|
-
testData.tx3.chain,
|
|
1318
|
-
serializedSignedTx,
|
|
1319
|
-
currentHeight,
|
|
1320
|
-
updatedExtra,
|
|
1321
|
-
updatedExtra2
|
|
1322
|
-
);
|
|
1323
|
-
|
|
1324
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
1325
|
-
tx.txId,
|
|
1326
|
-
tx.status,
|
|
1327
|
-
tx.lastCheck,
|
|
1328
|
-
tx.lastStatusUpdate,
|
|
1329
|
-
tx.serializedTx,
|
|
1330
|
-
tx.extra,
|
|
1331
|
-
tx.extra2,
|
|
1332
|
-
]);
|
|
1333
|
-
expect(txs).toEqual([
|
|
1334
|
-
[
|
|
1335
|
-
testData.tx3.txId,
|
|
1336
|
-
TransactionStatus.SIGNED,
|
|
1337
|
-
currentHeight,
|
|
1338
|
-
String(testData.currentTimeStampAsSeconds),
|
|
1339
|
-
serializedSignedTx,
|
|
1340
|
-
updatedExtra,
|
|
1341
|
-
updatedExtra2,
|
|
1342
|
-
],
|
|
1343
|
-
[
|
|
1344
|
-
testData.tx5.txId,
|
|
1345
|
-
testData.tx5.status,
|
|
1346
|
-
testData.tx5.lastCheck,
|
|
1347
|
-
testData.tx5.lastStatusUpdate,
|
|
1348
|
-
testData.tx5.serializedTx,
|
|
1349
|
-
testData.tx5.extra ?? null,
|
|
1350
|
-
testData.tx5.extra2 ?? null,
|
|
1351
|
-
],
|
|
1352
|
-
]);
|
|
1353
|
-
});
|
|
1354
|
-
});
|
|
1355
|
-
|
|
1356
|
-
describe('updateTxLastCheck', () => {
|
|
1357
|
-
/**
|
|
1358
|
-
* @target TxPot.updateTxLastCheck should update lastCheck column successfully
|
|
1359
|
-
* @dependencies
|
|
1360
|
-
* - database
|
|
1361
|
-
* @scenario
|
|
1362
|
-
* - insert 2 txs
|
|
1363
|
-
* - run test
|
|
1364
|
-
* - check db records
|
|
1365
|
-
* @expected
|
|
1366
|
-
* - lastCheck of target tx should be updated
|
|
1367
|
-
* - lastCheck of other txs should remain unchanged
|
|
1368
|
-
*/
|
|
1369
|
-
it('should update lastCheck column successfully', async () => {
|
|
1370
|
-
await txRepository.insert(testData.tx1);
|
|
1371
|
-
await txRepository.insert(testData.tx2);
|
|
1372
|
-
|
|
1373
|
-
const updatedLastCheck = testData.tx1.lastCheck + 100;
|
|
1374
|
-
await txPot.updateTxLastCheck(
|
|
1375
|
-
testData.tx1.txId,
|
|
1376
|
-
testData.tx1.chain,
|
|
1377
|
-
updatedLastCheck
|
|
1378
|
-
);
|
|
1379
|
-
|
|
1380
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
1381
|
-
tx.txId,
|
|
1382
|
-
tx.lastCheck,
|
|
1383
|
-
]);
|
|
1384
|
-
expect(txs).toEqual([
|
|
1385
|
-
[testData.tx1.txId, updatedLastCheck],
|
|
1386
|
-
[testData.tx2.txId, testData.tx2.lastCheck],
|
|
1387
|
-
]);
|
|
1388
|
-
});
|
|
1389
|
-
});
|
|
1390
|
-
|
|
1391
|
-
describe('resetFailedInSign', () => {
|
|
1392
|
-
/**
|
|
1393
|
-
* @target TxPot.resetFailedInSign should set failedInSign column to false successfully
|
|
1394
|
-
* @dependencies
|
|
1395
|
-
* - database
|
|
1396
|
-
* @scenario
|
|
1397
|
-
* - insert 3 txs
|
|
1398
|
-
* - 2 with failedInSign column as true
|
|
1399
|
-
* - 1 with failedInSign column as false
|
|
1400
|
-
* - run test
|
|
1401
|
-
* - check db records
|
|
1402
|
-
* @expected
|
|
1403
|
-
* - failedInSign of target tx should be false
|
|
1404
|
-
* - failedInSign of other txs should remain unchanged
|
|
1405
|
-
*/
|
|
1406
|
-
it('should set failedInSign column to false successfully', async () => {
|
|
1407
|
-
await txRepository.insert(testData.tx1); // failedInSign is false
|
|
1408
|
-
await txRepository.insert(testData.tx3);
|
|
1409
|
-
await txRepository.insert(testData.tx4);
|
|
1410
|
-
|
|
1411
|
-
await txPot.resetFailedInSign(testData.tx3.txId, testData.tx3.chain);
|
|
1412
|
-
|
|
1413
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
1414
|
-
tx.txId,
|
|
1415
|
-
tx.failedInSign,
|
|
1416
|
-
]);
|
|
1417
|
-
expect(txs).toEqual([
|
|
1418
|
-
[testData.tx1.txId, testData.tx1.failedInSign],
|
|
1419
|
-
[testData.tx3.txId, false],
|
|
1420
|
-
[testData.tx4.txId, testData.tx4.failedInSign],
|
|
1421
|
-
]);
|
|
1422
|
-
});
|
|
1423
|
-
});
|
|
1424
|
-
|
|
1425
|
-
describe('updateRequiredSign', () => {
|
|
1426
|
-
/**
|
|
1427
|
-
* @target TxPot.updateRequiredSign should update requiredSign column successfully
|
|
1428
|
-
* @dependencies
|
|
1429
|
-
* - database
|
|
1430
|
-
* @scenario
|
|
1431
|
-
* - insert 2 txs
|
|
1432
|
-
* - run test
|
|
1433
|
-
* - check db records
|
|
1434
|
-
* @expected
|
|
1435
|
-
* - requiredSign of target tx should be updated
|
|
1436
|
-
* - requiredSign of other txs should remain unchanged
|
|
1437
|
-
*/
|
|
1438
|
-
it('should update requiredSign column successfully', async () => {
|
|
1439
|
-
await txRepository.insert(testData.tx1);
|
|
1440
|
-
await txRepository.insert(testData.tx2);
|
|
1441
|
-
|
|
1442
|
-
const updatedRequiredSign = testData.tx1.requiredSign + 2;
|
|
1443
|
-
await txPot.updateRequiredSign(
|
|
1444
|
-
testData.tx1.txId,
|
|
1445
|
-
testData.tx1.chain,
|
|
1446
|
-
updatedRequiredSign
|
|
1447
|
-
);
|
|
1448
|
-
|
|
1449
|
-
const txs = (await txRepository.find()).map((tx) => [
|
|
1450
|
-
tx.txId,
|
|
1451
|
-
tx.requiredSign,
|
|
1452
|
-
]);
|
|
1453
|
-
expect(txs).toEqual([
|
|
1454
|
-
[testData.tx1.txId, updatedRequiredSign],
|
|
1455
|
-
[testData.tx2.txId, testData.tx2.requiredSign],
|
|
1456
|
-
]);
|
|
1457
|
-
});
|
|
1458
|
-
});
|
|
1459
|
-
|
|
1460
|
-
describe('getTxByKey', () => {
|
|
1461
|
-
/**
|
|
1462
|
-
* @target TxPot.getTxByKey should return the tx successfully
|
|
1463
|
-
* @dependencies
|
|
1464
|
-
* - database
|
|
1465
|
-
* @scenario
|
|
1466
|
-
* - insert 2 txs
|
|
1467
|
-
* - run test
|
|
1468
|
-
* - check returned value
|
|
1469
|
-
* @expected
|
|
1470
|
-
* - should return the expected tx
|
|
1471
|
-
*/
|
|
1472
|
-
it('should return the tx successfully', async () => {
|
|
1473
|
-
await txRepository.insert(testData.tx1);
|
|
1474
|
-
await txRepository.insert(testData.tx2);
|
|
1475
|
-
|
|
1476
|
-
const tx = await txPot.getTxByKey(testData.tx1.txId, testData.tx1.chain);
|
|
1477
|
-
expect(tx?.txId).toEqual(testData.tx1.txId);
|
|
1478
|
-
});
|
|
1479
|
-
|
|
1480
|
-
/**
|
|
1481
|
-
* @target TxPot.getTxByKey should return null when tx is not found
|
|
1482
|
-
* @dependencies
|
|
1483
|
-
* - database
|
|
1484
|
-
* @scenario
|
|
1485
|
-
* - insert 2 txs
|
|
1486
|
-
* - run test
|
|
1487
|
-
* - check returned value
|
|
1488
|
-
* @expected
|
|
1489
|
-
* - should return null
|
|
1490
|
-
*/
|
|
1491
|
-
it('should return null when tx is not found', async () => {
|
|
1492
|
-
await txRepository.insert(testData.tx1);
|
|
1493
|
-
await txRepository.insert(testData.tx2);
|
|
1494
|
-
|
|
1495
|
-
const tx = await txPot.getTxByKey(testData.tx3.txId, testData.tx3.chain);
|
|
1496
|
-
expect(tx).toBeNull();
|
|
1497
|
-
});
|
|
1498
|
-
});
|
|
1499
|
-
|
|
1500
|
-
describe('getTxsQuery', () => {
|
|
1501
|
-
/**
|
|
1502
|
-
* @target TxPot.getTxsQuery should return all txs when no option is passed
|
|
1503
|
-
* @dependencies
|
|
1504
|
-
* - database
|
|
1505
|
-
* @scenario
|
|
1506
|
-
* - insert 2 txs
|
|
1507
|
-
* - run test
|
|
1508
|
-
* - check returned value
|
|
1509
|
-
* @expected
|
|
1510
|
-
* - should return 2 txs
|
|
1511
|
-
*/
|
|
1512
|
-
it('should return all txs when no option is passed', async () => {
|
|
1513
|
-
await txRepository.insert(testData.tx1);
|
|
1514
|
-
await txRepository.insert(testData.tx2);
|
|
1515
|
-
|
|
1516
|
-
const txs = await txPot.getTxsQuery();
|
|
1517
|
-
expect(txs.length).toEqual(2);
|
|
1518
|
-
});
|
|
1519
|
-
|
|
1520
|
-
/**
|
|
1521
|
-
* @target TxPot.getTxsQuery should return txs filtered by txId
|
|
1522
|
-
* @dependencies
|
|
1523
|
-
* - database
|
|
1524
|
-
* @scenario
|
|
1525
|
-
* - insert 2 txs with different txIds
|
|
1526
|
-
* - run test
|
|
1527
|
-
* - check returned value
|
|
1528
|
-
* @expected
|
|
1529
|
-
* - should return filtered tx
|
|
1530
|
-
*/
|
|
1531
|
-
it('should return txs filtered by txId', async () => {
|
|
1532
|
-
await txRepository.insert(testData.tx1);
|
|
1533
|
-
await txRepository.insert(testData.tx2);
|
|
1534
|
-
|
|
1535
|
-
const txs = await txPot.getTxsQuery([{ txId: testData.tx1.txId }]);
|
|
1536
|
-
expect(txs.length).toEqual(1);
|
|
1537
|
-
expect(txs[0].txId).toEqual(testData.tx1.txId);
|
|
1538
|
-
});
|
|
1539
|
-
|
|
1540
|
-
/**
|
|
1541
|
-
* @target TxPot.getTxsQuery should return txs filtered by list of txId
|
|
1542
|
-
* @dependencies
|
|
1543
|
-
* - database
|
|
1544
|
-
* @scenario
|
|
1545
|
-
* - insert 3 txs with different txIds
|
|
1546
|
-
* - run test
|
|
1547
|
-
* - check returned value
|
|
1548
|
-
* @expected
|
|
1549
|
-
* - should return 2 filtered txs
|
|
1550
|
-
*/
|
|
1551
|
-
it('should return txs filtered by list of txId', async () => {
|
|
1552
|
-
await txRepository.insert(testData.tx1);
|
|
1553
|
-
await txRepository.insert(testData.tx2);
|
|
1554
|
-
await txRepository.insert(testData.tx3); // txId not on the list
|
|
1555
|
-
|
|
1556
|
-
const txs = await txPot.getTxsQuery([
|
|
1557
|
-
{ txId: [testData.tx1.txId, testData.tx2.txId] },
|
|
1558
|
-
]);
|
|
1559
|
-
expect(txs.length).toEqual(2);
|
|
1560
|
-
expect(txs[0].txId).toEqual(testData.tx1.txId);
|
|
1561
|
-
expect(txs[1].txId).toEqual(testData.tx2.txId);
|
|
1562
|
-
});
|
|
1563
|
-
|
|
1564
|
-
/**
|
|
1565
|
-
* @target TxPot.getTxsQuery should return txs filtered by chain
|
|
1566
|
-
* @dependencies
|
|
1567
|
-
* - database
|
|
1568
|
-
* @scenario
|
|
1569
|
-
* - insert 3 txs with different chains
|
|
1570
|
-
* - run test
|
|
1571
|
-
* - check returned value
|
|
1572
|
-
* @expected
|
|
1573
|
-
* - should return 2 filtered txs
|
|
1574
|
-
*/
|
|
1575
|
-
it('should return txs filtered by chain', async () => {
|
|
1576
|
-
await txRepository.insert(testData.tx1);
|
|
1577
|
-
await txRepository.insert(testData.tx2);
|
|
1578
|
-
await txRepository.insert(testData.tx3); // different chain
|
|
1579
|
-
|
|
1580
|
-
const txs = await txPot.getTxsQuery([{ chain: testData.tx1.chain }]);
|
|
1581
|
-
expect(txs.length).toEqual(2);
|
|
1582
|
-
expect(txs[0].txId).toEqual(testData.tx1.txId);
|
|
1583
|
-
expect(txs[1].txId).toEqual(testData.tx2.txId);
|
|
1584
|
-
});
|
|
1585
|
-
|
|
1586
|
-
/**
|
|
1587
|
-
* @target TxPot.getTxsQuery should return txs filtered by txType
|
|
1588
|
-
* @dependencies
|
|
1589
|
-
* - database
|
|
1590
|
-
* @scenario
|
|
1591
|
-
* - insert 3 txs with different txTypes
|
|
1592
|
-
* - run test
|
|
1593
|
-
* - check returned value
|
|
1594
|
-
* @expected
|
|
1595
|
-
* - should return 2 filtered txs
|
|
1596
|
-
*/
|
|
1597
|
-
it('should return txs filtered by txType', async () => {
|
|
1598
|
-
await txRepository.insert(testData.tx1);
|
|
1599
|
-
await txRepository.insert(testData.tx3);
|
|
1600
|
-
await txRepository.insert(testData.tx4); // different txType
|
|
1601
|
-
|
|
1602
|
-
const txs = await txPot.getTxsQuery([{ txType: testData.tx1.txType }]);
|
|
1603
|
-
expect(txs.length).toEqual(2);
|
|
1604
|
-
expect(txs[0].txId).toEqual(testData.tx1.txId);
|
|
1605
|
-
expect(txs[1].txId).toEqual(testData.tx3.txId);
|
|
1606
|
-
});
|
|
1607
|
-
|
|
1608
|
-
/**
|
|
1609
|
-
* @target TxPot.getTxsQuery should return txs filtered by status
|
|
1610
|
-
* @dependencies
|
|
1611
|
-
* - database
|
|
1612
|
-
* @scenario
|
|
1613
|
-
* - insert 3 txs with different status
|
|
1614
|
-
* - run test
|
|
1615
|
-
* - check returned value
|
|
1616
|
-
* @expected
|
|
1617
|
-
* - should return 2 filtered txs
|
|
1618
|
-
*/
|
|
1619
|
-
it('should return txs filtered by status', async () => {
|
|
1620
|
-
await txRepository.insert(testData.tx1); // different status
|
|
1621
|
-
await txRepository.insert(testData.tx3);
|
|
1622
|
-
await txRepository.insert(testData.tx5);
|
|
1623
|
-
|
|
1624
|
-
const txs = await txPot.getTxsQuery([
|
|
1625
|
-
{
|
|
1626
|
-
status: {
|
|
1627
|
-
not: false,
|
|
1628
|
-
value: testData.tx3.status as TransactionStatus,
|
|
1629
|
-
},
|
|
1630
|
-
},
|
|
1631
|
-
]);
|
|
1632
|
-
expect(txs.length).toEqual(2);
|
|
1633
|
-
expect(txs[0].txId).toEqual(testData.tx3.txId);
|
|
1634
|
-
expect(txs[1].txId).toEqual(testData.tx5.txId);
|
|
1635
|
-
});
|
|
1636
|
-
|
|
1637
|
-
/**
|
|
1638
|
-
* @target TxPot.getTxsQuery should return txs filtered by list of statuses
|
|
1639
|
-
* @dependencies
|
|
1640
|
-
* - database
|
|
1641
|
-
* @scenario
|
|
1642
|
-
* - insert 3 txs with different status
|
|
1643
|
-
* - run test
|
|
1644
|
-
* - check returned value
|
|
1645
|
-
* @expected
|
|
1646
|
-
* - should return 2 filtered txs
|
|
1647
|
-
*/
|
|
1648
|
-
it('should return txs filtered by list of statuses', async () => {
|
|
1649
|
-
await txRepository.insert(testData.tx1);
|
|
1650
|
-
await txRepository.insert(testData.tx2);
|
|
1651
|
-
await txRepository.insert(testData.tx3); // status not on the list
|
|
1652
|
-
|
|
1653
|
-
const txs = await txPot.getTxsQuery([
|
|
1654
|
-
{
|
|
1655
|
-
status: {
|
|
1656
|
-
not: false,
|
|
1657
|
-
value: [
|
|
1658
|
-
testData.tx1.status as TransactionStatus,
|
|
1659
|
-
testData.tx2.status as TransactionStatus,
|
|
1660
|
-
],
|
|
1661
|
-
},
|
|
1662
|
-
},
|
|
1663
|
-
]);
|
|
1664
|
-
expect(txs.length).toEqual(2);
|
|
1665
|
-
expect(txs[0].txId).toEqual(testData.tx1.txId);
|
|
1666
|
-
expect(txs[1].txId).toEqual(testData.tx2.txId);
|
|
1667
|
-
});
|
|
1668
|
-
|
|
1669
|
-
/**
|
|
1670
|
-
* @target TxPot.getTxsQuery should return txs that their status are not
|
|
1671
|
-
* equal to given status
|
|
1672
|
-
* @dependencies
|
|
1673
|
-
* - database
|
|
1674
|
-
* @scenario
|
|
1675
|
-
* - insert 3 txs with different status
|
|
1676
|
-
* - run test
|
|
1677
|
-
* - check returned value
|
|
1678
|
-
* @expected
|
|
1679
|
-
* - should return 2 filtered txs
|
|
1680
|
-
*/
|
|
1681
|
-
it('should return txs that their status are not equal to given status', async () => {
|
|
1682
|
-
await txRepository.insert(testData.tx1);
|
|
1683
|
-
await txRepository.insert(testData.tx2);
|
|
1684
|
-
await txRepository.insert(testData.tx3);
|
|
1685
|
-
|
|
1686
|
-
const txs = await txPot.getTxsQuery([
|
|
1687
|
-
{
|
|
1688
|
-
status: {
|
|
1689
|
-
not: true,
|
|
1690
|
-
value: testData.tx1.status as TransactionStatus,
|
|
1691
|
-
},
|
|
1692
|
-
},
|
|
1693
|
-
]);
|
|
1694
|
-
expect(txs.length).toEqual(2);
|
|
1695
|
-
expect(txs[0].txId).toEqual(testData.tx2.txId);
|
|
1696
|
-
expect(txs[1].txId).toEqual(testData.tx3.txId);
|
|
1697
|
-
});
|
|
1698
|
-
|
|
1699
|
-
/**
|
|
1700
|
-
* @target TxPot.getTxsQuery should return txs that their status are not
|
|
1701
|
-
* on given list of statuses
|
|
1702
|
-
* @dependencies
|
|
1703
|
-
* - database
|
|
1704
|
-
* @scenario
|
|
1705
|
-
* - insert 3 txs with different status
|
|
1706
|
-
* - run test
|
|
1707
|
-
* - check returned value
|
|
1708
|
-
* @expected
|
|
1709
|
-
* - should return filtered tx
|
|
1710
|
-
*/
|
|
1711
|
-
it('should return txs that their status are not on given list of statuses', async () => {
|
|
1712
|
-
await txRepository.insert(testData.tx1);
|
|
1713
|
-
await txRepository.insert(testData.tx2);
|
|
1714
|
-
await txRepository.insert(testData.tx3); // status not on the list
|
|
1715
|
-
|
|
1716
|
-
const txs = await txPot.getTxsQuery([
|
|
1717
|
-
{
|
|
1718
|
-
status: {
|
|
1719
|
-
not: true,
|
|
1720
|
-
value: [
|
|
1721
|
-
testData.tx1.status as TransactionStatus,
|
|
1722
|
-
testData.tx2.status as TransactionStatus,
|
|
1723
|
-
],
|
|
1724
|
-
},
|
|
1725
|
-
},
|
|
1726
|
-
]);
|
|
1727
|
-
expect(txs.length).toEqual(1);
|
|
1728
|
-
expect(txs[0].txId).toEqual(testData.tx3.txId);
|
|
1729
|
-
});
|
|
1730
|
-
|
|
1731
|
-
/**
|
|
1732
|
-
* @target TxPot.getTxsQuery should return txs filtered by failedInSign
|
|
1733
|
-
* @dependencies
|
|
1734
|
-
* - database
|
|
1735
|
-
* @scenario
|
|
1736
|
-
* - insert 3 txs with different failedInSign
|
|
1737
|
-
* - run test
|
|
1738
|
-
* - check returned value
|
|
1739
|
-
* @expected
|
|
1740
|
-
* - should return 2 filtered txs
|
|
1741
|
-
*/
|
|
1742
|
-
it('should return txs filtered by failedInSign', async () => {
|
|
1743
|
-
await txRepository.insert(testData.tx1);
|
|
1744
|
-
await txRepository.insert(testData.tx2);
|
|
1745
|
-
await txRepository.insert(testData.tx3); // different failedInSign
|
|
1746
|
-
|
|
1747
|
-
const txs = await txPot.getTxsQuery([
|
|
1748
|
-
{ failedInSign: testData.tx1.failedInSign },
|
|
1749
|
-
]);
|
|
1750
|
-
expect(txs.length).toEqual(2);
|
|
1751
|
-
expect(txs[0].txId).toEqual(testData.tx1.txId);
|
|
1752
|
-
expect(txs[1].txId).toEqual(testData.tx2.txId);
|
|
1753
|
-
});
|
|
1754
|
-
|
|
1755
|
-
/**
|
|
1756
|
-
* @target TxPot.getTxsQuery should return txs filtered by extra
|
|
1757
|
-
* @dependencies
|
|
1758
|
-
* - database
|
|
1759
|
-
* @scenario
|
|
1760
|
-
* - insert 2 txs with different extra
|
|
1761
|
-
* - run test
|
|
1762
|
-
* - check returned value
|
|
1763
|
-
* @expected
|
|
1764
|
-
* - should return filtered tx
|
|
1765
|
-
*/
|
|
1766
|
-
it('should return txs filtered by extra', async () => {
|
|
1767
|
-
await txRepository.insert(testData.tx1); // different extra
|
|
1768
|
-
await txRepository.insert(testData.tx3);
|
|
1769
|
-
|
|
1770
|
-
const txs = await txPot.getTxsQuery([{ extra: testData.tx3.extra }]);
|
|
1771
|
-
expect(txs.length).toEqual(1);
|
|
1772
|
-
expect(txs[0].txId).toEqual(testData.tx3.txId);
|
|
1773
|
-
});
|
|
1774
|
-
|
|
1775
|
-
/**
|
|
1776
|
-
* @target TxPot.getTxsQuery should return txs filtered by list of extra
|
|
1777
|
-
* @dependencies
|
|
1778
|
-
* - database
|
|
1779
|
-
* @scenario
|
|
1780
|
-
* - insert 3 txs with different list of extra
|
|
1781
|
-
* - run test
|
|
1782
|
-
* - check returned value
|
|
1783
|
-
* @expected
|
|
1784
|
-
* - should return 2 filtered txs
|
|
1785
|
-
*/
|
|
1786
|
-
it('should return txs filtered by list of extra', async () => {
|
|
1787
|
-
await txRepository.insert(testData.tx1); // extra not on the list
|
|
1788
|
-
await txRepository.insert(testData.tx3);
|
|
1789
|
-
await txRepository.insert(testData.tx4);
|
|
1790
|
-
|
|
1791
|
-
const txs = await txPot.getTxsQuery([
|
|
1792
|
-
{ extra: [testData.tx3.extra!, testData.tx4.extra!] },
|
|
1793
|
-
]);
|
|
1794
|
-
expect(txs.length).toEqual(2);
|
|
1795
|
-
expect(txs[0].txId).toEqual(testData.tx3.txId);
|
|
1796
|
-
expect(txs[1].txId).toEqual(testData.tx4.txId);
|
|
1797
|
-
});
|
|
1798
|
-
|
|
1799
|
-
/**
|
|
1800
|
-
* @target TxPot.getTxsQuery should combine two filter options successfully
|
|
1801
|
-
* @dependencies
|
|
1802
|
-
* - database
|
|
1803
|
-
* @scenario
|
|
1804
|
-
* - insert 3 txs with different txIds and chains
|
|
1805
|
-
* - run test
|
|
1806
|
-
* - check returned value
|
|
1807
|
-
* @expected
|
|
1808
|
-
* - should return 2 filtered txs
|
|
1809
|
-
*/
|
|
1810
|
-
it('should combine two filter options successfully', async () => {
|
|
1811
|
-
await txRepository.insert(testData.tx1);
|
|
1812
|
-
await txRepository.insert(testData.tx2);
|
|
1813
|
-
await txRepository.insert(testData.tx3);
|
|
1814
|
-
|
|
1815
|
-
const txs = await txPot.getTxsQuery([
|
|
1816
|
-
{ txId: testData.tx1.txId },
|
|
1817
|
-
{ chain: testData.tx1.chain },
|
|
1818
|
-
]);
|
|
1819
|
-
expect(txs.length).toEqual(2);
|
|
1820
|
-
expect(txs[0].txId).toEqual(testData.tx1.txId);
|
|
1821
|
-
expect(txs[1].txId).toEqual(testData.tx2.txId);
|
|
1822
|
-
});
|
|
1823
|
-
});
|
|
1824
|
-
|
|
1825
|
-
describe('updateExtra', () => {
|
|
1826
|
-
/**
|
|
1827
|
-
* @target TxPot.updateExtra should update extra columns successfully
|
|
1828
|
-
* @dependencies
|
|
1829
|
-
* - database
|
|
1830
|
-
* @scenario
|
|
1831
|
-
* - insert 2 txs
|
|
1832
|
-
* - run test
|
|
1833
|
-
* - check db records
|
|
1834
|
-
* @expected
|
|
1835
|
-
* - extra of target tx should be updated
|
|
1836
|
-
* - extra of other txs should remain unchanged
|
|
1837
|
-
*/
|
|
1838
|
-
it('should update extra columns successfully', async () => {
|
|
1839
|
-
await txRepository.insert(testData.tx3);
|
|
1840
|
-
await txRepository.insert(testData.tx4);
|
|
1841
|
-
|
|
1842
|
-
const updatedExtra = 'new-extra';
|
|
1843
|
-
await txPot.updateExtra(
|
|
1844
|
-
testData.tx3.txId,
|
|
1845
|
-
testData.tx3.chain,
|
|
1846
|
-
updatedExtra
|
|
1847
|
-
);
|
|
1848
|
-
|
|
1849
|
-
const txs = (await txRepository.find()).map((tx) => [tx.txId, tx.extra]);
|
|
1850
|
-
expect(txs).toEqual([
|
|
1851
|
-
[testData.tx3.txId, updatedExtra],
|
|
1852
|
-
[testData.tx4.txId, testData.tx4.extra],
|
|
1853
|
-
]);
|
|
1854
|
-
});
|
|
1855
|
-
|
|
1856
|
-
/**
|
|
1857
|
-
* @target TxPot.updateExtra should set null successfully
|
|
1858
|
-
* @dependencies
|
|
1859
|
-
* - database
|
|
1860
|
-
* @scenario
|
|
1861
|
-
* - insert a tx with extra
|
|
1862
|
-
* - run test
|
|
1863
|
-
* - check db records
|
|
1864
|
-
* @expected
|
|
1865
|
-
* - extra of target tx should be updated
|
|
1866
|
-
*/
|
|
1867
|
-
it('should set null successfully', async () => {
|
|
1868
|
-
await txRepository.insert(testData.tx3);
|
|
1869
|
-
|
|
1870
|
-
const updatedExtra = null;
|
|
1871
|
-
await txPot.updateExtra(
|
|
1872
|
-
testData.tx3.txId,
|
|
1873
|
-
testData.tx3.chain,
|
|
1874
|
-
updatedExtra
|
|
1875
|
-
);
|
|
1876
|
-
|
|
1877
|
-
const txs = (await txRepository.find()).map((tx) => [tx.txId, tx.extra]);
|
|
1878
|
-
expect(txs).toEqual([[testData.tx3.txId, updatedExtra]]);
|
|
1879
|
-
});
|
|
1880
|
-
});
|
|
1881
|
-
});
|