@haven-fi/solauto-sdk 1.0.739 → 1.0.741
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/services/transactions/manager/transactionsManager.d.ts +5 -3
- package/dist/services/transactions/manager/transactionsManager.d.ts.map +1 -1
- package/dist/services/transactions/manager/transactionsManager.js +102 -54
- package/local/txSandbox.ts +4 -4
- package/package.json +1 -1
- package/src/services/transactions/manager/transactionsManager.ts +109 -114
@@ -13,14 +13,15 @@ export declare enum TransactionStatus {
|
|
13
13
|
Successful = "Successful",
|
14
14
|
Failed = "Failed"
|
15
15
|
}
|
16
|
-
export
|
16
|
+
export interface TransactionManagerStatus {
|
17
17
|
name: string;
|
18
18
|
attemptNum: number;
|
19
19
|
status: TransactionStatus;
|
20
20
|
moreInfo?: string;
|
21
21
|
simulationSuccessful?: boolean;
|
22
22
|
txSig?: string;
|
23
|
-
}
|
23
|
+
}
|
24
|
+
export type TransactionManagerStatuses = TransactionManagerStatus[];
|
24
25
|
interface RetryConfig {
|
25
26
|
signableRetries?: number;
|
26
27
|
totalRetries?: number;
|
@@ -58,10 +59,11 @@ export declare class TransactionsManager<T extends TxHandler> {
|
|
58
59
|
private updateStatusForSets;
|
59
60
|
send(items: TransactionItem[]): Promise<TransactionManagerStatuses>;
|
60
61
|
private shouldProceedToSend;
|
62
|
+
private getTrueAttemptNum;
|
61
63
|
private processTransactionsAtomically;
|
62
64
|
private processTransactionSet;
|
63
65
|
private refreshItemSets;
|
64
|
-
protected sendTransaction(tx: TransactionBuilder,
|
66
|
+
protected sendTransaction(tx: TransactionBuilder, name: string, attemptNum: number, priorityFeeSetting?: PriorityFeeSetting, txRunType?: TransactionRunType): Promise<void>;
|
65
67
|
}
|
66
68
|
export {};
|
67
69
|
//# sourceMappingURL=transactionsManager.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"transactionsManager.d.ts","sourceRoot":"","sources":["../../../../src/services/transactions/manager/transactionsManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EACL,kBAAkB,EAElB,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,aAAa,EAId,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAkB,MAAM,UAAU,CAAC;AAEzE,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM;CAK5B;AAED,oBAAY,iBAAiB;IAC3B,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,MAAM,WAAW;IACjB,UAAU,eAAe;IACzB,MAAM,WAAW;CAClB;AAED,MAAM,
|
1
|
+
{"version":3,"file":"transactionsManager.d.ts","sourceRoot":"","sources":["../../../../src/services/transactions/manager/transactionsManager.ts"],"names":[],"mappings":"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"}
|
@@ -76,41 +76,30 @@ class TransactionsManager {
|
|
76
76
|
}
|
77
77
|
return transactionSets;
|
78
78
|
}
|
79
|
-
updateStatus(
|
80
|
-
if (!this.statuses.filter((x) => x.name === name)) {
|
81
|
-
this.statuses.push(
|
82
|
-
name,
|
83
|
-
status,
|
84
|
-
txSig,
|
85
|
-
attemptNum,
|
86
|
-
simulationSuccessful,
|
87
|
-
moreInfo,
|
88
|
-
});
|
79
|
+
updateStatus(args) {
|
80
|
+
if (!this.statuses.filter((x) => x.name === args.name)) {
|
81
|
+
this.statuses.push(args);
|
89
82
|
}
|
90
83
|
else {
|
91
|
-
const idx = this.statuses.findIndex((x) => x.name === name && x.attemptNum === attemptNum);
|
84
|
+
const idx = this.statuses.findIndex((x) => x.name === args.name && x.attemptNum === args.attemptNum);
|
92
85
|
if (idx !== -1) {
|
93
|
-
this.statuses[idx].status = status;
|
94
|
-
this.statuses[idx].txSig = txSig;
|
95
|
-
if (simulationSuccessful) {
|
96
|
-
this.statuses[idx].simulationSuccessful = simulationSuccessful;
|
86
|
+
this.statuses[idx].status = args.status;
|
87
|
+
this.statuses[idx].txSig = args.txSig;
|
88
|
+
if (args.simulationSuccessful) {
|
89
|
+
this.statuses[idx].simulationSuccessful = args.simulationSuccessful;
|
97
90
|
}
|
98
|
-
if (
|
99
|
-
|
91
|
+
// else if (status === TransactionStatus.Queued || status === TransactionStatus.Processing) {
|
92
|
+
// this.statuses[idx].simulationSuccessful = undefined;
|
93
|
+
// }
|
94
|
+
if (args.moreInfo) {
|
95
|
+
this.statuses[idx].moreInfo = args.moreInfo;
|
100
96
|
}
|
101
97
|
}
|
102
98
|
else {
|
103
|
-
this.statuses.push(
|
104
|
-
name,
|
105
|
-
status,
|
106
|
-
txSig,
|
107
|
-
attemptNum,
|
108
|
-
simulationSuccessful,
|
109
|
-
moreInfo,
|
110
|
-
});
|
99
|
+
this.statuses.push(args);
|
111
100
|
}
|
112
101
|
}
|
113
|
-
this.txHandler.log(`${name} is ${status.toString().toLowerCase()}`);
|
102
|
+
this.txHandler.log(`${args.name} ${args.attemptNum} is ${args.status.toString().toLowerCase()}`);
|
114
103
|
this.statusCallback?.([...this.statuses]);
|
115
104
|
}
|
116
105
|
async debugAccounts(itemSet, tx) {
|
@@ -135,9 +124,13 @@ class TransactionsManager {
|
|
135
124
|
}
|
136
125
|
return this.priorityFeeSetting;
|
137
126
|
}
|
138
|
-
updateStatusForSets(itemSets,
|
127
|
+
updateStatusForSets(itemSets, args, txSigs) {
|
139
128
|
itemSets.forEach((itemSet, i) => {
|
140
|
-
this.updateStatus(
|
129
|
+
this.updateStatus({
|
130
|
+
name: itemSet.name(),
|
131
|
+
txSig: txSigs && txSigs.length > i ? txSigs[i] : undefined,
|
132
|
+
...args,
|
133
|
+
});
|
141
134
|
});
|
142
135
|
}
|
143
136
|
async send(items) {
|
@@ -152,7 +145,10 @@ class TransactionsManager {
|
|
152
145
|
this.txHandler.log("Transaction items:", items.length);
|
153
146
|
return await this.assembleTransactionSets(items);
|
154
147
|
}, this.totalRetries);
|
155
|
-
this.updateStatusForSets(itemSets,
|
148
|
+
this.updateStatusForSets(itemSets, {
|
149
|
+
status: TransactionStatus.Queued,
|
150
|
+
attemptNum: 0,
|
151
|
+
});
|
156
152
|
this.txHandler.log("Initial item sets:", itemSets.length);
|
157
153
|
if (this.atomically) {
|
158
154
|
await this.processTransactionsAtomically(itemSets);
|
@@ -174,23 +170,33 @@ class TransactionsManager {
|
|
174
170
|
if (newItemSetNames.length === 1 &&
|
175
171
|
newItemSetNames[0] === this.updateOracleTxName) {
|
176
172
|
(0, utils_1.consoleLog)("Skipping unnecessary oracle update");
|
177
|
-
this.updateStatusForSets(itemSets,
|
173
|
+
this.updateStatusForSets(itemSets, {
|
174
|
+
status: TransactionStatus.Skipped,
|
175
|
+
attemptNum,
|
176
|
+
});
|
178
177
|
return false;
|
179
178
|
}
|
180
179
|
return true;
|
181
180
|
}
|
181
|
+
getTrueAttemptNum(itemSetName) {
|
182
|
+
const prevAttempts = this.statuses.filter((x) => x.name === itemSetName && x.status !== TransactionStatus.Queued);
|
183
|
+
const attemptNum = prevAttempts.length -
|
184
|
+
prevAttempts.filter((x) => x.status === TransactionStatus.Skipped)
|
185
|
+
?.length;
|
186
|
+
return attemptNum;
|
187
|
+
}
|
182
188
|
async processTransactionsAtomically(itemSets) {
|
183
|
-
let
|
189
|
+
let attemptNum = 0;
|
184
190
|
let transactions = [];
|
185
|
-
await (0, utils_1.retryWithExponentialBackoff)(async (
|
191
|
+
await (0, utils_1.retryWithExponentialBackoff)(async (retryNum, prevError) => {
|
186
192
|
if (prevError &&
|
187
193
|
this.statuses.filter((x) => x.simulationSuccessful).length >
|
188
194
|
this.signableRetries) {
|
189
195
|
throw prevError;
|
190
196
|
}
|
191
|
-
|
197
|
+
attemptNum = Math.max(...itemSets.map((x) => this.getTrueAttemptNum(x?.name() ?? "")));
|
192
198
|
this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting(prevError, attemptNum);
|
193
|
-
if (
|
199
|
+
if (retryNum > 0) {
|
194
200
|
const refreshedSets = await this.refreshItemSets(itemSets, attemptNum, prevError);
|
195
201
|
if (!refreshedSets || !refreshedSets.length) {
|
196
202
|
return;
|
@@ -208,17 +214,27 @@ class TransactionsManager {
|
|
208
214
|
}
|
209
215
|
transactions = transactions.filter((x) => x.getInstructions().length > 0);
|
210
216
|
if (transactions.length === 0) {
|
211
|
-
this.updateStatusForSets(itemSets,
|
217
|
+
this.updateStatusForSets(itemSets, {
|
218
|
+
status: TransactionStatus.Skipped,
|
219
|
+
attemptNum,
|
220
|
+
});
|
212
221
|
return;
|
213
222
|
}
|
214
|
-
this.updateStatusForSets(itemSets,
|
223
|
+
this.updateStatusForSets(itemSets, {
|
224
|
+
status: TransactionStatus.Processing,
|
225
|
+
attemptNum,
|
226
|
+
});
|
215
227
|
for (const itemSet of itemSets) {
|
216
228
|
await this.debugAccounts(itemSet, await itemSet.getSingleTransaction());
|
217
229
|
}
|
218
230
|
let txSigs;
|
219
231
|
let error;
|
220
232
|
try {
|
221
|
-
txSigs = await (0, utils_1.sendJitoBundledTransactions)(this.txHandler.umi, this.txHandler.connection, this.txHandler.signer, this.txHandler.otherSigners, transactions, this.txRunType, this.priorityFeeSetting, () => this.updateStatusForSets(itemSets,
|
233
|
+
txSigs = await (0, utils_1.sendJitoBundledTransactions)(this.txHandler.umi, this.txHandler.connection, this.txHandler.signer, this.txHandler.otherSigners, transactions, this.txRunType, this.priorityFeeSetting, () => this.updateStatusForSets(itemSets, {
|
234
|
+
status: TransactionStatus.Processing,
|
235
|
+
attemptNum,
|
236
|
+
simulationSuccessful: true,
|
237
|
+
}), this.abortController);
|
222
238
|
}
|
223
239
|
catch (e) {
|
224
240
|
error = e;
|
@@ -227,20 +243,28 @@ class TransactionsManager {
|
|
227
243
|
(this.txRunType !== "only-simulate" &&
|
228
244
|
(!Boolean(txSigs) || txSigs?.length === 0) &&
|
229
245
|
!this.abortController?.signal.aborted)) {
|
230
|
-
this.updateStatusForSets(itemSets,
|
246
|
+
this.updateStatusForSets(itemSets, {
|
247
|
+
status: TransactionStatus.Failed,
|
248
|
+
attemptNum,
|
249
|
+
moreInfo: error?.message,
|
250
|
+
}, txSigs);
|
231
251
|
throw error ? error : new Error("Unknown error");
|
232
252
|
}
|
233
|
-
this.updateStatusForSets(itemSets, TransactionStatus.Successful, attemptNum, txSigs);
|
253
|
+
this.updateStatusForSets(itemSets, { status: TransactionStatus.Successful, attemptNum }, txSigs);
|
234
254
|
}, this.totalRetries, this.retryDelay, this.errorsToThrow).catch((e) => {
|
235
255
|
this.txHandler.log("Capturing error info...");
|
236
|
-
const errorDetails = (0, transactionUtils_1.getErrorInfo)(this.txHandler.umi, transactions, e, itemSets.filter((x) => this.statuses.find((y) => x.name() === y.name && y.attemptNum ===
|
256
|
+
const errorDetails = (0, transactionUtils_1.getErrorInfo)(this.txHandler.umi, transactions, e, itemSets.filter((x) => this.statuses.find((y) => x.name() === y.name && y.attemptNum === attemptNum)?.simulationSuccessful).length === itemSets.length, this.priorityFeeSetting);
|
237
257
|
const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`;
|
238
258
|
const errorInfo = errorDetails.errorName || errorDetails.errorInfo
|
239
259
|
? errorString
|
240
260
|
: e.message;
|
241
|
-
this.updateStatusForSets(itemSets,
|
242
|
-
|
243
|
-
|
261
|
+
this.updateStatusForSets(itemSets, {
|
262
|
+
status: errorDetails.canBeIgnored
|
263
|
+
? TransactionStatus.Skipped
|
264
|
+
: TransactionStatus.Failed,
|
265
|
+
attemptNum,
|
266
|
+
moreInfo: errorInfo,
|
267
|
+
});
|
244
268
|
(0, utils_1.consoleLog)(errorString);
|
245
269
|
if (!errorDetails.canBeIgnored) {
|
246
270
|
throw new Error(errorInfo);
|
@@ -249,13 +273,14 @@ class TransactionsManager {
|
|
249
273
|
}
|
250
274
|
async processTransactionSet(itemSets, currentIndex) {
|
251
275
|
let itemSet = itemSets[currentIndex];
|
252
|
-
await (0, utils_1.retryWithExponentialBackoff)(async (
|
276
|
+
await (0, utils_1.retryWithExponentialBackoff)(async (retryNum, prevError) => {
|
253
277
|
if (prevError &&
|
254
278
|
this.statuses.filter((x) => x.simulationSuccessful).length >
|
255
279
|
this.signableRetries) {
|
256
280
|
throw prevError;
|
257
281
|
}
|
258
|
-
|
282
|
+
const attemptNum = this.getTrueAttemptNum(itemSet?.name() ?? "");
|
283
|
+
if (currentIndex > 0 || retryNum > 0) {
|
259
284
|
const refreshedSets = await this.refreshItemSets(itemSets, attemptNum, prevError, currentIndex);
|
260
285
|
itemSet = refreshedSets ? refreshedSets[0] : undefined;
|
261
286
|
}
|
@@ -264,7 +289,11 @@ class TransactionsManager {
|
|
264
289
|
}
|
265
290
|
const tx = await itemSet.getSingleTransaction();
|
266
291
|
if (tx.getInstructions().length === 0) {
|
267
|
-
this.updateStatus(
|
292
|
+
this.updateStatus({
|
293
|
+
name: itemSet.name(),
|
294
|
+
status: TransactionStatus.Skipped,
|
295
|
+
attemptNum,
|
296
|
+
});
|
268
297
|
}
|
269
298
|
else {
|
270
299
|
await this.debugAccounts(itemSet, tx);
|
@@ -302,22 +331,41 @@ class TransactionsManager {
|
|
302
331
|
}
|
303
332
|
return newItemSets;
|
304
333
|
}
|
305
|
-
async sendTransaction(tx,
|
306
|
-
this.updateStatus(
|
334
|
+
async sendTransaction(tx, name, attemptNum, priorityFeeSetting, txRunType) {
|
335
|
+
this.updateStatus({
|
336
|
+
name,
|
337
|
+
status: TransactionStatus.Processing,
|
338
|
+
attemptNum,
|
339
|
+
});
|
307
340
|
try {
|
308
|
-
const txSig = await (0, utils_1.sendSingleOptimizedTransaction)(this.txHandler.umi, this.txHandler.connection, tx, txRunType ?? this.txRunType, priorityFeeSetting, () => this.updateStatus(
|
309
|
-
|
341
|
+
const txSig = await (0, utils_1.sendSingleOptimizedTransaction)(this.txHandler.umi, this.txHandler.connection, tx, txRunType ?? this.txRunType, priorityFeeSetting, () => this.updateStatus({
|
342
|
+
name,
|
343
|
+
status: TransactionStatus.Processing,
|
344
|
+
attemptNum,
|
345
|
+
simulationSuccessful: true,
|
346
|
+
}), this.abortController);
|
347
|
+
this.updateStatus({
|
348
|
+
name,
|
349
|
+
status: TransactionStatus.Successful,
|
350
|
+
attemptNum,
|
351
|
+
txSig: txSig ? bs58_1.default.encode(txSig) : undefined,
|
352
|
+
});
|
310
353
|
}
|
311
354
|
catch (e) {
|
312
355
|
this.txHandler.log("Capturing error info...");
|
313
|
-
const errorDetails = (0, transactionUtils_1.getErrorInfo)(this.txHandler.umi, [tx], e, this.statuses.find((x) => x.name ===
|
356
|
+
const errorDetails = (0, transactionUtils_1.getErrorInfo)(this.txHandler.umi, [tx], e, this.statuses.find((x) => x.name === name && x.attemptNum === attemptNum)?.simulationSuccessful, priorityFeeSetting);
|
314
357
|
const errorString = `${errorDetails.errorName ?? "Unknown error"}: ${errorDetails.errorInfo?.split("\n")[0] ?? "unknown"}`;
|
315
358
|
const errorInfo = errorDetails.errorName || errorDetails.errorInfo
|
316
359
|
? errorString
|
317
360
|
: e.message;
|
318
|
-
this.updateStatus(
|
319
|
-
|
320
|
-
:
|
361
|
+
this.updateStatus({
|
362
|
+
name,
|
363
|
+
status: errorDetails.canBeIgnored
|
364
|
+
? TransactionStatus.Skipped
|
365
|
+
: TransactionStatus.Failed,
|
366
|
+
attemptNum,
|
367
|
+
moreInfo: errorInfo,
|
368
|
+
});
|
321
369
|
(0, utils_1.consoleLog)(errorString);
|
322
370
|
if (!errorDetails.canBeIgnored) {
|
323
371
|
throw new Error(errorInfo);
|
package/local/txSandbox.ts
CHANGED
@@ -47,20 +47,20 @@ export async function main() {
|
|
47
47
|
});
|
48
48
|
|
49
49
|
await client.initializeExistingSolautoPosition({
|
50
|
-
positionId:
|
51
|
-
authority: new PublicKey("
|
50
|
+
positionId: 1,
|
51
|
+
authority: new PublicKey("Bk6mdg4mg9BD217vZwk8WDv7YJ66VyPPRhhQpaZsQPfL"),
|
52
52
|
// lpUserAccount: new PublicKey(
|
53
53
|
// "GEokw9jqbh6d1xUNA3qaeYFFetbSR5Y1nt7C3chwwgSz"
|
54
54
|
// ),
|
55
55
|
});
|
56
56
|
|
57
|
-
const transactionItems = [rebalance(client)];
|
57
|
+
const transactionItems = [rebalance(client, undefined, 350)];
|
58
58
|
|
59
59
|
const txManager = new ClientTransactionsManager({
|
60
60
|
txHandler: client,
|
61
61
|
txRunType: payForTransaction ? "normal" : "only-simulate",
|
62
62
|
priorityFeeSetting: PriorityFeeSetting.Default,
|
63
|
-
retryConfig: { totalRetries:
|
63
|
+
retryConfig: { totalRetries: 4 },
|
64
64
|
});
|
65
65
|
const statuses = await txManager.send(transactionItems);
|
66
66
|
consoleLog(statuses);
|
package/package.json
CHANGED
@@ -33,14 +33,16 @@ export enum TransactionStatus {
|
|
33
33
|
Failed = "Failed",
|
34
34
|
}
|
35
35
|
|
36
|
-
export
|
36
|
+
export interface TransactionManagerStatus {
|
37
37
|
name: string;
|
38
38
|
attemptNum: number;
|
39
39
|
status: TransactionStatus;
|
40
40
|
moreInfo?: string;
|
41
41
|
simulationSuccessful?: boolean;
|
42
42
|
txSig?: string;
|
43
|
-
}
|
43
|
+
}
|
44
|
+
|
45
|
+
export type TransactionManagerStatuses = TransactionManagerStatus[];
|
44
46
|
|
45
47
|
interface RetryConfig {
|
46
48
|
signableRetries?: number;
|
@@ -137,48 +139,32 @@ export class TransactionsManager<T extends TxHandler> {
|
|
137
139
|
return transactionSets;
|
138
140
|
}
|
139
141
|
|
140
|
-
private updateStatus(
|
141
|
-
name
|
142
|
-
|
143
|
-
attemptNum: number,
|
144
|
-
txSig?: string,
|
145
|
-
simulationSuccessful?: boolean,
|
146
|
-
moreInfo?: string
|
147
|
-
) {
|
148
|
-
if (!this.statuses.filter((x) => x.name === name)) {
|
149
|
-
this.statuses.push({
|
150
|
-
name,
|
151
|
-
status,
|
152
|
-
txSig,
|
153
|
-
attemptNum,
|
154
|
-
simulationSuccessful,
|
155
|
-
moreInfo,
|
156
|
-
});
|
142
|
+
private updateStatus(args: TransactionManagerStatus) {
|
143
|
+
if (!this.statuses.filter((x) => x.name === args.name)) {
|
144
|
+
this.statuses.push(args);
|
157
145
|
} else {
|
158
146
|
const idx = this.statuses.findIndex(
|
159
|
-
(x) => x.name === name && x.attemptNum === attemptNum
|
147
|
+
(x) => x.name === args.name && x.attemptNum === args.attemptNum
|
160
148
|
);
|
161
149
|
if (idx !== -1) {
|
162
|
-
this.statuses[idx].status = status;
|
163
|
-
this.statuses[idx].txSig = txSig;
|
164
|
-
if (simulationSuccessful) {
|
165
|
-
this.statuses[idx].simulationSuccessful = simulationSuccessful;
|
150
|
+
this.statuses[idx].status = args.status;
|
151
|
+
this.statuses[idx].txSig = args.txSig;
|
152
|
+
if (args.simulationSuccessful) {
|
153
|
+
this.statuses[idx].simulationSuccessful = args.simulationSuccessful;
|
166
154
|
}
|
167
|
-
if (
|
168
|
-
|
155
|
+
// else if (status === TransactionStatus.Queued || status === TransactionStatus.Processing) {
|
156
|
+
// this.statuses[idx].simulationSuccessful = undefined;
|
157
|
+
// }
|
158
|
+
if (args.moreInfo) {
|
159
|
+
this.statuses[idx].moreInfo = args.moreInfo;
|
169
160
|
}
|
170
161
|
} else {
|
171
|
-
this.statuses.push(
|
172
|
-
name,
|
173
|
-
status,
|
174
|
-
txSig,
|
175
|
-
attemptNum,
|
176
|
-
simulationSuccessful,
|
177
|
-
moreInfo,
|
178
|
-
});
|
162
|
+
this.statuses.push(args);
|
179
163
|
}
|
180
164
|
}
|
181
|
-
this.txHandler.log(
|
165
|
+
this.txHandler.log(
|
166
|
+
`${args.name} ${args.attemptNum} is ${args.status.toString().toLowerCase()}`
|
167
|
+
);
|
182
168
|
this.statusCallback?.([...this.statuses]);
|
183
169
|
}
|
184
170
|
|
@@ -220,21 +206,15 @@ export class TransactionsManager<T extends TxHandler> {
|
|
220
206
|
|
221
207
|
private updateStatusForSets(
|
222
208
|
itemSets: TransactionSet[],
|
223
|
-
|
224
|
-
|
225
|
-
txSigs?: string[],
|
226
|
-
simulationSuccessful?: boolean,
|
227
|
-
moreInfo?: string
|
209
|
+
args: Omit<TransactionManagerStatus, "name">,
|
210
|
+
txSigs?: string[]
|
228
211
|
) {
|
229
212
|
itemSets.forEach((itemSet, i) => {
|
230
|
-
this.updateStatus(
|
231
|
-
itemSet.name(),
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
simulationSuccessful,
|
236
|
-
moreInfo
|
237
|
-
);
|
213
|
+
this.updateStatus({
|
214
|
+
name: itemSet.name(),
|
215
|
+
txSig: txSigs && txSigs.length > i ? txSigs[i] : undefined,
|
216
|
+
...args,
|
217
|
+
});
|
238
218
|
});
|
239
219
|
}
|
240
220
|
|
@@ -254,7 +234,10 @@ export class TransactionsManager<T extends TxHandler> {
|
|
254
234
|
return await this.assembleTransactionSets(items);
|
255
235
|
}, this.totalRetries);
|
256
236
|
|
257
|
-
this.updateStatusForSets(itemSets,
|
237
|
+
this.updateStatusForSets(itemSets, {
|
238
|
+
status: TransactionStatus.Queued,
|
239
|
+
attemptNum: 0,
|
240
|
+
});
|
258
241
|
this.txHandler.log("Initial item sets:", itemSets.length);
|
259
242
|
|
260
243
|
if (this.atomically) {
|
@@ -283,19 +266,33 @@ export class TransactionsManager<T extends TxHandler> {
|
|
283
266
|
newItemSetNames[0] === this.updateOracleTxName
|
284
267
|
) {
|
285
268
|
consoleLog("Skipping unnecessary oracle update");
|
286
|
-
this.updateStatusForSets(itemSets,
|
269
|
+
this.updateStatusForSets(itemSets, {
|
270
|
+
status: TransactionStatus.Skipped,
|
271
|
+
attemptNum,
|
272
|
+
});
|
287
273
|
return false;
|
288
274
|
}
|
289
275
|
|
290
276
|
return true;
|
291
277
|
}
|
292
278
|
|
279
|
+
private getTrueAttemptNum(itemSetName: string) {
|
280
|
+
const prevAttempts = this.statuses.filter(
|
281
|
+
(x) => x.name === itemSetName && x.status !== TransactionStatus.Queued
|
282
|
+
);
|
283
|
+
const attemptNum =
|
284
|
+
prevAttempts.length -
|
285
|
+
prevAttempts.filter((x) => x.status === TransactionStatus.Skipped)
|
286
|
+
?.length;
|
287
|
+
return attemptNum;
|
288
|
+
}
|
289
|
+
|
293
290
|
private async processTransactionsAtomically(itemSets: TransactionSet[]) {
|
294
|
-
let
|
291
|
+
let attemptNum = 0;
|
295
292
|
let transactions: TransactionBuilder[] = [];
|
296
293
|
|
297
294
|
await retryWithExponentialBackoff(
|
298
|
-
async (
|
295
|
+
async (retryNum, prevError) => {
|
299
296
|
if (
|
300
297
|
prevError &&
|
301
298
|
this.statuses.filter((x) => x.simulationSuccessful).length >
|
@@ -304,13 +301,16 @@ export class TransactionsManager<T extends TxHandler> {
|
|
304
301
|
throw prevError;
|
305
302
|
}
|
306
303
|
|
307
|
-
|
304
|
+
attemptNum = Math.max(
|
305
|
+
...itemSets.map((x) => this.getTrueAttemptNum(x?.name() ?? ""))
|
306
|
+
);
|
307
|
+
|
308
308
|
this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting(
|
309
309
|
prevError,
|
310
310
|
attemptNum
|
311
311
|
);
|
312
312
|
|
313
|
-
if (
|
313
|
+
if (retryNum > 0) {
|
314
314
|
const refreshedSets = await this.refreshItemSets(
|
315
315
|
itemSets,
|
316
316
|
attemptNum,
|
@@ -335,19 +335,17 @@ export class TransactionsManager<T extends TxHandler> {
|
|
335
335
|
(x) => x.getInstructions().length > 0
|
336
336
|
);
|
337
337
|
if (transactions.length === 0) {
|
338
|
-
this.updateStatusForSets(
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
);
|
338
|
+
this.updateStatusForSets(itemSets, {
|
339
|
+
status: TransactionStatus.Skipped,
|
340
|
+
attemptNum,
|
341
|
+
});
|
343
342
|
return;
|
344
343
|
}
|
345
344
|
|
346
|
-
this.updateStatusForSets(
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
);
|
345
|
+
this.updateStatusForSets(itemSets, {
|
346
|
+
status: TransactionStatus.Processing,
|
347
|
+
attemptNum,
|
348
|
+
});
|
351
349
|
for (const itemSet of itemSets) {
|
352
350
|
await this.debugAccounts(
|
353
351
|
itemSet,
|
@@ -367,13 +365,11 @@ export class TransactionsManager<T extends TxHandler> {
|
|
367
365
|
this.txRunType,
|
368
366
|
this.priorityFeeSetting,
|
369
367
|
() =>
|
370
|
-
this.updateStatusForSets(
|
371
|
-
|
372
|
-
TransactionStatus.Processing,
|
368
|
+
this.updateStatusForSets(itemSets, {
|
369
|
+
status: TransactionStatus.Processing,
|
373
370
|
attemptNum,
|
374
|
-
|
375
|
-
|
376
|
-
),
|
371
|
+
simulationSuccessful: true,
|
372
|
+
}),
|
377
373
|
this.abortController
|
378
374
|
);
|
379
375
|
} catch (e: any) {
|
@@ -388,19 +384,19 @@ export class TransactionsManager<T extends TxHandler> {
|
|
388
384
|
) {
|
389
385
|
this.updateStatusForSets(
|
390
386
|
itemSets,
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
387
|
+
{
|
388
|
+
status: TransactionStatus.Failed,
|
389
|
+
attemptNum,
|
390
|
+
moreInfo: error?.message,
|
391
|
+
},
|
392
|
+
txSigs
|
396
393
|
);
|
397
394
|
throw error ? error : new Error("Unknown error");
|
398
395
|
}
|
399
396
|
|
400
397
|
this.updateStatusForSets(
|
401
398
|
itemSets,
|
402
|
-
TransactionStatus.Successful,
|
403
|
-
attemptNum,
|
399
|
+
{ status: TransactionStatus.Successful, attemptNum },
|
404
400
|
txSigs
|
405
401
|
);
|
406
402
|
},
|
@@ -416,7 +412,7 @@ export class TransactionsManager<T extends TxHandler> {
|
|
416
412
|
itemSets.filter(
|
417
413
|
(x) =>
|
418
414
|
this.statuses.find(
|
419
|
-
(y) => x.name() === y.name && y.attemptNum ===
|
415
|
+
(y) => x.name() === y.name && y.attemptNum === attemptNum
|
420
416
|
)?.simulationSuccessful
|
421
417
|
).length === itemSets.length,
|
422
418
|
this.priorityFeeSetting
|
@@ -427,16 +423,13 @@ export class TransactionsManager<T extends TxHandler> {
|
|
427
423
|
errorDetails.errorName || errorDetails.errorInfo
|
428
424
|
? errorString
|
429
425
|
: e.message;
|
430
|
-
this.updateStatusForSets(
|
431
|
-
|
432
|
-
errorDetails.canBeIgnored
|
426
|
+
this.updateStatusForSets(itemSets, {
|
427
|
+
status: errorDetails.canBeIgnored
|
433
428
|
? TransactionStatus.Skipped
|
434
429
|
: TransactionStatus.Failed,
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
errorInfo
|
439
|
-
);
|
430
|
+
attemptNum,
|
431
|
+
moreInfo: errorInfo,
|
432
|
+
});
|
440
433
|
consoleLog(errorString);
|
441
434
|
|
442
435
|
if (!errorDetails.canBeIgnored) {
|
@@ -451,7 +444,7 @@ export class TransactionsManager<T extends TxHandler> {
|
|
451
444
|
) {
|
452
445
|
let itemSet: TransactionSet | undefined = itemSets[currentIndex];
|
453
446
|
await retryWithExponentialBackoff(
|
454
|
-
async (
|
447
|
+
async (retryNum, prevError) => {
|
455
448
|
if (
|
456
449
|
prevError &&
|
457
450
|
this.statuses.filter((x) => x.simulationSuccessful).length >
|
@@ -460,7 +453,8 @@ export class TransactionsManager<T extends TxHandler> {
|
|
460
453
|
throw prevError;
|
461
454
|
}
|
462
455
|
|
463
|
-
|
456
|
+
const attemptNum = this.getTrueAttemptNum(itemSet?.name() ?? "");
|
457
|
+
if (currentIndex > 0 || retryNum > 0) {
|
464
458
|
const refreshedSets = await this.refreshItemSets(
|
465
459
|
itemSets,
|
466
460
|
attemptNum,
|
@@ -475,11 +469,11 @@ export class TransactionsManager<T extends TxHandler> {
|
|
475
469
|
|
476
470
|
const tx = await itemSet.getSingleTransaction();
|
477
471
|
if (tx.getInstructions().length === 0) {
|
478
|
-
this.updateStatus(
|
479
|
-
itemSet.name(),
|
480
|
-
TransactionStatus.Skipped,
|
481
|
-
attemptNum
|
482
|
-
);
|
472
|
+
this.updateStatus({
|
473
|
+
name: itemSet.name(),
|
474
|
+
status: TransactionStatus.Skipped,
|
475
|
+
attemptNum,
|
476
|
+
});
|
483
477
|
} else {
|
484
478
|
await this.debugAccounts(itemSet, tx);
|
485
479
|
this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting(
|
@@ -552,12 +546,16 @@ export class TransactionsManager<T extends TxHandler> {
|
|
552
546
|
|
553
547
|
protected async sendTransaction(
|
554
548
|
tx: TransactionBuilder,
|
555
|
-
|
549
|
+
name: string,
|
556
550
|
attemptNum: number,
|
557
551
|
priorityFeeSetting?: PriorityFeeSetting,
|
558
552
|
txRunType?: TransactionRunType
|
559
553
|
) {
|
560
|
-
this.updateStatus(
|
554
|
+
this.updateStatus({
|
555
|
+
name,
|
556
|
+
status: TransactionStatus.Processing,
|
557
|
+
attemptNum,
|
558
|
+
});
|
561
559
|
try {
|
562
560
|
const txSig = await sendSingleOptimizedTransaction(
|
563
561
|
this.txHandler.umi,
|
@@ -566,21 +564,20 @@ export class TransactionsManager<T extends TxHandler> {
|
|
566
564
|
txRunType ?? this.txRunType,
|
567
565
|
priorityFeeSetting,
|
568
566
|
() =>
|
569
|
-
this.updateStatus(
|
570
|
-
|
571
|
-
TransactionStatus.Processing,
|
567
|
+
this.updateStatus({
|
568
|
+
name,
|
569
|
+
status: TransactionStatus.Processing,
|
572
570
|
attemptNum,
|
573
|
-
|
574
|
-
|
575
|
-
),
|
571
|
+
simulationSuccessful: true,
|
572
|
+
}),
|
576
573
|
this.abortController
|
577
574
|
);
|
578
|
-
this.updateStatus(
|
579
|
-
|
580
|
-
TransactionStatus.Successful,
|
575
|
+
this.updateStatus({
|
576
|
+
name,
|
577
|
+
status: TransactionStatus.Successful,
|
581
578
|
attemptNum,
|
582
|
-
txSig ? bs58.encode(txSig) : undefined
|
583
|
-
);
|
579
|
+
txSig: txSig ? bs58.encode(txSig) : undefined,
|
580
|
+
});
|
584
581
|
} catch (e: any) {
|
585
582
|
this.txHandler.log("Capturing error info...");
|
586
583
|
const errorDetails = getErrorInfo(
|
@@ -588,7 +585,7 @@ export class TransactionsManager<T extends TxHandler> {
|
|
588
585
|
[tx],
|
589
586
|
e,
|
590
587
|
this.statuses.find(
|
591
|
-
(x) => x.name ===
|
588
|
+
(x) => x.name === name && x.attemptNum === attemptNum
|
592
589
|
)?.simulationSuccessful,
|
593
590
|
priorityFeeSetting
|
594
591
|
);
|
@@ -598,16 +595,14 @@ export class TransactionsManager<T extends TxHandler> {
|
|
598
595
|
errorDetails.errorName || errorDetails.errorInfo
|
599
596
|
? errorString
|
600
597
|
: e.message;
|
601
|
-
this.updateStatus(
|
602
|
-
|
603
|
-
errorDetails.canBeIgnored
|
598
|
+
this.updateStatus({
|
599
|
+
name,
|
600
|
+
status: errorDetails.canBeIgnored
|
604
601
|
? TransactionStatus.Skipped
|
605
602
|
: TransactionStatus.Failed,
|
606
603
|
attemptNum,
|
607
|
-
|
608
|
-
|
609
|
-
errorInfo
|
610
|
-
);
|
604
|
+
moreInfo: errorInfo,
|
605
|
+
});
|
611
606
|
consoleLog(errorString);
|
612
607
|
|
613
608
|
if (!errorDetails.canBeIgnored) {
|