Skip to content

Commit b85b1d3

Browse files
authored
fix: handle updated chain tip on rollbacks correctly (#261)
* fix: rollbacks * test: status
1 parent 9403c2c commit b85b1d3

File tree

5 files changed

+22
-43
lines changed

5 files changed

+22
-43
lines changed

src/api/util/helpers.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ export function parseMetadataLocaleBundle(
3232
if (locale.properties.length > 0) {
3333
const mergedProperties: MetadataPropertiesType = {};
3434
for (const property of locale.properties) {
35-
if (property.value) {
36-
mergedProperties[property.name] = property.value as MetadataValueType;
37-
}
35+
mergedProperties[property.name] = property.value as MetadataValueType;
3836
}
3937
response.properties = mergedProperties;
4038
}

src/pg/chainhook/chainhook-pg-store.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export class ChainhookPgStore extends BasePgStoreModule {
3939
} finished in ${time.getElapsedSeconds()}s`
4040
);
4141
}
42+
if (payload.rollback.length) {
43+
const earliestRolledBack = Math.min(...payload.rollback.map(r => r.block_identifier.index));
44+
await this.updateChainTipBlockHeight(earliestRolledBack - 1);
45+
}
4246
for (const block of payload.apply) {
4347
if (block.block_identifier.index <= (await this.getLastIngestedBlockHeight())) {
4448
logger.info(
@@ -114,7 +118,7 @@ export class ChainhookPgStore extends BasePgStoreModule {
114118
}
115119

116120
async updateChainTipBlockHeight(blockHeight: number): Promise<void> {
117-
await this.sql`UPDATE chain_tip SET block_height = GREATEST(${blockHeight}, block_height)`;
121+
await this.sql`UPDATE chain_tip SET block_height = ${blockHeight}`;
118122
}
119123

120124
private async getLastIngestedBlockHeight(): Promise<number> {

tests/api/nft.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ describe('NFT routes', () => {
221221
name: 'prop3',
222222
value: true,
223223
},
224+
{
225+
name: 'prop4',
226+
value: false,
227+
},
224228
],
225229
},
226230
],
@@ -256,6 +260,7 @@ describe('NFT routes', () => {
256260
prop1: 'ABC',
257261
prop2: 1,
258262
prop3: true,
263+
prop4: false,
259264
},
260265
},
261266
});

tests/api/status.test.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,13 @@ describe('Status routes', () => {
4444
db,
4545
'SP2SYHR84SDJJDK8M09HFS4KBFXPPCX9H7RZ9YVTS.hello-world',
4646
DbSipNumber.sip009,
47-
1n
47+
4n
4848
);
4949
await db.chainhook.updateChainTipBlockHeight(100);
50+
await db.sql`UPDATE jobs SET status = 'failed' WHERE id = 2`;
51+
await db.sql`UPDATE jobs SET status = 'invalid' WHERE id = 3`;
52+
await db.sql`UPDATE jobs SET status = 'queued' WHERE id = 4`;
53+
await db.sql`UPDATE jobs SET status = 'done' WHERE id = 5`;
5054

5155
const response = await fastify.inject({ method: 'GET', url: '/metadata/v1/' });
5256
const json = response.json();
@@ -57,13 +61,17 @@ describe('Status routes', () => {
5761
block_height: 100,
5862
},
5963
job_queue: {
60-
pending: 2,
64+
pending: 1,
65+
failed: 1,
66+
invalid: 1,
67+
queued: 1,
68+
done: 1,
6169
},
6270
token_contracts: {
6371
'sip-009': 1,
6472
},
6573
tokens: {
66-
nft: 1,
74+
nft: 4,
6775
},
6876
});
6977
});

tests/chainhook/chainhook-observer.test.ts

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -59,42 +59,6 @@ describe('Chainhook observer', () => {
5959
await expect(db.getChainTipBlockHeight()).resolves.toBe(101);
6060
});
6161

62-
test('keeps only the highest chain tip value', async () => {
63-
await db.chainhook.processPayload(
64-
new TestChainhookPayloadBuilder()
65-
.apply()
66-
.block({ height: 100 })
67-
.transaction({ hash: '0x01', sender: 'SP1K1A1PMGW2ZJCNF46NWZWHG8TS1D23EGH1KNK60' })
68-
.contractDeploy('SP1K1A1PMGW2ZJCNF46NWZWHG8TS1D23EGH1KNK60.friedger-pool-nft', {
69-
maps: [],
70-
functions: [],
71-
variables: [],
72-
fungible_tokens: [],
73-
non_fungible_tokens: [],
74-
})
75-
.build()
76-
);
77-
await expect(db.getChainTipBlockHeight()).resolves.toBe(100);
78-
79-
await db.chainhook.processPayload(
80-
new TestChainhookPayloadBuilder()
81-
.apply()
82-
.block({ height: 65 })
83-
.transaction({ hash: '0x01', sender: 'SP1K1A1PMGW2ZJCNF46NWZWHG8TS1D23EGH1KNK60' })
84-
.event({
85-
type: 'SmartContractEvent',
86-
position: { index: 0 },
87-
data: {
88-
contract_identifier: 'SP1K1A1PMGW2ZJCNF46NWZWHG8TS1D23EGH1KNK60.friedger-pool-nft',
89-
topic: 'print',
90-
raw_value: cvToHex(stringUtf8CV('test')),
91-
},
92-
})
93-
.build()
94-
);
95-
await expect(db.getChainTipBlockHeight()).resolves.toBe(100);
96-
});
97-
9862
test('enqueues dynamic tokens for refresh with standard interval', async () => {
9963
const address = 'SP1K1A1PMGW2ZJCNF46NWZWHG8TS1D23EGH1KNK60';
10064
const contractId = `${address}.friedger-pool-nft`;

0 commit comments

Comments
 (0)