diff --git a/ironfish-cli/src/commands/wallet/notes/combine.ts b/ironfish-cli/src/commands/wallet/notes/combine.ts index b94f2fd89f..87cedbc1e9 100644 --- a/ironfish-cli/src/commands/wallet/notes/combine.ts +++ b/ironfish-cli/src/commands/wallet/notes/combine.ts @@ -18,7 +18,11 @@ import { IronFlag, RemoteFlags } from '../../../flags' import { getExplorer } from '../../../utils/explorer' import { selectFee } from '../../../utils/fees' import { fetchNotes } from '../../../utils/note' -import { getSpendPostTimeInMs } from '../../../utils/spendPostTime' +import { + benchmarkSpendPostTime, + getSpendPostTimeInMs, + updateSpendPostTimeInMs, +} from '../../../utils/spendPostTime' import { displayTransactionSummary, TransactionTimer, @@ -232,7 +236,11 @@ export class CombineNotesCommand extends IronfishCommand { await this.ensureUserHasEnoughNotesToCombine(client, from) - const spendPostTime = await getSpendPostTimeInMs(this.sdk, client, from, flags.benchmark) + let spendPostTime = getSpendPostTimeInMs(this.sdk) + + if (spendPostTime === 0 || flags.benchmark) { + spendPostTime = await benchmarkSpendPostTime(client, from) + } let numberOfNotes = flags.notes @@ -330,6 +338,13 @@ export class CombineNotesCommand extends IronfishCommand { transactionTimer.end() + await updateSpendPostTimeInMs( + this.sdk, + raw, + transactionTimer.getStartTime(), + transactionTimer.getEndTime(), + ) + this.log( `Combining took ${TimeUtils.renderSpan( transactionTimer.getEndTime() - transactionTimer.getStartTime(), diff --git a/ironfish-cli/src/commands/wallet/send.ts b/ironfish-cli/src/commands/wallet/send.ts index 84c4d21008..97354acb95 100644 --- a/ironfish-cli/src/commands/wallet/send.ts +++ b/ironfish-cli/src/commands/wallet/send.ts @@ -18,7 +18,7 @@ import { selectAsset } from '../../utils/asset' import { promptCurrency } from '../../utils/currency' import { getExplorer } from '../../utils/explorer' import { selectFee } from '../../utils/fees' -import { getSpendPostTimeInMs } from '../../utils/spendPostTime' +import { getSpendPostTimeInMs, updateSpendPostTimeInMs } from '../../utils/spendPostTime' import { displayTransactionSummary, TransactionTimer, @@ -109,11 +109,6 @@ export class Send extends IronfishCommand { description: 'The note hashes to include in the transaction', multiple: true, }), - benchmark: Flags.boolean({ - hidden: true, - default: false, - description: 'Force run the benchmark to measure the time to combine 1 note', - }), } async start(): Promise { @@ -250,7 +245,7 @@ export class Send extends IronfishCommand { displayTransactionSummary(raw, assetId, amount, from, to, memo) - const spendPostTime = await getSpendPostTimeInMs(this.sdk, client, from, flags.benchmark) + const spendPostTime = getSpendPostTimeInMs(this.sdk) const transactionTimer = new TransactionTimer(spendPostTime, raw) @@ -290,6 +285,13 @@ export class Send extends IronfishCommand { )}`, ) + await updateSpendPostTimeInMs( + this.sdk, + raw, + transactionTimer.getStartTime(), + transactionTimer.getEndTime(), + ) + if (response.content.accepted === false) { this.warn( `Transaction '${transaction.hash().toString('hex')}' was not accepted into the mempool`, diff --git a/ironfish-cli/src/utils/spendPostTime.ts b/ironfish-cli/src/utils/spendPostTime.ts index 903b75cf6d..cf43bb5067 100644 --- a/ironfish-cli/src/utils/spendPostTime.ts +++ b/ironfish-cli/src/utils/spendPostTime.ts @@ -7,6 +7,7 @@ import { CurrencyUtils, EstimateFeeRatesResponse, IronfishSdk, + RawTransaction, RawTransactionSerde, RpcClient, RpcResponseEnded, @@ -15,38 +16,31 @@ import { import { CliUx } from '@oclif/core' import { fetchNotes } from './note' -export async function getSpendPostTimeInMs( +export async function updateSpendPostTimeInMs( sdk: IronfishSdk, - client: RpcClient, - account: string, - forceBenchmark: boolean, -): Promise { - try { - let spendPostTime = sdk.internal.get('spendPostTime') - - const spendPostTimeAt = sdk.internal.get('spendPostTimeAt') - - const shouldbenchmark = - forceBenchmark || - spendPostTime <= 0 || - Date.now() - spendPostTimeAt > 1000 * 60 * 60 * 24 * 30 // 1 month - - if (shouldbenchmark) { - spendPostTime = await benchmarkSpendPostTime(client, account) - - sdk.internal.set('spendPostTime', spendPostTime) - sdk.internal.set('spendPostTimeAt', Date.now()) - await sdk.internal.save() - } - - return spendPostTime - } catch (e) { - // if benchmarking fails, return 0. The consumer of this function should not show an estimate - return 0 + raw: RawTransaction, + startTime: number, + endTime: number, +) { + const totalTime = endTime - startTime + const transactionSpendPostTime = Math.ceil(totalTime / raw.spends.length) + let spendPostTime = sdk.internal.get('spendPostTime') + if (transactionSpendPostTime > spendPostTime) { + spendPostTime = transactionSpendPostTime + sdk.internal.set('spendPostTime', spendPostTime) + sdk.internal.set('spendPostTimeAt', Date.now()) + await sdk.internal.save() } } -async function benchmarkSpendPostTime(client: RpcClient, account: string): Promise { +export function getSpendPostTimeInMs(sdk: IronfishSdk): number { + return sdk.internal.get('spendPostTime') +} + +export async function benchmarkSpendPostTime( + client: RpcClient, + account: string, +): Promise { const publicKey = ( await client.wallet.getAccountPublicKey({ account: account, diff --git a/ironfish-cli/src/utils/transaction.ts b/ironfish-cli/src/utils/transaction.ts index 3a249cde9f..6fcb46967e 100644 --- a/ironfish-cli/src/utils/transaction.ts +++ b/ironfish-cli/src/utils/transaction.ts @@ -50,7 +50,10 @@ export class TransactionTimer { } start() { + this.startTime = Date.now() + if (this.estimateInMs <= 0) { + CliUx.ux.action.start('Sending the transaction') return } @@ -58,8 +61,6 @@ export class TransactionTimer { format: '{title}: [{bar}] {percentage}% | {estimate}', }) as ProgressBar - this.startTime = performance.now() - this.progressBar.start(100, 0, { title: 'Sending the transaction', estimate: TimeUtils.renderSpan(this.estimateInMs, { hideMilliseconds: true }), @@ -69,7 +70,7 @@ export class TransactionTimer { if (!this.progressBar || !this.startTime) { return } - const durationInMs = performance.now() - this.startTime + const durationInMs = Date.now() - this.startTime const timeRemaining = this.estimateInMs - durationInMs const progress = Math.round((durationInMs / this.estimateInMs) * 100) @@ -80,18 +81,23 @@ export class TransactionTimer { } end() { - if (this.estimateInMs <= 0) { + if (!this.startTime) { + // transaction timer has not been started return } - if (!this.progressBar || !this.startTime || !this.timer) { + this.endTime = Date.now() + + if (!this.progressBar || !this.timer || this.estimateInMs <= 0) { + CliUx.ux.action.stop() return } clearInterval(this.timer) - this.progressBar.update(100) + this.progressBar.update(100, { + estimate: 'done', + }) this.progressBar.stop() - this.endTime = performance.now() } }