Commit 7825c53
authored
Coordination windows performance improvements (#3864)
## Summary
- `FindDepositsToSweep` now limits `DepositRevealed` event scanning to
the most recent ~30 days (`DepositSweepLookBackBlocks = 216000` blocks)
instead of querying from block 0, significantly reducing RPC load on
long-running nodes
- Includes underflow protection: when `currentBlock < 216000`,
`filterStartBlock` remains `0` to avoid uint64 wraparound
- `FindDeposits` (used by the MovingFunds safety guard) continues to
scan from block 0 to preserve full-history coverage for wallet safety
checks
- Unswept deposits are now grouped by vault address (case-insensitive)
before sweep proposal; the largest group is selected to maximize
per-transaction throughput, since deposits targeting different vaults
cannot be swept together
- Vault=0x0 (nil-vault) deposits excluded from the selected group are
logged at Warn level for operator follow-up; they remain recoverable via
later sweep cycles, depositor refunds, or reinitializer re-assignment
- The `Vault` field is propagated through `DepositReference` and
`Deposit` structs for downstream consumers
- DepositSweep and MovedFundsSweep coordination actions switch from
every 4th coordination window to every window at block 24559289 (~March
1st 2026); MovingFunds retains the 4th-window guard to avoid multiplying
its full-history chain scan load
## Coordination actions — before and after
**Before:**
| Priority | Action | Frequency | Lookback |
|----------|--------|-----------|----------|
| 0 | ActionRedemption | Every window | Full history (block 0) —
`redemptionTimeout` was ~20 years, exceeds chain height |
| 1 | ActionDepositSweep | Every 4th window | Full history (block 0) |
| 2 | ActionMovedFundsSweep | Every 4th window | Full history (block 0)
|
| 3 | ActionMovingFunds | Every 4th window | Full history (block 0) |
| 4 | ActionHeartbeat | 6.25% probability | No chain scan |
**After (block >= 24559289):**
| Priority | Action | Frequency | Lookback |
|----------|--------|-----------|----------|
| 0 | ActionRedemption | Every window | 94,600 blocks (~13.14 days) —
`redemptionTimeout` changed to 13 days on-chain |
| 1 | ActionDepositSweep | Every window | 216,000 blocks (~30 days) |
| 2 | ActionMovedFundsSweep | Every window | 216,000 blocks (~30 days) |
| 3 | ActionMovingFunds | Every 4th window | Full history (block 0) |
| 4 | ActionHeartbeat | 6.25% probability | No chain scan |
## Changes
**Coordination layer** (`coordination.go`):
- Add exported `DepositSweepEveryWindowActivationBlock` constant set to
block 24559289 (~March 1st 2026 00:00 UTC)
- Add `coordinationBlock` parameter to `getActionsChecklist`
- Before activation block: all three actions (DepositSweep,
MovedFundsSweep, MovingFunds) gated to every 4th window
- After activation block: DepositSweep and MovedFundsSweep run on every
coordination window; MovingFunds stays gated to every 4th window to
protect against excessive full-history scans
**Coordination tests** (`coordination_test.go`):
- `TestCoordinationExecutor_GetActionsChecklist` covers pre-activation
behavior (blocks below 24559289): non-4th windows get only Redemption,
4th windows get all actions
- `TestCoordinationExecutor_GetActionsChecklist_PostActivation` covers
post-activation behavior (blocks above 24559289) with safety invariant
assertions
- `assertPostActivationSafety` helper — verifies ActionRedemption at
index 0, DepositSweep and MovedFundsSweep always present, MovingFunds
absent on non-4th windows
- `assertChecklistOrdering` helper — verifies canonical priority
ordering across the checklist
**Production code** (`deposit_sweep.go`):
- Add exported `DepositSweepLookBackBlocks` constant (216000 blocks, ~30
days at 12s/block)
- Add `filterStartBlock` parameter to internal `findDeposits()` function
- `FindDepositsToSweep()` computes bounded start block via
`BlockCounter.CurrentBlock()` with underflow guard
- `FindDeposits()` passes `filterStartBlock=0` to preserve full-history
behavior
- Set `DepositRevealedEventFilter.StartBlock` from the computed value
- Group unswept deposits by vault address with case-insensitive
normalization
- Select the largest vault group for sweep proposal (largest-group-first
policy)
- Log multi-group scenarios at Info level; log excluded nil-vault
deposits at Warn level
- Propagate `Vault` field through `Deposit` and `DepositReference`
structs
**Test helpers** (`tbtcpgtest.go`):
- Add `Vault` field to test `Deposit` struct and `DepositsReferences()`
output
**Tests** (`deposit_sweep_test.go`):
- Add `TestDepositSweepLookBackBlocks` — validates the constant equals
216000
- Add `TestDepositSweepTask_FindDepositsToSweep_BoundedLookback` —
exercises the bounded path with `currentBlock=300000`
- Add `TestDepositSweepTask_FindDepositsToSweep_UnderflowGuard` —
exercises the underflow path with `currentBlock=100000`
- Wire `MockBlockCounter` into existing JSON-driven scenario tests
- Add `TestFindDepositsToSweep_VaultGrouping` with 10 sub-tests covering
nil vaults, mixed vaults, case normalization, tied groups, and
multi-group selection
## Test plan
- [ ] `go test ./pkg/tbtcpg/... -v` — all tests pass
- [ ] `go test ./pkg/tbtc/... -run
TestCoordinationExecutor_GetActionsChecklist -v` — all coordination
tests pass
- [ ] `go build ./pkg/...` — compiles cleanly
- [ ] `go vet ./pkg/...` — no new issues
- [ ] Verify `FindDeposits` (MovingFunds path) still uses
`filterStartBlock=0`
- [ ] Vault grouping selects correct largest group in multi-vault
scenarios
- [ ] Nil-vault deposits are logged but not lost (recoverable paths
documented)
- [ ] Pre-activation: all three actions gated to every 4th window
- [ ] Post-activation (block >= 24559289): DepositSweep and
MovedFundsSweep on every window
- [ ] Post-activation: MovingFunds remains gated to every 4th window
- [ ] All operators must upgrade before block 24559289 (~March 1st 2026)File tree
5 files changed
+1369
-20
lines changed- pkg
- tbtcpg
- internal/test
- tbtc
5 files changed
+1369
-20
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
62 | 69 | | |
63 | 70 | | |
64 | 71 | | |
| |||
387 | 394 | | |
388 | 395 | | |
389 | 396 | | |
390 | | - | |
| 397 | + | |
391 | 398 | | |
392 | 399 | | |
393 | 400 | | |
| |||
575 | 582 | | |
576 | 583 | | |
577 | 584 | | |
| 585 | + | |
578 | 586 | | |
579 | 587 | | |
580 | 588 | | |
| |||
591 | 599 | | |
592 | 600 | | |
593 | 601 | | |
594 | | - | |
595 | | - | |
596 | | - | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
597 | 617 | | |
598 | | - | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
599 | 623 | | |
600 | | - | |
601 | 624 | | |
602 | | - | |
603 | | - | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
604 | 632 | | |
605 | 633 | | |
606 | 634 | | |
| |||
0 commit comments