@ocap/tx-protocols 1.29.7 → 1.29.9
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/esm/execute.d.mts +3 -0
- package/esm/execute.mjs +37 -5
- package/esm/pipes/write-ledger.d.mts +4 -0
- package/esm/pipes/write-ledger.mjs +2 -0
- package/esm/tx-timer.d.mts +17 -0
- package/esm/tx-timer.mjs +31 -0
- package/lib/execute.cjs +37 -5
- package/lib/execute.d.cts +3 -0
- package/lib/pipes/write-ledger.cjs +2 -0
- package/lib/pipes/write-ledger.d.cts +4 -0
- package/lib/tx-timer.cjs +32 -0
- package/lib/tx-timer.d.cts +17 -0
- package/package.json +18 -18
package/esm/execute.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TxTimer } from "./tx-timer.mjs";
|
|
1
2
|
import { CustomError } from "@ocap/util/lib/error";
|
|
2
3
|
import { Blacklist } from "@ocap/state";
|
|
3
4
|
import { IAccountState, IGasContext } from "@ocap/types";
|
|
@@ -31,6 +32,8 @@ interface IExecutionContext extends IGasContext {
|
|
|
31
32
|
ledgerSequence?: number;
|
|
32
33
|
/** State commit hash set by onCommit callback (Dolt only) */
|
|
33
34
|
stateCommitHash?: string;
|
|
35
|
+
/** Transaction execution timer */
|
|
36
|
+
timer?: TxTimer;
|
|
34
37
|
}
|
|
35
38
|
/** Protocol runner interface */
|
|
36
39
|
interface IProtocolRunner {
|
package/esm/execute.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ensure_cost_default from "./pipes/ensure-cost.mjs";
|
|
2
2
|
import ensure_gas_default from "./pipes/ensure-gas.mjs";
|
|
3
3
|
import { WriteLedger } from "./pipes/write-ledger.mjs";
|
|
4
|
+
import { TxTimer } from "./tx-timer.mjs";
|
|
4
5
|
import { Runner, pipes } from "@ocap/tx-pipeline";
|
|
5
6
|
import { CustomError } from "@ocap/util/lib/error";
|
|
6
7
|
import camelCase from "lodash/camelCase.js";
|
|
@@ -101,6 +102,7 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
101
102
|
const protocol = protocols[getTxName(context.txType)];
|
|
102
103
|
if (!protocol) return reject(new CustomError("UNSUPPORTED_TX", `Unsupported tx type ${context.txType}`));
|
|
103
104
|
protocol.run(context, async (error) => {
|
|
105
|
+
context.timer?.mark("protocol");
|
|
104
106
|
if (isRetrySupported) {
|
|
105
107
|
if (error) return reject(error);
|
|
106
108
|
return resolve(context);
|
|
@@ -114,7 +116,9 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
114
116
|
txState = states.tx.create(context, txStatus);
|
|
115
117
|
}
|
|
116
118
|
await context.statedb.tx.create(txState.hash, txState, context);
|
|
119
|
+
context.timer?.mark("commit");
|
|
117
120
|
flushEvents(context, { txState });
|
|
121
|
+
context.timer?.mark("indexdb");
|
|
118
122
|
} catch (e) {
|
|
119
123
|
context.logger?.error("Failed to save transaction to statedb", {
|
|
120
124
|
error: e,
|
|
@@ -128,7 +132,8 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
128
132
|
txHash: context.txHash,
|
|
129
133
|
txStatus,
|
|
130
134
|
txState,
|
|
131
|
-
error
|
|
135
|
+
error,
|
|
136
|
+
timing: context.timer?.summary()
|
|
132
137
|
});
|
|
133
138
|
if (error) return reject(error);
|
|
134
139
|
return resolve(context);
|
|
@@ -137,7 +142,9 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
137
142
|
});
|
|
138
143
|
if (typeof runAsLambda === "function") return async (context, protocols) => {
|
|
139
144
|
let ctx = context;
|
|
140
|
-
|
|
145
|
+
context.timer = new TxTimer();
|
|
146
|
+
let entryFinalized = false;
|
|
147
|
+
let savedLedgerSequence;
|
|
141
148
|
try {
|
|
142
149
|
const txState = await runAsLambda(async (txn) => {
|
|
143
150
|
ctx = pick(context, [
|
|
@@ -150,10 +157,12 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
150
157
|
"filter",
|
|
151
158
|
"extra",
|
|
152
159
|
"logger",
|
|
153
|
-
"ledgerSequence"
|
|
160
|
+
"ledgerSequence",
|
|
161
|
+
"timer"
|
|
154
162
|
]);
|
|
155
163
|
ctx.txn = txn;
|
|
156
164
|
await execute(ctx, protocols, true);
|
|
165
|
+
if (ctx.ledgerSequence && !savedLedgerSequence) savedLedgerSequence = ctx.ledgerSequence;
|
|
157
166
|
const state = getStates(context).tx.create(ctx, "OK");
|
|
158
167
|
await context.statedb.tx.create(state.hash, state, ctx);
|
|
159
168
|
return state;
|
|
@@ -165,6 +174,7 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
165
174
|
if (ctx.txHash && ctx.ledger && ctx.ledgerSequence && ctx.txBase64) try {
|
|
166
175
|
await ctx.ledger.finalizeEntry(ctx.txHash, stateCommitHash || "", ctx.ledgerSequence, ctx.txBase64);
|
|
167
176
|
ctx.stateCommitHash = stateCommitHash || "";
|
|
177
|
+
entryFinalized = true;
|
|
168
178
|
} catch (err) {
|
|
169
179
|
ctx.logger?.error("Failed to finalize ledger entry", {
|
|
170
180
|
txHash: ctx.txHash,
|
|
@@ -174,7 +184,9 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
174
184
|
}
|
|
175
185
|
}
|
|
176
186
|
});
|
|
187
|
+
ctx.timer?.mark("commit");
|
|
177
188
|
flushEvents(ctx, { txState });
|
|
189
|
+
ctx.timer?.mark("indexdb");
|
|
178
190
|
ctx.ledger?.createCheckpointIfNeeded()?.catch((err) => {
|
|
179
191
|
ctx.logger?.error("Background checkpoint creation failed", {
|
|
180
192
|
txHash: ctx.txHash,
|
|
@@ -185,7 +197,7 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
185
197
|
txHash: ctx.txHash,
|
|
186
198
|
txState,
|
|
187
199
|
txStatus: "OK",
|
|
188
|
-
|
|
200
|
+
timing: ctx.timer?.summary()
|
|
189
201
|
});
|
|
190
202
|
} catch (error) {
|
|
191
203
|
const err = error;
|
|
@@ -217,6 +229,7 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
217
229
|
if (ctx.txHash && ctx.ledger && ctx.ledgerSequence && ctx.txBase64) try {
|
|
218
230
|
await ctx.ledger.finalizeEntry(ctx.txHash, stateCommitHash || "", ctx.ledgerSequence, ctx.txBase64);
|
|
219
231
|
ctx.stateCommitHash = stateCommitHash || "";
|
|
232
|
+
entryFinalized = true;
|
|
220
233
|
} catch (err$1) {
|
|
221
234
|
ctx.logger?.error("Failed to finalize ledger entry", {
|
|
222
235
|
txHash: ctx.txHash,
|
|
@@ -226,7 +239,9 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
226
239
|
}
|
|
227
240
|
}
|
|
228
241
|
});
|
|
242
|
+
ctx.timer?.mark("commit");
|
|
229
243
|
flushEvents(ctx, { txState });
|
|
244
|
+
ctx.timer?.mark("indexdb");
|
|
230
245
|
ctx.ledger?.createCheckpointIfNeeded()?.catch((err$1) => {
|
|
231
246
|
ctx.logger?.error("Background checkpoint creation failed", {
|
|
232
247
|
txHash: ctx.txHash,
|
|
@@ -238,7 +253,7 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
238
253
|
txState,
|
|
239
254
|
txStatus,
|
|
240
255
|
error,
|
|
241
|
-
|
|
256
|
+
timing: ctx.timer?.summary()
|
|
242
257
|
});
|
|
243
258
|
} catch (innerErr) {
|
|
244
259
|
ctx.logger?.error("Failed to save invalid transaction to statedb", {
|
|
@@ -253,11 +268,27 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
253
268
|
}
|
|
254
269
|
throw error;
|
|
255
270
|
} finally {
|
|
271
|
+
if (!entryFinalized) {
|
|
272
|
+
const ledger = ctx.ledger || context.ledger;
|
|
273
|
+
const txHash = ctx.txHash || context.txHash;
|
|
274
|
+
const txBase64 = ctx.txBase64 || context.txBase64;
|
|
275
|
+
const sequence = ctx.ledgerSequence || savedLedgerSequence || context.ledgerSequence;
|
|
276
|
+
if (ledger && txHash && sequence && txBase64) try {
|
|
277
|
+
await ledger.finalizeEntry(txHash, "", sequence, txBase64);
|
|
278
|
+
} catch (err) {
|
|
279
|
+
(ctx.logger || context.logger)?.error("Failed to finalize orphaned ledger entry", {
|
|
280
|
+
txHash,
|
|
281
|
+
sequence,
|
|
282
|
+
error: err
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
256
286
|
merge(context, ctx);
|
|
257
287
|
}
|
|
258
288
|
return ctx;
|
|
259
289
|
};
|
|
260
290
|
return async (context, protocols) => {
|
|
291
|
+
context.timer = new TxTimer();
|
|
261
292
|
const result = await execute(context, protocols);
|
|
262
293
|
if (result.ledger && result.txHash && result.ledgerSequence && result.txBase64) try {
|
|
263
294
|
await result.ledger.finalizeEntry(result.txHash, "", result.ledgerSequence, result.txBase64);
|
|
@@ -267,6 +298,7 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
267
298
|
error: err
|
|
268
299
|
});
|
|
269
300
|
}
|
|
301
|
+
result.timer?.mark("finalize");
|
|
270
302
|
result.ledger?.createCheckpointIfNeeded()?.catch((err) => {
|
|
271
303
|
result.logger?.error("Background checkpoint creation failed", {
|
|
272
304
|
txHash: result.txHash,
|
|
@@ -70,7 +70,9 @@ const WriteLedger = async (context, next) => {
|
|
|
70
70
|
timestamp: txTime ? new Date(txTime).getTime() : Date.now(),
|
|
71
71
|
txExtra
|
|
72
72
|
};
|
|
73
|
+
context.timer?.mark("verify");
|
|
73
74
|
const entry = await ledger.append(txInput);
|
|
75
|
+
context.timer?.mark("ledger");
|
|
74
76
|
context.ledgerSequence = entry.sequence;
|
|
75
77
|
debug("Transaction written to ledger", {
|
|
76
78
|
txHash,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/tx-timer.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Lightweight transaction execution timer.
|
|
4
|
+
*
|
|
5
|
+
* Records named marks at key stages and computes per-stage durations.
|
|
6
|
+
* Overhead per mark() call is a single Date.now() invocation (< 1 µs).
|
|
7
|
+
*/
|
|
8
|
+
declare class TxTimer {
|
|
9
|
+
private marks;
|
|
10
|
+
private origin;
|
|
11
|
+
/** Record a named timestamp. */
|
|
12
|
+
mark(label: string): void;
|
|
13
|
+
/** Compute per-stage durations (ms) between consecutive marks. */
|
|
14
|
+
summary(): Record<string, number>;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { TxTimer };
|
package/esm/tx-timer.mjs
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/tx-timer.ts
|
|
2
|
+
/**
|
|
3
|
+
* Lightweight transaction execution timer.
|
|
4
|
+
*
|
|
5
|
+
* Records named marks at key stages and computes per-stage durations.
|
|
6
|
+
* Overhead per mark() call is a single Date.now() invocation (< 1 µs).
|
|
7
|
+
*/
|
|
8
|
+
var TxTimer = class {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.marks = [];
|
|
11
|
+
this.origin = Date.now();
|
|
12
|
+
}
|
|
13
|
+
/** Record a named timestamp. */
|
|
14
|
+
mark(label) {
|
|
15
|
+
this.marks.push([label, Date.now()]);
|
|
16
|
+
}
|
|
17
|
+
/** Compute per-stage durations (ms) between consecutive marks. */
|
|
18
|
+
summary() {
|
|
19
|
+
const result = {};
|
|
20
|
+
let prev = this.origin;
|
|
21
|
+
for (const [label, time] of this.marks) {
|
|
22
|
+
result[label] = time - prev;
|
|
23
|
+
prev = time;
|
|
24
|
+
}
|
|
25
|
+
result.total = prev - this.origin;
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
export { TxTimer };
|
package/lib/execute.cjs
CHANGED
|
@@ -3,6 +3,7 @@ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
|
3
3
|
const require_pipes_ensure_cost = require('./pipes/ensure-cost.cjs');
|
|
4
4
|
const require_pipes_ensure_gas = require('./pipes/ensure-gas.cjs');
|
|
5
5
|
const require_pipes_write_ledger = require('./pipes/write-ledger.cjs');
|
|
6
|
+
const require_tx_timer = require('./tx-timer.cjs');
|
|
6
7
|
let _ocap_tx_pipeline = require("@ocap/tx-pipeline");
|
|
7
8
|
let _ocap_util_lib_error = require("@ocap/util/lib/error");
|
|
8
9
|
let lodash_camelCase = require("lodash/camelCase");
|
|
@@ -107,6 +108,7 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
107
108
|
const protocol = protocols[getTxName(context.txType)];
|
|
108
109
|
if (!protocol) return reject(new _ocap_util_lib_error.CustomError("UNSUPPORTED_TX", `Unsupported tx type ${context.txType}`));
|
|
109
110
|
protocol.run(context, async (error) => {
|
|
111
|
+
context.timer?.mark("protocol");
|
|
110
112
|
if (isRetrySupported) {
|
|
111
113
|
if (error) return reject(error);
|
|
112
114
|
return resolve(context);
|
|
@@ -120,7 +122,9 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
120
122
|
txState = states.tx.create(context, txStatus);
|
|
121
123
|
}
|
|
122
124
|
await context.statedb.tx.create(txState.hash, txState, context);
|
|
125
|
+
context.timer?.mark("commit");
|
|
123
126
|
flushEvents(context, { txState });
|
|
127
|
+
context.timer?.mark("indexdb");
|
|
124
128
|
} catch (e) {
|
|
125
129
|
context.logger?.error("Failed to save transaction to statedb", {
|
|
126
130
|
error: e,
|
|
@@ -134,7 +138,8 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
134
138
|
txHash: context.txHash,
|
|
135
139
|
txStatus,
|
|
136
140
|
txState,
|
|
137
|
-
error
|
|
141
|
+
error,
|
|
142
|
+
timing: context.timer?.summary()
|
|
138
143
|
});
|
|
139
144
|
if (error) return reject(error);
|
|
140
145
|
return resolve(context);
|
|
@@ -143,7 +148,9 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
143
148
|
});
|
|
144
149
|
if (typeof runAsLambda === "function") return async (context, protocols) => {
|
|
145
150
|
let ctx = context;
|
|
146
|
-
|
|
151
|
+
context.timer = new require_tx_timer.TxTimer();
|
|
152
|
+
let entryFinalized = false;
|
|
153
|
+
let savedLedgerSequence;
|
|
147
154
|
try {
|
|
148
155
|
const txState = await runAsLambda(async (txn) => {
|
|
149
156
|
ctx = (0, lodash_pick.default)(context, [
|
|
@@ -156,10 +163,12 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
156
163
|
"filter",
|
|
157
164
|
"extra",
|
|
158
165
|
"logger",
|
|
159
|
-
"ledgerSequence"
|
|
166
|
+
"ledgerSequence",
|
|
167
|
+
"timer"
|
|
160
168
|
]);
|
|
161
169
|
ctx.txn = txn;
|
|
162
170
|
await execute(ctx, protocols, true);
|
|
171
|
+
if (ctx.ledgerSequence && !savedLedgerSequence) savedLedgerSequence = ctx.ledgerSequence;
|
|
163
172
|
const state = getStates(context).tx.create(ctx, "OK");
|
|
164
173
|
await context.statedb.tx.create(state.hash, state, ctx);
|
|
165
174
|
return state;
|
|
@@ -171,6 +180,7 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
171
180
|
if (ctx.txHash && ctx.ledger && ctx.ledgerSequence && ctx.txBase64) try {
|
|
172
181
|
await ctx.ledger.finalizeEntry(ctx.txHash, stateCommitHash || "", ctx.ledgerSequence, ctx.txBase64);
|
|
173
182
|
ctx.stateCommitHash = stateCommitHash || "";
|
|
183
|
+
entryFinalized = true;
|
|
174
184
|
} catch (err) {
|
|
175
185
|
ctx.logger?.error("Failed to finalize ledger entry", {
|
|
176
186
|
txHash: ctx.txHash,
|
|
@@ -180,7 +190,9 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
180
190
|
}
|
|
181
191
|
}
|
|
182
192
|
});
|
|
193
|
+
ctx.timer?.mark("commit");
|
|
183
194
|
flushEvents(ctx, { txState });
|
|
195
|
+
ctx.timer?.mark("indexdb");
|
|
184
196
|
ctx.ledger?.createCheckpointIfNeeded()?.catch((err) => {
|
|
185
197
|
ctx.logger?.error("Background checkpoint creation failed", {
|
|
186
198
|
txHash: ctx.txHash,
|
|
@@ -191,7 +203,7 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
191
203
|
txHash: ctx.txHash,
|
|
192
204
|
txState,
|
|
193
205
|
txStatus: "OK",
|
|
194
|
-
|
|
206
|
+
timing: ctx.timer?.summary()
|
|
195
207
|
});
|
|
196
208
|
} catch (error) {
|
|
197
209
|
const err = error;
|
|
@@ -223,6 +235,7 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
223
235
|
if (ctx.txHash && ctx.ledger && ctx.ledgerSequence && ctx.txBase64) try {
|
|
224
236
|
await ctx.ledger.finalizeEntry(ctx.txHash, stateCommitHash || "", ctx.ledgerSequence, ctx.txBase64);
|
|
225
237
|
ctx.stateCommitHash = stateCommitHash || "";
|
|
238
|
+
entryFinalized = true;
|
|
226
239
|
} catch (err$1) {
|
|
227
240
|
ctx.logger?.error("Failed to finalize ledger entry", {
|
|
228
241
|
txHash: ctx.txHash,
|
|
@@ -232,7 +245,9 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
232
245
|
}
|
|
233
246
|
}
|
|
234
247
|
});
|
|
248
|
+
ctx.timer?.mark("commit");
|
|
235
249
|
flushEvents(ctx, { txState });
|
|
250
|
+
ctx.timer?.mark("indexdb");
|
|
236
251
|
ctx.ledger?.createCheckpointIfNeeded()?.catch((err$1) => {
|
|
237
252
|
ctx.logger?.error("Background checkpoint creation failed", {
|
|
238
253
|
txHash: ctx.txHash,
|
|
@@ -244,7 +259,7 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
244
259
|
txState,
|
|
245
260
|
txStatus,
|
|
246
261
|
error,
|
|
247
|
-
|
|
262
|
+
timing: ctx.timer?.summary()
|
|
248
263
|
});
|
|
249
264
|
} catch (innerErr) {
|
|
250
265
|
ctx.logger?.error("Failed to save invalid transaction to statedb", {
|
|
@@ -259,11 +274,27 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
259
274
|
}
|
|
260
275
|
throw error;
|
|
261
276
|
} finally {
|
|
277
|
+
if (!entryFinalized) {
|
|
278
|
+
const ledger = ctx.ledger || context.ledger;
|
|
279
|
+
const txHash = ctx.txHash || context.txHash;
|
|
280
|
+
const txBase64 = ctx.txBase64 || context.txBase64;
|
|
281
|
+
const sequence = ctx.ledgerSequence || savedLedgerSequence || context.ledgerSequence;
|
|
282
|
+
if (ledger && txHash && sequence && txBase64) try {
|
|
283
|
+
await ledger.finalizeEntry(txHash, "", sequence, txBase64);
|
|
284
|
+
} catch (err) {
|
|
285
|
+
(ctx.logger || context.logger)?.error("Failed to finalize orphaned ledger entry", {
|
|
286
|
+
txHash,
|
|
287
|
+
sequence,
|
|
288
|
+
error: err
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
262
292
|
(0, lodash_merge.default)(context, ctx);
|
|
263
293
|
}
|
|
264
294
|
return ctx;
|
|
265
295
|
};
|
|
266
296
|
return async (context, protocols) => {
|
|
297
|
+
context.timer = new require_tx_timer.TxTimer();
|
|
267
298
|
const result = await execute(context, protocols);
|
|
268
299
|
if (result.ledger && result.txHash && result.ledgerSequence && result.txBase64) try {
|
|
269
300
|
await result.ledger.finalizeEntry(result.txHash, "", result.ledgerSequence, result.txBase64);
|
|
@@ -273,6 +304,7 @@ const createExecute = ({ filter, runAsLambda }) => {
|
|
|
273
304
|
error: err
|
|
274
305
|
});
|
|
275
306
|
}
|
|
307
|
+
result.timer?.mark("finalize");
|
|
276
308
|
result.ledger?.createCheckpointIfNeeded()?.catch((err) => {
|
|
277
309
|
result.logger?.error("Background checkpoint creation failed", {
|
|
278
310
|
txHash: result.txHash,
|
package/lib/execute.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TxTimer } from "./tx-timer.cjs";
|
|
1
2
|
import { IAccountState, IGasContext } from "@ocap/types";
|
|
2
3
|
import { CustomError } from "@ocap/util/lib/error";
|
|
3
4
|
import { Blacklist } from "@ocap/state";
|
|
@@ -31,6 +32,8 @@ interface IExecutionContext extends IGasContext {
|
|
|
31
32
|
ledgerSequence?: number;
|
|
32
33
|
/** State commit hash set by onCommit callback (Dolt only) */
|
|
33
34
|
stateCommitHash?: string;
|
|
35
|
+
/** Transaction execution timer */
|
|
36
|
+
timer?: TxTimer;
|
|
34
37
|
}
|
|
35
38
|
/** Protocol runner interface */
|
|
36
39
|
interface IProtocolRunner {
|
|
@@ -73,7 +73,9 @@ const WriteLedger = async (context, next) => {
|
|
|
73
73
|
timestamp: txTime ? new Date(txTime).getTime() : Date.now(),
|
|
74
74
|
txExtra
|
|
75
75
|
};
|
|
76
|
+
context.timer?.mark("verify");
|
|
76
77
|
const entry = await ledger.append(txInput);
|
|
78
|
+
context.timer?.mark("ledger");
|
|
77
79
|
context.ledgerSequence = entry.sequence;
|
|
78
80
|
debug$1("Transaction written to ledger", {
|
|
79
81
|
txHash,
|
package/lib/tx-timer.cjs
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/tx-timer.ts
|
|
3
|
+
/**
|
|
4
|
+
* Lightweight transaction execution timer.
|
|
5
|
+
*
|
|
6
|
+
* Records named marks at key stages and computes per-stage durations.
|
|
7
|
+
* Overhead per mark() call is a single Date.now() invocation (< 1 µs).
|
|
8
|
+
*/
|
|
9
|
+
var TxTimer = class {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.marks = [];
|
|
12
|
+
this.origin = Date.now();
|
|
13
|
+
}
|
|
14
|
+
/** Record a named timestamp. */
|
|
15
|
+
mark(label) {
|
|
16
|
+
this.marks.push([label, Date.now()]);
|
|
17
|
+
}
|
|
18
|
+
/** Compute per-stage durations (ms) between consecutive marks. */
|
|
19
|
+
summary() {
|
|
20
|
+
const result = {};
|
|
21
|
+
let prev = this.origin;
|
|
22
|
+
for (const [label, time] of this.marks) {
|
|
23
|
+
result[label] = time - prev;
|
|
24
|
+
prev = time;
|
|
25
|
+
}
|
|
26
|
+
result.total = prev - this.origin;
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
exports.TxTimer = TxTimer;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/tx-timer.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Lightweight transaction execution timer.
|
|
4
|
+
*
|
|
5
|
+
* Records named marks at key stages and computes per-stage durations.
|
|
6
|
+
* Overhead per mark() call is a single Date.now() invocation (< 1 µs).
|
|
7
|
+
*/
|
|
8
|
+
declare class TxTimer {
|
|
9
|
+
private marks;
|
|
10
|
+
private origin;
|
|
11
|
+
/** Record a named timestamp. */
|
|
12
|
+
mark(label: string): void;
|
|
13
|
+
/** Compute per-stage durations (ms) between consecutive marks. */
|
|
14
|
+
summary(): Record<string, number>;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { TxTimer };
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.29.
|
|
6
|
+
"version": "1.29.9",
|
|
7
7
|
"description": "Predefined tx pipeline sets to execute certain type of transactions",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "./lib/index.cjs",
|
|
@@ -46,22 +46,22 @@
|
|
|
46
46
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
47
47
|
"license": "MIT",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@arcblock/did": "1.29.
|
|
50
|
-
"@arcblock/did-util": "1.29.
|
|
51
|
-
"@arcblock/jwt": "1.29.
|
|
52
|
-
"@arcblock/validator": "1.29.
|
|
53
|
-
"@arcblock/vc": "1.29.
|
|
49
|
+
"@arcblock/did": "1.29.9",
|
|
50
|
+
"@arcblock/did-util": "1.29.9",
|
|
51
|
+
"@arcblock/jwt": "1.29.9",
|
|
52
|
+
"@arcblock/validator": "1.29.9",
|
|
53
|
+
"@arcblock/vc": "1.29.9",
|
|
54
54
|
"@blocklet/xss": "^0.3.7",
|
|
55
|
-
"@ocap/asset": "1.29.
|
|
56
|
-
"@ocap/client": "1.29.
|
|
57
|
-
"@ocap/mcrypto": "1.29.
|
|
58
|
-
"@ocap/merkle-tree": "1.29.
|
|
59
|
-
"@ocap/message": "1.29.
|
|
60
|
-
"@ocap/state": "1.29.
|
|
61
|
-
"@ocap/tx-pipeline": "1.29.
|
|
62
|
-
"@ocap/types": "1.29.
|
|
63
|
-
"@ocap/util": "1.29.
|
|
64
|
-
"@ocap/wallet": "1.29.
|
|
55
|
+
"@ocap/asset": "1.29.9",
|
|
56
|
+
"@ocap/client": "1.29.9",
|
|
57
|
+
"@ocap/mcrypto": "1.29.9",
|
|
58
|
+
"@ocap/merkle-tree": "1.29.9",
|
|
59
|
+
"@ocap/message": "1.29.9",
|
|
60
|
+
"@ocap/state": "1.29.9",
|
|
61
|
+
"@ocap/tx-pipeline": "1.29.9",
|
|
62
|
+
"@ocap/types": "1.29.9",
|
|
63
|
+
"@ocap/util": "1.29.9",
|
|
64
|
+
"@ocap/wallet": "1.29.9",
|
|
65
65
|
"debug": "^4.4.3",
|
|
66
66
|
"deep-diff": "^1.0.2",
|
|
67
67
|
"lodash": "^4.17.23",
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
"elliptic": "6.5.3"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@ocap/e2e-test": "1.29.
|
|
76
|
-
"@ocap/statedb-memory": "1.29.
|
|
75
|
+
"@ocap/e2e-test": "1.29.9",
|
|
76
|
+
"@ocap/statedb-memory": "1.29.9",
|
|
77
77
|
"@types/debug": "^4.1.12",
|
|
78
78
|
"@types/lodash": "^4.17.16",
|
|
79
79
|
"start-server-and-test": "^1.14.0"
|