-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCargo.toml
More file actions
459 lines (429 loc) · 18.1 KB
/
Cargo.toml
File metadata and controls
459 lines (429 loc) · 18.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
[workspace]
members = [".", "tests/network-peer"]
# Note: loom-tests is intentionally NOT in the workspace because it requires
# special cfg flags (--cfg loom) that conflict with normal builds
[package]
name = "fortress-rollback"
version = "0.8.0"
authors = ["wallstop <wallstop@wallstopstudios.com>"]
edition = "2021"
rust-version = "1.86" # Minimum Supported Rust Version (MSRV) - required by criterion 0.8.1
description = "Fortress Rollback (a fork of GGRS) is a fortified, verified P2P rollback networking library for Rust."
license = "MIT OR Apache-2.0"
readme = "README.md"
repository = "https://github.com/wallstop/fortress-rollback"
keywords = ["gamedev", "networking", "ggpo", "rollback"]
categories = ["network-programming", "game-development"]
documentation = "https://docs.rs/fortress-rollback"
exclude = [
# Build/CI artifacts
".tla-tools/",
".devcontainer/",
".github/",
"docker/",
"scripts/",
"specs/",
"proptest-regressions/",
"actionlint",
# Security scanning baseline (development only)
".secrets.baseline",
# Mutation testing artifacts (can be very large ~1GB+)
"mutants.out/",
# TLA+ model checker output
"states/",
"states.dot",
# Development config files (not needed by users)
".cargo/",
".config/",
".claude/",
".cursorrules",
".dockerignore",
".llm/",
".markdown-link-check.json",
".markdownlint.json",
".pre-commit-config.yaml",
".z3-trace",
"clippy.toml",
"deny.toml",
"rustfmt.toml",
# CI/tooling configuration files (only used for development workflows)
".lychee.toml",
".typos.toml",
".vale.ini",
".vale/",
"codecov.yml",
"Cross.toml",
"mkdocs.yml",
"requirements-docs.txt",
# Python virtual environment and cache (for TLA+ tooling)
".venv/",
".pytest_cache/",
# Session progress tracking files
"progress/",
# GitHub wiki mirror
"wiki/",
# LLM instruction files (for contributing to this project, not for users)
"AGENTS.md",
"CLAUDE.md",
# Development planning document (not for users)
"PLAN.md",
# Note: .cursorrules is already excluded above with development config files
# Note: llms.txt is intentionally NOT excluded - it helps AI tools understand
# the library API for users integrating Fortress Rollback into their projects
# Supply chain audits (cargo-vet metadata)
"supply-chain/",
# Tests are large and users can clone repo to run them
"tests/",
# Benchmarks - users can clone repo to run them
"benches/",
"loom-tests/",
"fuzz/",
# Documentation that's development-focused (user-guide and architecture are kept)
"docs/ggrs-changelog-archive.md",
"docs/contributing.md",
"docs/code-of-conduct.md",
# Cargo.lock not needed for library crates (now excluded since no binaries in main crate)
"Cargo.lock",
]
[badges]
maintenance = { status = "actively-developed" }
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(kani)', 'cfg(loom)'] }
# Allow unknown lints during lint rename transitions (e.g., unchecked_duration_subtraction -> unchecked_time_subtraction in Rust 1.92)
unknown_lints = "allow"
# Allow renamed lints during Rust version transitions
renamed_and_removed_lints = "allow"
# Defensive programming clippy lints
# Reference: https://corrode.dev/blog/defensive-programming/
[lints.clippy]
# Ensure all public API methods that return values have #[must_use]
must_use_candidate = "warn"
# Catch fallible From implementations that should be TryFrom
fallible_impl_from = "deny"
# Make clone() calls explicit for readability
implicit_clone = "warn"
# Remove unnecessary clone() calls
redundant_clone = "warn"
# Use to_owned() for &str instead of to_string() for clarity
inefficient_to_string = "warn"
# === Additional defensive lints ===
# No TODOs in production code
todo = "deny"
# No unimplemented!() in production code
unimplemented = "deny"
# No debug macros in production (use tracing)
dbg_macro = "warn"
# Use tracing instead of print statements
print_stdout = "warn"
print_stderr = "warn"
# === Pedantic lints (enabled selectively) ===
# Enable pedantic as baseline, then allow noisy ones
pedantic = { level = "warn", priority = -1 }
# Allow these commonly noisy pedantic lints
module_name_repetitions = "allow"
similar_names = "allow"
too_many_lines = "allow"
missing_errors_doc = "allow"
missing_panics_doc = "allow"
# These are too strict for this codebase
if_not_else = "allow"
match_same_arms = "allow"
single_match_else = "allow"
unnested_or_patterns = "allow"
unreadable_literal = "allow"
items_after_statements = "allow"
# Allow precision loss for frame calculations (never exceed mantissa)
cast_precision_loss = "allow"
# Allow sign loss for frame index calculations (validated elsewhere)
cast_sign_loss = "allow"
# Allow possible truncation (sizes are always within bounds)
cast_possible_truncation = "allow"
# Allow lossless casts (clearer intent)
cast_lossless = "allow"
# Allow possible wrap for intentional bit manipulation
cast_possible_wrap = "allow"
# Allow indexing - we use bounds checking where critical
indexing_slicing = "allow"
# Allow needless pass by value for small Copy types
needless_pass_by_value = "allow"
# Allow doc markdown flexibility
doc_markdown = "allow"
# Allow format string style choice
uninlined_format_args = "allow"
# Allow explicit returns for clarity
needless_return = "allow"
# Allow wildcard imports in tests
wildcard_imports = "allow"
# Allow redundant else for clarity
redundant_else = "allow"
# Allow bool comparison for readability
bool_comparison = "allow"
# Allow used underscore binding
used_underscore_binding = "allow"
# Allow struct field names
struct_field_names = "allow"
# Allow needless continue for clarity
needless_continue = "allow"
# Allow borrow as ptr patterns
borrow_as_ptr = "allow"
# Allow checked conversions style choice
checked_conversions = "allow"
# Allow explicit iter loops
explicit_iter_loop = "allow"
# Allow manual let else
manual_let_else = "allow"
# Allow range plus one patterns
range_plus_one = "allow"
# Allow explicit into iter
explicit_into_iter_loop = "allow"
# Allow semicolon if nothing returned style
semicolon_if_nothing_returned = "allow"
# Allow struct excessive bools (protocol state)
struct_excessive_bools = "allow"
# Allow trivially copy pass by ref (API consistency)
trivially_copy_pass_by_ref = "allow"
# Allow unchecked time subtraction (validated by our logic)
# Note: unchecked_duration_subtraction was renamed to unchecked_time_subtraction in Rust 1.92.
unchecked_time_subtraction = "allow"
# Note: wildcard_enum_match_arm is NOT enabled because internal test code uses wildcards
# intentionally for internal enums like MessageBody, and we want to allow example code to
# demonstrate patterns without requiring exhaustive matching.
# === Defensive programming pattern enforcement ===
# Warn about unneeded field patterns in struct destructuring
unneeded_field_pattern = "warn"
# Warn about functions with too many boolean parameters (4+ by default)
fn_params_excessive_bools = "warn"
# === No-panic enforcement (for production safety) ===
# These lints help achieve zero production panics
# Note: Set to "warn" to allow gradual migration; change to "deny" once codebase is clean
unwrap_used = "warn"
expect_used = "warn"
# Panic macro should only be used in truly unrecoverable situations
panic = "warn"
# Indexing can panic; prefer .get() with proper handling
# (Currently allowed in pedantic section - indexing_slicing = "allow")
# === Nursery lints (experimental but useful) ===
# Enable nursery as baseline, then allow overly strict ones
nursery = { level = "warn", priority = -1 }
# Allow these commonly noisy nursery lints
significant_drop_tightening = "allow"
redundant_pub_crate = "allow"
future_not_send = "allow"
cognitive_complexity = "allow"
missing_const_for_fn = "allow"
option_if_let_else = "allow"
or_fun_call = "allow"
suboptimal_flops = "allow"
# === Cargo lints (Cargo.toml quality) ===
# Enable cargo lints for better Cargo.toml hygiene
cargo = { level = "warn", priority = -1 }
# Allow multiple crate versions (common in complex dependency trees)
multiple_crate_versions = "allow"
# === Restriction lints (cherry-picked for safety) ===
# Note: Restriction lints must be individually enabled, never as a group
# See: https://doc.rust-lang.org/clippy/lints.html#restriction
#
# Safety-critical: Prevent panics and memory issues
mem_forget = "deny" # Memory leaks via std::mem::forget
exit = "deny" # Library should never call std::process::exit
#
# String safety
string_slice = "warn" # Track string slicing (can panic on non-char boundaries)
#
# Error handling quality
map_err_ignore = "warn" # Preserve error context when mapping errors
#
# Code quality and safety
rest_pat_in_fully_bound_structs = "warn" # Catch new struct fields (no `..` in patterns)
verbose_file_reads = "warn" # Use fs::read_to_string() instead of File::open + read
#
# Smart pointer hygiene
rc_buffer = "warn" # Use Rc<[T]> instead of Rc<Vec<T>>
rc_mutex = "warn" # Use Arc<Mutex<T>> instead of Rc<Mutex<T>>
#
# === Additional restriction lints (high-value, low false positive) ===
# Panic prevention
if_then_some_else_none = "warn" # Use .then() or .then_some() for cleaner code
#
# Correctness
empty_drop = "warn" # Empty Drop implementations are dead code
create_dir = "warn" # Use create_dir_all() for robustness
#
# API consistency
mutex_atomic = "warn" # Use AtomicBool instead of Mutex<bool>
#
# Performance and idioms
string_add = "warn" # Use push_str() instead of + for efficiency
#
# Documentation hygiene
unnecessary_safety_comment = "warn" # Remove spurious // SAFETY: comments
unnecessary_safety_doc = "warn" # Remove spurious /// # Safety sections
#
# === Additional defensive restriction lints ===
# Explicit patterns over implicit behavior
# NOTE: clone_on_ref_ptr is NOT enabled because `arc.clone()` is idiomatic Rust
# and clearer than `Arc::clone(&arc)` in most contexts. The explicit form is only
# needed when there's ambiguity about which clone is being called.
format_push_string = "warn" # Use write! instead of format! + push_str
mixed_read_write_in_expression = "warn" # Avoid confusing read+write in same expression
# NOTE: same_name_method is NOT enabled because PCG32's next_u32/next_u64 intentionally
# shadow the RngCore trait methods for better API ergonomics.
# NOTE: std_instead_of_core and alloc_instead_of_core are NOT enabled because this crate
# is std-only and does not aim for no_std compatibility. Enabling these would require
# changing hundreds of std:: references for no practical benefit.
#
# Additional safety-focused lints
as_underscore = "warn" # Explicit type in `as _` conversions
# NOTE: assertions_on_result_states is NOT enabled because test code frequently uses
# assert!(result.is_ok()) and assert!(result.is_err()) for clarity in test assertions.
# NOTE: decimal_literal_representation is NOT enabled because it triggers on common
# values like 16384, 1000, etc. that are more readable in decimal in context.
default_union_representation = "warn" # Require repr(C) on unions for FFI safety
empty_structs_with_brackets = "warn" # Use `struct Foo;` not `struct Foo {}`
error_impl_error = "warn" # Custom Error types should impl std::error::Error
fn_to_numeric_cast_any = "warn" # Catch function pointer to int casts
# NOTE: impl_trait_in_params is NOT enabled because `impl AsRef<[u8]>` is idiomatic
# and clearer than verbose generic parameters for this use case.
infinite_loop = "warn" # Warn on `loop {}` without break
iter_over_hash_type = "warn" # Warn about non-deterministic iteration order
# NOTE: let_underscore_must_use is NOT enabled because test code frequently uses
# `let _ = expression` to verify code compiles and doesn't panic, and examples
# ignore channel send results as best practice for documentation examples.
# NOTE: min_ident_chars is NOT enabled because it triggers on common idiomatic patterns
# like `let (k, v)`, `Some(s)`, etc. that are clear from context.
# NOTE: missing_assert_message is NOT enabled because test code uses hundreds of asserts
# where the context is already clear from the surrounding test function name.
needless_raw_strings = "warn" # Don't use r"" when "" works
# NOTE: partial_pub_fields is NOT enabled because test stubs intentionally mix pub/private
# fields to match production structs' field visibility.
# NOTE: redundant_type_annotations is NOT enabled because test code uses explicit
# type annotations for documentation purposes to show expected types.
renamed_function_params = "warn" # Consistent parameter names across impls
# NOTE: self_named_module_files is NOT enabled because integration tests use the standard
# tests/*.rs pattern which is clearer than tests/*/mod.rs for this project.
# NOTE: tests_outside_test_module is NOT enabled because integration tests are in the
# standard tests/ directory, not inside #[cfg(test)] modules.
try_err = "warn" # Use ? instead of Err(e)?
undocumented_unsafe_blocks = "warn" # Require SAFETY comments on unsafe
# cargo-shear: macroquad and z3 are optional deps behind feature flags
# (graphical-examples and z3-verification). They cannot be dev-dependencies
# because dev-deps cannot be feature-gated in Cargo.
[package.metadata.cargo-shear]
ignored = ["macroquad", "z3"]
[features]
sync-send = []
# Enable runtime invariant checking in release builds (for debugging production issues)
paranoid = []
# Enable loom-compatible synchronization primitives for concurrency testing
# NOTE: This changes the internal sync primitives from parking_lot to std/loom
loom = []
# Enable Z3 formal verification tests (requires system Z3: apt install libz3-dev)
z3-verification = ["dep:z3"]
# Enable Z3 with bundled build (slow - builds Z3 from source, ~30+ minutes)
# Use this only if you don't have Z3 installed system-wide
z3-verification-bundled = ["z3-verification", "z3?/bundled"]
# Enable graphical examples (ex_game_*) - requires system audio/graphics libraries
# On Linux: sudo apt-get install libasound2-dev libx11-dev libxi-dev libgl1-mesa-dev
graphical-examples = ["dep:macroquad"]
# Enable tokio async runtime integration for async socket adapters
# Provides TokioUdpSocket for use with async networking code
tokio = ["dep:tokio"]
# Enable JSON serialization for telemetry types (adds serde_json dependency)
# Provides to_json() and to_json_pretty() methods on SpecViolation and InvariantViolation
json = ["dep:serde_json"]
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", optional = true }
bincode = { version = "2.0", features = ["serde"] }
parking_lot = "0.12"
web-time = "1.1"
tracing = "0.1"
# SmallVec for stack-allocated small vectors (avoids heap allocation for 1-4 players)
smallvec = { version = "1.13", features = ["serde"] }
# SMT solver for formal verification
# Only compiled when z3-verification feature is enabled
# For bundled build (slow), use z3-verification-bundled feature instead
z3 = { version = "0.20", optional = true }
# Graphical examples dependency (requires system audio/graphics libraries)
# On Linux: sudo apt-get install libasound2-dev libx11-dev libxi-dev libgl1-mesa-dev
macroquad = { version = "0.4", optional = true }
# Tokio async runtime for async socket adapters
# Only compiled when tokio feature is enabled
tokio = { version = "1.52", features = ["net", "io-util", "sync", "rt", "macros", "time"], optional = true }
# Loom for concurrency testing - only used when cfg(loom) is set
[target.'cfg(loom)'.dependencies]
loom = "0.7"
[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = "0.3"
[dev-dependencies]
serial_test = "3.4"
clap = { version = "4.6", features = ["derive"] }
tracing-subscriber = "0.3"
tracing-log = "0.2"
proptest = "1.11"
# JSON parsing for tests (also enables the "json" feature for telemetry tests)
serde_json = "1.0"
# Benchmarking
criterion = { version = "0.8", features = ["html_reports"] }
# Macro utilities for data-driven tests
pastey = "0.2"
# Examples
[[example]]
name = "ex_game_p2p"
path = "examples/ex_game/ex_game_p2p.rs"
required-features = ["graphical-examples"]
[[example]]
name = "ex_game_spectator"
path = "examples/ex_game/ex_game_spectator.rs"
required-features = ["graphical-examples"]
[[example]]
name = "ex_game_synctest"
path = "examples/ex_game/ex_game_synctest.rs"
required-features = ["graphical-examples"]
# Benchmarks (using criterion)
[[bench]]
name = "input_queue"
harness = false
[[bench]]
name = "sync_layer"
harness = false
[[bench]]
name = "p2p_session"
harness = false
[[bench]]
name = "compression"
harness = false
# Profile for benchmarks
[profile.bench]
debug = true
lto = "thin"
# Profile for faster dev builds (optimized deps, unoptimized local code)
[profile.dev.package."*"]
opt-level = 1
# === Safety-focused release profile ===
# Enable overflow checks in release mode for maximum safety
# This catches integer overflow bugs that would otherwise wrap silently
[profile.release]
overflow-checks = true
# Link-Time Optimization for better performance (10-20% improvement typical)
# "thin" provides most of the benefit with reasonable build times
lto = "thin"
# Single codegen unit for maximum optimization (slightly slower builds)
codegen-units = 1
# Strip symbols from release binaries for 50-80% size reduction
# Safe for production since we have comprehensive error handling
strip = true
# Use abort on panic for 10-20% size reduction (removes unwinding machinery)
# Safe because this crate follows a zero-panic policy - all errors return Result
panic = "abort"
# CI-specific profile with both overflow checks and debug assertions
# Used by ci-safety.yml for maximum runtime checking
[profile.release-safe]
inherits = "release"
overflow-checks = true
debug-assertions = true
# Loom concurrency tests - isolated from other dev-deps
[[test]]
name = "loom_concurrency"
path = "tests/loom_concurrency.rs"
required-features = [] # No features required, but only runs under cfg(loom)