You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor: restructure loadtest into library with mode packages (#828)
* refactor: restructure loadtest into library with mode packages
- Move loadtest logic from cmd/loadtest/ to loadtest/ library
- Create loadtest/mode/ for shared infrastructure (interface, registry, dependencies, util)
- Create loadtest/modes/ for mode implementations
- Create loadtest/config/ for configuration types
- Refactor UniswapV3Mode to use dependencies directly instead of callback
- Fix strings.HasPrefix() argument order in recall.go for ERC20/ERC721 detection
- Fix index mismatch in rpc.go using wrong array length after deduplication
- Replace println() with fmt.Println() in util.go for proper stdout output
- Simplify deduplicate() using maps.Keys and slices.Collect
- Rename Initialize to Init in mode interface
- Move AccountPoolConfig to loadtest/account.go
* fix: resolve variable shadowing errors in loadtest/runner.go
* fix: lint
* fix: remove ineffectual assignment to gasPrice in account.go
* fix: initialize RandSource in mode dependencies
* fix: regressions
* fix: more regressions
* fix: more regressions
* fix: even more regressions
* fix: regressions
* fix: regressions
* fix: improve shutdown handling and initialization order
* fix: lint
* fix: more regressions
* fix: lint
* fix: uniswapv3 subcommand
* fix: regression
* fix: rename var
This is pure redundancy - if the value can't be MaxUint64 (validated at line 211), checking again at line 231 adds zero value.
167
183
168
184
### 1. Security
185
+
169
186
-**HTML/Template Injection**: Always use `html.EscapeString()` for any data interpolated into HTML, even if currently from trusted sources
170
187
-**Input Validation**: Validate all user inputs at boundaries (flags, API inputs)
171
188
-**SQL Injection**: Use parameterized queries, never string concatenation
172
189
-**Command Injection**: Never pass user input directly to shell commands
173
190
-**Question to ask**: "What data is untrusted? Where does it flow? Is it escaped/validated at every output point?"
174
191
175
192
### 2. Resource Management & Performance
193
+
176
194
-**Goroutine Lifecycle**: Every goroutine must have a clear termination condition via context cancellation
177
195
-**Timer Cleanup**: Use `time.NewTimer()` + `defer timer.Stop()`, never `time.After()` in select statements (causes goroutine leaks)
178
196
-**Channel Buffers**: Use small fixed buffers (e.g., `concurrency*2`), never proportional to total dataset size
179
197
-**Memory Allocation**: Consider behavior with 10x, 100x, 1000x expected input
180
198
-**Question to ask**: "How does every goroutine, timer, and channel clean up on cancellation? What's the memory footprint at scale?"
181
199
182
200
### 3. Context Propagation
201
+
183
202
-**Never create root contexts**: Always thread `context.Context` through call chains; never use `context.Background()` in the middle of operations
184
203
-**Cancellation Flow**: Context should flow through every I/O operation, long-running task, and goroutine
185
204
-**Timeout Management**: Create child contexts with `context.WithTimeout(parentCtx, duration)`, not `context.WithTimeout(context.Background(), duration)`
186
205
-**Question to ask**: "Does context flow through all long-running operations? Will Ctrl+C immediately stop everything?"
187
206
188
207
### 4. Data Integrity & Determinism
208
+
189
209
-**Completeness**: Data collection operations must fetch ALL requested data or fail entirely - never produce partial results
190
210
-**Retry Logic**: Failed operations should retry (with backoff) before failing
191
211
-**Idempotency**: Same input parameters should produce identical output every time
@@ -194,6 +214,7 @@ This is pure redundancy - if the value can't be MaxUint64 (validated at line 211
194
214
-**Question to ask**: "If I run this twice with the same parameters, will I get identical results? What makes this non-deterministic? Am I reading from the authoritative data source?"
195
215
196
216
### 5. Error Handling & Logging
217
+
197
218
-**Error Wrapping**: Use `fmt.Errorf("context: %w", err)` to wrap errors with context
198
219
-**Single-line Messages**: Put context before `%w` in single line: `fmt.Errorf("failed after %d attempts: %w", n, err)`
199
220
-**Failure Modes**: Consider and handle all failure paths explicitly
@@ -202,6 +223,7 @@ This is pure redundancy - if the value can't be MaxUint64 (validated at line 211
202
223
-**Question to ask**: "What can fail? How is each failure mode handled? Are errors properly wrapped? Is progress logging accurate during retries/failures?"
203
224
204
225
### 6. Concurrency Patterns
226
+
205
227
-**Channel Closing**: Close channels in the correct goroutine (usually the sender); use atomic counters to coordinate
206
228
-**Channel Draining**: When using select with multiple channels and one closes, drain remaining channels to avoid missing messages
207
229
-**Worker Pools**: Use `sync.WaitGroup` to wait for workers; protect shared state with mutexes or channels
@@ -210,6 +232,7 @@ This is pure redundancy - if the value can't be MaxUint64 (validated at line 211
210
232
-**Question to ask**: "Who closes each channel? Can any goroutine block forever? Does this have race conditions? Are all channel messages guaranteed to be read?"
211
233
212
234
### 7. Testing & Validation
235
+
213
236
-**Test Coverage**: Write tests for edge cases, not just happy paths
214
237
-**Error Injection**: Test retry logic, failure modes, and error paths
215
238
-**Resource Limits**: Test with large inputs to verify scalability
@@ -297,6 +320,7 @@ go func() {
297
320
## Code Style
298
321
299
322
### Cobra Flags
323
+
300
324
- Flag names: lowercase with hyphens (kebab-case), e.g., `--output-file`
301
325
- Usage strings: lowercase, no ending punctuation, e.g., `"path to output file"`
302
326
- Remove unnecessary leading articles and filler words (e.g., "the", "a", "an") from usage strings
@@ -317,9 +341,11 @@ go func() {
317
341
```
318
342
319
343
### Cobra Command Arguments
344
+
320
345
- Prefer to use Cobra built-in validators (`cobra.NoArgs`, `cobra.ExactArgs(n)`, `cobra.MinimumNArgs(n)`, `cobra.MaximumNArgs(n)`, `cobra.ArbitraryArgs`) instead of custom `Args: func(cmd *cobra.Command, args []string) error` functions, and move argument parsing/validation logic to `PreRunE` hook
321
346
322
347
### Cobra Commands
348
+
323
349
- Command `Short` descriptions: sentence case with ending period, e.g., `"Generate a node list to seed a node."`
324
350
- Command `Long` descriptions: consider using embedded usage.md file via `//go:embed usage.md` pattern; when using inline strings, use sentence case with ending period for complete sentences
325
351
- Command `Short` should be brief (~50 characters or less), appears in help menus and command lists
0 commit comments