Skip to content

Commit 9e20435

Browse files
JohnnyLawDGBclaude
andcommitted
fix: mint UTXO consolidation sweep entire balance with subtractfee
The previous consolidation logic calculated a target of collateral + 10% margin + 0.1 DGB, then checked if total balance exceeded that target. When the margin pushed the target above the available balance (e.g., 250K collateral + 10% = 275K > 274K available), the consolidation rejected with "Insufficient funds" even though enough DGB existed. Fix: sweep the entire wallet balance to self using subtractfeefromamount, which always succeeds and consolidates all UTXOs into one output. The fee check now only verifies that collateral + 0.2 DGB fees < total balance (the actual minimum needed). Tested: wallet with 500 UTXOs of 500 DGB each (250K total) where the top 400 UTXOs sum to only 221K — below the 250K collateral requirement. Previous code threw "Insufficient funds"; fix correctly consolidates and retries. Supersedes PR DigiByte-Core#391 consolidation logic. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6d8cbef commit 9e20435

1 file changed

Lines changed: 14 additions & 13 deletions

File tree

src/rpc/digidollar.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -983,24 +983,24 @@ RPCHelpMan mintdigidollar()
983983
LogPrintf("DigiDollar RPC Mint: UTXO fragmentation detected (%zu UTXOs). Auto-consolidating...\n",
984984
availableUtxos.size());
985985

986-
// Calculate consolidation target: collateral + fees + 10% margin
987-
CAmount consolidationTarget = result.collateralRequired +
988-
(result.collateralRequired / 10) + 10000000; // +10% + 0.1 DGB fee buffer
989-
990-
// Cap at available balance
986+
// Check if total balance covers collateral (ignore margin — the
987+
// consolidation itself reduces input count, not total value)
991988
CAmount totalAvailable = 0;
992989
for (const auto& [outpoint, value] : utxoValues) {
993990
totalAvailable += value;
994991
}
995-
if (consolidationTarget > totalAvailable) {
992+
// Need collateral + estimated fees (~0.2 DGB buffer)
993+
CAmount minRequired = result.collateralRequired + 20000000;
994+
if (totalAvailable < minRequired) {
996995
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS,
997-
strprintf("Insufficient funds for collateral. Need %.2f DGB, have %.2f DGB across %zu small UTXOs.",
996+
strprintf("Insufficient funds for collateral. Need %.2f DGB, have %.2f DGB.",
998997
result.collateralRequired / 100000000.0,
999-
totalAvailable / 100000000.0,
1000-
availableUtxos.size()));
998+
totalAvailable / 100000000.0));
1001999
}
10021000

1003-
// Create consolidation transaction using wallet's standard coin selection
1001+
// Consolidate: send-to-self sweeping as many UTXOs as possible
1002+
// into one large output. Use subtractfeefromamount so the
1003+
// consolidation always succeeds regardless of margin.
10041004
CTxDestination consolidationDest;
10051005
{
10061006
LOCK(pwallet->cs_wallet);
@@ -1011,8 +1011,9 @@ RPCHelpMan mintdigidollar()
10111011
consolidationDest = *op_dest;
10121012
}
10131013

1014+
// Send entire balance to self, fee subtracted from amount
10141015
wallet::CCoinControl coin_control;
1015-
wallet::CRecipient recipient{consolidationDest, consolidationTarget, false};
1016+
wallet::CRecipient recipient{consolidationDest, totalAvailable, /*subtract_fee=*/true};
10161017
std::vector<wallet::CRecipient> recipients = {recipient};
10171018

10181019
auto consolidation_result = wallet::CreateTransaction(*pwallet, recipients, /*change_pos=*/-1, coin_control, /*sign=*/true);
@@ -1030,8 +1031,8 @@ RPCHelpMan mintdigidollar()
10301031
pwallet->CommitTransaction(consolidation_tx, {}, {});
10311032
}
10321033

1033-
LogPrintf("DigiDollar RPC Mint: Consolidation tx broadcast: %s (%.2f DGB)\n",
1034-
consolidation_txid, consolidationTarget / 100000000.0);
1034+
LogPrintf("DigiDollar RPC Mint: Consolidation tx broadcast: %s (swept %.2f DGB)\n",
1035+
consolidation_txid, totalAvailable / 100000000.0);
10351036

10361037
// Re-gather UTXOs (now includes unconfirmed consolidation output)
10371038
availableUtxos.clear();

0 commit comments

Comments
 (0)