More robust error checking & handling in CPFP repositories
This commit is contained in:
parent
69f5d483ee
commit
900e66aef7
@ -111,7 +111,7 @@ class CpfpRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $getCluster(clusterRoot: string): Promise<Cluster> {
|
public async $getCluster(clusterRoot: string): Promise<Cluster | void> {
|
||||||
const [clusterRows]: any = await DB.query(
|
const [clusterRows]: any = await DB.query(
|
||||||
`
|
`
|
||||||
SELECT *
|
SELECT *
|
||||||
@ -121,8 +121,11 @@ class CpfpRepository {
|
|||||||
[clusterRoot]
|
[clusterRoot]
|
||||||
);
|
);
|
||||||
const cluster = clusterRows[0];
|
const cluster = clusterRows[0];
|
||||||
cluster.txs = this.unpack(cluster.txs);
|
if (cluster?.txs) {
|
||||||
return cluster;
|
cluster.txs = this.unpack(cluster.txs);
|
||||||
|
return cluster;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $deleteClustersFrom(height: number): Promise<void> {
|
public async $deleteClustersFrom(height: number): Promise<void> {
|
||||||
@ -136,9 +139,9 @@ class CpfpRepository {
|
|||||||
[height]
|
[height]
|
||||||
) as RowDataPacket[][];
|
) as RowDataPacket[][];
|
||||||
if (rows?.length) {
|
if (rows?.length) {
|
||||||
for (let clusterToDelete of rows) {
|
for (const clusterToDelete of rows) {
|
||||||
const txs = this.unpack(clusterToDelete.txs);
|
const txs = this.unpack(clusterToDelete?.txs);
|
||||||
for (let tx of txs) {
|
for (const tx of txs) {
|
||||||
await transactionRepository.$removeTransaction(tx.txid);
|
await transactionRepository.$removeTransaction(tx.txid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,20 +207,25 @@ class CpfpRepository {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const arrayBuffer = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
try {
|
||||||
const txs: Ancestor[] = [];
|
const arrayBuffer = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
||||||
const view = new DataView(arrayBuffer);
|
const txs: Ancestor[] = [];
|
||||||
for (let offset = 0; offset < arrayBuffer.byteLength; offset += 44) {
|
const view = new DataView(arrayBuffer);
|
||||||
const txid = Array.from(new Uint8Array(arrayBuffer, offset, 32)).reverse().map(b => b.toString(16).padStart(2, '0')).join('');
|
for (let offset = 0; offset < arrayBuffer.byteLength; offset += 44) {
|
||||||
const weight = view.getUint32(offset + 32);
|
const txid = Array.from(new Uint8Array(arrayBuffer, offset, 32)).reverse().map(b => b.toString(16).padStart(2, '0')).join('');
|
||||||
const fee = Number(view.getBigUint64(offset + 36));
|
const weight = view.getUint32(offset + 32);
|
||||||
txs.push({
|
const fee = Number(view.getBigUint64(offset + 36));
|
||||||
txid,
|
txs.push({
|
||||||
weight,
|
txid,
|
||||||
fee
|
weight,
|
||||||
});
|
fee
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return txs;
|
||||||
|
} catch (e) {
|
||||||
|
logger.warn(`Failed to unpack CPFP cluster. Reason: ` + (e instanceof Error ? e.message : e));
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
return txs;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,15 +3,6 @@ import logger from '../logger';
|
|||||||
import { Ancestor, CpfpInfo } from '../mempool.interfaces';
|
import { Ancestor, CpfpInfo } from '../mempool.interfaces';
|
||||||
import cpfpRepository from './CpfpRepository';
|
import cpfpRepository from './CpfpRepository';
|
||||||
|
|
||||||
interface CpfpSummary {
|
|
||||||
txid: string;
|
|
||||||
cluster: string;
|
|
||||||
root: string;
|
|
||||||
txs: Ancestor[];
|
|
||||||
height: number;
|
|
||||||
fee_rate: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
class TransactionRepository {
|
class TransactionRepository {
|
||||||
public async $setCluster(txid: string, clusterRoot: string): Promise<void> {
|
public async $setCluster(txid: string, clusterRoot: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
@ -72,7 +63,9 @@ class TransactionRepository {
|
|||||||
const txid = txRows[0].id.toLowerCase();
|
const txid = txRows[0].id.toLowerCase();
|
||||||
const clusterId = txRows[0].root.toLowerCase();
|
const clusterId = txRows[0].root.toLowerCase();
|
||||||
const cluster = await cpfpRepository.$getCluster(clusterId);
|
const cluster = await cpfpRepository.$getCluster(clusterId);
|
||||||
return this.convertCpfp(txid, cluster);
|
if (cluster) {
|
||||||
|
return this.convertCpfp(txid, cluster);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.err('Cannot get transaction cpfp info from db. Reason: ' + (e instanceof Error ? e.message : e));
|
logger.err('Cannot get transaction cpfp info from db. Reason: ' + (e instanceof Error ? e.message : e));
|
||||||
@ -81,13 +74,18 @@ class TransactionRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async $removeTransaction(txid: string): Promise<void> {
|
public async $removeTransaction(txid: string): Promise<void> {
|
||||||
await DB.query(
|
try {
|
||||||
`
|
await DB.query(
|
||||||
DELETE FROM compact_transactions
|
`
|
||||||
WHERE txid = UNHEX(?)
|
DELETE FROM compact_transactions
|
||||||
`,
|
WHERE txid = UNHEX(?)
|
||||||
[txid]
|
`,
|
||||||
);
|
[txid]
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
logger.warn('Cannot delete transaction cpfp info from db. Reason: ' + (e instanceof Error ? e.message : e));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private convertCpfp(txid, cluster): CpfpInfo {
|
private convertCpfp(txid, cluster): CpfpInfo {
|
||||||
@ -95,7 +93,7 @@ class TransactionRepository {
|
|||||||
const ancestors: Ancestor[] = [];
|
const ancestors: Ancestor[] = [];
|
||||||
let matched = false;
|
let matched = false;
|
||||||
|
|
||||||
for (const tx of cluster.txs) {
|
for (const tx of (cluster?.txs || [])) {
|
||||||
if (tx.txid === txid) {
|
if (tx.txid === txid) {
|
||||||
matched = true;
|
matched = true;
|
||||||
} else if (!matched) {
|
} else if (!matched) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user