diff --git a/packages/common/src/utils/stream-utils.ts b/packages/common/src/utils/stream-utils.ts index 70c7025126..0f39cdc1c7 100644 --- a/packages/common/src/utils/stream-utils.ts +++ b/packages/common/src/utils/stream-utils.ts @@ -1,6 +1,7 @@ import cloneDeep from 'lodash.clonedeep' import * as uint8arrays from 'uint8arrays' import { toCID } from './cid-utils.js' +import type { DiagnosticsLogger } from '@ceramicnetwork/common' import * as dagCBOR from '@ipld/dag-cbor' import { AnchorCommit, @@ -354,7 +355,7 @@ export class StreamUtils { /** * Takes a StreamState and validates that none of the commits in its log are based on expired CACAOs. */ - static checkForCacaoExpiration(state: StreamState): void { + static checkForCacaoExpiration(state: StreamState, logger: DiagnosticsLogger): void { const now = Math.floor(Date.now() / 1000) // convert millis to seconds for (const logEntry of state.log) { const timestamp = logEntry.timestamp ?? now @@ -366,6 +367,12 @@ export class StreamUtils { logEntry.expirationTime }. Loading the stream with 'sync: SyncOptions.ALWAYS_SYNC' will restore the stream to a usable state, by discarding the invalid commits (this means losing the data from those invalid writes!)` ) + } else if (logEntry.expirationTime && logEntry.expirationTime - timestamp < 12 * 60 * 60) { + logger.warn( + `CACAO anchored with less then 12 hours left. ${logEntry.cid.toString()} of ${StreamUtils.streamIdFromState( + state + ).toString()}: anchorTime=${logEntry.timestamp} expirationTime=${logEntry.expirationTime}` + ) } } } diff --git a/packages/core/src/state-management/repository.ts b/packages/core/src/state-management/repository.ts index 627d639074..8cb42cba7a 100644 --- a/packages/core/src/state-management/repository.ts +++ b/packages/core/src/state-management/repository.ts @@ -301,7 +301,7 @@ export class Repository { }) if (checkCacaoExpiration) { - StreamUtils.checkForCacaoExpiration(state$.state) + StreamUtils.checkForCacaoExpiration(state$.state, this.logger) } if (syncStatus != SyncStatus.ALREADY_SYNCED) { @@ -485,7 +485,7 @@ export class Repository { const stateAtCommit = await this.streamLoader.stateAtCommit(existingState$.state, commitId) // Since we skipped CACAO expiration checking earlier we need to make sure to do it here. - StreamUtils.checkForCacaoExpiration(stateAtCommit) + StreamUtils.checkForCacaoExpiration(stateAtCommit, this.logger) // If the provided CommitID is ahead of what we have in the cache and state store, then we // should update them to include it. diff --git a/packages/core/src/stream-loading/state-manipulator.ts b/packages/core/src/stream-loading/state-manipulator.ts index b113b56344..3e51610cd6 100644 --- a/packages/core/src/stream-loading/state-manipulator.ts +++ b/packages/core/src/stream-loading/state-manipulator.ts @@ -324,7 +324,7 @@ export class StateManipulator { // The initial state may have included commits that were valid previously but have since had // their CACAOs expire. Before returning the state back to the caller we should double-check // that it is based all on valid commits without expired CACAOs. - StreamUtils.checkForCacaoExpiration(state) + StreamUtils.checkForCacaoExpiration(state, this.logger) return state }