Commit 48bbcc4
committed
kv(composed1): ABORT bypass + happy-path test + doc fix (round-3 on PR #895)
Three remaining items from claude's round-2 follow-up review + the
gemini HIGH-priority finding that was missed in round 2:
* gemini HIGH (kv/fsm.go) — ABORT requests MUST bypass the
Composed-1 gate. If a route shifted between PREPARE and
ABORT (or the observed version was evicted), a rejected
ABORT would leave the txn's intent locks pinned in MVCC
until LockResolver's TTL — minutes of write-blocked keys
for what should be a one-RPC cleanup.
Production callers (transaction.go, sharded_coordinator.go)
happen to leave ObservedRouteVersion=0 on ABORT requests, so
today the existing observedVer==0 short-circuit already
protects them. But that is enforcement-by-convention; a
future ABORT construction site that copies a COMMIT struct
by mistake would silently start failing aborts.
Fix: add `if r.GetPhase() == pb.Phase_ABORT { return nil }`
as the FIRST guard in verifyComposed1, before the
routes/shardGroupID check. Enforcement-in-code rather than
enforcement-by-convention.
Caller audit (the loop directive's semantic-change check):
verifyComposed1 is only called from handleTxnRequest, which
treats nil as success. The ABORT bypass returns nil, so the
caller's semantics are preserved. No further wiring change.
* claude follow-up #1 (distribution/engine.go) — The
SetHistoryDepthForTest doc comment said "no internal
synchronisation here" even though the function acquired
e.mu.Lock. Future readers would see the contradiction and
not know which was authoritative. Rewrote the comment to
describe the actual contract: the write is lock-protected,
but callers should still set depth before sharing the
Engine with concurrent SnapshotAt/Current readers to avoid
interleaving surprises around the eviction watermark.
* claude follow-up #2 (kv/fsm_composed1_test.go) — The gate
suite had no happy-path test. An off-by-one in OwnerOf, a
reversed comparison, or a sign-flip in the group-ID match
would silently false-reject every valid commit and the
failure-only suite would not catch it. Added
TestVerifyComposed1_ValidOwnershipPassesGate: this FSM
serves the group that owns the key at BOTH the observed
version AND the current catalog version, so the gate must
return nil.
* claude follow-up nit (kv/fsm_composed1_test.go) — The
`//nolint:unparam` annotation on newComposed1FSM is now
redundant: the new ABORT and shardGroupID=0 tests pass
distinct shardGroupID values, so golangci-lint no longer
flags the parameter as constant. Removed (verified with
`make lint` → 0 issues).
Also added TestVerifyComposed1_AbortPhaseSkipsGate as the
regression for the ABORT bypass: deliberately sets
ObservedRouteVersion=1 (non-zero) on the ABORT to defeat the
existing observedVer==0 short-circuit and isolate the new
Phase_ABORT guard.
Verification: go test -race -count=1 ./kv ./distribution → pass.
make lint → 0 issues.1 parent 6108626 commit 48bbcc4
3 files changed
Lines changed: 93 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
209 | 209 | | |
210 | 210 | | |
211 | 211 | | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
218 | | - | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
219 | 221 | | |
220 | 222 | | |
221 | 223 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
580 | 580 | | |
581 | 581 | | |
582 | 582 | | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
583 | 597 | | |
584 | 598 | | |
585 | 599 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | 31 | | |
37 | 32 | | |
38 | 33 | | |
| |||
256 | 251 | | |
257 | 252 | | |
258 | 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 | + | |
0 commit comments