Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add initial instrumentation
  • Loading branch information
matthewwalsh0 committed Aug 1, 2024
commit a891af89be36bc51234b43f0a14afeb6085a8d2c
134 changes: 95 additions & 39 deletions packages/transaction-controller/src/TransactionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import type {
GasFeeEstimates,
GasFeeFlowResponse,
TraceCallback,
TraceContext,
} from './types';
import {
TransactionEnvelopeType,
Expand Down Expand Up @@ -813,7 +814,7 @@ export class TransactionController extends BaseController<
this.#transactionHistoryLimit = transactionHistoryLimit;
this.sign = sign;
this.#testGasFeeFlows = testGasFeeFlows === true;
this.#trace = trace ?? ((_request, fn) => fn());
this.#trace = trace ?? (((_request, fn) => fn?.()) as TraceCallback);

this.afterSign = hooks?.afterSign ?? (() => true);
this.beforeApproveOnInit = hooks?.beforeApproveOnInit ?? (() => true);
Expand Down Expand Up @@ -983,7 +984,7 @@ export class TransactionController extends BaseController<
* @param opts.swaps.hasApproveTx - Whether the transaction has an approval transaction.
* @param opts.swaps.meta - Metadata for swap transaction.
* @param opts.networkClientId - The id of the network client for this transaction.
* @param opts.traceContext - The trace context for this transaction.
* @param opts.traceContext - The parent context for any new traces.
* @returns Object containing a promise resolving to the transaction hash if approved.
*/
async addTransaction(
Expand All @@ -997,6 +998,7 @@ export class TransactionController extends BaseController<
securityAlertResponse,
sendFlowHistory,
swaps = {},
traceContext,
type,
networkClientId: requestNetworkClientId,
}: {
Expand Down Expand Up @@ -1083,7 +1085,13 @@ export class TransactionController extends BaseController<
networkClientId,
};

await this.updateGasProperties(addedTransactionMeta);
await this.#trace(
{ name: 'Estimate Gas Properties', parentContext: traceContext },
(context) =>
this.updateGasProperties(addedTransactionMeta, {
traceContext: context,
}),
);

// Checks if a transaction already exists with a given actionId
if (!existingTransactionMeta) {
Expand Down Expand Up @@ -1136,6 +1144,7 @@ export class TransactionController extends BaseController<
isExisting: Boolean(existingTransactionMeta),
requireApproval,
actionId,
traceContext,
}),
transactionMeta: addedTransactionMeta,
};
Expand Down Expand Up @@ -2446,7 +2455,10 @@ export class TransactionController extends BaseController<
});
}

private async updateGasProperties(transactionMeta: TransactionMeta) {
private async updateGasProperties(
transactionMeta: TransactionMeta,
{ traceContext }: { traceContext?: TraceContext } = {},
) {
const isEIP1559Compatible =
(await this.getEIP1559Compatibility(transactionMeta.networkClientId)) &&
transactionMeta.txParams.type !== TransactionEnvelopeType.legacy;
Expand All @@ -2465,27 +2477,40 @@ export class TransactionController extends BaseController<
chainId,
});

await updateGas({
ethQuery,
chainId,
isCustomNetwork,
txMeta: transactionMeta,
});
await this.#trace(
{ name: 'Update Gas', parentContext: traceContext },
async () => {
await updateGas({
ethQuery,
chainId,
isCustomNetwork,
txMeta: transactionMeta,
});
},
);

await updateGasFees({
eip1559: isEIP1559Compatible,
ethQuery,
gasFeeFlows: this.gasFeeFlows,
getGasFeeEstimates: this.getGasFeeEstimates,
getSavedGasFees: this.getSavedGasFees.bind(this),
txMeta: transactionMeta,
});
await this.#trace(
{ name: 'Update Gas Fees', parentContext: traceContext },
async () =>
await updateGasFees({
eip1559: isEIP1559Compatible,
ethQuery,
gasFeeFlows: this.gasFeeFlows,
getGasFeeEstimates: this.getGasFeeEstimates,
getSavedGasFees: this.getSavedGasFees.bind(this),
txMeta: transactionMeta,
}),
);

await updateTransactionLayer1GasFee({
layer1GasFeeFlows: this.layer1GasFeeFlows,
provider,
transactionMeta,
});
await this.#trace(
{ name: 'Update Layer 1 Gas Fees', parentContext: traceContext },
async () =>
await updateTransactionLayer1GasFee({
layer1GasFeeFlows: this.layer1GasFeeFlows,
provider,
transactionMeta,
}),
);
}

