@across-protocol/sdk 3.2.14 → 3.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.d.ts +2 -1
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +7 -4
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.d.ts +0 -2
- package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js +1 -2
- package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
- package/dist/cjs/providers/rateLimitedProvider.js +1 -0
- package/dist/cjs/providers/rateLimitedProvider.js.map +1 -1
- package/dist/cjs/utils/Profiler.d.ts +40 -0
- package/dist/cjs/utils/Profiler.js +114 -0
- package/dist/cjs/utils/Profiler.js.map +1 -0
- package/dist/esm/clients/BundleDataClient/BundleDataClient.d.ts +2 -1
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js +11 -4
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.d.ts +0 -2
- package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js +2 -3
- package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
- package/dist/esm/providers/rateLimitedProvider.js +1 -0
- package/dist/esm/providers/rateLimitedProvider.js.map +1 -1
- package/dist/esm/utils/Profiler.d.ts +81 -0
- package/dist/esm/utils/Profiler.js +155 -0
- package/dist/esm/utils/Profiler.js.map +1 -0
- package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts +2 -1
- package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
- package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts +0 -2
- package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts.map +1 -1
- package/dist/types/providers/rateLimitedProvider.d.ts.map +1 -1
- package/dist/types/utils/Profiler.d.ts +82 -0
- package/dist/types/utils/Profiler.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/clients/BundleDataClient/BundleDataClient.ts +12 -4
- package/src/clients/BundleDataClient/utils/SuperstructUtils.ts +2 -2
- package/src/providers/rateLimitedProvider.ts +1 -0
- package/src/utils/Profiler.ts +194 -0
|
@@ -171,8 +171,16 @@ export class BundleDataClient {
|
|
|
171
171
|
this.bundleTimestampCache[key] = timestamps;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
static getArweaveClientKey(blockRangesForChains: number[][]): string {
|
|
175
|
+
// As a unique key for this bundle, use the bundle mainnet end block, which should
|
|
176
|
+
// never be duplicated between bundles as long as thebundle block range
|
|
177
|
+
// always progresses forwards, which I think is a safe assumption. Other chains might pause
|
|
178
|
+
// but mainnet should never pause.
|
|
179
|
+
return blockRangesForChains[0][1].toString();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private getArweaveBundleDataClientKey(blockRangesForChains: number[][]): string {
|
|
183
|
+
return `bundles-${BundleDataClient.getArweaveClientKey(blockRangesForChains)}`;
|
|
176
184
|
}
|
|
177
185
|
|
|
178
186
|
private async loadPersistedDataFromArweave(
|
|
@@ -183,7 +191,7 @@ export class BundleDataClient {
|
|
|
183
191
|
}
|
|
184
192
|
const start = performance.now();
|
|
185
193
|
const persistedData = await this.clients.arweaveClient.getByTopic(
|
|
186
|
-
this.
|
|
194
|
+
this.getArweaveBundleDataClientKey(blockRangesForChains),
|
|
187
195
|
BundleDataSS
|
|
188
196
|
);
|
|
189
197
|
// If there is no data or the data is empty, return undefined because we couldn't
|
|
@@ -579,7 +587,7 @@ export class BundleDataClient {
|
|
|
579
587
|
}
|
|
580
588
|
|
|
581
589
|
private async loadArweaveData(blockRangesForChains: number[][]): Promise<LoadDataReturnValue> {
|
|
582
|
-
const arweaveKey = this.
|
|
590
|
+
const arweaveKey = this.getArweaveBundleDataClientKey(blockRangesForChains);
|
|
583
591
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
584
592
|
if (!this.arweaveDataCache[arweaveKey]) {
|
|
585
593
|
this.arweaveDataCache[arweaveKey] = this.loadPersistedDataFromArweave(blockRangesForChains);
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
pattern,
|
|
11
11
|
boolean,
|
|
12
12
|
defaulted,
|
|
13
|
+
type,
|
|
13
14
|
} from "superstruct";
|
|
14
15
|
import { BigNumber } from "../../../utils";
|
|
15
16
|
|
|
@@ -122,8 +123,7 @@ const nestedV3BundleFillsSS = record(
|
|
|
122
123
|
)
|
|
123
124
|
);
|
|
124
125
|
|
|
125
|
-
export const BundleDataSS =
|
|
126
|
-
bundleBlockRanges: array(array(number())),
|
|
126
|
+
export const BundleDataSS = type({
|
|
127
127
|
bundleDepositsV3: nestedV3DepositRecordSS,
|
|
128
128
|
expiredDepositsToRefundV3: nestedV3DepositRecordSS,
|
|
129
129
|
unexecutableSlowFills: nestedV3DepositRecordWithLpFeePctSS,
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { performance } from "node:perf_hooks";
|
|
2
|
+
import { Logger } from "winston";
|
|
3
|
+
import crypto from "crypto";
|
|
4
|
+
import { DefaultLogLevels } from "./LogUtils";
|
|
5
|
+
|
|
6
|
+
type Detail = {
|
|
7
|
+
message?: string;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const defaultMeta = { datadog: true };
|
|
12
|
+
|
|
13
|
+
export type PerformanceData = {
|
|
14
|
+
task: string; // The name of the task being measured.
|
|
15
|
+
duration: number; // Duration in milliseconds.
|
|
16
|
+
message: string; // A descriptive message about the task.
|
|
17
|
+
at: string; // Identifier indicating where the profiling is happening.
|
|
18
|
+
data?: Record<string, unknown>; // Additional detail data.
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
type ProfilerOptions = {
|
|
22
|
+
logger: Logger;
|
|
23
|
+
at: string;
|
|
24
|
+
logLevel?: DefaultLogLevels;
|
|
25
|
+
} & Record<string, unknown>;
|
|
26
|
+
|
|
27
|
+
export class Profiler {
|
|
28
|
+
private marks: Map<string, { time: number; detail?: Record<string, unknown> }>;
|
|
29
|
+
private at: string;
|
|
30
|
+
private detail: Detail;
|
|
31
|
+
private logger: Logger;
|
|
32
|
+
private logLevel: DefaultLogLevels;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Initializes a new instance of the Profiler class.
|
|
36
|
+
* @param logger The logger instance for logging performance data.
|
|
37
|
+
* @param at A string identifier for where the profiler is used.
|
|
38
|
+
* @param detail Optional additional detail data.
|
|
39
|
+
*/
|
|
40
|
+
constructor({ logger, at, logLevel, ...detail }: ProfilerOptions) {
|
|
41
|
+
this.marks = new Map();
|
|
42
|
+
this.logger = logger;
|
|
43
|
+
this.at = at;
|
|
44
|
+
this.logLevel = logLevel ?? "debug";
|
|
45
|
+
this.detail = detail;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
log(logLevel: DefaultLogLevels, data: Parameters<Logger["log"]>[1]): void {
|
|
49
|
+
this.logger.log(logLevel, {
|
|
50
|
+
at: this.at,
|
|
51
|
+
...defaultMeta,
|
|
52
|
+
...data,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
logMeasure(data: Omit<PerformanceData, "at">, logLevel: DefaultLogLevels = this.logLevel): void {
|
|
57
|
+
this.log(logLevel, {
|
|
58
|
+
...data,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Starts a profiling session for a task.
|
|
64
|
+
* @param task The name of the task being measured.
|
|
65
|
+
* @param detail Optional detail data to merge.
|
|
66
|
+
* @returns An object containing the start time and a stop function.
|
|
67
|
+
*/
|
|
68
|
+
start(task: string, detail?: Detail): { startTime: number; stop: (_detail?: Detail) => number | undefined } {
|
|
69
|
+
const start = crypto.randomUUID();
|
|
70
|
+
const startTime = this.mark(start, detail);
|
|
71
|
+
return {
|
|
72
|
+
startTime,
|
|
73
|
+
stop: (_detail?: Detail) => this.measure(task, { from: start, ...(detail ?? {}), ...(_detail ?? {}) }),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Records a mark with a label and optional detail.
|
|
79
|
+
* @param label The label for the mark.
|
|
80
|
+
* @param detail Optional detail data to merge.
|
|
81
|
+
* @returns The current timestamp in milliseconds.
|
|
82
|
+
*/
|
|
83
|
+
mark(label: string, detail?: Detail): number {
|
|
84
|
+
const currentTime = performance.now();
|
|
85
|
+
|
|
86
|
+
// Merge additional data
|
|
87
|
+
this.detail = { ...(this.detail ?? {}), ...(detail ?? {}) };
|
|
88
|
+
|
|
89
|
+
// Store the mark
|
|
90
|
+
this.marks.set(label, { time: currentTime, detail });
|
|
91
|
+
return currentTime;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Measures the duration between two marks and logs the performance data.
|
|
96
|
+
* @param task The name of the task for this measurement.
|
|
97
|
+
* @param params An object containing:
|
|
98
|
+
* - `from`: The label of the starting mark.
|
|
99
|
+
* - `to` (optional): The label of the ending mark.
|
|
100
|
+
* - Additional detail data to merge.
|
|
101
|
+
* @returns The duration in milliseconds, or undefined if the start mark is not found.
|
|
102
|
+
*/
|
|
103
|
+
measure(
|
|
104
|
+
task: string,
|
|
105
|
+
params: {
|
|
106
|
+
from: string;
|
|
107
|
+
to?: string;
|
|
108
|
+
} & Detail
|
|
109
|
+
): number | undefined {
|
|
110
|
+
const { from, to, ...detail } = params;
|
|
111
|
+
const startMark = this.marks.get(from);
|
|
112
|
+
const endMark = to ? this.marks.get(to) : undefined;
|
|
113
|
+
|
|
114
|
+
if (!startMark) {
|
|
115
|
+
this.log("warn", {
|
|
116
|
+
message: `Cannot find start mark for label "${from}".`,
|
|
117
|
+
...this.detail,
|
|
118
|
+
});
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const endTime = endMark?.time ?? performance.now();
|
|
122
|
+
|
|
123
|
+
const duration = endTime - startMark.time;
|
|
124
|
+
|
|
125
|
+
// Merge detail
|
|
126
|
+
const { message, ...combinedDetail } = { ...(this.detail ?? {}), ...(detail ?? {}) };
|
|
127
|
+
const defaultMessage = `Profiler Log: ${task}`;
|
|
128
|
+
|
|
129
|
+
this.logMeasure({
|
|
130
|
+
task,
|
|
131
|
+
duration,
|
|
132
|
+
message: message ?? defaultMessage,
|
|
133
|
+
data: combinedDetail,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
return duration;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Measures the performance of an asynchronous operation represented by a promise.
|
|
141
|
+
* @param pr The promise representing the asynchronous operation to measure.
|
|
142
|
+
* @param task The name of the task for this measurement.
|
|
143
|
+
* @param detail Optional detail data to merge.
|
|
144
|
+
* @returns A promise that resolves with the result of the asynchronous operation.
|
|
145
|
+
*/
|
|
146
|
+
async measureAsync<T>(pr: Promise<T>, task: string, detail?: Detail): Promise<T> {
|
|
147
|
+
const startTime = performance.now();
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
const result = await pr;
|
|
151
|
+
return result;
|
|
152
|
+
} finally {
|
|
153
|
+
const endTime = performance.now();
|
|
154
|
+
const duration = endTime - startTime;
|
|
155
|
+
const { message, ...combinedDetail } = { ...detail };
|
|
156
|
+
const defaultMessage = `Profiler Log: ${task}`;
|
|
157
|
+
|
|
158
|
+
this.logMeasure({
|
|
159
|
+
task,
|
|
160
|
+
duration,
|
|
161
|
+
message: message ?? defaultMessage,
|
|
162
|
+
data: combinedDetail,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Measures the performance of a synchronous function by wrapping it.
|
|
169
|
+
* @param fn The synchronous function to measure.
|
|
170
|
+
* @param task The name of the task for this measurement.
|
|
171
|
+
* @param detail Optional detail data to merge.
|
|
172
|
+
* @returns The result of the synchronous function.
|
|
173
|
+
*/
|
|
174
|
+
measureSync<T>(fn: () => T, task: string, detail?: Detail): T {
|
|
175
|
+
const startTime = performance.now();
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
const result = fn();
|
|
179
|
+
return result;
|
|
180
|
+
} finally {
|
|
181
|
+
const endTime = performance.now();
|
|
182
|
+
const duration = endTime - startTime;
|
|
183
|
+
const { message, ...combinedDetail } = { ...detail };
|
|
184
|
+
const defaultMessage = `Profiler Log: ${task}`;
|
|
185
|
+
|
|
186
|
+
this.logMeasure({
|
|
187
|
+
task,
|
|
188
|
+
duration,
|
|
189
|
+
message: message ?? defaultMessage,
|
|
190
|
+
data: combinedDetail,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|