@developeruche/tx-spammer-sdk 1.0.1 → 1.0.3
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/SpamOrchestrator.d.ts +2 -6
- package/dist/SpamOrchestrator.js +34 -6
- package/dist/types.d.ts +18 -0
- package/dist/types.js +1 -1
- package/package.json +2 -2
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { SpamSequenceConfig } from './types';
|
|
1
|
+
import { SpamSequenceConfig, SpamResult } from './types';
|
|
3
2
|
/**
|
|
4
3
|
* The central coordinator for the spam sequence.
|
|
5
4
|
*
|
|
@@ -38,8 +37,5 @@ export declare class SpamOrchestrator {
|
|
|
38
37
|
*
|
|
39
38
|
* Stops when the duration expires or gas limits are reached.
|
|
40
39
|
*/
|
|
41
|
-
start(): Promise<
|
|
42
|
-
blockNumber: bigint;
|
|
43
|
-
txHash: Hash | null;
|
|
44
|
-
}>;
|
|
40
|
+
start(): Promise<SpamResult>;
|
|
45
41
|
}
|
package/dist/SpamOrchestrator.js
CHANGED
|
@@ -104,8 +104,9 @@ class SpamOrchestrator {
|
|
|
104
104
|
: Infinity;
|
|
105
105
|
const startTime = Date.now();
|
|
106
106
|
let lastTxHash = null;
|
|
107
|
+
const activeGuardians = [this.gasGuardian];
|
|
107
108
|
// Helper to run a strategy loop for a subset of workers
|
|
108
|
-
const runLoop = async (workers, stratConfig, guardian) => {
|
|
109
|
+
const runLoop = async (workers, stratConfig, guardian, onSuccess) => {
|
|
109
110
|
const loopTasks = workers.map(async (worker, index) => {
|
|
110
111
|
while (true) {
|
|
111
112
|
if (guardian.isLimitReached)
|
|
@@ -114,17 +115,25 @@ class SpamOrchestrator {
|
|
|
114
115
|
break;
|
|
115
116
|
try {
|
|
116
117
|
let txHash;
|
|
118
|
+
let executed = false;
|
|
117
119
|
if (stratConfig.mode === 'transfer') {
|
|
118
120
|
txHash = await (0, strategies_1.executeEthTransfer)(worker, stratConfig, guardian, this.publicClient);
|
|
121
|
+
executed = true;
|
|
119
122
|
}
|
|
120
123
|
else if (stratConfig.mode === 'deploy') {
|
|
121
124
|
txHash = await (0, strategies_1.executeContractDeploy)(worker, stratConfig, guardian, this.publicClient);
|
|
125
|
+
executed = true;
|
|
122
126
|
}
|
|
123
127
|
else if (stratConfig.mode === 'read') {
|
|
124
128
|
await (0, strategies_1.executeContractRead)(worker, stratConfig, guardian, this.publicClient);
|
|
129
|
+
executed = true;
|
|
125
130
|
}
|
|
126
131
|
else if (stratConfig.mode === 'write') {
|
|
127
132
|
txHash = await (0, strategies_1.executeContractWrite)(worker, stratConfig, guardian, this.publicClient);
|
|
133
|
+
executed = true;
|
|
134
|
+
}
|
|
135
|
+
if (executed) {
|
|
136
|
+
onSuccess();
|
|
128
137
|
}
|
|
129
138
|
if (txHash) {
|
|
130
139
|
lastTxHash = txHash;
|
|
@@ -142,6 +151,7 @@ class SpamOrchestrator {
|
|
|
142
151
|
});
|
|
143
152
|
await Promise.all(loopTasks);
|
|
144
153
|
};
|
|
154
|
+
const stats = {};
|
|
145
155
|
if (strategy.mode === 'mixed') {
|
|
146
156
|
console.log('Executing Mixed Strategy...');
|
|
147
157
|
let workerOffset = 0;
|
|
@@ -167,25 +177,43 @@ class SpamOrchestrator {
|
|
|
167
177
|
// but we can assign a portion of the max limit to its guardian just in case.
|
|
168
178
|
const gasLimitShare = BigInt(Math.floor(Number(this.config.maxGasLimit) * sharePercent));
|
|
169
179
|
const subGuardian = new GasGuardian_1.GasGuardian(gasLimitShare);
|
|
180
|
+
activeGuardians.push(subGuardian);
|
|
170
181
|
console.log(`- Sub-strategy '${subStrat.config.mode}': ${count} workers, ~${gasLimitShare} gas limit`);
|
|
171
|
-
|
|
182
|
+
const label = `Strategy ${i} (${subStrat.config.mode})`;
|
|
183
|
+
stats[label] = 0;
|
|
184
|
+
tasks.push(runLoop(assignedWorkers, subStrat.config, subGuardian, () => {
|
|
185
|
+
stats[label]++;
|
|
186
|
+
}));
|
|
172
187
|
}
|
|
173
188
|
await Promise.all(tasks);
|
|
174
189
|
}
|
|
175
190
|
else {
|
|
176
191
|
// Single Mode
|
|
177
|
-
|
|
192
|
+
const label = `Strategy (${strategy.mode})`;
|
|
193
|
+
stats[label] = 0;
|
|
194
|
+
await runLoop(this.workers, strategy, this.gasGuardian, () => {
|
|
195
|
+
stats[label]++;
|
|
196
|
+
});
|
|
178
197
|
}
|
|
179
198
|
console.log('Spam sequence finished.');
|
|
199
|
+
let blockNumber;
|
|
180
200
|
if (lastTxHash) {
|
|
181
201
|
console.log(`Waiting for last transaction ${lastTxHash} to be mined...`);
|
|
182
202
|
const receipt = await this.publicClient.waitForTransactionReceipt({ hash: lastTxHash });
|
|
183
|
-
|
|
203
|
+
blockNumber = receipt.blockNumber;
|
|
184
204
|
}
|
|
185
205
|
else {
|
|
186
|
-
|
|
187
|
-
return { blockNumber, txHash: null };
|
|
206
|
+
blockNumber = await this.publicClient.getBlockNumber();
|
|
188
207
|
}
|
|
208
|
+
const statsBlock = await this.publicClient.getBlock({ blockNumber });
|
|
209
|
+
const totalGasUsed = activeGuardians.reduce((acc, g) => acc + g.gasUsed, 0n);
|
|
210
|
+
return {
|
|
211
|
+
blockNumber,
|
|
212
|
+
txHash: lastTxHash,
|
|
213
|
+
totalGasUsed,
|
|
214
|
+
finalBlockGasUsed: statsBlock.gasUsed,
|
|
215
|
+
stats,
|
|
216
|
+
};
|
|
189
217
|
}
|
|
190
218
|
}
|
|
191
219
|
exports.SpamOrchestrator = SpamOrchestrator;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { Hex } from 'viem';
|
|
2
3
|
/**
|
|
3
4
|
* Configuration for ETH transfer spam strategy.
|
|
4
5
|
* Includes depth for recursive transfers (if implemented) and recipient handling.
|
|
@@ -204,3 +205,20 @@ export type MixedStrategyConfig = z.infer<typeof MixedStrategyConfigSchema>;
|
|
|
204
205
|
export type SpamStrategyConfig = z.infer<typeof SpamStrategySchema>;
|
|
205
206
|
/** TypeScript type alias for the full Spam Sequence config. */
|
|
206
207
|
export type SpamSequenceConfig = z.infer<typeof SpamSequenceConfigSchema>;
|
|
208
|
+
/**
|
|
209
|
+
* Result returned after the spam sequence completes.
|
|
210
|
+
*/
|
|
211
|
+
export interface SpamResult {
|
|
212
|
+
/** The block number of the last transaction mined (or current block if no txs). */
|
|
213
|
+
blockNumber: bigint;
|
|
214
|
+
/** The hash of the last transaction sent, if any. */
|
|
215
|
+
txHash: Hex | null;
|
|
216
|
+
/** Total cumulative gas used by all transactions in this sequence (local estimate). */
|
|
217
|
+
totalGasUsed: bigint;
|
|
218
|
+
/** The total gas used in the block corresponding to blockNumber. */
|
|
219
|
+
finalBlockGasUsed: bigint;
|
|
220
|
+
/** Breakdown of operations performed by each strategy. Key is strategy label, value is count. */
|
|
221
|
+
stats: {
|
|
222
|
+
[key: string]: number;
|
|
223
|
+
};
|
|
224
|
+
}
|
package/dist/types.js
CHANGED
|
@@ -111,7 +111,7 @@ exports.SpamSequenceConfigSchema = zod_1.z.object({
|
|
|
111
111
|
/** The selected spam strategy configuration. */
|
|
112
112
|
strategy: exports.SpamStrategySchema,
|
|
113
113
|
/** Optional duration in seconds to run the spam sequence. */
|
|
114
|
-
durationSeconds: zod_1.z.number().int().
|
|
114
|
+
durationSeconds: zod_1.z.number().int().nonnegative().optional(),
|
|
115
115
|
/** Optional maximum total transactions to attempts (if implemented). */
|
|
116
116
|
totalTxs: zod_1.z.number().int().positive().optional(),
|
|
117
117
|
});
|
package/package.json
CHANGED