private onBootCleanup() {
Expand Down Expand Up @@ -2517,11 +2542,13 @@ export class TransactionController extends BaseController<
requireApproval,
shouldShowRequest = true,
actionId,
traceContext,
}: {
isExisting?: boolean;
requireApproval?: boolean | undefined;
shouldShowRequest?: boolean;
actionId?: string;
traceContext?: TraceContext;
},
): Promise<string> {
const transactionId = transactionMeta.id;
Expand All @@ -2534,9 +2561,15 @@ export class TransactionController extends BaseController<
if (meta && !isExisting && !isCompleted) {
try {
if (requireApproval !== false) {
const acceptResult = await this.requestApproval(transactionMeta, {
shouldShowRequest,
});
const acceptResult = await this.#trace(
{ name: 'Await Approval', parentContext: traceContext },
(context) =>
this.requestApproval(transactionMeta, {
shouldShowRequest,
traceContext: context,
}),
);

resultCallbacks = acceptResult.resultCallbacks;

const approvalValue = acceptResult.value as
Expand Down Expand Up @@ -2564,7 +2597,10 @@ export class TransactionController extends BaseController<
this.isTransactionCompleted(transactionId);

if (!isTxCompleted) {
const approvalResult = await this.approveTransaction(transactionId);
const approvalResult = await this.approveTransaction(
transactionId,
traceContext,
);
if (
approvalResult === ApprovalState.SkippedViaBeforePublishHook &&
resultCallbacks
Expand Down Expand Up @@ -2631,8 +2667,12 @@ export class TransactionController extends BaseController<
* A `<tx.id>:finished` hub event is fired after success or failure.
*
* @param transactionId - The ID of the transaction to approve.
* @param traceContext - The parent context for any new traces.
*/
private async approveTransaction(transactionId: string) {
private async approveTransaction(
transactionId: string,
traceContext?: unknown,
) {
const cleanupTasks = new Array<() => void>();
cleanupTasks.push(await this.mutex.acquire());

Expand Down Expand Up @@ -2694,9 +2734,9 @@ export class TransactionController extends BaseController<

this.onTransactionStatusChange(transactionMeta);

const rawTx = await this.signTransaction(
transactionMeta,
transactionMeta.txParams,
const rawTx = await this.#trace(
{ name: 'Sign', parentContext: traceContext },
() => this.signTransaction(transactionMeta, transactionMeta.txParams),
);

if (!this.beforePublish(transactionMeta)) {
Expand Down Expand Up @@ -2731,14 +2771,21 @@ export class TransactionController extends BaseController<

log('Publishing transaction', transactionMeta.txParams);

let { transactionHash: hash } = await this.publish(
transactionMeta,
rawTx,
);
let hash: string | undefined;

if (hash === undefined) {
hash = await this.publishTransaction(ethQuery, rawTx);
}
await this.#trace(
{ name: 'Publish', parentContext: traceContext },
async () => {
({ transactionHash: hash } = await this.publish(
transactionMeta,
rawTx,
));

if (hash === undefined) {
hash = await this.publishTransaction(ethQuery, rawTx);
}
},
);

log('Publish successful', hash);

Expand Down Expand Up @@ -2908,13 +2955,22 @@ export class TransactionController extends BaseController<

private async requestApproval(
txMeta: TransactionMeta,
{ shouldShowRequest }: { shouldShowRequest: boolean },
{
shouldShowRequest,
traceContext,
}: { shouldShowRequest: boolean; traceContext?: TraceContext },
): Promise<AddResult> {
const id = this.getApprovalId(txMeta);
const { origin } = txMeta;
const type = ApprovalType.Transaction;
const requestData = { txId: txMeta.id };

await this.#trace({
name: 'Notification Display',
id,
parentContext: traceContext,
});

return (await this.messagingSystem.call(
'ApprovalController:addRequest',
{
Expand Down
14 changes: 10 additions & 4 deletions packages/transaction-controller/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1303,16 +1303,22 @@ export type SimulationData = {
/** A context in which to execute a trace, in order to generate nested timings. */
export type TraceContext = unknown;

/** Request to trace the performance of an operation. */
/** Request to trace an operation. */
export type TraceRequest = {
/** Additional data to include in the trace. */
data?: Record<string, number | string | boolean>;

/** Name of the operation. */
name: string;

/**
* Unique identifier for the trace.
* Required if starting a trace and not providing a callback.
*/
id?: string;

/** Trace context in which to execute the operation. */
context?: TraceContext;
parentContext?: TraceContext;

/** Additional tags to include in the trace to filter results. */
tags?: Record<string, number | string | boolean>;
Expand All @@ -1328,5 +1334,5 @@ export type TraceCallback = <ReturnType>(
* Thrown errors will not be caught, but the trace will still be recorded.
* @param context - The context in which the operation is running.
*/
fn: (context?: unknown) => ReturnType,
) => ReturnType;
fn?: (context?: TraceContext) => ReturnType,
) => Promise<ReturnType>;