Skip to content

Commit

Permalink
transaction send uses last transaction as a method to benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
patnir committed Mar 26, 2024
1 parent b3b32be commit fc79724
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 44 deletions.
19 changes: 17 additions & 2 deletions ironfish-cli/src/commands/wallet/notes/combine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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(),
Expand Down
16 changes: 9 additions & 7 deletions ironfish-cli/src/commands/wallet/send.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<void> {
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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`,
Expand Down
50 changes: 22 additions & 28 deletions ironfish-cli/src/utils/spendPostTime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
CurrencyUtils,
EstimateFeeRatesResponse,
IronfishSdk,
RawTransaction,
RawTransactionSerde,
RpcClient,
RpcResponseEnded,
Expand All @@ -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<number> {
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<number> {
export function getSpendPostTimeInMs(sdk: IronfishSdk): number {
return sdk.internal.get('spendPostTime')
}

export async function benchmarkSpendPostTime(
client: RpcClient,
account: string,
): Promise<number> {
const publicKey = (
await client.wallet.getAccountPublicKey({
account: account,
Expand Down
20 changes: 13 additions & 7 deletions ironfish-cli/src/utils/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,17 @@ export class TransactionTimer {
}

start() {
this.startTime = Date.now()

if (this.estimateInMs <= 0) {
CliUx.ux.action.start('Sending the transaction')
return
}

this.progressBar = CliUx.ux.progress({
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 }),
Expand All @@ -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)

Expand All @@ -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()
}
}

Expand Down

0 comments on commit fc79724

Please sign in to comment.