diff --git a/src/Health/HealthController.ts b/src/Health/HealthController.ts index 20ca9ddf..ec6087ed 100644 --- a/src/Health/HealthController.ts +++ b/src/Health/HealthController.ts @@ -3,13 +3,11 @@ import * as Pino from 'pino' import { pick, pipeP } from 'ramda' import { childWithFileName } from 'Helpers/Logging' -import { IPFSHashFailure, ClaimIPFSHashPair } from 'Interfaces' +import { HealthError, IPFSHashFailure, TransactionAnchorRetryInfo } from 'Interfaces' import { IPFSHashTxId } from 'Messaging/Messages' - -import { BlockchainInfo, WalletInfo, NetworkInfo, IPFSInfo, EstimatedSmartFeeInfo, HealthDAO } from './HealthDAO' -import { TransactionAnchorRetryInfo, IPFSDirectoryHashDAO } from './IPFSDirectoryHashDAO' - +import { BlockchainInfo, EstimatedSmartFeeInfo, HealthDAO, IPFSInfo, NetworkInfo, WalletInfo } from './HealthDAO' import { IPFS } from './IPFS' +import { IPFSDirectoryHashDAO } from './IPFSDirectoryHashDAO' enum LogTypes { info = 'info', @@ -17,10 +15,6 @@ enum LogTypes { error = 'error', } -export interface HealthError { - readonly error: string -} - export interface HealthControllerConfiguration { readonly lowWalletBalanceInBitcoin: number readonly feeEstimateMinTargetBlock: number @@ -159,6 +153,11 @@ export class HealthController { return transactionAnchorRetryInfo } + private async upsertIpfsDirectoryHashTxId(ipfsHashTxId: IPFSHashTxId): Promise { + await this.ipfsDirectoryHashDAO.updateAnchorAttemptsInfo(ipfsHashTxId) + return ipfsHashTxId + } + private async removeIPFSDirectoryHashByTransactionId(transactionIds: ReadonlyArray): Promise { await this.ipfsDirectoryHashDAO.deleteByTransactionIds(transactionIds) } @@ -173,6 +172,12 @@ export class HealthController { ) } + public upsertIpfsHashTxId = pipeP( + this.log(LogTypes.trace)('updating ipfsDirectoryHash info'), + this.upsertIpfsDirectoryHashTxId, + this.log(LogTypes.trace)('updated ipfsDirectoryHash info'), + ) + public purgeIpfsDirectoryHashByTransactionIds = pipeP( this.log(LogTypes.trace)('purging IPFSDirectoryHash for transactionIds'), this.removeIPFSDirectoryHashByTransactionId, diff --git a/src/Health/HealthDAO.ts b/src/Health/HealthDAO.ts index e66c95f3..8438f71c 100644 --- a/src/Health/HealthDAO.ts +++ b/src/Health/HealthDAO.ts @@ -1,5 +1,6 @@ import { Collection, Db } from 'mongodb' -import { TransactionAnchorRetryInfo } from './IPFSDirectoryHashDAO' + +import { TransactionAnchorRetryInfo } from 'Interfaces' export interface BlockchainInfo { readonly blocks: number @@ -124,7 +125,9 @@ export class HealthDAO { ) } - readonly updateTransactionAnchorRetryInfo: updateTransactionAnchorRetryInfo = async transactionAnchorRetryInfo => { + readonly updateTransactionAnchorRetryInfo: updateTransactionAnchorRetryInfo = async ( + transactionAnchorRetryInfo: TransactionAnchorRetryInfo, + ) => { await this.collection.updateOne( { name: 'transactionAnchorRetryInfo' }, { diff --git a/src/Health/IPFSDirectoryHashDAO.ts b/src/Health/IPFSDirectoryHashDAO.ts index 53bc4f94..09d60ddc 100644 --- a/src/Health/IPFSDirectoryHashDAO.ts +++ b/src/Health/IPFSDirectoryHashDAO.ts @@ -1,8 +1,8 @@ +import { TransactionAnchorRetryInfo } from 'Interfaces' +import { IPFSHashTxId } from 'Messaging/Messages' import { Collection } from 'mongodb' import { isNil } from 'ramda' -import { IPFSHashTxId } from 'Messaging/Messages' - type updateAnchorAttemptsInfo = (x: IPFSHashTxId) => Promise export interface AnchorRetryDAOResult { @@ -10,12 +10,6 @@ export interface AnchorRetryDAOResult { readonly count: number } -export interface TransactionAnchorRetryEntry { - readonly attempts: number - readonly count: number -} - -export type TransactionAnchorRetryInfo = ReadonlyArray export type getTransactionAnchorRetryInfo = () => Promise type deleteByTransactionIds = (transactionIds: ReadonlyArray) => Promise diff --git a/src/Health/Router.ts b/src/Health/Router.ts index 00a0b842..c92106e2 100644 --- a/src/Health/Router.ts +++ b/src/Health/Router.ts @@ -42,6 +42,7 @@ export class Router { async start() { await this.messaging.consume(this.exchange.getHealth, this.onGetHealth) await this.messaging.consumeClaimsNotDownloaded(this.onClaimsNotDownloaded) + await this.messaging.consumeIPFSHashTxId(this.ipfsHashTxIdConsumer) await this.messaging.consumeBlockDownloaded(this.blockDownloadedConsumer) } @@ -70,6 +71,18 @@ export class Router { } } + ipfsHashTxIdConsumer = async (hashTxId: IPFSHashTxId): Promise => { + const logger = this.logger.child({ method: 'ipfsHashTxIdConsumer' }) + + logger.debug({ hashTxId }, 'IPFS Directory Hash assigned a transactionId, updating counts') + try { + await this.controller.upsertIpfsHashTxId(hashTxId) + logger.info({ hashTxId }, 'Updated count for IPFS Directory Hash') + } catch (error) { + logger.error({ error }, 'Failed to upsert IPFSDirectoryHash') + } + } + blockDownloadedConsumer = async (blockDownloaded: BlockDownloaded): Promise => { const logger = this.logger.child({ method: 'blockDownloadedConsumer' }) @@ -77,6 +90,7 @@ export class Router { try { const transactionIds = blockDownloaded.poetBlockAnchors.map(_ => _.transactionId) await this.controller.purgeIpfsDirectoryHashByTransactionIds(transactionIds) + logger.info({ blockDownloaded }, 'Block downloaded, associated transactions removed') } catch (error) { logger.error({ error }, 'Failed to remove transactions') } diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 81234a63..26f528f0 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -27,3 +27,14 @@ const hasFailureType = has('failureType') const hasFailureReason = has('failureReason') const hasFailureTime = has('failureTime') export const isIPFSHashFailure = allPass([hasIPFSFileHash, hasFailureReason, hasFailureType, hasFailureTime]) + +export interface HealthError { + readonly error: string +} + +export interface TransactionAnchorRetryEntry { + readonly attempts: number + readonly count: number +} + +export type TransactionAnchorRetryInfo = ReadonlyArray