Multi-Part Payments (MPP)
Multi-Part Payments allow splitting a single payment across multiple routes. This enables larger payments and improves success rates by utilizing multiple channels. Instead of sending one large payment through a single route, MPP splits the payment into multiple smaller parts that can take different routes.
Example
Single Payment (fails):
Alice → Bob → Carol → Dave
Amount: 500,000 sats
Problem: Carol's channel only has 200,000 sats capacity
MPP Payment (succeeds):
Route 1: Alice → Bob → Carol → Dave (200,000 sats)
Route 2: Alice → Eve → Dave (200,000 sats)
Route 3: Alice → Fred → George → Dave (100,000 sats)
Total: 500,000 sats
Why Use MPP?
Benefits
- Larger Payments: Can send amounts larger than any single channel
- Higher Success Rate: Multiple routes increase chance of success
- Better Liquidity Utilization: Use multiple channels simultaneously
- Fault Tolerance: If one route fails, others can still succeed
Use Cases
- Large Payments: Payments larger than channel capacity
- Unbalanced Channels: When direct channels are one-sided
- Network Congestion: When single routes are unreliable
- Optimization: Split to minimize fees or maximize speed
How MPP Works
Payment Splitting
- Determine Split: Divide payment into multiple parts
- Find Routes: Find routes for each part
- Send Simultaneously: Send all parts at once
- Wait for All: Wait for all parts to complete
- Verify Completion: Ensure all parts succeeded
Equal Splitting
Simplest approach: divide payment equally among routes:
Payment: 120,000 sats
Routes: 3
Split: 120,000 / 3 = 40,000 sats per route
Optimal Splitting
More advanced: split based on:
- Channel capacities
- Fee optimization
- Success probability
- Route quality
TLV Encoding for MPP
MPP payments include special TLV (Type-Length-Value) fields in the final hop of each route.
Payment Data TLV
Type: 8
Length: 40 bytes
Value (40 bytes):
32 bytes: payment_secret (payment_address)
8 bytes: total_msat (total payment amount)
Example
Payment Secret: b3c3965128b05c96d76348158f8f3a1b92e2847172f9adebb400a9e83e62f066
Total Amount: 120,000 msat
TLV Encoding:
Type: 0000000000000008 (8)
Length: 0000000000000028 (40)
Value: b3c3965128b05c96d76348158f8f3a1b92e2847172f9adebb400a9e83e62f0660000000000000078
Where to Include
- Last hop of each path: Include in final hop's TLV
- Same values: All paths use same payment_secret and total_msat
- Other hops: NULL TLV for non-final hops
MPP Implementation
Step 1: Simple Route
For single-path payments, no MPP TLV is needed:
Route: Alice → Bob → Carol → Dave
Amount: 100,000 sats
TLV: NULL (no MPP field)
Step 2: Multi-Path Payment
For multi-path payments, include TLV in last hop of each path:
Path 1: Alice → Bob → Carol → Dave
Last hop (Carol → Dave): Include MPP TLV
Path 2: Alice → Eve → Dave
Last hop (Eve → Dave): Include MPP TLV
Path 3: Alice → Fred → George → Dave
Last hop (George → Dave): Include MPP TLV
TLV Structure
The TLV uses simplified encoding (not full BOLT specification):
Type [uint64]: 8
Length [uint64]: 40
Values [40 bytes]:
32 bytes: payment_secret (hex)
8 bytes: total_msat (uint64, big-endian)
Payment Secret
The payment secret (also called payment_address) is:
- 32 bytes: Random value generated by recipient
- Same for all parts: All MPP parts use the same secret
- Verification: Recipient verifies all parts use same secret
- Security: Prevents payment mixing attacks
Total Amount
The total_msat field specifies:
- Total payment: Sum of all MPP parts
- Verification: Recipient verifies sum matches invoice
- Same for all parts: All parts include the same total
- 8 bytes: uint64 in big-endian format
Example: 3-Path MPP
Invoice Details
Invoice Amount: 120,000 sats
Payment Secret: b3c3965128b05c96d76348158f8f3a1b92e2847172f9adebb400a9e83e62f066
Route Calculation
Path 0: Alice → Bob → Carol → Dave
Amount per path: 40,000 sats
Fees: Calculate for each hop
Path 1: Alice → Eve → Dave
Amount per path: 40,000 sats
Fees: Calculate for each hop
Path 2: Alice → Fred → George → Dave
Amount per path: 40,000 sats
Fees: Calculate for each hop
TLV for Each Path
All three paths include the same TLV in their final hop:
TLV: 00000000000000080000000000000028b3c3965128b05c96d76348158f8f3a1b92e2847172f9adebb400a9e83e62f0660000000000000078
Verification
Recipient Verification
The recipient verifies:
- All parts received: All MPP parts arrived
- Same secret: All parts use same payment_secret
- Correct total: Sum of parts equals total_msat
- Valid preimage: All parts have valid preimages
Sender Verification
The sender verifies:
- All parts sent: All parts were sent
- All succeeded: All parts completed successfully
- Correct amounts: Sum equals invoice amount
- Preimages match: All preimages are the same
Best Practices
For Senders
- Equal Splitting: Start with equal splits
- Route Quality: Use best available routes
- Monitor Progress: Track all parts
- Handle Failures: Retry failed parts if needed
For Recipients
- Wait for All: Don't settle until all parts arrive
- Verify Totals: Ensure sum matches invoice
- Check Secrets: Verify all parts use same secret
- Timeout Handling: Handle partial payments
Common Issues
Partial Payment Received
Problem: Only some MPP parts succeed
Solution:
- Wait for timeout
- Request remaining parts
- Or cancel and retry
TLV Encoding Errors
Problem: TLV not encoded correctly
Solution:
- Verify type is 8
- Check length is 40
- Ensure correct byte order
- Validate hex encoding
Amount Mismatch
Problem: Sum of parts doesn't match total
Solution:
- Verify calculation
- Check fee inclusion
- Ensure correct splitting
Summary
Multi-Part Payments enable:
- Larger payments: Split across multiple routes
- Better success rates: Multiple paths increase reliability
- Liquidity utilization: Use multiple channels
- TLV encoding: Payment data in final hops
- Verification: Recipient verifies all parts
MPP is essential for handling large payments and improving Lightning Network usability.
