| 2785 | } |
| 2786 | |
| 2787 | bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl* coinControl, AvailableCoinsType coin_type, bool useIX, CAmount nFeePay, CAmount nGasFee, bool sign) |
| 2788 | { |
| 2789 | # if defined(DEBUG_DUMP_STAKING_INFO) && defined(DEBUG_DUMP_CreateTransaction_1) |
| 2790 | DEBUG_DUMP_CreateTransaction_1(); |
| 2791 | # endif |
| 2792 | |
| 2793 | if (useIX && nFeePay < CENT) nFeePay = CENT; |
| 2794 | |
| 2795 | CAmount nValue = 0; |
| 2796 | int nChangePosRequest = nChangePosInOut; |
| 2797 | unsigned int nSubtractFeeFromAmount = 0; |
| 2798 | |
| 2799 | for (const auto& recipient : vecSend) |
| 2800 | { |
| 2801 | if (nValue < 0 || recipient.nAmount < 0) |
| 2802 | { |
| 2803 | strFailReason = _("Transaction amounts must be positive"); |
| 2804 | return false; |
| 2805 | } |
| 2806 | nValue += recipient.nAmount; |
| 2807 | |
| 2808 | if (recipient.fSubtractFeeFromAmount) |
| 2809 | nSubtractFeeFromAmount++; |
| 2810 | } |
| 2811 | if (vecSend.empty()) |
| 2812 | { |
| 2813 | strFailReason = _("Transaction must have at least one recipient"); |
| 2814 | return false; |
| 2815 | } |
| 2816 | |
| 2817 | wtxNew.fTimeReceivedIsTxTime = true; |
| 2818 | wtxNew.BindWallet(this); |
| 2819 | CMutableTransaction txNew; |
| 2820 | |
| 2821 | // Discourage fee sniping. |
| 2822 | // |
| 2823 | // For a large miner the value of the transactions in the best block and |
| 2824 | // the mempool can exceed the cost of deliberately attempting to mine two |
| 2825 | // blocks to orphan the current best block. By setting nLockTime such that |
| 2826 | // only the next block can include the transaction, we discourage this |
| 2827 | // practice as the height restricted and limited blocksize gives miners |
| 2828 | // considering fee sniping fewer options for pulling off this attack. |
| 2829 | // |
| 2830 | // A simple way to think about this is from the wallet's point of view we |
| 2831 | // always want the blockchain to move forward. By setting nLockTime this |
| 2832 | // way we're basically making the statement that we only want this |
| 2833 | // transaction to appear in the next block; we don't want to potentially |
| 2834 | // encourage reorgs by allowing transactions to appear at lower heights |
| 2835 | // than the next block in forks of the best chain. |
| 2836 | // |
| 2837 | // Of course, the subsidy is high enough, and transaction volume low |
| 2838 | // enough, that fee sniping isn't a problem yet, but by implementing a fix |
| 2839 | // now we ensure code won't be written that makes assumptions about |
| 2840 | // nLockTime that preclude a fix later. |
| 2841 | txNew.nLockTime = chainActive.Height(); |
| 2842 | |
| 2843 | { |
| 2844 | LOCK2(cs_main, cs_wallet); |
no test coverage detected