Skip to content

Commit 11b2581

Browse files
committed
fix: reject getReferencedTransactions when scan range exceeds indexed watermark
Adds a check in IIndexedQueryManager.getReferencedTransactions that returns DATA_AVAILABILITY_FAILURE if firstOverflowBlock.blockNumber - 1 exceeds lastConfirmedBlockNumber, enforcing the spec requirement that the verifier must have a complete view of all blocks in the scan range before attesting nonexistence. In practice, the verifier-xrp-indexer writes blocks, transactions, and the state watermark in a single ACID transaction (SaveAllEntities), so the blocks table cannot have rows beyond last_indexed_block_number at runtime. The check is kept as explicit spec enforcement so correctness does not depend on that indexer implementation detail. Also adds an explicit null guard in XrpIndexerQueryManager._getStateObject.
1 parent e66add4 commit 11b2581

3 files changed

Lines changed: 14 additions & 2 deletions

File tree

src/entity/xrp-entity-definitions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ export class DBXrpTransaction {
114114
// Delete me after 1777366800 Thursday, 28 April 2026 at 11:00:00 CEST keep
115115
// const modifiedTimestamp = this.timestamp - XRP_UTD;
116116
const LUT_FORK_TIMESTAMP = 1777366800;
117-
const modifiedTimestamp = this.timestamp < LUT_FORK_TIMESTAMP
117+
const modifiedTimestamp =
118+
this.timestamp < LUT_FORK_TIMESTAMP
118119
? this.timestamp
119120
: this.timestamp - XRP_UTD;
120121

src/indexed-query-manager/IIndexedQueryManager.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ export abstract class IIndexedQueryManager {
176176
};
177177
}
178178

179+
const lastConfirmedBlock = await this.getLastConfirmedBlockNumber();
180+
if (firstOverflowBlock.blockNumber - 1 > lastConfirmedBlock) {
181+
return {
182+
status: 'DATA_AVAILABILITY_FAILURE',
183+
};
184+
}
185+
179186
const transactionsQueryResult = await this.queryTransactions({
180187
startBlockNumber: params.minimalBlockNumber,
181188
endBlockNumber: firstOverflowBlock.blockNumber - 1,

src/indexed-query-manager/XrpIndexerQueryManager.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ export class XrpIndexerQueryManager extends IIndexedQueryManager {
3939

4040
private async _getStateObject(): Promise<DBXrpState> {
4141
const query = this.entityManager.createQueryBuilder(this.tipState, 'state');
42-
return query.getOne();
42+
const res = await query.getOne();
43+
if (res === undefined || res === null) {
44+
throw new Error('Cannot find XRP state in DB');
45+
}
46+
return res;
4347
}
4448

4549
public async getLastConfirmedBlockNumber(): Promise<number> {

0 commit comments

Comments
 (0)