Skip to content

Commit ce9b38f

Browse files
authored
fix: handle Problematic status in /drop_mempool_tx event (#1790)
1 parent eb36b33 commit ce9b38f

File tree

8 files changed

+52
-5
lines changed

8 files changed

+52
-5
lines changed

docs/entities/mempool-transactions/transaction-status.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"title": "MempoolTransactionStatus",
33
"description": "Status of the transaction",
44
"type": "string",
5-
"enum": ["pending", "dropped_replace_by_fee", "dropped_replace_across_fork", "dropped_too_expensive", "dropped_stale_garbage_collect"]
5+
"enum": ["pending", "dropped_replace_by_fee", "dropped_replace_across_fork", "dropped_too_expensive", "dropped_stale_garbage_collect", "dropped_problematic"]
66
}

docs/generated.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,8 @@ export type MempoolTransactionStatus =
569569
| "dropped_replace_by_fee"
570570
| "dropped_replace_across_fork"
571571
| "dropped_too_expensive"
572-
| "dropped_stale_garbage_collect";
572+
| "dropped_stale_garbage_collect"
573+
| "dropped_problematic";
573574
/**
574575
* Describes representation of a Type-1 Stacks 2.0 transaction. https://github.com/blockstack/stacks-blockchain/blob/master/sip/sip-005-blocks-and-transactions.md#type-1-instantiating-a-smart-contract
575576
*/

src/api/controllers/db-controller.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ function getTxStatusString(txStatus: DbTxStatus): TransactionStatus | MempoolTra
161161
return 'dropped_replace_across_fork';
162162
case DbTxStatus.DroppedTooExpensive:
163163
return 'dropped_too_expensive';
164+
case DbTxStatus.DroppedProblematic:
165+
return 'dropped_problematic';
164166
case DbTxStatus.DroppedStaleGarbageCollect:
165167
case DbTxStatus.DroppedApiGarbageCollect:
166168
return 'dropped_stale_garbage_collect';

src/datastore/common.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ export enum DbTxStatus {
117117
DroppedStaleGarbageCollect = -13,
118118
/** Dropped by the API (even though the Stacks node hadn't dropped it) because it exceeded maximum mempool age */
119119
DroppedApiGarbageCollect = -14,
120+
/** Transaction is problematic (e.g. a DDoS vector) and should be dropped. */
121+
DroppedProblematic = -15,
120122
}
121123

122124
export enum DbTxAnchorMode {

src/datastore/helpers.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,8 @@ export function getTxDbStatus(
990990
return DbTxStatus.DroppedTooExpensive;
991991
case 'StaleGarbageCollect':
992992
return DbTxStatus.DroppedStaleGarbageCollect;
993+
case 'Problematic':
994+
return DbTxStatus.DroppedProblematic;
993995
default:
994996
throw new Error(`Unexpected tx status: ${txCoreStatus}`);
995997
}

src/datastore/pg-store.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,7 @@ export class PgStore extends BasePgStore {
12471247
DbTxStatus.DroppedTooExpensive,
12481248
DbTxStatus.DroppedStaleGarbageCollect,
12491249
DbTxStatus.DroppedApiGarbageCollect,
1250+
DbTxStatus.DroppedProblematic,
12501251
];
12511252
const resultQuery = await sql<(MempoolTxQueryResult & { count: number })[]>`
12521253
SELECT ${unsafeCols(sql, [

src/event-stream/core-node-message.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,8 @@ export type CoreNodeDropMempoolTxReasonType =
301301
| 'ReplaceByFee'
302302
| 'ReplaceAcrossFork'
303303
| 'TooExpensive'
304-
| 'StaleGarbageCollect';
304+
| 'StaleGarbageCollect'
305+
| 'Problematic';
305306

306307
export interface CoreNodeDropMempoolTxMessage {
307308
dropped_txids: string[];

src/tests/mempool-tests.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,14 @@ describe('mempool tests', () => {
323323
tx_id: '0x8912000000000000000000000000000000000000000000000000000000000005',
324324
receipt_time: 1594307705,
325325
};
326+
const mempoolTx6: DbMempoolTxRaw = {
327+
...mempoolTx1,
328+
tx_id: '0x8912000000000000000000000000000000000000000000000000000000000006',
329+
receipt_time: 1594307706,
330+
};
326331

327332
await db.updateMempoolTxs({
328-
mempoolTxs: [mempoolTx1, mempoolTx2, mempoolTx3, mempoolTx4, mempoolTx5],
333+
mempoolTxs: [mempoolTx1, mempoolTx2, mempoolTx3, mempoolTx4, mempoolTx5, mempoolTx6],
329334
});
330335
await db.dropMempoolTxs({
331336
status: DbTxStatus.DroppedReplaceAcrossFork,
@@ -450,6 +455,31 @@ describe('mempool tests', () => {
450455
};
451456
expect(JSON.parse(searchResult5.text)).toEqual(expectedResp5);
452457

458+
await db.dropMempoolTxs({
459+
status: DbTxStatus.DroppedProblematic,
460+
txIds: [mempoolTx6.tx_id],
461+
});
462+
const searchResult6 = await supertest(api.server).get(`/extended/v1/tx/${mempoolTx6.tx_id}`);
463+
expect(searchResult6.status).toBe(200);
464+
expect(searchResult6.type).toBe('application/json');
465+
const expectedResp6 = {
466+
tx_id: '0x8912000000000000000000000000000000000000000000000000000000000006',
467+
tx_status: 'dropped_problematic',
468+
tx_type: 'coinbase',
469+
fee_rate: '1234',
470+
nonce: 0,
471+
anchor_mode: 'any',
472+
sender_address: 'sender-addr',
473+
sponsor_address: 'sponsor-addr',
474+
sponsored: true,
475+
post_condition_mode: 'allow',
476+
post_conditions: [],
477+
receipt_time: 1594307706,
478+
receipt_time_iso: '2020-07-09T15:15:06.000Z',
479+
coinbase_payload: { data: '0x636f696e62617365206869', alt_recipient: null },
480+
};
481+
expect(JSON.parse(searchResult6.text)).toEqual(expectedResp6);
482+
453483
const mempoolDroppedResult1 = await supertest(api.server).get(
454484
'/extended/v1/tx/mempool/dropped'
455485
);
@@ -458,6 +488,10 @@ describe('mempool tests', () => {
458488
expect(mempoolDroppedResult1.body).toEqual(
459489
expect.objectContaining({
460490
results: expect.arrayContaining([
491+
expect.objectContaining({
492+
tx_id: '0x8912000000000000000000000000000000000000000000000000000000000006',
493+
tx_status: 'dropped_problematic',
494+
}),
461495
expect.objectContaining({
462496
tx_id: '0x8912000000000000000000000000000000000000000000000000000000000005',
463497
tx_status: 'dropped_stale_garbage_collect',
@@ -549,10 +583,14 @@ describe('mempool tests', () => {
549583
);
550584
expect(mempoolDroppedResult2.status).toBe(200);
551585
expect(mempoolDroppedResult2.type).toBe('application/json');
552-
expect(mempoolDroppedResult2.body.results).toHaveLength(4);
586+
expect(mempoolDroppedResult2.body.results).toHaveLength(5);
553587
expect(mempoolDroppedResult2.body).toEqual(
554588
expect.objectContaining({
555589
results: expect.arrayContaining([
590+
expect.objectContaining({
591+
tx_id: '0x8912000000000000000000000000000000000000000000000000000000000006',
592+
tx_status: 'dropped_problematic',
593+
}),
556594
expect.objectContaining({
557595
tx_id: '0x8912000000000000000000000000000000000000000000000000000000000005',
558596
tx_status: 'dropped_stale_garbage_collect',

0 commit comments

Comments
 (0)