Skip to content

Commit

Permalink
Rahul/ifl 2399 move spendposttime to utils (#4859)
Browse files Browse the repository at this point in the history
* add spend post time to utils

* using getSpendPostTime in notes combine
  • Loading branch information
patnir committed Mar 21, 2024
1 parent fee5eeb commit ca1029b
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 119 deletions.
121 changes: 2 additions & 119 deletions ironfish-cli/src/commands/wallet/notes/combine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { Asset } from '@ironfish/rust-nodejs'
import {
BenchUtils,
CreateTransactionRequest,
CurrencyUtils,
EstimateFeeRatesResponse,
RawTransaction,
RawTransactionSerde,
RpcClient,
RpcResponseEnded,
TimeUtils,
Transaction,
} from '@ironfish/sdk'
Expand All @@ -21,6 +18,7 @@ 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 {
displayTransactionSummary,
TransactionTimer,
Expand Down Expand Up @@ -74,121 +72,6 @@ export class CombineNotesCommand extends IronfishCommand {
}),
}

private async getSpendPostTimeInMs(
client: RpcClient,
account: string,
forceBenchmark: boolean,
): Promise<number> {
let spendPostTime = this.sdk.internal.get('spendPostTime')

const spendPostTimeAt = this.sdk.internal.get('spendPostTimeAt')

const shouldbenchmark =
forceBenchmark ||
spendPostTime <= 0 ||
Date.now() - spendPostTimeAt > 1000 * 60 * 60 * 24 * 30 // 1 month

if (shouldbenchmark) {
spendPostTime = await this.benchmarkSpendPostTime(client, account)

this.sdk.internal.set('spendPostTime', spendPostTime)
this.sdk.internal.set('spendPostTimeAt', Date.now())
await this.sdk.internal.save()
}

return spendPostTime
}

private async benchmarkSpendPostTime(client: RpcClient, account: string): Promise<number> {
const publicKey = (
await client.wallet.getAccountPublicKey({
account: account,
})
).content.publicKey

const notes = await fetchNotes(client, account, 10)

CliUx.ux.action.start('Measuring time to combine 1 note')

const feeRates = await client.wallet.estimateFeeRates()

/** Transaction 1: selects 1 note */

const txn1Params: CreateTransactionRequest = {
account: account,
outputs: [
{
publicAddress: publicKey,
amount: CurrencyUtils.encode(BigInt(notes[0].value)),
memo: '',
},
],
fee: null,
feeRate: null,
notes: [notes[0].noteHash],
}

/** Transaction 2: selects two notes */

const txn2Params: CreateTransactionRequest = {
account: account,
outputs: [
{
publicAddress: publicKey,
amount: CurrencyUtils.encode(BigInt(notes[0].value) + BigInt(notes[1].value)),
memo: '',
},
],
fee: null,
feeRate: null,
notes: [notes[0].noteHash, notes[1].noteHash],
}

const promisesTxn1 = []
const promisesTxn2 = []

for (let i = 0; i < 3; i++) {
promisesTxn1.push(this.measureTransactionPostTime(client, txn1Params, feeRates))
promisesTxn2.push(this.measureTransactionPostTime(client, txn2Params, feeRates))
}

const resultTxn1 = await Promise.all(promisesTxn1)
const resultTxn2 = await Promise.all(promisesTxn2)

const delta = Math.ceil(
(resultTxn2.reduce((acc, curr) => acc + curr, 0) -
resultTxn1.reduce((acc, curr) => acc + curr, 0)) /
3,
)

CliUx.ux.action.stop(TimeUtils.renderSpan(delta))

return delta
}

private async measureTransactionPostTime(
client: RpcClient,
params: CreateTransactionRequest,
feeRates: RpcResponseEnded<EstimateFeeRatesResponse>,
) {
const response = await client.wallet.createTransaction({
...params,
feeRate: feeRates.content.fast,
})

const bytes = Buffer.from(response.content.transaction, 'hex')
const raw = RawTransactionSerde.deserialize(bytes)

const start = BenchUtils.start()

await client.wallet.postTransaction({
transaction: RawTransactionSerde.serialize(raw).toString('hex'),
broadcast: false,
})

return BenchUtils.end(start)
}

