Skip to content

Commit b1d6be9

Browse files
authored
fix: pox events should use same index as associated contract log event (#1994)
* fix: pox events should use same index as associated contract log event #1983 * test: add test
1 parent 5ce9b44 commit b1d6be9

File tree

3 files changed

+2396
-3
lines changed

3 files changed

+2396
-3
lines changed

src/event-stream/event-server.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,8 @@ function parseDataStoreTxEventData(
480480
return dbTx;
481481
});
482482

483+
const poxEventLogs: Map<DbPoxSyntheticEvent, DbSmartContractEvent> = new Map();
484+
483485
for (const event of events) {
484486
if (!event.committed) {
485487
logger.debug(`Ignoring uncommitted tx event from tx ${event.txid}`);
@@ -548,6 +550,7 @@ function parseDataStoreTxEventData(
548550
...dbEvent,
549551
...poxEventData,
550552
};
553+
poxEventLogs.set(dbPoxEvent, entry);
551554
switch (contractName) {
552555
case POX_2_CONTRACT_NAME: {
553556
dbTx.pox2Events.push(dbPoxEvent);
@@ -723,16 +726,20 @@ function parseDataStoreTxEventData(
723726
tx.nftEvents,
724727
tx.stxEvents,
725728
tx.stxLockEvents,
726-
tx.pox2Events,
727-
tx.pox3Events,
728-
tx.pox4Events,
729729
]
730730
.flat()
731731
.sort((a, b) => a.event_index - b.event_index);
732732
tx.tx.event_count = sortedEvents.length;
733733
for (let i = 0; i < sortedEvents.length; i++) {
734734
sortedEvents[i].event_index = i;
735735
}
736+
for (const poxEvent of [tx.pox2Events, tx.pox3Events, tx.pox4Events].flat()) {
737+
const associatedLogEvent = poxEventLogs.get(poxEvent);
738+
if (!associatedLogEvent) {
739+
throw new Error(`Missing associated contract log event for pox event ${poxEvent.tx_id}`);
740+
}
741+
poxEvent.event_index = associatedLogEvent.event_index;
742+
}
736743
}
737744

738745
return dbData;

src/tests/synthetic-stx-txs-tests.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as path from 'path';
44
import { DecodedTxResult, TxPayloadTypeID } from 'stacks-encoding-native-js';
55
import { CoreNodeBlockMessage } from '../event-stream/core-node-message';
66
import { parseMessageTransaction } from '../event-stream/reader';
7+
import { parseNewBlockMessage } from '../event-stream/event-server';
78

89
// Test processing of the psuedo-Stacks transactions, i.e. the ones that
910
// originate on the Bitcoin chain, and have a `raw_tx == '0x00'.
@@ -194,6 +195,34 @@ describe('synthetic stx txs', () => {
194195
expect(parsed.parsed_tx).toEqual(expect.objectContaining(expected));
195196
});
196197

198+
test('test synthetic tx stx lock 3', () => {
199+
const file =
200+
'synthetic-tx-payloads/stx_lock-1994-0xd45e090ac442380cf50655e3d1c904c355a501d6dffa3b5e4799083062469dbc.json';
201+
const txid = file.split('-').slice(-1)[0].split('.')[0];
202+
const payloadStr = fs.readFileSync(path.join(__dirname, file), { encoding: 'utf8' });
203+
const blockMsg = JSON.parse(payloadStr) as CoreNodeBlockMessage;
204+
const txMsg = blockMsg.transactions.find(t => t.txid === txid);
205+
if (!txMsg) {
206+
throw new Error(`Cound not find tx ${txid}`);
207+
}
208+
const parsed = parseNewBlockMessage(ChainID.Mainnet, blockMsg);
209+
if (!parsed) {
210+
throw new Error(`Failed to parse ${txid}`);
211+
}
212+
// Ensure real contract event indexes are contiguous
213+
const events = [parsed.txs[0].contractLogEvents, parsed.txs[0].stxLockEvents]
214+
.flat()
215+
.sort((a, b) => a.event_index - b.event_index);
216+
expect(events).toHaveLength(13);
217+
for (let i = 0; i < events.length; i++) {
218+
expect(events[i].event_index).toEqual(i);
219+
}
220+
// Ensure synthetic pox event indexes are in expected range
221+
for (const poxEvent of parsed.txs[0].pox4Events) {
222+
expect(poxEvent.event_index).toBeLessThan(events.length);
223+
}
224+
});
225+
197226
test('test synthetic tx stx lock 2', () => {
198227
// Testing a newer tx from mainnet (at block 51451)
199228
const file =

0 commit comments

Comments
 (0)