feat: single funded contracts#3
Draft
bennyhodl wants to merge 3 commits into
Draft
Conversation
ef7181e to
e389637
Compare
e389637 to
d215bc7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Single Funded DLC Implementation - Rust DLC
Overview
This document explains the implementation of single-funded Discreet Log Contracts (DLCs) in Rust DLC, where only one party provides collateral and covers all transaction fees, while the other party (acceptor) contributes no inputs or fees.
Problem Statement
In the existing Rust DLC implementation, both parties in a DLC split the fees for:
This dual-funding model requires both parties to provide inputs and pay their portion of fees. However, there are use cases where only one party (the offeror) should provide all collateral and cover all fees, while the acceptor provides no inputs.
Solution Design
The solution implements a fee distribution model based on collateral contribution:
Fee Distribution Logic
own_collateral == 0, the party pays no fees and provides no inputsown_collateral == total_collateral, the party pays all fees0 < own_collateral < total_collateral, fees are split between parties (existing behavior)Key Changes
1. DLC Manager Changes (
dlc-manager/src/)Files Modified:
channel_updater.rscontract_updater.rsutils.rsCore Changes:
total_collateralparameter toget_party_params()function callsget_appr_required_amount()function with conditional fee logic2. DLC Core Changes (
dlc/src/lib.rs)Core Changes:
PartyParams::get_change_output_and_fees()to accepttotal_collateralparameterKey Logic:
Implementation Details
Fee Calculation Changes
Funding Transaction Fees
FUND_TX_BASE_WEIGHTFUND_TX_BASE_WEIGHT / 20Contract Execution Transaction (CET) Fees
CET_BASE_WEIGHTCET_BASE_WEIGHT / 20Input Requirements
The
get_appr_required_amount()function determines the total amount each party needs to provide:0collateral + full_feescollateral + half_feesChange Output Handling
For unfunded parties, a zero-value change output is created to maintain transaction structure while indicating no funding requirement.
Testing
The implementation includes comprehensive tests covering:
Test Cases Added
Migration Path
Step 1: Rust DLC Integration
total_collateralparameterStep 2: DLC DevKit (DDK) Integration
Backward Compatibility
The implementation maintains full backward compatibility:
Usage Examples
Creating a Single-Funded DLC
Fee Verification
Benefits
Testing and Reproduction
Reproducing Single-Funded DLC with Rust DLC Sample
To test and demonstrate the single-funded DLC functionality, follow these steps using the Rust DLC sample:
Follow the standard Rust DLC sample setup:
Before creating wallets, modify the wallet creation script to prevent Bob from receiving any Bitcoin:
In scripts/create_wallets.sh:
This ensures Bob starts with zero UTXOs.
3. Create Modified Contract Input
Create or modify the contract JSON to set up a single-funded DLC:
In examples/contracts/single_funded_contract.json:
{ "offer_collateral": 200000000, // 2 BTC (Alice provides all collateral) "accept_collateral": 0, // 0 BTC (Bob provides no collateral) "fee_rate": 2, "contract_info": [ { "oracles": { "oracle_params": [{ "oracle_public_key": "...", "oracle_nonces": ["..."] }] }, "contract_descriptor": { "outcome_payouts": [ {"outcome": "outcome1", "offer_payout": 200000000, "accept_payout": 0}, {"outcome": "outcome2", "offer_payout": 100000000, "accept_payout": 100000000} ] } } ] }Update the block generation script to use Bob's wallet (since Bob won't have funds):
In scripts/generate_blocks.sh:
Execute the standard setup:
In a different terminal:
# Start Bob's instance cargo run ./examples/configurations/bob.ymlFrom Bob's instance (despite having no funds):
From Alice's instance:
Generate blocks to confirm:
bashdocker compose exec bitcoind /scripts/generate_blocks.shWith Single-Funded Implementation:
Without Single-Funded Implementation (Previous Behavior):
Key Observations
Fee Distribution: Alice now pays the full transaction fee (~420 sats) instead of the previous split model (~214 sats each)
Input Requirements: Bob provides zero inputs while Alice provides sufficient inputs to cover:
Her collateral (2 BTC)
Full funding transaction fees
Full CET/refund transaction fees
Zero-Value Outputs: Bob's change output will have zero value, indicating no funding contribution
Backward Compatibility: Dual-funded DLCs continue to work with the existing fee-splitting model
Integration and Release Strategy
Phase 1: Rust DLC Core Integration
Immediate Priority: This PR must be merged into Rust DLC first due to dependency architecture and compatibility requirements.
Why Rust DLC First:
dlc/src/lib.rs(specificallyPartyParams::get_change_output_and_fees()) must be available in the published crateChanges Included:
dlc/src/lib.rs)dlc-manager/src/)Phase 2: Rust DLC Release (v0.8)
Critical Requirement: A new Rust DLC release (e.g., v0.8) must be published after merging.
Why New Release is Required:
bitcoin::Amountthroughout the codebasebitcoin::Amountstandardizationget_change_output_and_fees()APIPhase 3: DLC DevKit Integration
Post-Release Integration: Only after Rust DLC v0.8 is published can DDK be updated.
DDK Integration Requirements:
bitcoin::Amountthroughout DDKCurrent Workaround for Development:
Timeline and Dependencies
Blocking Factors
Cannot proceed with DDK production integration until:
Current Development Status: