Skip to content

Commit 0b42e64

Browse files
author
DigiByte Dev
committed
Merge branch 'feature/bitcoin-v26.2-merge' of https://github.com/DigiByte-Core/digibyte into feature/bitcoin-v26.2-merge
2 parents b03e984 + 06f2b32 commit 0b42e64

1 file changed

Lines changed: 313 additions & 0 deletions

File tree

DIGIBYTE_FEE_ANALYSIS_V8.26.md

Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
# DigiByte v8.26 Transaction Fee Analysis and Implementation Specification
2+
3+
## Executive Summary
4+
5+
DigiByte v8.26 currently implements a **fee-per-kilobyte** model inherited from Bitcoin, which does not enforce a minimum absolute fee of 0.1 DGB per transaction as required for spam protection. This document provides a comprehensive analysis of the current fee implementation and specifications for necessary changes.
6+
7+
**Critical Finding**: The current implementation allows transactions as small as 250 bytes to pay only 0.025 DGB in fees (at the default 0.1 DGB/kvB rate), which is insufficient for spam protection given DigiByte's 1000x larger supply compared to Bitcoin.
8+
9+
## Current Fee Implementation in DigiByte v8.26
10+
11+
### Fee Constants and Their Values
12+
13+
| Constant | Value (satoshis) | Value (DGB) | Location | Purpose |
14+
|----------|------------------|-------------|----------|---------|
15+
| `DEFAULT_TRANSACTION_MINFEE` | 10,000,000 | 0.1 DGB/kvB | `wallet/wallet.h:117` | Wallet minimum fee rate |
16+
| `DEFAULT_MIN_RELAY_TX_FEE` | 100,000 | 0.001 DGB/kvB | `policy/policy.h:59` | Network relay minimum |
17+
| `DUST_RELAY_TX_FEE` | 30,000 | 0.0003 DGB/kvB | `policy/policy.h:57` | Dust threshold calculation |
18+
| `DEFAULT_FALLBACK_FEE` | 1,000,000 | 0.01 DGB/kvB | `wallet/wallet.h:113` | Fallback when fee estimation fails |
19+
| `WALLET_INCREMENTAL_RELAY_FEE` | 1,000,000 | 0.01 DGB/kvB | `wallet/wallet.h:131` | RBF fee increment |
20+
| `DEFAULT_DISCARD_FEE` | 10,000 | 0.0001 DGB/kvB | `wallet/wallet.h:115` | Small change discard threshold |
21+
22+
### Fee Calculation Model
23+
24+
The current implementation uses a **fee-per-kilobyte** model:
25+
26+
```cpp
27+
// From policy/feerate.cpp:22-35
28+
CAmount CFeeRate::GetFee(uint32_t num_bytes) const
29+
{
30+
// Calculate fee as: (rate_per_kvB * size_in_bytes) / 1000
31+
CAmount nFee = std::ceil(nSatoshisPerK * num_bytes / 1000.0);
32+
return nFee;
33+
}
34+
```
35+
36+
**Problem**: This means a 250-byte transaction pays:
37+
- Fee = 10,000,000 * 250 / 1000 = 2,500,000 satoshis = **0.025 DGB**
38+
- This is 4x less than the required 0.1 DGB minimum
39+
40+
### Fee Enforcement Points
41+
42+
1. **Wallet Fee Calculation** (`wallet/fees.cpp`)
43+
- `GetMinimumFeeRate()`: Returns max of wallet minimum and relay minimum
44+
- `GetRequiredFeeRate()`: Enforces wallet.m_min_fee (0.1 DGB/kvB)
45+
- No absolute minimum enforced
46+
47+
2. **Mempool Acceptance** (`validation.cpp`)
48+
- Line 874-876: Checks against `m_pool.m_min_relay_feerate` (0.001 DGB/kvB)
49+
- Line 674-681: `CheckFeeRate()` validates against dynamic mempool minimum
50+
- No absolute minimum enforced
51+
52+
3. **Network Relay** (`net_processing.cpp`)
53+
- Uses `DEFAULT_MIN_RELAY_TX_FEE` for relay decisions
54+
- Fee filter uses same per-kilobyte rates
55+
56+
## Bitcoin vs DigiByte Fee Scaling Analysis
57+
58+
### Supply and Economic Differences
59+
60+
| Metric | Bitcoin | DigiByte | Ratio |
61+
|--------|---------|----------|-------|
62+
| Max Supply | 21 million | 21 billion | 1000x |
63+
| Block Time | 600 seconds | 15 seconds | 40x faster |
64+
| Typical TX Size | 250 bytes | 250 bytes | Same |
65+
| Min Relay Fee | 0.00001 BTC/kvB | 0.001 DGB/kvB | 100x |
66+
| Wallet Min Fee | 0.00001 BTC/kvB | 0.1 DGB/kvB | 10,000x |
67+
68+
### Current Fee Comparison for 250-byte Transaction
69+
70+
| Network | Fee Rate | Actual Fee | USD Value* |
71+
|---------|----------|------------|------------|
72+
| Bitcoin | 0.00001 BTC/kvB | 0.0000025 BTC | ~$0.25 |
73+
| DigiByte (current) | 0.1 DGB/kvB | 0.025 DGB | ~$0.0003 |
74+
| DigiByte (required) | 0.4 DGB/kvB OR absolute 0.1 DGB | 0.1 DGB | ~$0.001 |
75+
76+
*USD values are illustrative based on approximate market prices
77+
78+
## Required Changes for 0.1 DGB Minimum Fee
79+
80+
### Option 1: Absolute Minimum Fee (Recommended)
81+
82+
Implement an absolute minimum fee check that overrides the per-kilobyte calculation:
83+
84+
```cpp
85+
// New constant in policy/policy.h
86+
static constexpr CAmount ABSOLUTE_MIN_TX_FEE{10000000}; // 0.1 DGB absolute minimum
87+
88+
// Modified fee calculation in wallet/fees.cpp
89+
CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes,
90+
const CCoinControl& coin_control, FeeCalculation* feeCalc)
91+
{
92+
CFeeRate feerate_needed = GetMinimumFeeRate(wallet, coin_control, feeCalc);
93+
CAmount calculated_fee = feerate_needed.GetFee(nTxBytes);
94+
95+
// Enforce absolute minimum
96+
return std::max(calculated_fee, ABSOLUTE_MIN_TX_FEE);
97+
}
98+
```
99+
100+
### Option 2: Increased Fee Rate
101+
102+
Increase the minimum fee rate to ensure even small transactions meet the 0.1 DGB minimum:
103+
104+
```cpp
105+
// For a 250-byte transaction to pay 0.1 DGB:
106+
// Required rate = 0.1 DGB * 1000 / 250 = 0.4 DGB/kvB = 40,000,000 satoshis/kvB
107+
static const CAmount DEFAULT_TRANSACTION_MINFEE = 40000000; // 0.4 DGB/kvB
108+
```
109+
110+
### Option 3: Hybrid Approach (Most Flexible)
111+
112+
Combine both approaches for maximum flexibility:
113+
114+
```cpp
115+
// Use higher of: calculated fee or absolute minimum
116+
CAmount final_fee = std::max(
117+
feerate.GetFee(tx_size), // Per-kilobyte calculation
118+
ABSOLUTE_MIN_TX_FEE // Absolute minimum of 0.1 DGB
119+
);
120+
```
121+
122+
## Files Requiring Modification
123+
124+
### Core Implementation Files
125+
126+
1. **src/policy/policy.h**
127+
- Add `ABSOLUTE_MIN_TX_FEE` constant
128+
- Update `DEFAULT_MIN_RELAY_TX_FEE` if using Option 2
129+
130+
2. **src/wallet/wallet.h**
131+
- Update `DEFAULT_TRANSACTION_MINFEE` if using Option 2
132+
- Add absolute minimum fee member variable
133+
134+
3. **src/wallet/fees.cpp**
135+
- Modify `GetMinimumFee()` to enforce absolute minimum
136+
- Update `GetRequiredFee()` similarly
137+
138+
4. **src/validation.cpp**
139+
- Update `CheckFeeRate()` to enforce absolute minimum
140+
- Modify mempool acceptance logic (lines 874-876)
141+
142+
5. **src/wallet/spend.cpp**
143+
- Update fee calculation in `CreateTransactionInternal()`
144+
- Ensure coin selection respects new minimums
145+
146+
6. **src/txmempool.cpp**
147+
- Update `GetMinFee()` to respect absolute minimum
148+
149+
### Configuration and RPC Files
150+
151+
7. **src/init.cpp**
152+
- Update help text for `-mintxfee` and `-minrelaytxfee`
153+
- Add new `-absolutemintxfee` option if desired
154+
155+
8. **src/rpc/mempool.cpp**
156+
- Update fee-related RPC responses
157+
158+
9. **src/wallet/rpc/spend.cpp**
159+
- Update `sendtoaddress`, `sendmany`, etc. to respect new minimums
160+
161+
## Test Files Requiring Updates
162+
163+
### Primary Fee-Related Tests
164+
165+
1. **test/functional/feature_fee_estimation.py**
166+
- Update expected fee calculations
167+
- Add tests for absolute minimum
168+
169+
2. **test/functional/wallet_fallbackfee.py**
170+
- Verify fallback respects absolute minimum
171+
172+
3. **test/functional/wallet_bumpfee.py**
173+
- Ensure RBF respects new minimums
174+
175+
4. **test/functional/mempool_accept.py**
176+
- Test rejection of low-fee transactions
177+
178+
5. **test/functional/mempool_dust.py**
179+
- Update dust threshold calculations
180+
181+
6. **test/functional/p2p_feefilter.py**
182+
- Update fee filter expectations
183+
184+
7. **test/functional/rpc_estimatefee.py**
185+
- Verify estimation respects minimums
186+
187+
### Secondary Tests Affected by Fee Changes
188+
189+
8. **test/functional/wallet_basic.py**
190+
- Transaction creation tests
191+
192+
9. **test/functional/wallet_sendmany_chain.py**
193+
- Multi-output transaction fees
194+
195+
10. **test/functional/wallet_fundrawtransaction.py**
196+
- Raw transaction funding
197+
198+
11. **test/functional/mempool_limit.py**
199+
- Mempool eviction by fee
200+
201+
12. **test/functional/mempool_packages.py**
202+
- Package fee validation
203+
204+
13. **test/functional/feature_rbf.py**
205+
- Replace-by-fee increments
206+
207+
14. **test/functional/wallet_create_tx.py**
208+
- Transaction creation edge cases
209+
210+
15. **test/functional/wallet_groups.py**
211+
- Coin selection with fees
212+
213+
## Implementation Recommendations
214+
215+
### 1. Immediate Actions
216+
217+
1. **Implement Option 3 (Hybrid Approach)**
218+
- Provides both per-kilobyte and absolute minimum protection
219+
- Most flexible for different transaction sizes
220+
- Easiest to roll back if issues arise
221+
222+
2. **Add Configuration Option**
223+
```cpp
224+
// Add to init.cpp
225+
"-absolutemintxfee=<amt> Absolute minimum fee per transaction (default: 0.1 DGB)"
226+
```
227+
228+
3. **Gradual Rollout**
229+
- Start with wallet enforcement only
230+
- Monitor network acceptance
231+
- Then enforce in mempool/relay
232+
233+
### 2. Testing Strategy
234+
235+
1. **Unit Tests**
236+
- Test fee calculation with various transaction sizes
237+
- Verify absolute minimum enforcement
238+
- Check edge cases (very large transactions)
239+
240+
2. **Functional Tests**
241+
- Update all fee-related tests listed above
242+
- Add new test: `test/functional/feature_absolute_min_fee.py`
243+
- Verify network propagation
244+
245+
3. **Testnet Deployment**
246+
- Deploy to testnet first
247+
- Monitor for transaction rejection issues
248+
- Gather fee metrics
249+
250+
### 3. Monitoring and Metrics
251+
252+
Add logging to track:
253+
- Transactions paying exactly minimum fee
254+
- Transactions rejected for low fees
255+
- Average fee per transaction
256+
- Fee distribution histogram
257+
258+
## Potential Issues and Mitigations
259+
260+
### Issue 1: Large Transaction Overhead
261+
**Problem**: A 10KB transaction would pay 1.0 DGB at 0.1 DGB/kvB rate
262+
**Mitigation**: Use hybrid approach - larger transactions use per-kilobyte rate
263+
264+
### Issue 2: Wallet Compatibility
265+
**Problem**: Older wallets may create invalid transactions
266+
**Mitigation**:
267+
- Implement grace period with warnings
268+
- Provide clear error messages
269+
- Update wallet software first
270+
271+
### Issue 3: Exchange Integration
272+
**Problem**: Exchanges may have hardcoded fee logic
273+
**Mitigation**:
274+
- Provide advance notice
275+
- Offer integration support
276+
- Consider phased rollout
277+
278+
### Issue 4: Smart Contract/Script Transactions
279+
**Problem**: Complex transactions may be disproportionately affected
280+
**Mitigation**: Monitor and adjust rates based on actual usage
281+
282+
## Conclusion
283+
284+
The current DigiByte v8.26 fee structure allows transactions to pay less than the required 0.1 DGB minimum, creating spam vulnerability. The recommended solution is a hybrid approach that enforces both:
285+
286+
1. **Absolute minimum**: 0.1 DGB per transaction
287+
2. **Rate-based fees**: For larger transactions
288+
289+
This approach provides spam protection while maintaining fairness for legitimate large transactions. Implementation should be gradual with extensive testing and clear communication to the ecosystem.
290+
291+
## Appendix: Quick Reference
292+
293+
### Current State
294+
- Small TX (250 bytes) pays: **0.025 DGB**
295+
- Medium TX (1000 bytes) pays: **0.1 DGB**
296+
- Large TX (10000 bytes) pays: **1.0 DGB**
297+
298+
### After Implementation
299+
- Small TX (250 bytes) pays: **0.1 DGB**
300+
- Medium TX (1000 bytes) pays: **0.1 DGB**
301+
- Large TX (10000 bytes) pays: **1.0 DGB**
302+
303+
### Key Files to Modify
304+
1. `src/policy/policy.h` - Add `ABSOLUTE_MIN_TX_FEE`
305+
2. `src/wallet/fees.cpp` - Enforce in `GetMinimumFee()`
306+
3. `src/validation.cpp` - Enforce in `CheckFeeRate()`
307+
4. 15+ test files - Update expectations
308+
309+
### Testing Command
310+
```bash
311+
# Run all fee-related tests after changes
312+
./test/functional/test_runner.py --extended feature_fee wallet_fee mempool_fee
313+
```

0 commit comments

Comments
 (0)