|
| 1 | +import { migrate } from '../utils/test-helpers'; |
| 2 | +import { importEventsFromTsv } from '../../src/event-replay/event-replay'; |
1 | 3 | import { decodeClarityValueList } from 'stacks-encoding-native-js'; |
| 4 | +import * as fs from 'fs'; |
| 5 | +import * as readline from 'readline'; |
| 6 | +import { PgSqlClient, timeout } from '@hirosystems/api-toolkit'; |
| 7 | +import { ChainID } from '@stacks/common'; |
| 8 | +import { ApiServer, startApiServer } from '../../src/api/init'; |
| 9 | +import { PgWriteStore } from '../../src/datastore/pg-write-store'; |
| 10 | +import { EventStreamServer, startEventServer } from '../../src/event-stream/event-server'; |
| 11 | +import { httpPostRequest } from '../../src/helpers'; |
2 | 12 |
|
3 | | -test('buggy parsing of contract-call args', () => { |
4 | | - // Contract-call args from tx 0xb066874942e97d6e7ecfedb999a788edf7fbdbe51ab4b172ea05e8ede9b0ae9c |
5 | | - const contractCallArgsWithEmptyList = |
6 | | - '000000030c00000007066865696768740100000000000000000000000000005cc20b6d65726b6c652d726f6f7402000000201302a1b1fa53c11ac01ce480937dcd1ef550b4799070878e20b3b97bb99b58ec056e62697473020000000424961417056e6f6e6365020000000434a32a2106706172656e740200000020d0c9ebf9784f0670eb9bfac963114a02cff58bdc2669000000000000000000000974696d657374616d70020000000452b003610776657273696f6e0200000004040000200c0000000403696e730b000000010c00000003086f7574706f696e740c0000000204686173680200000020e85fb1e809db705121d92f3ec7f9ea4bafd065a8651408f507223efa8ede146605696e64657802000000040300000009736372697074536967020000006b48304502210096638a2336c383a99b009025534ae00f0bb689888c3898e6723497324c92806802205a3eee656775961780676f48f2fc1514142cadcd49efe1893d75517ab47a7f620121022a0160b2ed13b803ddca6f6f04606f56dfadee571d683725c7a58d0ed199de790873657175656e63650200000004fdffffff086c6f636b74696d65020000000400000000046f7574730b000000000776657273696f6e0200000004010000000c00000003066861736865730b000000000a747265652d646570746801000000000000000000000000000000080874782d696e64657801ffffffffffffffffffffffffffffffff'; |
7 | | - const fnArgs = Buffer.from(contractCallArgsWithEmptyList, 'hex'); |
8 | | - const clarityVals = decodeClarityValueList(fnArgs); |
9 | | - clarityVals.map(c => { |
10 | | - expect(c.hex).not.toBe(''); |
| 13 | +describe('transaction parsing', () => { |
| 14 | + test('buggy parsing of contract-call args', () => { |
| 15 | + // Contract-call args from tx 0xb066874942e97d6e7ecfedb999a788edf7fbdbe51ab4b172ea05e8ede9b0ae9c |
| 16 | + const contractCallArgsWithEmptyList = |
| 17 | + '000000030c00000007066865696768740100000000000000000000000000005cc20b6d65726b6c652d726f6f7402000000201302a1b1fa53c11ac01ce480937dcd1ef550b4799070878e20b3b97bb99b58ec056e62697473020000000424961417056e6f6e6365020000000434a32a2106706172656e740200000020d0c9ebf9784f0670eb9bfac963114a02cff58bdc2669000000000000000000000974696d657374616d70020000000452b003610776657273696f6e0200000004040000200c0000000403696e730b000000010c00000003086f7574706f696e740c0000000204686173680200000020e85fb1e809db705121d92f3ec7f9ea4bafd065a8651408f507223efa8ede146605696e64657802000000040300000009736372697074536967020000006b48304502210096638a2336c383a99b009025534ae00f0bb689888c3898e6723497324c92806802205a3eee656775961780676f48f2fc1514142cadcd49efe1893d75517ab47a7f620121022a0160b2ed13b803ddca6f6f04606f56dfadee571d683725c7a58d0ed199de790873657175656e63650200000004fdffffff086c6f636b74696d65020000000400000000046f7574730b000000000776657273696f6e0200000004010000000c00000003066861736865730b000000000a747265652d646570746801000000000000000000000000000000080874782d696e64657801ffffffffffffffffffffffffffffffff'; |
| 18 | + const fnArgs = Buffer.from(contractCallArgsWithEmptyList, 'hex'); |
| 19 | + const clarityVals = decodeClarityValueList(fnArgs); |
| 20 | + clarityVals.map(c => { |
| 21 | + expect(c.hex).not.toBe(''); |
| 22 | + }); |
| 23 | + }); |
| 24 | + |
| 25 | + describe('fuzzed tsvs', () => { |
| 26 | + let db: PgWriteStore; |
| 27 | + let client: PgSqlClient; |
| 28 | + let api: ApiServer; |
| 29 | + |
| 30 | + beforeEach(async () => { |
| 31 | + await migrate('up'); |
| 32 | + db = await PgWriteStore.connect({ |
| 33 | + usageName: 'tests', |
| 34 | + withNotifier: true, |
| 35 | + skipMigrations: true, |
| 36 | + }); |
| 37 | + client = db.sql; |
| 38 | + api = await startApiServer({ datastore: db, chainId: ChainID.Testnet }); |
| 39 | + |
| 40 | + // set chainId env, because TSV import reads it manually |
| 41 | + process.env['STACKS_CHAIN_ID'] = ChainID.Testnet.toString(); |
| 42 | + }); |
| 43 | + |
| 44 | + afterEach(async () => { |
| 45 | + await api.terminate(); |
| 46 | + await db?.close(); |
| 47 | + await migrate('down'); |
| 48 | + }); |
| 49 | + |
| 50 | + test('parse fuzzed transactions', async () => { |
| 51 | + const eventServer = await startEventServer({ |
| 52 | + datastore: db, |
| 53 | + chainId: ChainID.Testnet, |
| 54 | + serverHost: '127.0.0.1', |
| 55 | + serverPort: 0, |
| 56 | + }); |
| 57 | + |
| 58 | + const readStream = readline.createInterface({ |
| 59 | + input: fs.createReadStream('tests/api/tsv/fuzzed-transactions-1.tsv', { encoding: 'utf8' }), |
| 60 | + crlfDelay: Infinity, |
| 61 | + }); |
| 62 | + for await (const line of readStream) { |
| 63 | + const [id, timestamp, eventPath, payload] = line.split('\t'); |
| 64 | + await httpPostRequest({ |
| 65 | + host: '127.0.0.1', |
| 66 | + port: eventServer.serverAddress.port, |
| 67 | + path: eventPath, |
| 68 | + headers: { 'Content-Type': 'application/json' }, |
| 69 | + body: Buffer.from(payload, 'utf8'), |
| 70 | + throwOnNotOK: true, |
| 71 | + }); |
| 72 | + } |
| 73 | + |
| 74 | + await eventServer.closeAsync(); |
| 75 | + }); |
11 | 76 | }); |
12 | 77 | }); |
0 commit comments