What are Rounds?
Rounds are the core mechanism by which captaind batches off-chain payments. Each round:- Collects payment requests from multiple users
- Constructs a shared VTXO tree
- Creates an on-chain funding transaction
- Issues new VTXOs to participants
Round Lifecycle
States
Each round progresses through several states:Phases
1. Attempt Initiation (< 1ms)
- Generate one-time cosign key
- Generate round attempt challenge
- Broadcast
RoundAttemptevent to clients
2. Receiving Payments (default: 2 seconds)
Clients submit payment requests:- ✅ VTXOs exist and are unspent
- ✅ User owns input VTXOs (ownership proof)
- ✅ Input amount ≥ output amount + fees
- ✅ Output amounts ≥ dust limits
- ✅ Correct number of nonces provided
- Interactive: User submits during this phase (requires signatures)
- Non-Interactive (hArk): Pre-registered participations from database
3. Constructing VTXO Tree (< 100ms)
- Aggregate all outputs into a VTXO tree structure
- Add dummy VTXOs if needed (minimum 2 leaves)
- Calculate aggregate nonces for each internal node
- Build round funding transaction
- Lock wallet UTXO for round input
nb_round_nonces).
4. Sending VTXO Proposal (< 10ms)
BroadcastVtxoProposal to clients:
5. Receiving VTXO Signatures (default: 2 seconds)
Clients submit partial MuSig2 signatures:- ✅ Pubkey is a participant in this round
- ✅ Correct number of signatures
- ✅ Signatures verify against aggregate nonces
- Ban non-signing users from this round
- Restart from phase 2 with remaining users
- Reuse the same round funding UTXO
- Increment
attempt_seq
6. Combining Signatures (< 50ms)
- Aggregate all partial signatures
- Verify combined signatures
- Finalize VTXO tree with witnesses
7. Signing On-chain Transaction (< 100ms)
- Sign round funding transaction with BDK wallet
- Commit wallet state (marks UTXOs as spent)
- Persist wallet changeset to database
8. Broadcasting (< 500ms)
- Submit signed transaction to Bitcoin network
- Broadcast
RoundFinishedevent to clients:
9. Persisting (< 500ms)
- Store round record to database
- Mark input VTXOs as spent
- Insert new output VTXOs
- Store virtual transactions
- Update round participations
Round Results
- Success: Round completed and broadcast
- Empty: No payments received, round skipped
- Abandoned: All retries exhausted, no signers left
- Error: Fatal error occurred (database, wallet, etc.)
Configuration
Timing Parameters
Tuning Tips:
- Shorter
round_interval= better UX, higher resource usage - Longer
round_submit_time= more inclusive, slower rounds - Longer
round_sign_time= tolerates network lag, slower rounds
Capacity Parameters
Forfeit Parameters
Monitoring Rounds
Admin RPC
Trigger a round manually:Logs
Round lifecycle events:Metrics
OpenTelemetry metrics:bark_round_seq: Current round sequence numberbark_round_state: Current round state (enum)bark_round_attempt: Current attempt within roundbark_round_input_volume: Total input satsbark_round_input_count: Number of input VTXOsbark_round_output_count: Number of output VTXOsbark_round_step_duration: Time spent in each phase
Round Events Stream
Clients subscribe to the round event stream via gRPC:- Attempt: Round started, provides challenge
- VtxoProposal: VTXO tree proposed
- Finished: Round completed with transaction
Common Issues
Empty Rounds
Symptom: Rounds complete with no payments Causes:- No users connected
- Users not submitting payments
- Round interval too short for users to prepare
- Increase
round_interval - Check client connectivity
- Verify users have spendable VTXOs
Abandoned Rounds
Symptom:RoundAbandoned after retries
Causes:
- All users failed to sign
- Network issues preventing signature delivery
- Client bugs
- Increase
round_sign_time - Check server network latency
- Update client software
Slow Rounds
Symptom: Rounds taking > 10 seconds Causes:- Database slow (many VTXOs)
- Large VTXO tree (many outputs)
- Slow Bitcoin Core RPC
- Optimize PostgreSQL (indexes, vacuum)
- Reduce
nb_round_nonces - Use faster hardware (SSD)
- Reduce
max_output_vtxos
Failed Broadcasts
Symptom: Round completes but tx not in mempool Causes:- Bitcoin Core connectivity issues
- Transaction rejected (fees, conflicts)
- Mempool full
- Check Bitcoin Core logs
- Verify round tx meets policy rules
- Increase fee rates
- Wait and let TX Nursery rebroadcast
Advanced Topics
Non-Interactive Participations (hArk)
Users can pre-register payments that don’t require signing: Database Storage:- Async payments when user offline
- Server-initiated rebalancing
- Automated liquidity management
Round Sequence Numbers
Round sequence (RoundSeq) is a monotonically increasing timestamp:
- Globally unique (assuming server time is accurate)
- Sortable
- Human-readable (Unix timestamp offset)
Forfeit Nonces
For the deprecated forfeit mechanism (replaced by watchman): Storage:round_forfeit_nonces_timeout.
Wallet UTXO Locking
Prevents double-spending the same UTXO across rounds:Best Practices
Monitor round health
Monitor round health
Set up alerts for:
- High abandonment rate (> 10%)
- Slow round durations (> 2x expected)
- Empty round rate (> 50%)
Tune for your workload
Tune for your workload
- High traffic: Increase
nb_round_nonces, decreaseround_interval - Low traffic: Increase
round_intervalto batch more payments - Variable traffic: Use default settings and monitor
Handle retries gracefully
Handle retries gracefully
- Log banned VTXOs to identify problematic users
- Consider manual intervention for repeated failures
- Implement client-side retry logic
Database maintenance
Database maintenance
- Regularly
VACUUMandANALYZE - Monitor table sizes (rounds grow indefinitely)
- Consider archiving old rounds (future feature)