diff options
| -rw-r--r-- | src/auxpow.cpp | 4 | ||||
| -rw-r--r-- | src/chainparams.cpp | 7 | ||||
| -rw-r--r-- | src/consensus/consensus.h | 6 | ||||
| -rw-r--r-- | src/consensus/params.h | 1 | ||||
| -rw-r--r-- | src/dogecoin.cpp | 13 | ||||
| -rw-r--r-- | src/dogecoin.h | 2 | ||||
| -rw-r--r-- | src/main.cpp | 12 | ||||
| -rw-r--r-- | src/qt/coincontroldialog.cpp | 2 | ||||
| -rw-r--r-- | src/qt/sendcoinsdialog.cpp | 2 | ||||
| -rw-r--r-- | src/qt/transactiondesc.cpp | 5 | ||||
| -rw-r--r-- | src/qt/walletmodel.cpp | 4 | ||||
| -rw-r--r-- | src/test/script_P2SH_tests.cpp | 4 | ||||
| -rw-r--r-- | src/test/transaction_tests.cpp | 2 | ||||
| -rw-r--r-- | src/txmempool.cpp | 4 | ||||
| -rw-r--r-- | src/wallet/test/wallet_tests.cpp | 36 | ||||
| -rw-r--r-- | src/wallet/wallet.cpp | 18 | ||||
| -rw-r--r-- | src/wallet/wallet.h | 6 |
17 files changed, 95 insertions, 33 deletions
diff --git a/src/auxpow.cpp b/src/auxpow.cpp index 3c350a67a..7356d0202 100644 --- a/src/auxpow.cpp +++ b/src/auxpow.cpp @@ -7,6 +7,7 @@ #include "auxpow.h" +#include "chainparams.h" #include "consensus/validation.h" #include "main.h" #include "script/script.h" @@ -89,7 +90,8 @@ int CMerkleTx::GetBlocksToMaturity() const { if (!IsCoinBase()) return 0; - return std::max(0, (COINBASE_MATURITY + 1) - GetDepthInMainChain()); + int nCoinbaseMaturity = Params().GetConsensus(chainActive.Height()).nCoinbaseMaturity; + return std::max(0, (nCoinbaseMaturity + 1) - GetDepthInMainChain()); } diff --git a/src/chainparams.cpp b/src/chainparams.cpp index d1796decc..0b72eef86 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -51,6 +51,7 @@ public: consensus.fAllowLegacyBlocks = true; consensus.nHeightEffective = 0; consensus.fDigishieldDifficultyCalculation = false; + consensus.nCoinbaseMaturity = 30; // Blocks 145000 - 371336 are Digishield without AuxPoW digishieldConsensus = consensus; @@ -58,6 +59,7 @@ public: digishieldConsensus.fSimplifiedRewards = true; digishieldConsensus.fDigishieldDifficultyCalculation = true; digishieldConsensus.nPowTargetTimespan = 60; // post-digishield: 1 minute + digishieldConsensus.nCoinbaseMaturity = 240; // Blocks 371337+ are AuxPoW auxpowConsensus = digishieldConsensus; @@ -197,6 +199,7 @@ public: digishieldConsensus.fDigishieldDifficultyCalculation = true; digishieldConsensus.fSimplifiedRewards = true; digishieldConsensus.fPowAllowMinDifficultyBlocks = false; + digishieldConsensus.nCoinbaseMaturity = 240; // Blocks 157500 - 158099 are Digishield with minimum difficulty on all blocks minDifficultyConsensus = digishieldConsensus; @@ -279,9 +282,11 @@ public: consensus.nMajorityRejectBlockOutdated = 950; consensus.nMajorityWindow = 1000; consensus.nPowTargetTimespan = 4 * 60 * 60; // pre-digishield: 4 hours + consensus.nPowTargetSpacing = 1; // regtest: 1 second blocks consensus.powLimit = uint256S("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 1; consensus.fStrictChainId = true; consensus.fAllowLegacyBlocks = false; // Never allow legacy blocks on RegTest + consensus.fSimplifiedRewards = true; // Reset links before we copy parameters consensus.pLeft = NULL; @@ -289,7 +294,7 @@ public: digishieldConsensus = consensus; digishieldConsensus.nHeightEffective = 10; - digishieldConsensus.nPowTargetTimespan = 60; // post-digishield: 1 minute + digishieldConsensus.nPowTargetTimespan = 1; // // regtest: also retarget every second in digishield mode, for conformity digishieldConsensus.fDigishieldDifficultyCalculation = true; auxpowConsensus = digishieldConsensus; diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 1bf388bef..414c509fa 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -10,12 +10,6 @@ static const unsigned int MAX_BLOCK_SIZE = 1000000; /** The maximum allowed number of signature check operations in a block (network rule) */ static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; -/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ -static const int COINBASE_MATURITY = 60*4; // 4 hours of blocks -/** Coinbase maturity before block 145000 **/ -static const int COINBASE_MATURITY_OLD = 30; -/** Block at which COINBASE_MATURITY_OLD was deprecated **/ -static const int COINBASE_MATURITY_SWITCH = 145000; /** Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. */ static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC diff --git a/src/consensus/params.h b/src/consensus/params.h index 906599ff4..45c0bde5f 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -19,6 +19,7 @@ struct Params { int nMajorityEnforceBlockUpgrade; int nMajorityRejectBlockOutdated; int nMajorityWindow; + int nCoinbaseMaturity; /** Proof of work parameters */ uint256 powLimit; bool fPowAllowMinDifficultyBlocks; diff --git a/src/dogecoin.cpp b/src/dogecoin.cpp index 90eaec9ec..0321a6527 100644 --- a/src/dogecoin.cpp +++ b/src/dogecoin.cpp @@ -7,6 +7,7 @@ #include "arith_uint256.h" #include "dogecoin.h" +#include "main.h" #include "util.h" int static generateMTRandom(unsigned int s, int range) @@ -144,3 +145,15 @@ CAmount GetDogecoinBlockSubsidy(int nHeight, const Consensus::Params& consensusP return 10000 * COIN; } } + + +int64_t GetDogecoinDustFee(const std::vector<CTxOut> &vout, CFeeRate &baseFeeRate) { + int64_t nFee = 0; + + // To limit dust spam, add base fee for each output less than DUST_SOFT_LIMIT + BOOST_FOREACH(const CTxOut& txout, vout) + if (txout.IsDust(::minRelayTxFee)) + nFee += baseFeeRate.GetFeePerK(); + + return nFee; +} diff --git a/src/dogecoin.h b/src/dogecoin.h index e466d1e98..40766fe36 100644 --- a/src/dogecoin.h +++ b/src/dogecoin.h @@ -17,3 +17,5 @@ unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex* pindexLast, in * @return True iff the PoW is correct. */ bool CheckAuxPowProofOfWork(const CBlockHeader& block, const Consensus::Params& params); + +int64_t GetDogecoinDustFee(const std::vector<CTxOut> &vout, CFeeRate &baseFeeRate); diff --git a/src/main.cpp b/src/main.cpp index b42638096..a3d5dcc30 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -66,7 +66,7 @@ uint64_t nPruneTarget = 0; bool fAlerts = DEFAULT_ALERTS; /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */ -CFeeRate minRelayTxFee = CFeeRate(1000); +CFeeRate minRelayTxFee = CFeeRate(COIN); CTxMemPool mempool(::minRelayTxFee); @@ -868,8 +868,10 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF } CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes); + nMinFee += GetDogecoinDustFee(tx.vout, ::minRelayTxFee); - if (fAllowFree) + // Dogecoin: Disable free transactions + /* if (fAllowFree) { // There is a free transaction area in blocks created by most miners, // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000 @@ -877,7 +879,7 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF // multiple transactions instead of one big transaction to avoid fees. if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000)) nMinFee = 0; - } + } */ if (!MoneyRange(nMinFee)) nMinFee = MAX_MONEY; @@ -1446,9 +1448,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // If prev is coinbase, check that it's matured if (coins->IsCoinBase()) { // Dogecoin: Switch maturity at depth 145,000 - int nCoinbaseMaturity = coins->nHeight < COINBASE_MATURITY_SWITCH - ? COINBASE_MATURITY_OLD - : COINBASE_MATURITY; + int nCoinbaseMaturity = Params().GetConsensus(coins->nHeight).nCoinbaseMaturity; if (nSpendHeight - coins->nHeight < nCoinbaseMaturity) return state.Invalid( error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight), diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 7531fbddc..e2679958f 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -548,7 +548,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) nBytes -= 34; // Fee - nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool); + nPayFee = CWallet::GetMinimumFee(txDummy, nBytes, nTxConfirmTarget, mempool); // Allow free? double dPriorityNeeded = mempoolEstimatePriority; diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 3d5771156..2f3c2eba1 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -528,7 +528,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn msgParams.second = CClientUIInterface::MSG_ERROR; break; case WalletModel::AbsurdFee: - msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000)); + msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 100 * COIN)); break; case WalletModel::PaymentRequestExpired: msgParams.first = tr("Payment request expired."); diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 5662b1665..aab31f1c1 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -10,6 +10,7 @@ #include "transactionrecord.h" #include "base58.h" +#include "chainparams.h" #include "consensus/consensus.h" #include "main.h" #include "script/script.h" @@ -264,8 +265,8 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco if (wtx.IsCoinBase()) { - quint32 numBlocksToMaturity = COINBASE_MATURITY + 1; - strHTML += "<br>" + tr("Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.").arg(QString::number(numBlocksToMaturity)) + "<br>"; + quint32 nCoinbaseMaturity = Params().GetConsensus(chainActive.Height()).nCoinbaseMaturity + 1; + strHTML += "<br>" + tr("Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.").arg(QString::number(nCoinbaseMaturity)) + "<br>"; } // diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 9b8be76be..852913fc6 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -290,8 +290,8 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact return TransactionCreationFailed; } - // reject absurdly high fee > 0.1 bitcoin - if (nFeeRequired > 10000000) + // reject absurdly high fee > 100 DOGE + if (nFeeRequired > (100 * COIN)) return AbsurdFee; } diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index c8cfe2872..51bf47c9d 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -184,7 +184,7 @@ BOOST_AUTO_TEST_CASE(set) for (int i = 0; i < 4; i++) { txFrom.vout[i].scriptPubKey = outer[i]; - txFrom.vout[i].nValue = CENT; + txFrom.vout[i].nValue = COIN; } BOOST_CHECK(IsStandardTx(txFrom, reason)); @@ -195,7 +195,7 @@ BOOST_AUTO_TEST_CASE(set) txTo[i].vout.resize(1); txTo[i].vin[0].prevout.n = i; txTo[i].vin[0].prevout.hash = txFrom.GetHash(); - txTo[i].vout[0].nValue = 1*CENT; + txTo[i].vout[0].nValue = 1*COIN; txTo[i].vout[0].scriptPubKey = inner[i]; #ifdef ENABLE_WALLET BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index d12535e43..7f7133793 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -343,7 +343,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) t.vout[0].nValue = 501; // dust BOOST_CHECK(!IsStandardTx(t, reason)); - t.vout[0].nValue = 601; // not dust + t.vout[0].nValue = COIN; // not dust BOOST_CHECK(IsStandardTx(t, reason)); t.vout[0].scriptPubKey = CScript() << OP_1; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 1c16e2092..1502cc6d2 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -5,6 +5,7 @@ #include "txmempool.h" +#include "chainparams.h" #include "clientversion.h" #include "consensus/consensus.h" #include "consensus/validation.h" @@ -166,7 +167,8 @@ void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned in continue; const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); if (fSanityCheck) assert(coins); - if (!coins || (coins->IsCoinBase() && nMemPoolHeight - coins->nHeight < COINBASE_MATURITY)) { + int nCoinbaseMaturity = Params().GetConsensus(coins->nHeight).nCoinbaseMaturity; + if (!coins || (coins->IsCoinBase() && nMemPoolHeight - coins->nHeight < nCoinbaseMaturity)) { transactionsToRemove.push_back(tx); break; } diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index a5bc52b8d..af687462a 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "txmempool.h" #include "wallet/wallet.h" #include <set> @@ -307,4 +308,39 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) empty_wallet(); } +BOOST_AUTO_TEST_CASE(GetMinimumFee_test) +{ + uint64_t value = 1000 * COIN; // 1,000 DOGE + + CMutableTransaction tx; + CTxMemPool pool(payTxFee); + CTxOut txout1(value, (CScript)vector<unsigned char>(24, 0)); + tx.vout.push_back(txout1); + + int64_t nMinTxFee = COIN; + + BOOST_CHECK_EQUAL(CWallet::GetMinimumFee(tx, 250, 0, pool), nMinTxFee); + BOOST_CHECK_EQUAL(CWallet::GetMinimumFee(tx, 1000, 0, pool), 2 * nMinTxFee); + BOOST_CHECK_EQUAL(CWallet::GetMinimumFee(tx, 1999, 0, pool), 2 * nMinTxFee); +} + +BOOST_AUTO_TEST_CASE(GetMinimumFee_dust_test) +{ + // Derived from main net TX 3d6ec3ae2aca3ae0a6c65074fd8ee888cd7ed262f2cbaa25d33861989324a14e + CMutableTransaction tx; + CTxMemPool pool(payTxFee); + CTxOut txout1(139496846, (CScript)vector<unsigned char>(24, 0)); // Regular output + CTxOut txout2(15499649, (CScript)vector<unsigned char>(24, 0)); // Dust output + tx.vout.push_back(txout1); + tx.vout.push_back(txout2); + + int64_t nMinTxFee = COIN; + + // Confirm dust penalty fees are added on + + BOOST_CHECK_EQUAL(CWallet::GetMinimumFee(tx, 963, 0, pool), 2 * nMinTxFee); + BOOST_CHECK_EQUAL(CWallet::GetMinimumFee(tx, 1000, 0, pool), 3 * nMinTxFee); + BOOST_CHECK_EQUAL(CWallet::GetMinimumFee(tx, 1999, 0, pool), 3 * nMinTxFee); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index c4562badd..98d01978c 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -10,6 +10,7 @@ #include "coincontrol.h" #include "consensus/consensus.h" #include "consensus/validation.h" +#include "dogecoin.h" #include "main.h" #include "net.h" #include "script/script.h" @@ -40,7 +41,7 @@ bool fPayAtLeastCustomFee = true; * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) * Override with -mintxfee */ -CFeeRate CWallet::minTxFee = CFeeRate(1000); +CFeeRate CWallet::minTxFee = CFeeRate(COIN); /** @defgroup mapWallet * @@ -1935,7 +1936,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, break; } - CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool); + CAmount nFeeNeeded = GetMinimumFee(txNew, nBytes, nTxConfirmTarget, mempool); // If we made it here and we aren't even able to meet the relay fee on the next pass, give up // because we must be at the maximum allowed fee. @@ -2010,8 +2011,12 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) return true; } -CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool) +CAmount CWallet::GetMinimumFee(const CMutableTransaction& tx, unsigned int nTxBytes, + unsigned int nConfirmTarget, const CTxMemPool& pool) { + // Dogecoin: Round TX bytes up to the next 1,000 bytes + nTxBytes += 1000 - (nTxBytes % 1000); + // payTxFee is user-set "I want to pay this much" CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes); // user selected total at least (default=true) @@ -2022,8 +2027,11 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes); // ... unless we don't have enough mempool data, in which case fall // back to a hard-coded fee - if (nFeeNeeded == 0) + if (nFeeNeeded == 0) { nFeeNeeded = minTxFee.GetFee(nTxBytes); + // Dogecoin: Add an increased fee for each dust output + nFeeNeeded += GetDogecoinDustFee(tx.vout, minTxFee); + } // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes)) nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes); @@ -2034,8 +2042,6 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge } - - DBErrors CWallet::LoadWallet(bool& fFirstRunRet) { if (!fFileBacked) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index e1ce6f795..8fcb09b40 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -42,9 +42,9 @@ extern bool fPayAtLeastCustomFee; //! -paytxfee default static const CAmount DEFAULT_TRANSACTION_FEE = 0; //! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB -static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; +static const CAmount nHighTransactionFeeWarning = 10 * COIN; //! -maxtxfee default -static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; +static const CAmount DEFAULT_TRANSACTION_MAXFEE = 100 * COIN; //! -txconfirmtarget default static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; //! -maxtxfee will warn if called with a higher fee than this amount (in satoshis) @@ -573,7 +573,7 @@ public: bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); static CFeeRate minTxFee; - static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool); + static CAmount GetMinimumFee(const CMutableTransaction& tx, unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool); bool NewKeyPool(); bool TopUpKeyPool(unsigned int kpSize = 0); |