private async selectNotesToCombine(spendPostTimeMs: number): Promise<number> {
const spendsPerMinute = Math.max(Math.floor(60000 / spendPostTimeMs), 2) // minimum of 2 notes per minute in case the spentPostTime is very high

Expand Down Expand Up @@ -349,7 +232,7 @@ export class CombineNotesCommand extends IronfishCommand {

await this.ensureUserHasEnoughNotesToCombine(client, from)

const spendPostTime = await this.getSpendPostTimeInMs(client, from, flags.benchmark)
const spendPostTime = await getSpendPostTimeInMs(this.sdk, client, from, flags.benchmark)

let numberOfNotes = flags.notes

Expand Down
132 changes: 132 additions & 0 deletions ironfish-cli/src/utils/spendPostTime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import {
BenchUtils,
CreateTransactionRequest,
CurrencyUtils,
EstimateFeeRatesResponse,
IronfishSdk,
RawTransactionSerde,
RpcClient,
RpcResponseEnded,
TimeUtils,
} from '@ironfish/sdk'
import { CliUx } from '@oclif/core'
import { fetchNotes } from './note'

export async function getSpendPostTimeInMs(
sdk: IronfishSdk,
client: RpcClient,
account: string,
forceBenchmark: boolean,
): Promise<number> {
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
}

async function benchmarkSpendPostTime(client: RpcClient, account: string): Promise<number> {
const publicKey = (
await client.wallet.getAccountPublicKey({
account: account,
})
).content.publicKey

const notes = await fetchNotes(client, account, 10)

CliUx.ux.action.start('Measuring time to combine 1 note')

const feeRates = await client.wallet.estimateFeeRates()

/** Transaction 1: selects 1 note */

const txn1Params: CreateTransactionRequest = {
account: account,
outputs: [
{
publicAddress: publicKey,
amount: CurrencyUtils.encode(BigInt(notes[0].value)),
memo: '',
},
],
fee: null,
feeRate: null,
notes: [notes[0].noteHash],
}

/** Transaction 2: selects two notes */

const txn2Params: CreateTransactionRequest = {
account: account,
outputs: [
{
publicAddress: publicKey,
amount: CurrencyUtils.encode(BigInt(notes[0].value) + BigInt(notes[1].value)),
memo: '',
},
],
fee: null,
feeRate: null,
notes: [notes[0].noteHash, notes[1].noteHash],
}

const promisesTxn1 = []
const promisesTxn2 = []

for (let i = 0; i < 3; i++) {
promisesTxn1.push(measureTransactionPostTime(client, txn1Params, feeRates))
promisesTxn2.push(measureTransactionPostTime(client, txn2Params, feeRates))
}

const resultTxn1 = await Promise.all(promisesTxn1)
const resultTxn2 = await Promise.all(promisesTxn2)

const delta = Math.ceil(
(resultTxn2.reduce((acc, curr) => acc + curr, 0) -
resultTxn1.reduce((acc, curr) => acc + curr, 0)) /
3,
)

CliUx.ux.action.stop(TimeUtils.renderSpan(delta))

return delta
}

async function measureTransactionPostTime(
client: RpcClient,
params: CreateTransactionRequest,
feeRates: RpcResponseEnded<EstimateFeeRatesResponse>,
) {
const response = await client.wallet.createTransaction({
...params,
feeRate: feeRates.content.fast,
})

const bytes = Buffer.from(response.content.transaction, 'hex')
const raw = RawTransactionSerde.deserialize(bytes)

const start = BenchUtils.start()

await client.wallet.postTransaction({
transaction: RawTransactionSerde.serialize(raw).toString('hex'),
broadcast: false,
})

return BenchUtils.end(start)
}

0 comments on commit ca1029b

Please sign in to comment.