-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: add latency detection scripts (#3583)
- Loading branch information
1 parent
56adcc5
commit b4f5279
Showing
16 changed files
with
613 additions
and
211 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
148 changes: 148 additions & 0 deletions
148
packages/fuel-gauge/scripts/latency-detection/helpers.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
import { Provider, Wallet } from 'fuels'; | ||
import ora from 'ora'; | ||
|
||
import { TransferContract, TransferContractFactory } from '../../test/typegen/contracts'; | ||
import { PredicateWithConfigurable } from '../../test/typegen/predicates'; | ||
|
||
import type { | ||
MeasureResponse, | ||
Operation, | ||
PerformanceOperationParams, | ||
PerformanceResult, | ||
} from './types'; | ||
|
||
/** | ||
* Function to measure the execution time (in seconds) of an asynchronous operation. | ||
* | ||
* @param operation - The asynchronous function (Promise) that will be executed and measured. | ||
* @returns An object containing the `response` of the operation and the `duration` in seconds. | ||
*/ | ||
export async function measure<T>(operation: () => Promise<T>): Promise<MeasureResponse<T>> { | ||
const start = Date.now(); | ||
const response = await operation(); | ||
const end = Date.now(); | ||
|
||
return { | ||
response, | ||
duration: (end - start) / 1000, | ||
}; | ||
} | ||
|
||
/** | ||
* Executes preparatory steps for latency detection. | ||
* | ||
* This function performs the following steps: | ||
* 1. Retrieves the provider URL and private key from environment variables. | ||
* 2. Initializes a logger to indicate the progress of the preparatory steps. | ||
* 3. Creates a provider and account using the retrieved credentials. | ||
* 4. Retrieves the base asset ID from the provider. | ||
* 5. Deploys a transfer contract and waits for the deployment result. | ||
* 6. Instantiates a predicate with configurable constants. | ||
* 7. Funds the predicate with a specified amount. | ||
* | ||
* | ||
* @returns The parameters to run a performance operation. | ||
*/ | ||
export const preparatorySteps = async (): Promise<PerformanceOperationParams> => { | ||
// Preparatory steps | ||
const providerUrl = process.env.PERFORMANCE_ANALYSIS_TEST_URL; | ||
const privateKey = process.env.PERFORMANCE_ANALYSIS_PVT_KEY; | ||
const contractAddress = process.env.PERFORMANCE_ANALYSIS_CONTRACT_ADDRESS; | ||
|
||
if (!providerUrl || !privateKey) { | ||
throw new Error( | ||
'Please provide PERFORMANCE_ANALYSIS_TEST_URL and PERFORMANCE_ANALYSIS_PVT_KEY in the .env file' | ||
); | ||
} | ||
|
||
const logger = ora({ | ||
text: 'Running preparatory steps..', | ||
color: 'green', | ||
}).start(); | ||
|
||
try { | ||
const provider = new Provider(providerUrl); | ||
const account = Wallet.fromPrivateKey(privateKey, provider); | ||
const baseAssetId = await provider.getBaseAssetId(); | ||
const amount = 100; | ||
const callParams = [ | ||
{ | ||
recipient: { Address: { bits: account.address.toB256() } }, | ||
asset_id: { bits: baseAssetId }, | ||
amount, | ||
}, | ||
]; | ||
|
||
// Deploying contract that will be executed | ||
let contract: TransferContract; | ||
let deployedMsg = ''; | ||
if (!contractAddress) { | ||
const factory = new TransferContractFactory(account); | ||
const deploy = await factory.deploy(); | ||
const result = await deploy.waitForResult(); | ||
contract = result.contract; | ||
deployedMsg = `\n- contract deployed on address: ${contract.id.toB256()}`; | ||
} else { | ||
contract = new TransferContract(contractAddress, account); | ||
} | ||
|
||
// Instantiating predicate | ||
const predicate = new PredicateWithConfigurable({ | ||
provider: contract.provider, | ||
data: [10, account.address.toString()], | ||
configurableConstants: { | ||
ADDRESS: account.address.toString(), | ||
FEE: 10, | ||
}, | ||
}); | ||
|
||
// Funding predicate | ||
const res = await account.transfer(predicate.address, 3000, baseAssetId); | ||
await res.waitForResult(); | ||
|
||
logger.succeed(`Preparatory steps done${deployedMsg}`); | ||
|
||
return { account, baseAssetId, provider, contract, callParams, predicate }; | ||
} catch (e) { | ||
logger.fail('Failed to run preparatory steps'); | ||
throw e; | ||
} | ||
}; | ||
|
||
/** | ||
* Executes a series of performance measure operations and returns their results. | ||
* | ||
* @param operations - An array of operations to be performed. | ||
* @param params - Parameters to be passed to each operation. | ||
* @returns A promise that resolves to an array of performance results. | ||
*/ | ||
export const runOperations = async ( | ||
operations: Array<Operation>, | ||
params: PerformanceOperationParams | ||
) => { | ||
const results: PerformanceResult[] = []; | ||
|
||
// Performing measure operations | ||
for (const operation of operations) { | ||
const logger = ora({ | ||
text: `Performing operation: ${operation.name}`, | ||
color: 'green', | ||
}).start(); | ||
try { | ||
// Clear chain info cache | ||
Provider.clearChainAndNodeCaches(); | ||
|
||
const result = await operation(params); | ||
|
||
logger.text = `Operation: ${operation.name} completed`; | ||
logger.succeed(); | ||
|
||
results.push(result); | ||
} catch (e) { | ||
logger.fail(`Operation: ${operation.name} failed`); | ||
throw e; | ||
} | ||
} | ||
|
||
return results; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import 'dotenv/config'; | ||
import fs from 'fs'; | ||
|
||
import { preparatorySteps, runOperations } from './helpers'; | ||
import { missing4xOutputVariableCall } from './missing-4x-variable-output-call'; | ||
import { missingOutputVariableCall } from './missing-variable-output-call'; | ||
import { scriptCall } from './script-call'; | ||
import { scriptWithPredicateCall } from './script-with-predicate-call'; | ||
|
||
const { log, error } = console; | ||
|
||
const DIR_NAME = 'snapshots'; | ||
|
||
const main = async () => { | ||
const operations = [ | ||
scriptCall, | ||
missingOutputVariableCall, | ||
missing4xOutputVariableCall, | ||
scriptWithPredicateCall, | ||
]; | ||
|
||
const operationsParams = await preparatorySteps(); | ||
const results = await runOperations(operations, operationsParams); | ||
|
||
const date = new Date(); | ||
|
||
const filename = `${date.toISOString().slice(0, 16)}.json`; | ||
|
||
fs.mkdirSync(DIR_NAME, { recursive: true }); | ||
fs.writeFileSync(`${DIR_NAME}/${filename}`, JSON.stringify(results, null, 2)); | ||
|
||
log(`Snapshots saved into "${DIR_NAME}/${filename}"`); | ||
}; | ||
|
||
main().catch(error); |
43 changes: 43 additions & 0 deletions
43
packages/fuel-gauge/scripts/latency-detection/missing-4x-variable-output-call.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { measure } from './helpers'; | ||
import type { PerformanceOperationParams, PerformanceResult } from './types'; | ||
import { TagEnum } from './types'; | ||
|
||
export async function missing4xOutputVariableCall( | ||
params: PerformanceOperationParams | ||
): Promise<PerformanceResult> { | ||
const { account, baseAssetId, contract } = params; | ||
|
||
const callParams = [ | ||
{ | ||
recipient: { Address: { bits: account.address.toB256() } }, | ||
asset_id: { bits: baseAssetId }, | ||
amount: 25, | ||
}, | ||
{ | ||
recipient: { Address: { bits: account.address.toB256() } }, | ||
asset_id: { bits: baseAssetId }, | ||
amount: 25, | ||
}, | ||
{ | ||
recipient: { Address: { bits: account.address.toB256() } }, | ||
asset_id: { bits: baseAssetId }, | ||
amount: 25, | ||
}, | ||
{ | ||
recipient: { Address: { bits: account.address.toB256() } }, | ||
asset_id: { bits: baseAssetId }, | ||
amount: 25, | ||
}, | ||
]; | ||
|
||
const { duration } = await measure(async () => { | ||
const call = await contract.functions | ||
.execute_transfer(callParams) | ||
.callParams({ forward: [1000, baseAssetId] }) | ||
.call(); | ||
|
||
return call.waitForResult(); | ||
}); | ||
|
||
return { tag: TagEnum.Missing4xOutputVariable, duration }; | ||
} |
20 changes: 20 additions & 0 deletions
20
packages/fuel-gauge/scripts/latency-detection/missing-variable-output-call.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { measure } from './helpers'; | ||
import type { PerformanceOperationParams, PerformanceResult } from './types'; | ||
import { TagEnum } from './types'; | ||
|
||
export async function missingOutputVariableCall( | ||
params: PerformanceOperationParams | ||
): Promise<PerformanceResult> { | ||
const { baseAssetId, contract, callParams } = params; | ||
|
||
const { duration } = await measure(async () => { | ||
const call = await contract.functions | ||
.execute_transfer(callParams) | ||
.callParams({ forward: [100, baseAssetId] }) | ||
.call(); | ||
|
||
return call.waitForResult(); | ||
}); | ||
|
||
return { tag: TagEnum.MissingOutputVariable, duration }; | ||
} |
19 changes: 19 additions & 0 deletions
19
packages/fuel-gauge/scripts/latency-detection/script-call.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { measure } from './helpers'; | ||
import type { PerformanceOperationParams, PerformanceResult } from './types'; | ||
import { TagEnum } from './types'; | ||
|
||
export async function scriptCall(params: PerformanceOperationParams): Promise<PerformanceResult> { | ||
const { baseAssetId, contract, callParams } = params; | ||
|
||
const { duration } = await measure(async () => { | ||
const call = await contract.functions | ||
.execute_transfer(callParams) | ||
.txParams({ variableOutputs: 1 }) | ||
.callParams({ forward: [100, baseAssetId] }) | ||
.call(); | ||
|
||
return call.waitForResult(); | ||
}); | ||
|
||
return { tag: TagEnum.Script, duration }; | ||
} |
22 changes: 22 additions & 0 deletions
22
packages/fuel-gauge/scripts/latency-detection/script-with-predicate-call.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { measure } from './helpers'; | ||
import type { PerformanceOperationParams, PerformanceResult } from './types'; | ||
import { TagEnum } from './types'; | ||
|
||
export async function scriptWithPredicateCall( | ||
params: PerformanceOperationParams | ||
): Promise<PerformanceResult> { | ||
const { baseAssetId, contract, callParams, predicate } = params; | ||
|
||
const { duration } = await measure(async () => { | ||
contract.account = predicate; | ||
const call = await contract.functions | ||
.execute_transfer(callParams) | ||
.txParams({ variableOutputs: 1 }) | ||
.callParams({ forward: [100, baseAssetId] }) | ||
.call(); | ||
|
||
return call.waitForResult(); | ||
}); | ||
|
||
return { tag: TagEnum.ScriptWithPredicate, duration }; | ||
} |
Oops, something went wrong.