diff --git a/src/stakeinput.cpp b/src/stakeinput.cpp index 0a77332fe374..aa4acd6678f4 100644 --- a/src/stakeinput.cpp +++ b/src/stakeinput.cpp @@ -227,7 +227,8 @@ bool CPivStake::CreateTxOuts(CWallet* pwallet, std::vector& vout, CAmoun vout.emplace_back(CTxOut(0, scriptPubKey)); // Calculate if we need to split the output - int nSplit = nTotal / (static_cast(pwallet->nStakeSplitThreshold * COIN)); + int nSplitThreshold = GetBlockValue(chainActive.Height()) > pwallet->nStakeSplitThreshold * COIN ? GetBlockValue(chainActive.Height()) : pwallet->nStakeSplitThreshold * COIN; + int nSplit = nTotal / (static_cast(nSplitThreshold)); if (nSplit > 1) { // if nTotal is twice or more of the threshold; create more outputs int txSizeMax = MAX_STANDARD_TX_SIZE >> 11; // limit splits to <10% of the max TX size (/2048) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 247341090b80..fb9d4d37eebf 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2691,12 +2691,14 @@ bool CWallet::CreateCoinStake( // Calculate reward CAmount nReward; + CAmount nMasternodeReward; nReward = GetBlockValue(chainActive.Height() + 1); + nMasternodeReward = GetMasternodePayment(chainActive.Height() + 1 , nReward, 0, false); nCredit += nReward; // Create the output transaction(s) std::vector vout; - if (!stakeInput->CreateTxOuts(this, vout, nCredit)) { + if (!stakeInput->CreateTxOuts(this, vout, nCredit - nMasternodeReward)) { LogPrintf("%s : failed to create output\n", __func__); continue; } @@ -3810,7 +3812,11 @@ bool CWallet::MultiSend() COutPoint outpoint(out.tx->GetHash(), out.i); bool sendMSonMNReward = fMultiSendMasternodeReward && outpoint.IsMasternodeReward(out.tx); - bool sendMSOnStake = fMultiSendStake && out.tx->IsCoinStake() && !sendMSonMNReward; //output is either mnreward or stake reward, not both + bool sendMSOnStake = fMultiSendStake && out.tx->IsCoinStake() && !outpoint.IsMasternodeReward(out.tx); + + // Don't send multiple multisend transactions after UTXO split + if (sendMSOnStake && stakeSent) + continue; if (!(sendMSOnStake || sendMSonMNReward)) continue; @@ -3845,9 +3851,23 @@ bool CWallet::MultiSend() // loop through multisend vector and add amounts and addresses to the sending vector const isminefilter filter = ISMINE_SPENDABLE; CAmount nAmount = 0; + CAmount nMultiSendAmount = out.tx->GetCredit(filter) - out.tx->GetDebit(filter); + CAmount blockValue = GetBlockValue(chainActive.Height() - Params().COINBASE_MATURITY()); + CAmount masternodePayment = GetMasternodePayment(chainActive.Height() - Params().COINBASE_MATURITY(), blockValue, 0, false); + + // remove relevant portion of reward where we win entire block reward but only have partial multisend active + if (nMultiSendAmount == blockValue) { + if (!fMultiSendMasternodeReward) { + nMultiSendAmount -= masternodePayment; + } + if (!fMultiSendStake) { + nMultiSendAmount -= (blockValue - masternodePayment); + } + } + for (unsigned int i = 0; i < vMultiSend.size(); i++) { // MultiSend vector is a pair of 1)Address as a std::string 2) Percent of stake to send as an int - nAmount = ((out.tx->GetCredit(filter) - out.tx->GetDebit(filter)) * vMultiSend[i].second) / 100; + nAmount = (nMultiSendAmount * vMultiSend[i].second) / 100; CBitcoinAddress strAddSend(vMultiSend[i].first); CScript scriptPubKey; scriptPubKey = GetScriptForDestination(strAddSend.Get()); @@ -3886,7 +3906,10 @@ bool CWallet::MultiSend() LogPrintf("MultiSend successfully sent\n"); //set which MultiSend triggered - if (sendMSOnStake) + if (fMultiSendNotify && nMultiSendAmount == blockValue) { + stakeSent = true; + mnSent = true; + } else if (sendMSOnStake) stakeSent = true; else mnSent = true;