Fix block summaries repo upsert race condition

This commit is contained in:
Mononaut 2022-12-03 10:49:10 +09:00
parent 5ff5275b36
commit 132e848fdc
No known key found for this signature in database
GPG key ID: A3F058E41374C04E
2 changed files with 30 additions and 13 deletions

View file

@ -439,7 +439,7 @@ class WebsocketHandler {
}; };
}) : []; }) : [];
BlocksSummariesRepository.$saveSummary({ BlocksSummariesRepository.$saveTemplate({
height: block.height, height: block.height,
template: { template: {
id: block.id, id: block.id,

View file

@ -17,19 +17,16 @@ class BlocksSummariesRepository {
return undefined; return undefined;
} }
public async $saveSummary(params: { height: number, mined?: BlockSummary, template?: BlockSummary}) { public async $saveSummary(params: { height: number, mined?: BlockSummary}) {
const blockId = params.mined?.id ?? params.template?.id; const blockId = params.mined?.id;
try { try {
const [dbSummary]: any[] = await DB.query(`SELECT * FROM blocks_summaries WHERE id = "${blockId}"`); const transactions = JSON.stringify(params.mined?.transactions || []);
if (dbSummary.length === 0) { // First insertion await DB.query(`
await DB.query(`INSERT INTO blocks_summaries VALUE (?, ?, ?, ?)`, [ INSERT INTO blocks_summaries (height, id, transactions, template)
params.height, blockId, JSON.stringify(params.mined?.transactions ?? []), JSON.stringify(params.template?.transactions ?? []) VALUE (?, ?, ?, ?)
]); ON DUPLICATE KEY UPDATE
} else if (params.mined !== undefined) { // Update mined block summary transactions = ?
await DB.query(`UPDATE blocks_summaries SET transactions = ? WHERE id = "${params.mined.id}"`, [JSON.stringify(params.mined.transactions)]); `, [params.height, blockId, transactions, '[]', transactions]);
} else if (params.template !== undefined) { // Update template block summary
await DB.query(`UPDATE blocks_summaries SET template = ? WHERE id = "${params.template.id}"`, [JSON.stringify(params.template?.transactions)]);
}
} catch (e: any) { } catch (e: any) {
if (e.errno === 1062) { // ER_DUP_ENTRY - This scenario is possible upon node backend restart if (e.errno === 1062) { // ER_DUP_ENTRY - This scenario is possible upon node backend restart
logger.debug(`Cannot save block summary for ${blockId} because it has already been indexed, ignoring`); logger.debug(`Cannot save block summary for ${blockId} because it has already been indexed, ignoring`);
@ -40,6 +37,26 @@ class BlocksSummariesRepository {
} }
} }
public async $saveTemplate(params: { height: number, template: BlockSummary}) {
const blockId = params.template?.id;
try {
const transactions = JSON.stringify(params.template?.transactions || []);
await DB.query(`
INSERT INTO blocks_summaries (height, id, transactions, template)
VALUE (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
template = ?
`, [params.height, blockId, '[]', transactions, transactions]);
} catch (e: any) {
if (e.errno === 1062) { // ER_DUP_ENTRY - This scenario is possible upon node backend restart
logger.debug(`Cannot save block template for ${blockId} because it has already been indexed, ignoring`);
} else {
logger.debug(`Cannot save block template for ${blockId}. Reason: ${e instanceof Error ? e.message : e}`);
throw e;
}
}
}
public async $getIndexedSummariesId(): Promise<string[]> { public async $getIndexedSummariesId(): Promise<string[]> {
try { try {
const [rows]: any[] = await DB.query(`SELECT id from blocks_summaries`); const [rows]: any[] = await DB.query(`SELECT id from blocks_summaries`);