Merge pull request #3649 from mempool/nymkappa/indexing-error
Fix indexing error
This commit is contained in:
		
						commit
						b8d063a4f7
					
				@ -857,6 +857,7 @@ class Blocks {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        if (cleanBlock.fee_amt_percentiles !== null) {
 | 
					        if (cleanBlock.fee_amt_percentiles !== null) {
 | 
				
			||||||
          cleanBlock.median_fee_amt = cleanBlock.fee_amt_percentiles[3];
 | 
					          cleanBlock.median_fee_amt = cleanBlock.fee_amt_percentiles[3];
 | 
				
			||||||
 | 
					          await blocksRepository.$updateFeeAmounts(cleanBlock.hash, cleanBlock.fee_amt_percentiles, cleanBlock.median_fee_amt);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,48 @@ import chainTips from '../api/chain-tips';
 | 
				
			|||||||
import blocks from '../api/blocks';
 | 
					import blocks from '../api/blocks';
 | 
				
			||||||
import BlocksAuditsRepository from './BlocksAuditsRepository';
 | 
					import BlocksAuditsRepository from './BlocksAuditsRepository';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface DatabaseBlock {
 | 
				
			||||||
 | 
					  id: string;
 | 
				
			||||||
 | 
					  height: number;
 | 
				
			||||||
 | 
					  version: number;
 | 
				
			||||||
 | 
					  timestamp: number;
 | 
				
			||||||
 | 
					  bits: number;
 | 
				
			||||||
 | 
					  nonce: number;
 | 
				
			||||||
 | 
					  difficulty: number;
 | 
				
			||||||
 | 
					  merkle_root: string;
 | 
				
			||||||
 | 
					  tx_count: number;
 | 
				
			||||||
 | 
					  size: number;
 | 
				
			||||||
 | 
					  weight: number;
 | 
				
			||||||
 | 
					  previousblockhash: string;
 | 
				
			||||||
 | 
					  mediantime: number;
 | 
				
			||||||
 | 
					  totalFees: number;
 | 
				
			||||||
 | 
					  medianFee: number;
 | 
				
			||||||
 | 
					  feeRange: string;
 | 
				
			||||||
 | 
					  reward: number;
 | 
				
			||||||
 | 
					  poolId: number;
 | 
				
			||||||
 | 
					  poolName: string;
 | 
				
			||||||
 | 
					  poolSlug: string;
 | 
				
			||||||
 | 
					  avgFee: number;
 | 
				
			||||||
 | 
					  avgFeeRate: number;
 | 
				
			||||||
 | 
					  coinbaseRaw: string;
 | 
				
			||||||
 | 
					  coinbaseAddress: string;
 | 
				
			||||||
 | 
					  coinbaseSignature: string;
 | 
				
			||||||
 | 
					  coinbaseSignatureAscii: string;
 | 
				
			||||||
 | 
					  avgTxSize: number;
 | 
				
			||||||
 | 
					  totalInputs: number;
 | 
				
			||||||
 | 
					  totalOutputs: number;
 | 
				
			||||||
 | 
					  totalOutputAmt: number;
 | 
				
			||||||
 | 
					  medianFeeAmt: number;
 | 
				
			||||||
 | 
					  feePercentiles: string;
 | 
				
			||||||
 | 
					  segwitTotalTxs: number;
 | 
				
			||||||
 | 
					  segwitTotalSize: number;
 | 
				
			||||||
 | 
					  segwitTotalWeight: number;
 | 
				
			||||||
 | 
					  header: string;
 | 
				
			||||||
 | 
					  utxoSetChange: number;
 | 
				
			||||||
 | 
					  utxoSetSize: number;
 | 
				
			||||||
 | 
					  totalInputAmt: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const BLOCK_DB_FIELDS = `
 | 
					const BLOCK_DB_FIELDS = `
 | 
				
			||||||
  blocks.hash AS id,
 | 
					  blocks.hash AS id,
 | 
				
			||||||
  blocks.height,
 | 
					  blocks.height,
 | 
				
			||||||
@ -52,7 +94,7 @@ const BLOCK_DB_FIELDS = `
 | 
				
			|||||||
  blocks.header,
 | 
					  blocks.header,
 | 
				
			||||||
  blocks.utxoset_change AS utxoSetChange,
 | 
					  blocks.utxoset_change AS utxoSetChange,
 | 
				
			||||||
  blocks.utxoset_size AS utxoSetSize,
 | 
					  blocks.utxoset_size AS utxoSetSize,
 | 
				
			||||||
  blocks.total_input_amt AS totalInputAmts
 | 
					  blocks.total_input_amt AS totalInputAmt
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BlocksRepository {
 | 
					class BlocksRepository {
 | 
				
			||||||
@ -171,6 +213,32 @@ class BlocksRepository {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Update missing fee amounts fields
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @param blockHash 
 | 
				
			||||||
 | 
					   * @param feeAmtPercentiles 
 | 
				
			||||||
 | 
					   * @param medianFeeAmt 
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public async $updateFeeAmounts(blockHash: string, feeAmtPercentiles, medianFeeAmt) : Promise<void> {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      const query = `
 | 
				
			||||||
 | 
					        UPDATE blocks
 | 
				
			||||||
 | 
					        SET fee_percentiles = ?, median_fee_amt = ?
 | 
				
			||||||
 | 
					        WHERE hash = ?
 | 
				
			||||||
 | 
					      `;
 | 
				
			||||||
 | 
					      const params: any[] = [
 | 
				
			||||||
 | 
					        JSON.stringify(feeAmtPercentiles),
 | 
				
			||||||
 | 
					        medianFeeAmt,
 | 
				
			||||||
 | 
					        blockHash
 | 
				
			||||||
 | 
					      ];
 | 
				
			||||||
 | 
					      await DB.query(query, params);
 | 
				
			||||||
 | 
					    } catch (e: any) {
 | 
				
			||||||
 | 
					      logger.err(`Cannot update fee amounts for block ${blockHash}. Reason: ' + ${e instanceof Error ? e.message : e}`);
 | 
				
			||||||
 | 
					      throw e;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Get all block height that have not been indexed between [startHeight, endHeight]
 | 
					   * Get all block height that have not been indexed between [startHeight, endHeight]
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
@ -432,7 +500,7 @@ class BlocksRepository {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      const blocks: BlockExtended[] = [];
 | 
					      const blocks: BlockExtended[] = [];
 | 
				
			||||||
      for (const block of rows) {
 | 
					      for (const block of rows) {
 | 
				
			||||||
        blocks.push(await this.formatDbBlockIntoExtendedBlock(block));
 | 
					        blocks.push(await this.formatDbBlockIntoExtendedBlock(block as DatabaseBlock));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return blocks;
 | 
					      return blocks;
 | 
				
			||||||
@ -459,7 +527,7 @@ class BlocksRepository {
 | 
				
			|||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return await this.formatDbBlockIntoExtendedBlock(rows[0]);  
 | 
					      return await this.formatDbBlockIntoExtendedBlock(rows[0] as DatabaseBlock);  
 | 
				
			||||||
    } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
      logger.err(`Cannot get indexed block ${height}. Reason: ` + (e instanceof Error ? e.message : e));
 | 
					      logger.err(`Cannot get indexed block ${height}. Reason: ` + (e instanceof Error ? e.message : e));
 | 
				
			||||||
      throw e;
 | 
					      throw e;
 | 
				
			||||||
@ -908,7 +976,7 @@ class BlocksRepository {
 | 
				
			|||||||
   * 
 | 
					   * 
 | 
				
			||||||
   * @param dbBlk 
 | 
					   * @param dbBlk 
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  private async formatDbBlockIntoExtendedBlock(dbBlk: any): Promise<BlockExtended> {
 | 
					  private async formatDbBlockIntoExtendedBlock(dbBlk: DatabaseBlock): Promise<BlockExtended> {
 | 
				
			||||||
    const blk: Partial<BlockExtended> = {};
 | 
					    const blk: Partial<BlockExtended> = {};
 | 
				
			||||||
    const extras: Partial<BlockExtension> = {};
 | 
					    const extras: Partial<BlockExtension> = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -980,11 +1048,12 @@ class BlocksRepository {
 | 
				
			|||||||
      if (extras.feePercentiles === null) {
 | 
					      if (extras.feePercentiles === null) {
 | 
				
			||||||
        const block = await bitcoinClient.getBlock(dbBlk.id, 2);
 | 
					        const block = await bitcoinClient.getBlock(dbBlk.id, 2);
 | 
				
			||||||
        const summary = blocks.summarizeBlock(block);
 | 
					        const summary = blocks.summarizeBlock(block);
 | 
				
			||||||
        await BlocksSummariesRepository.$saveTransactions(dbBlk.height, dbBlk.hash, summary.transactions);
 | 
					        await BlocksSummariesRepository.$saveTransactions(dbBlk.height, dbBlk.id, summary.transactions);
 | 
				
			||||||
        extras.feePercentiles = await BlocksSummariesRepository.$getFeePercentilesByBlockId(dbBlk.id);
 | 
					        extras.feePercentiles = await BlocksSummariesRepository.$getFeePercentilesByBlockId(dbBlk.id);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (extras.feePercentiles !== null) {
 | 
					      if (extras.feePercentiles !== null) {
 | 
				
			||||||
        extras.medianFeeAmt = extras.feePercentiles[3];
 | 
					        extras.medianFeeAmt = extras.feePercentiles[3];
 | 
				
			||||||
 | 
					        await this.$updateFeeAmounts(dbBlk.id, extras.feePercentiles, extras.medianFeeAmt);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -17,26 +17,6 @@ class BlocksSummariesRepository {
 | 
				
			|||||||
    return undefined;
 | 
					    return undefined;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public async $saveSummary(params: { height: number, mined?: BlockSummary}): Promise<void> {
 | 
					 | 
				
			||||||
    const blockId = params.mined?.id;
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      const transactions = JSON.stringify(params.mined?.transactions || []);
 | 
					 | 
				
			||||||
      await DB.query(`
 | 
					 | 
				
			||||||
        INSERT INTO blocks_summaries (height, id, transactions, template)
 | 
					 | 
				
			||||||
        VALUE (?, ?, ?, ?)
 | 
					 | 
				
			||||||
        ON DUPLICATE KEY UPDATE
 | 
					 | 
				
			||||||
          transactions = ?
 | 
					 | 
				
			||||||
      `, [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 summary for ${blockId} because it has already been indexed, ignoring`);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        logger.debug(`Cannot save block summary for ${blockId}. Reason: ${e instanceof Error ? e.message : e}`);
 | 
					 | 
				
			||||||
        throw e;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public async $saveTransactions(blockHeight: number, blockId: string, transactions: TransactionStripped[]): Promise<void> {
 | 
					  public async $saveTransactions(blockHeight: number, blockId: string, transactions: TransactionStripped[]): Promise<void> {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      const transactionsStr = JSON.stringify(transactions);
 | 
					      const transactionsStr = JSON.stringify(transactions);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user