@haven-fi/solauto-sdk 1.0.739 → 1.0.740
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 +101 -53
- package/local/txSandbox.ts +3 -3
- package/package.json +1 -1
- package/src/services/transactions/manager/transactionsManager.ts +104 -113
@@ -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,38 +76,27 @@ 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
102
|
this.txHandler.log(`${name} is ${status.toString().toLowerCase()}`);
|
@@ -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);
|
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,14 +47,14 @@ 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, 25)];
|
58
58
|
|
59
59
|
const txManager = new ClientTransactionsManager({
|
60
60
|
txHandler: client,
|
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,45 +139,27 @@ 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
165
|
this.txHandler.log(`${name} is ${status.toString().toLowerCase()}`);
|
@@ -220,21 +204,15 @@ export class TransactionsManager<T extends TxHandler> {
|
|
220
204
|
|
221
205
|
private updateStatusForSets(
|
222
206
|
itemSets: TransactionSet[],
|
223
|
-
|
224
|
-
|
225
|
-
txSigs?: string[],
|
226
|
-
simulationSuccessful?: boolean,
|
227
|
-
moreInfo?: string
|
207
|
+
args: Omit<TransactionManagerStatus, "name">,
|
208
|
+
txSigs?: string[]
|
228
209
|
) {
|
229
210
|
itemSets.forEach((itemSet, i) => {
|
230
|
-
this.updateStatus(
|
231
|
-
itemSet.name(),
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
simulationSuccessful,
|
236
|
-
moreInfo
|
237
|
-
);
|
211
|
+
this.updateStatus({
|
212
|
+
name: itemSet.name(),
|
213
|
+
txSig: txSigs && txSigs.length > i ? txSigs[i] : undefined,
|
214
|
+
...args,
|
215
|
+
});
|
238
216
|
});
|
239
217
|
}
|
240
218
|
|
@@ -254,7 +232,10 @@ export class TransactionsManager<T extends TxHandler> {
|
|
254
232
|
return await this.assembleTransactionSets(items);
|
255
233
|
}, this.totalRetries);
|
256
234
|
|
257
|
-
this.updateStatusForSets(itemSets,
|
235
|
+
this.updateStatusForSets(itemSets, {
|
236
|
+
status: TransactionStatus.Queued,
|
237
|
+
attemptNum: 0,
|
238
|
+
});
|
258
239
|
this.txHandler.log("Initial item sets:", itemSets.length);
|
259
240
|
|
260
241
|
if (this.atomically) {
|
@@ -283,19 +264,31 @@ export class TransactionsManager<T extends TxHandler> {
|
|
283
264
|
newItemSetNames[0] === this.updateOracleTxName
|
284
265
|
) {
|
285
266
|
consoleLog("Skipping unnecessary oracle update");
|
286
|
-
this.updateStatusForSets(itemSets,
|
267
|
+
this.updateStatusForSets(itemSets, {
|
268
|
+
status: TransactionStatus.Skipped,
|
269
|
+
attemptNum,
|
270
|
+
});
|
287
271
|
return false;
|
288
272
|
}
|
289
273
|
|
290
274
|
return true;
|
291
275
|
}
|
292
276
|
|
277
|
+
private getTrueAttemptNum(itemSetName: string) {
|
278
|
+
const prevAttempts = this.statuses.filter((x) => x.name === itemSetName);
|
279
|
+
const attemptNum =
|
280
|
+
prevAttempts.length -
|
281
|
+
prevAttempts.filter((x) => x.status === TransactionStatus.Skipped)
|
282
|
+
?.length;
|
283
|
+
return attemptNum;
|
284
|
+
}
|
285
|
+
|
293
286
|
private async processTransactionsAtomically(itemSets: TransactionSet[]) {
|
294
|
-
let
|
287
|
+
let attemptNum = 0;
|
295
288
|
let transactions: TransactionBuilder[] = [];
|
296
289
|
|
297
290
|
await retryWithExponentialBackoff(
|
298
|
-
async (
|
291
|
+
async (retryNum, prevError) => {
|
299
292
|
if (
|
300
293
|
prevError &&
|
301
294
|
this.statuses.filter((x) => x.simulationSuccessful).length >
|
@@ -304,13 +297,16 @@ export class TransactionsManager<T extends TxHandler> {
|
|
304
297
|
throw prevError;
|
305
298
|
}
|
306
299
|
|
307
|
-
|
300
|
+
attemptNum = Math.max(
|
301
|
+
...itemSets.map((x) => this.getTrueAttemptNum(x?.name() ?? ""))
|
302
|
+
);
|
303
|
+
|
308
304
|
this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting(
|
309
305
|
prevError,
|
310
306
|
attemptNum
|
311
307
|
);
|
312
308
|
|
313
|
-
if (
|
309
|
+
if (retryNum > 0) {
|
314
310
|
const refreshedSets = await this.refreshItemSets(
|
315
311
|
itemSets,
|
316
312
|
attemptNum,
|
@@ -335,19 +331,17 @@ export class TransactionsManager<T extends TxHandler> {
|
|
335
331
|
(x) => x.getInstructions().length > 0
|
336
332
|
);
|
337
333
|
if (transactions.length === 0) {
|
338
|
-
this.updateStatusForSets(
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
);
|
334
|
+
this.updateStatusForSets(itemSets, {
|
335
|
+
status: TransactionStatus.Skipped,
|
336
|
+
attemptNum,
|
337
|
+
});
|
343
338
|
return;
|
344
339
|
}
|
345
340
|
|
346
|
-
this.updateStatusForSets(
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
);
|
341
|
+
this.updateStatusForSets(itemSets, {
|
342
|
+
status: TransactionStatus.Processing,
|
343
|
+
attemptNum,
|
344
|
+
});
|
351
345
|
for (const itemSet of itemSets) {
|
352
346
|
await this.debugAccounts(
|
353
347
|
itemSet,
|
@@ -367,13 +361,11 @@ export class TransactionsManager<T extends TxHandler> {
|
|
367
361
|
this.txRunType,
|
368
362
|
this.priorityFeeSetting,
|
369
363
|
() =>
|
370
|
-
this.updateStatusForSets(
|
371
|
-
|
372
|
-
TransactionStatus.Processing,
|
364
|
+
this.updateStatusForSets(itemSets, {
|
365
|
+
status: TransactionStatus.Processing,
|
373
366
|
attemptNum,
|
374
|
-
|
375
|
-
|
376
|
-
),
|
367
|
+
simulationSuccessful: true,
|
368
|
+
}),
|
377
369
|
this.abortController
|
378
370
|
);
|
379
371
|
} catch (e: any) {
|
@@ -388,19 +380,19 @@ export class TransactionsManager<T extends TxHandler> {
|
|
388
380
|
) {
|
389
381
|
this.updateStatusForSets(
|
390
382
|
itemSets,
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
383
|
+
{
|
384
|
+
status: TransactionStatus.Failed,
|
385
|
+
attemptNum,
|
386
|
+
moreInfo: error?.message,
|
387
|
+
},
|
388
|
+
txSigs
|
396
389
|
);
|
397
390
|
throw error ? error : new Error("Unknown error");
|
398
391
|
}
|
399
392
|
|
400
393
|
this.updateStatusForSets(
|
401
394
|
itemSets,
|
402
|
-
TransactionStatus.Successful,
|
403
|
-
attemptNum,
|
395
|
+
{ status: TransactionStatus.Successful, attemptNum },
|
404
396
|
txSigs
|
405
397
|
);
|
406
398
|
},
|
@@ -416,7 +408,7 @@ export class TransactionsManager<T extends TxHandler> {
|
|
416
408
|
itemSets.filter(
|
417
409
|
(x) =>
|
418
410
|
this.statuses.find(
|
419
|
-
(y) => x.name() === y.name && y.attemptNum ===
|
411
|
+
(y) => x.name() === y.name && y.attemptNum === attemptNum
|
420
412
|
)?.simulationSuccessful
|
421
413
|
).length === itemSets.length,
|
422
414
|
this.priorityFeeSetting
|
@@ -427,16 +419,13 @@ export class TransactionsManager<T extends TxHandler> {
|
|
427
419
|
errorDetails.errorName || errorDetails.errorInfo
|
428
420
|
? errorString
|
429
421
|
: e.message;
|
430
|
-
this.updateStatusForSets(
|
431
|
-
|
432
|
-
errorDetails.canBeIgnored
|
422
|
+
this.updateStatusForSets(itemSets, {
|
423
|
+
status: errorDetails.canBeIgnored
|
433
424
|
? TransactionStatus.Skipped
|
434
425
|
: TransactionStatus.Failed,
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
errorInfo
|
439
|
-
);
|
426
|
+
attemptNum,
|
427
|
+
moreInfo: errorInfo,
|
428
|
+
});
|
440
429
|
consoleLog(errorString);
|
441
430
|
|
442
431
|
if (!errorDetails.canBeIgnored) {
|
@@ -451,7 +440,7 @@ export class TransactionsManager<T extends TxHandler> {
|
|
451
440
|
) {
|
452
441
|
let itemSet: TransactionSet | undefined = itemSets[currentIndex];
|
453
442
|
await retryWithExponentialBackoff(
|
454
|
-
async (
|
443
|
+
async (retryNum, prevError) => {
|
455
444
|
if (
|
456
445
|
prevError &&
|
457
446
|
this.statuses.filter((x) => x.simulationSuccessful).length >
|
@@ -460,7 +449,8 @@ export class TransactionsManager<T extends TxHandler> {
|
|
460
449
|
throw prevError;
|
461
450
|
}
|
462
451
|
|
463
|
-
|
452
|
+
const attemptNum = this.getTrueAttemptNum(itemSet?.name() ?? "");
|
453
|
+
if (currentIndex > 0 || retryNum > 0) {
|
464
454
|
const refreshedSets = await this.refreshItemSets(
|
465
455
|
itemSets,
|
466
456
|
attemptNum,
|
@@ -475,11 +465,11 @@ export class TransactionsManager<T extends TxHandler> {
|
|
475
465
|
|
476
466
|
const tx = await itemSet.getSingleTransaction();
|
477
467
|
if (tx.getInstructions().length === 0) {
|
478
|
-
this.updateStatus(
|
479
|
-
itemSet.name(),
|
480
|
-
TransactionStatus.Skipped,
|
481
|
-
attemptNum
|
482
|
-
);
|
468
|
+
this.updateStatus({
|
469
|
+
name: itemSet.name(),
|
470
|
+
status: TransactionStatus.Skipped,
|
471
|
+
attemptNum,
|
472
|
+
});
|
483
473
|
} else {
|
484
474
|
await this.debugAccounts(itemSet, tx);
|
485
475
|
this.priorityFeeSetting = this.getUpdatedPriorityFeeSetting(
|
@@ -552,12 +542,16 @@ export class TransactionsManager<T extends TxHandler> {
|
|
552
542
|
|
553
543
|
protected async sendTransaction(
|
554
544
|
tx: TransactionBuilder,
|
555
|
-
|
545
|
+
name: string,
|
556
546
|
attemptNum: number,
|
557
547
|
priorityFeeSetting?: PriorityFeeSetting,
|
558
548
|
txRunType?: TransactionRunType
|
559
549
|
) {
|
560
|
-
this.updateStatus(
|
550
|
+
this.updateStatus({
|
551
|
+
name,
|
552
|
+
status: TransactionStatus.Processing,
|
553
|
+
attemptNum,
|
554
|
+
});
|
561
555
|
try {
|
562
556
|
const txSig = await sendSingleOptimizedTransaction(
|
563
557
|
this.txHandler.umi,
|
@@ -566,21 +560,20 @@ export class TransactionsManager<T extends TxHandler> {
|
|
566
560
|
txRunType ?? this.txRunType,
|
567
561
|
priorityFeeSetting,
|
568
562
|
() =>
|
569
|
-
this.updateStatus(
|
570
|
-
|
571
|
-
TransactionStatus.Processing,
|
563
|
+
this.updateStatus({
|
564
|
+
name,
|
565
|
+
status: TransactionStatus.Processing,
|
572
566
|
attemptNum,
|
573
|
-
|
574
|
-
|
575
|
-
),
|
567
|
+
simulationSuccessful: true,
|
568
|
+
}),
|
576
569
|
this.abortController
|
577
570
|
);
|
578
|
-
this.updateStatus(
|
579
|
-
|
580
|
-
TransactionStatus.Successful,
|
571
|
+
this.updateStatus({
|
572
|
+
name,
|
573
|
+
status: TransactionStatus.Successful,
|
581
574
|
attemptNum,
|
582
|
-
txSig ? bs58.encode(txSig) : undefined
|
583
|
-
);
|
575
|
+
txSig: txSig ? bs58.encode(txSig) : undefined,
|
576
|
+
});
|
584
577
|
} catch (e: any) {
|
585
578
|
this.txHandler.log("Capturing error info...");
|
586
579
|
const errorDetails = getErrorInfo(
|
@@ -588,7 +581,7 @@ export class TransactionsManager<T extends TxHandler> {
|
|
588
581
|
[tx],
|
589
582
|
e,
|
590
583
|
this.statuses.find(
|
591
|
-
(x) => x.name ===
|
584
|
+
(x) => x.name === name && x.attemptNum === attemptNum
|
592
585
|
)?.simulationSuccessful,
|
593
586
|
priorityFeeSetting
|
594
587
|
);
|
@@ -598,16 +591,14 @@ export class TransactionsManager<T extends TxHandler> {
|
|
598
591
|
errorDetails.errorName || errorDetails.errorInfo
|
599
592
|
? errorString
|
600
593
|
: e.message;
|
601
|
-
this.updateStatus(
|
602
|
-
|
603
|
-
errorDetails.canBeIgnored
|
594
|
+
this.updateStatus({
|
595
|
+
name,
|
596
|
+
status: errorDetails.canBeIgnored
|
604
597
|
? TransactionStatus.Skipped
|
605
598
|
: TransactionStatus.Failed,
|
606
599
|
attemptNum,
|
607
|
-
|
608
|
-
|
609
|
-
errorInfo
|
610
|
-
);
|
600
|
+
moreInfo: errorInfo,
|
601
|
+
});
|
611
602
|
consoleLog(errorString);
|
612
603
|
|
613
604
|
if (!errorDetails.canBeIgnored) {
|