diff --git a/Linda-qt.pro b/Linda-qt.pro index eb80350..da2d04e 100644 --- a/Linda-qt.pro +++ b/Linda-qt.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = Linda-qt -VERSION = 1.0.0.0 +VERSION = 2.0.0.0 INCLUDEPATH += src src/json src/qt QT += network DEFINES += ENABLE_WALLET diff --git a/src/activemasternode.cpp b/src/activemasternode.cpp index 4958de2..189ef9e 100644 --- a/src/activemasternode.cpp +++ b/src/activemasternode.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "protocol.h" +#include "main.h" #include "activemasternode.h" #include #include "clientversion.h" @@ -362,6 +363,10 @@ bool CActiveMasternode::GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubke // get all possible outputs for running masternode vector CActiveMasternode::SelectCoinsMasternode() { + // MBK: Process V2 masternode coing selection + if(CURRENT_WALLET_VERSION == 2) + return SelectCoinsMasternodeV2(); + vector vCoins; vector filteredCoins; @@ -371,13 +376,58 @@ vector CActiveMasternode::SelectCoinsMasternode() // Filter BOOST_FOREACH(const COutput& out, vCoins) { - if(out.tx->vout[out.i].nValue == 30000000*COIN) { //exactly + // MBK: Replaced the value with the global collateral constant + if(out.tx->vout[out.i].nValue == MASTERNODE_COLLATERAL_V1) + { filteredCoins.push_back(out); } + } + return filteredCoins; } +// MBK: Process masternode coin selection for V2 wallet +vector CActiveMasternode::SelectCoinsMasternodeV2() +{ + vector vCoins; + vector filteredCoins; + + // Retrieve all possible outputs + pwalletMain->AvailableCoins(vCoins); + + // Filter + BOOST_FOREACH(const COutput& out, vCoins) + { + if(nBestHeight < MASTERNODE_V2_START_BLOCK) + { + // MBK: Have note reached blockheight to swap 2m/30m masternode activation (this may change in the future) + if(out.tx->vout[out.i].nValue == MASTERNODE_COLLATERAL_V1) + { + filteredCoins.push_back(out); + } + + } + else if(nBestHeight >= MASTERNODE_V2_STOP_BLOCK) + { + // MBK: Have reached the blockheight when masternodes no longer activate (this may change in the future) + LogPrintf("CActiveMasternode::SelectCoinsMasternodeV2() -> Cannot select coins, Masternode activation has ended."); + return filteredCoins; + } + else + { + // MBK: Have reached the blockheight when swap to 2m masternode activation starts + if(out.tx->vout[out.i].nValue == MASTERNODE_COLLATERAL_V2) + { + filteredCoins.push_back(out); + } + + } + + } + + return filteredCoins; +} /* select coins with specified transaction hash and output index */ /* diff --git a/src/activemasternode.h b/src/activemasternode.h index 958e86a..a48b0e7 100644 --- a/src/activemasternode.h +++ b/src/activemasternode.h @@ -51,6 +51,9 @@ class CActiveMasternode bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey); bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex); vector SelectCoinsMasternode(); + // MBK: V2 function prototype + vector SelectCoinsMasternodeV2(); + bool GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey); //bool SelectCoinsMasternode(CTxIn& vin, int64& nValueIn, CScript& pubScript, std::string strTxHash, std::string strOutputIndex); diff --git a/src/clientversion.h b/src/clientversion.h index f4f8583..582a017 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -6,10 +6,10 @@ // // These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it -#define CLIENT_VERSION_MAJOR 1 +#define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 -#define CLIENT_VERSION_REVISION 1 -#define CLIENT_VERSION_BUILD 3 +#define CLIENT_VERSION_REVISION 0 +#define CLIENT_VERSION_BUILD 0 // Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true diff --git a/src/darksend.cpp b/src/darksend.cpp index c564d4b..1c9831c 100644 --- a/src/darksend.cpp +++ b/src/darksend.cpp @@ -283,8 +283,9 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream& missingTx = true; } } - - if (nValueIn > DARKSEND_POOL_MAX) { + + // MBK: Added support for block height darksend fee change + if (nValueIn > (nBestHeight >= DARKSEND_V2_START_BLOCK ? DARKSEND_POOL_MAX_V2 : DARKSEND_POOL_MAX_V1)/*DARKSEND_POOL_MAX*/) { LogPrintf("dsi -- more than darksend pool max! %s\n", tx.ToString().c_str()); error = _("Value more than Darksend pool maximum allows."); pfrom->PushMessage("dssu", darkSendPool.sessionID, darkSendPool.GetState(), darkSendPool.GetEntriesCount(), MASTERNODE_REJECTED, error); @@ -410,7 +411,8 @@ int GetInputDarksendRounds(CTxIn in, int rounds) // bounds check if(in.prevout.n >= tx.vout.size()) return -4; - if(tx.vout[in.prevout.n].nValue == DARKSEND_FEE) return -3; + // MBK: Added support for block height darksend fee change + if(tx.vout[in.prevout.n].nValue == (nBestHeight >= DARKSEND_V2_START_BLOCK ? DARKSEND_FEE_V2 : DARKSEND_FEE_V1)/*DARKSEND_FEE*/) return -3; //make sure the final output is non-denominate if(rounds == 0 && !pwalletMain->IsDenominatedAmount(tx.vout[in.prevout.n].nValue)) return -2; //NOT DENOM @@ -965,7 +967,8 @@ bool CDarkSendPool::IsCollateralValid(const CTransaction& txCollateral){ } //collateral transactions are required to pay out DARKSEND_COLLATERAL as a fee to the miners - if(nValueIn-nValueOut < DARKSEND_COLLATERAL) { + // MBK: Added support for block height darksend fee change + if(nValueIn-nValueOut < (nBestHeight >= DARKSEND_V2_START_BLOCK ? DARKSEND_COLLATERAL_V2 : DARKSEND_COLLATERAL_V1)/*DARKSEND_COLLATERAL*/) { if(fDebug) LogPrintf ("CDarkSendPool::IsCollateralValid - did not include enough fees in transaction %d\n%s\n", nValueOut-nValueIn, txCollateral.ToString().c_str()); return false; } @@ -1395,19 +1398,30 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready) std::vector vCoins2; int64_t nValueMin = CENT; int64_t nValueIn = 0; + + // MBK: Added support for block height darksend fee and collateral change + int64_t nDarkSendFee = DARKSEND_FEE_V1; + int64_t nDarkSendCollateral = DARKSEND_COLLATERAL_V1; + int64_t nDarkSendPoolMax = DARKSEND_POOL_MAX_V1; + if(nBestHeight >= DARKSEND_V2_START_BLOCK) + { + nDarkSendFee = DARKSEND_FEE_V2; + nDarkSendCollateral = DARKSEND_COLLATERAL_V2; + nDarkSendPoolMax = DARKSEND_POOL_MAX_V2; + } // should not be less than fees in DARKSEND_FEE + few (lets say 5) smallest denoms - int64_t nLowestDenom = DARKSEND_FEE + darkSendDenominations[darkSendDenominations.size() - 1]*5; + int64_t nLowestDenom = nDarkSendFee/*DARKSEND_FEE*/ + darkSendDenominations[darkSendDenominations.size() - 1]*5; // if there are no DS collateral inputs yet if(!pwalletMain->HasCollateralInputs()) // should have some additional amount for them - nLowestDenom += (DARKSEND_COLLATERAL*4)+DARKSEND_FEE*2; + nLowestDenom += (nDarkSendCollateral/*DARKSEND_COLLATERAL*/*4)+nDarkSendFee/*DARKSEND_FEE*/*2; int64_t nBalanceNeedsAnonymized = nAnonymizeLindaAmount*COIN - pwalletMain->GetAnonymizedBalance(); // if balanceNeedsAnonymized is more than pool max, take the pool max - if(nBalanceNeedsAnonymized > DARKSEND_POOL_MAX) nBalanceNeedsAnonymized = DARKSEND_POOL_MAX; + if(nBalanceNeedsAnonymized > nDarkSendPoolMax/*DARKSEND_POOL_MAX*/) nBalanceNeedsAnonymized = nDarkSendPoolMax/*DARKSEND_POOL_MAX*/; // if balanceNeedsAnonymized is more than non-anonymized, take non-anonymized int64_t nBalanceNotYetAnonymized = pwalletMain->GetBalance() - pwalletMain->GetAnonymizedBalance(); @@ -1677,8 +1691,17 @@ bool CDarkSendPool::MakeCollateralAmounts() std::string strFail = ""; vector< pair > vecSend; - vecSend.push_back(make_pair(scriptChange, (DARKSEND_COLLATERAL*2)+DARKSEND_FEE)); - vecSend.push_back(make_pair(scriptChange, (DARKSEND_COLLATERAL*2)+DARKSEND_FEE)); + // MBK: Added support for block height darksend fee and collateral change + int64_t nDarkSendFee = DARKSEND_FEE_V1; + int64_t nDarkSendCollateral = DARKSEND_COLLATERAL_V1; + if(nBestHeight >= DARKSEND_V2_START_BLOCK) + { + nDarkSendFee = DARKSEND_FEE_V2; + nDarkSendCollateral = DARKSEND_COLLATERAL_V2; + } + + vecSend.push_back(make_pair(scriptChange, (nDarkSendCollateral/*DARKSEND_COLLATERAL*/*2)+nDarkSendFee/*DARKSEND_FEE*/)); + vecSend.push_back(make_pair(scriptChange, (nDarkSendCollateral/*DARKSEND_COLLATERAL*/*2)+nDarkSendFee/*DARKSEND_FEE*/)); CCoinControl *coinControl=NULL; int32_t nChangePos; @@ -1722,12 +1745,21 @@ bool CDarkSendPool::CreateDenominated(int64_t nTotalValue) vector< pair > vecSend; int64_t nValueLeft = nTotalValue; + // MBK: Added support for block height darksend fee and collateral change + int64_t nDarkSendFee = DARKSEND_FEE_V1; + int64_t nDarkSendCollateral = DARKSEND_COLLATERAL_V1; + if(nBestHeight >= DARKSEND_V2_START_BLOCK) + { + nDarkSendFee = DARKSEND_FEE_V2; + nDarkSendCollateral = DARKSEND_COLLATERAL_V2; + } + // ****** Add collateral outputs ************ / if(!pwalletMain->HasCollateralInputs()) { - vecSend.push_back(make_pair(scriptChange, (DARKSEND_COLLATERAL*2)+DARKSEND_FEE)); - nValueLeft -= (DARKSEND_COLLATERAL*2)+DARKSEND_FEE; - vecSend.push_back(make_pair(scriptChange, (DARKSEND_COLLATERAL*2)+DARKSEND_FEE)); - nValueLeft -= (DARKSEND_COLLATERAL*2)+DARKSEND_FEE; + vecSend.push_back(make_pair(scriptChange, (nDarkSendCollateral/*DARKSEND_COLLATERAL*/*2)+nDarkSendFee/*DARKSEND_FEE*/)); + nValueLeft -= (nDarkSendCollateral/*DARKSEND_COLLATERAL*/*2)+nDarkSendFee/*DARKSEND_FEE*/; + vecSend.push_back(make_pair(scriptChange, (nDarkSendCollateral/*DARKSEND_COLLATERAL*/*2)+nDarkSendFee/*DARKSEND_FEE*/)); + nValueLeft -= (nDarkSendCollateral/*DARKSEND_COLLATERAL*/*2)+nDarkSendFee/*DARKSEND_FEE*/; } // ****** Add denoms ************ / @@ -1735,7 +1767,7 @@ bool CDarkSendPool::CreateDenominated(int64_t nTotalValue) int nOutputs = 0; // add each output up to 10 times until it can't be added again - while(nValueLeft - v >= DARKSEND_FEE && nOutputs <= 10) { + while(nValueLeft - v >= nDarkSendFee/*DARKSEND_FEE*/ && nOutputs <= 10) { CScript scriptChange; CPubKey vchPubKey; //use a unique change address diff --git a/src/main.cpp b/src/main.cpp index 02192bc..cd153f4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -595,8 +595,21 @@ bool CTransaction::CheckTransaction() const int64_t GetMinFee(const CTransaction& tx, unsigned int nBlockSize, enum GetMinFee_mode mode, unsigned int nBytes) { + + // MBK: Determine the minimum tx fee based on current blockheight + int txMinimumFee = MIN_TX_FEE_V1; + int txMinimumRelayFee = MIN_RELAY_TX_FEE_V1; + // MBK: Support the tx fee increase at blockheight + if(nBestHeight >= TX_FEE_V2_INCREASE_BLOCK) + { + txMinimumFee = MIN_TX_FEE_V2; + txMinimumRelayFee = MIN_RELAY_TX_FEE_V2; + } + // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE - int64_t nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE; + // MBK: Support the tx fee increase at blockheight + //int64_t nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE; + int64_t nBaseFee = (mode == GMF_RELAY) ? txMinimumRelayFee : txMinimumFee; unsigned int nNewBlockSize = nBlockSize + nBytes; int64_t nMinFee = (1 + (int64_t)nBytes / 1000) * nBaseFee; @@ -697,8 +710,9 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool fLimitFree, unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); // Don't accept it if it can't get into a block + // MBK: Support the tx fee increase at blockheight int64_t txMinFee = GetMinFee(tx, 1000, GMF_RELAY, nSize); - if ((fLimitFree && nFees < txMinFee) || (!fLimitFree && nFees < MIN_TX_FEE)) + if ((fLimitFree && nFees < txMinFee) || (!fLimitFree && nFees < (nBestHeight >= TX_FEE_V2_INCREASE_BLOCK ? MIN_TX_FEE_V2 : MIN_TX_FEE_V1))) return error("AcceptToMemoryPool : not enough fees %s, %d < %d", hash.ToString(), nFees, txMinFee); @@ -706,7 +720,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool fLimitFree, // Continuously rate-limit free transactions // This mitigates 'penny-flooding' -- sending thousands of free transactions just to // be annoying or make others' transactions take longer to confirm. - if (fLimitFree && nFees < MIN_RELAY_TX_FEE) + // MBK: Support the tx fee increase at blockheight + if (fLimitFree && nFees < (nBestHeight >= TX_FEE_V2_INCREASE_BLOCK ? MIN_RELAY_TX_FEE_V2 : MIN_RELAY_TX_FEE_V1)) { static CCriticalSection csFreeLimiter; static double dFreeCount; @@ -845,8 +860,9 @@ bool AcceptableInputs(CTxMemPool& pool, const CTransaction &txo, bool fLimitFree unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); // Don't accept it if it can't get into a block + // MBK: Support the tx fee increase at blockheight int64_t txMinFee = GetMinFee(tx, 1000, GMF_RELAY, nSize); - if ((fLimitFree && nFees < txMinFee) || (!fLimitFree && nFees < MIN_TX_FEE)) + if ((fLimitFree && nFees < txMinFee) || (!fLimitFree && nFees < (nBestHeight >= TX_FEE_V2_INCREASE_BLOCK ? MIN_TX_FEE_V2 : MIN_TX_FEE_V1))) return error("AcceptableInputs : not enough fees %s, %d < %d", hash.ToString(), nFees, txMinFee); @@ -854,7 +870,8 @@ bool AcceptableInputs(CTxMemPool& pool, const CTransaction &txo, bool fLimitFree // Continuously rate-limit free transactions // This mitigates 'penny-flooding' -- sending thousands of free transactions just to // be annoying or make others' transactions take longer to confirm. - if (fLimitFree && nFees < MIN_RELAY_TX_FEE) + // MBK: Support the tx fee increase at blockheight + if (fLimitFree && nFees < (nBestHeight >= TX_FEE_V2_INCREASE_BLOCK ? MIN_RELAY_TX_FEE_V2 : MIN_RELAY_TX_FEE_V1)) { static CCriticalSection csFreeLimiter; static double dFreeCount; @@ -1135,7 +1152,7 @@ static CBigNum GetProofOfStakeLimit(int nHeight) int64_t GetProofOfWorkReward(int64_t nFees, unsigned int nHeight) { int64_t nSubsidy = 0; - + if(pindexBest->nHeight < PREMINE_BLOCK) { nSubsidy = 500000000 * COIN; // PREMINE 10 BLOCKS @@ -1154,6 +1171,43 @@ int64_t GetProofOfWorkReward(int64_t nFees, unsigned int nHeight) } LogPrint("creation", "GetProofOfWorkReward() : create=%s nSubsidy=%d\n", FormatMoney(nSubsidy), nSubsidy); + // MBK: Added some additional debugging information + if (MBK_EXTRA_DEBUG) LogPrintf("creation -> GetProofOfWorkReward() : create=%s nSubsidy=%d\n", FormatMoney(nSubsidy), nSubsidy); + + return nSubsidy + nFees; +} + +// miner's coin base reward +// MBK: Update PoW reward structure to reflect reduction to help combat inflation +int64_t GetProofOfWorkRewardV2(int64_t nFees, unsigned int nHeight) +{ + int64_t nSubsidy = 0; + + if(pindexBest->nHeight < POW_REWARD_V2_START_BLOCK) + { + // MBK: PoW reward change starts after wallet release so until then return current V1 reward + nSubsidy = POW_REWARD_V1_FULL * COIN; + } + else if(pindexBest->nHeight >= POW_REWARD_V2_START_BLOCK) + { + // MBK: Have reached blockheight to begin reward PoW reward burn + nSubsidy = POW_REWARD_V2_FULL * COIN; + } + else if(pindexBest->nHeight >= REWARD_HALVE) + { + // MBK: Have reached the blockheight to half PoW reward on blocks + nSubsidy = POW_REWARD_V2_HALF * COIN; + } + else if(pindexBest->nHeight > V2_EMISSION_CAP_START_BLOCK) + { + // MBK: Have reached the blockheight where rewards are finished + nSubsidy = 0; + } + + LogPrint("creation", "GetProofOfWorkRewardV2() : create=%d(%s)\n", nSubsidy, FormatMoney(nSubsidy)); + // MBK: Added some additional debugging information + double percent = ((double)nSubsidy / (double)(POW_REWARD_V1_FULL*COIN)) * (double)100.0f; + if (MBK_EXTRA_DEBUG) LogPrintf("creation -> GetProofOfWorkRewardV2() : create=%d(%s)[%d] nSubsidy=%d\n", nSubsidy, FormatMoney(nSubsidy), percent, nSubsidy); return nSubsidy + nFees; } @@ -1161,13 +1215,50 @@ int64_t GetProofOfWorkReward(int64_t nFees, unsigned int nHeight) // miner's coin stake reward based on coin age spent (coin-days) int64_t GetProofOfStakeReward(int64_t nCoinAge, int64_t nFees, unsigned int nHeight) { - int64_t nSubsidy; - + int64_t nSubsidy = 0; nSubsidy = nCoinAge * COIN_YEAR_REWARD * 33 / (365 * 33 + 8); - LogPrint("creation", "GetProofOfStakeReward(): create=%s nCoinAge=%d\n", FormatMoney(nSubsidy), nCoinAge); + // MBK: Added some additional debugging information + if (MBK_EXTRA_DEBUG) LogPrintf("creation -> GetProofOfStakeReward(): create=%s nCoinAge=%d\n", FormatMoney(nSubsidy), nCoinAge); + + return nSubsidy + nFees; +} + +// miner's coin stake reward based on coin age spent (coin-days) +// MBK: Update PoS reward structure to reflect reduction to help combat inflation +int64_t GetProofOfStakeRewardV2(int64_t nCoinAge, int64_t nFees, unsigned int nHeight) +{ + int64_t nSubsidy = 0; + int64_t nBlockReward = 0; + + nBlockReward = nCoinAge * COIN_YEAR_REWARD_V2 * 33 / (365 * 33 + 8); + // MBK: Burn % of the stake reward to help curb inflation if V2 wallet + if(nHeight >= POS_REWARD_V2_START_BLOCK /*|| CURRENT_WALLET_VERSION == 2*/) + { + if(nHeight >= V2_EMISSION_CAP_START_BLOCK) + { + // MBK: Have reached the blockheight when rewards are finished + nSubsidy = 0; + } + else + { + // MBK: Have reached the blockheight to start the % burn on PoS rewards to help curb inflation + nSubsidy = nBlockReward - (nBlockReward * POS_REWARD_V2_BURN_RATE); + } + } + else + { + // MBK: Have not reached the blockheight to start the PoS reward burn + nSubsidy = nBlockReward; + } + + LogPrint("creation", "GetProofOfStakeRewardV2(): create=%s nCoinAge=%d\n", FormatMoney(nSubsidy), nCoinAge); + // MBK: Added some additional debugging information + double percent = ((double)nSubsidy / (double)nBlockReward) * (double)100.0f; + //if (MBK_EXTRA_DEBUG) LogPrintf("creation -> GetProofOfStakeRewardV2(): nSubsidy=%d preburn=%d(%f)\n", nSubsidy, nBlockReward, percent); + if (MBK_EXTRA_DEBUG) LogPrintf("creation -> GetProofOfStakeRewardV2(): create=%d(%s)[%d] nCoinAge=%d preburn=%d(%s)\n",nSubsidy, FormatMoney(nSubsidy), percent, nCoinAge, nBlockReward, FormatMoney(nBlockReward)); return nSubsidy + nFees; } @@ -1224,8 +1315,8 @@ const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfSta unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) { - // if(pindexLast->GetBlockTime() > STAKE_TIMESPAN_SWITCH_TIME) - //nTargetTimespan = 2 * 60; // 2 minutes + //if(pindexLast->GetBlockTime() > STAKE_TIMESPAN_SWITCH_TIME) + // nTargetTimespan = 2 * 60; // 2 minutes CBigNum bnTargetLimit = fProofOfStake ? GetProofOfStakeLimit(pindexLast->nHeight) : Params().ProofOfWorkLimit(); @@ -1307,11 +1398,12 @@ void Misbehaving(NodeId pnode, int howmuch) int banscore = GetArg("-banscore", 100); if (pn->nMisbehavior >= banscore && pn->nMisbehavior - howmuch < banscore) { - LogPrintf("Misbehaving: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", pn->addrName, pn->nMisbehavior-howmuch, pn->nMisbehavior); + // MBK: Added some additional debugging information + LogPrintf("Misbehaving() -> Misbehaving: %s howmuch=%d (%d -> %d) BAN THRESHOLD EXCEEDED\n", pn->addrName, howmuch, pn->nMisbehavior-howmuch, pn->nMisbehavior); //pn->fShouldBan = true; } else - LogPrintf("Misbehaving: %s (%d -> %d)\n", pn->addrName, pn->nMisbehavior-howmuch, pn->nMisbehavior); + LogPrintf("Misbehaving() -> Misbehaving: %s howmuch=%d (%d -> %d)\n", pn->addrName, howmuch, pn->nMisbehavior-howmuch, pn->nMisbehavior); break; } @@ -1763,7 +1855,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) BOOST_FOREACH(CTransaction& tx, vtx) { uint256 hashTx = tx.GetHash(); - nInputs += tx.vin.size(); + nInputs += tx.vin.size(); // Do not allow blocks that contain transactions which 'overwrite' older transactions, // unless those are already completely spent. @@ -1816,7 +1908,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) nFees += nTxValueIn - nTxValueOut; if (tx.IsCoinStake()) nStakeReward = nTxValueOut - nTxValueIn; - + //if(setValidatedTx.find(hashTx) == setValidatedTx.end()) //{ if (!tx.ConnectInputs(txdb, mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, flags)) @@ -1842,13 +1934,35 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (IsProofOfWork()) { - int64_t nReward = GetProofOfWorkReward(nFees,pindex->nHeight); + // MBK: Calculate the reward based on the wallet version + int64_t nReward = 0; + if(CURRENT_WALLET_VERSION == 2) + { + nReward = GetProofOfWorkRewardV2(nFees,pindex->nHeight); + } + else + { + nReward = GetProofOfWorkReward(nFees,pindex->nHeight); + } + // Check coinbase reward if (vtx[0].GetValueOut() > nReward) return DoS(50, error("ConnectBlock() : coinbase reward exceeded (actual=%d vs calculated=%d)", vtx[0].GetValueOut(), nReward)); } + + // MBK: Calculate the stake reward burn + if(CURRENT_WALLET_VERSION == 2) + { + // MBK: Start the PoS reward burn to help offset future inflation to cap + if(pindex->nHeight >= POS_REWARD_V2_START_BLOCK /*|| CURRENT_WALLET_VERSION == 2*/) + { + nStakeReward = nStakeReward - (nStakeReward * POS_REWARD_V2_BURN_RATE); + } + + } + if (IsProofOfStake()) { // ppcoin: coin stake tx earns reward instead of paying fee @@ -1856,10 +1970,22 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (!vtx[1].GetCoinAge(txdb, nCoinAge)) return error("ConnectBlock() : %s unable to get coin age for coinstake", vtx[1].GetHash().ToString()); - int64_t nCalculatedStakeReward = GetProofOfStakeReward(nCoinAge, nFees, pindex->nHeight); + // MBK: Calculate the stake reward based on current wallet version + int64_t nCalculatedStakeReward = 0; + if(CURRENT_WALLET_VERSION == 2) + { + nCalculatedStakeReward = GetProofOfStakeRewardV2(nCoinAge, nFees, pindex->nHeight); + } + else + { + nCalculatedStakeReward = GetProofOfStakeReward(nCoinAge, nFees, pindex->nHeight); + } if (nStakeReward > nCalculatedStakeReward) return DoS(100, error("ConnectBlock() : coinstake pays too much(actual=%d vs calculated=%d)", nStakeReward, nCalculatedStakeReward)); + + // MBK: Added some additional debugging information + if (MBK_EXTRA_DEBUG) LogPrintf("ConnectBlock() -> nStakeReward=%d(%s) nCalculatedStakeReward=%d(%s)\n", nStakeReward, FormatMoney(nStakeReward), nCalculatedStakeReward, FormatMoney(nCalculatedStakeReward)); } // ppcoin: track money supply and mint amount info @@ -2221,12 +2347,14 @@ bool CTransaction::GetCoinAge(CTxDB& txdb, uint64_t& nCoinAge) const int64_t nValueIn = txPrev.vout[txin.prevout.n].nValue; bnCentSecond += CBigNum(nValueIn) * (nTime-txPrev.nTime) / CENT; - + LogPrint("coinage", "coin age nValueIn=%d nTimeDiff=%d bnCentSecond=%s\n", nValueIn, nTime - txPrev.nTime, bnCentSecond.ToString()); + LogPrintf("CTransaction::GetCoinAge() -> coin age nValueIn=%d(%s) nTimeDiff=%d bnCentSecond=%s\n", nValueIn, FormatMoney(nValueIn), nTime - txPrev.nTime, bnCentSecond.ToString()); } CBigNum bnCoinDay = bnCentSecond * CENT / COIN / (24 * 60 * 60); LogPrint("coinage", "coin age bnCoinDay=%s\n", bnCoinDay.ToString()); + LogPrintf("CTransaction::GetCoinAge() -> coin age bnCoinDay=%s\n", bnCoinDay.ToString()); nCoinAge = bnCoinDay.getuint64(); return true; } @@ -4300,7 +4428,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) int64_t GetMasternodePayment(int nHeight, int64_t blockValue) { - int64_t ret = static_cast(0); //100% masternode - + // MBK: Set masternode reward phase + int64_t ret = static_cast(67.33333333333333333); // ~2/3 masternode stake reward return ret; } diff --git a/src/main.h b/src/main.h index 6d29c6b..ad5d42e 100644 --- a/src/main.h +++ b/src/main.h @@ -20,14 +20,45 @@ class CValidationState; #define START_MASTERNODE_PAYMENTS_TESTNET 1429738064 #define START_MASTERNODE_PAYMENTS 1429738064 -static const int64_t DARKSEND_COLLATERAL = (30000000*COIN); -static const int64_t DARKSEND_FEE = (0.0001*COIN); -static const int64_t DARKSEND_POOL_MAX = (1111.99*COIN); -static const int REWARD_START = 51; -static const int REWARD_HALVE = 790115; -static const int PREMINE_BLOCK = 10; +// MBK: Global wallet version. (Switch to V2 changes where appropriate) +static const int CURRENT_WALLET_VERSION = 2; + +static const int64_t DARKSEND_COLLATERAL_V1 = (30000000*COIN); +static const int64_t DARKSEND_FEE_V1 = (0.0001*COIN); +static const int64_t DARKSEND_POOL_MAX_V1 = (1111.99*COIN); + +static const int REWARD_START = 51; +static const int REWARD_HALVE = 790115; +static const int PREMINE_BLOCK = 10; static const int FAIR_LAUNCH_BLOCK = 50; +// MBK: Added globals to simplify future potential changes +static const int64_t MASTERNODE_COLLATERAL_V1 = (30000000*COIN); +static const int64_t MASTERNODE_COLLATERAL_V2 = (2000000*COIN); +static const int64_t COIN_YEAR_REWARD_V2 = (99*CENT); +static const int64_t MIN_TX_FEE_V2 = 100000; +static const int64_t MIN_RELAY_TX_FEE_V2 = MIN_TX_FEE_V2; +static const int64_t DARKSEND_COLLATERAL_V2 = (2000000*COIN); +static const int64_t DARKSEND_FEE_V2 = (0.0001*COIN); +static const int64_t DARKSEND_POOL_MAX_V2 = (1111.99*COIN); +// MBK: Following are block heights to begin V2 swap +static const int POS_REWARD_V2_START_BLOCK = 359930;//371180; // ~03312018 (March 31, 2018) +static const int POW_REWARD_V2_START_BLOCK = 378230; // ~04052018 (April 5, 2018) +static const int TX_FEE_V2_INCREASE_BLOCK = 378230; // ~04052018 (April 5, 2018) +static const int MASTERNODE_V2_START_BLOCK = 378230; // ~04052018 (April 5, 2018) +static const int MASTERNODE_V2_FULLSWAP_BLOCK = 540380; // ~08012018 (August 1, 2018) +static const int DARKSEND_V2_START_BLOCK = 359930; //371180; // ~03312018 (March 31, 2018) +static const int MASTERNODE_V2_STOP_BLOCK = 1575000; // ~07012020 (July 1, 2020) +static const int V2_EMISSION_CAP_START_BLOCK = 1575000; // ~07012020 (July 1, 2020) +// MBK: Following define PoW/PoS reward parameters +static const int POW_REWARD_V1_FULL = 14150; +static const int POW_REWARD_V2_FULL = 13726; // ~3% reduction from V1 block reward +static const int POW_REWARD_V1_HALF = POW_REWARD_V1_FULL/2; +static const int POW_REWARD_V2_HALF = POW_REWARD_V2_FULL/2; +static const double POS_REWARD_V2_BURN_RATE = 0.02f; // ~2% reduction from V1 stake reward + +static const int MBK_EXTRA_DEBUG = 1; + /* At 15 signatures, 1/2 of the masternode network can be owned by one party without comprimising the security of InstantX @@ -81,9 +112,9 @@ static const unsigned int DEFAULT_MAX_ORPHAN_BLOCKS = 750; /** The maximum number of entries in an 'inv' protocol message */ static const unsigned int MAX_INV_SZ = 50000; /** Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) */ -static const int64_t MIN_TX_FEE = 10000; +static const int64_t MIN_TX_FEE_V1 = 10000; /** Fees smaller than this (in satoshi) are considered zero fee (for relaying) */ -static const int64_t MIN_RELAY_TX_FEE = MIN_TX_FEE; +static const int64_t MIN_RELAY_TX_FEE_V1 = MIN_TX_FEE_V1; /** No amount larger than this (in satoshi) is valid */ static const int64_t MAX_MONEY = 50000000000 * COIN; // 50B coins inline bool MoneyRange(int64_t nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } @@ -178,6 +209,10 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits); unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake); int64_t GetProofOfWorkReward(int64_t nFees, unsigned int nHeight); int64_t GetProofOfStakeReward(int64_t nCoinAge, int64_t nFees, unsigned int nHeight); +// MBK: V2 Wallet +int64_t GetProofOfWorkRewardV2(int64_t nFees, unsigned int nHeight); +int64_t GetProofOfStakeRewardV2(int64_t nCoinAge, int64_t nFees, unsigned int nHeight); + unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime); unsigned int ComputeMinStake(unsigned int nBase, int64_t nTime, unsigned int nBlockTime); bool IsInitialBlockDownload(); diff --git a/src/masternode.cpp b/src/masternode.cpp index 8eeda07..90dce56 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -154,7 +154,14 @@ void ProcessMessageMasternode(CNode* pfrom, std::string& strCommand, CDataStream CValidationState state; CTransaction tx = CTransaction(); - CTxOut vout = CTxOut(29999999*COIN, darkSendPool.collateralPubKey); + // MBK: Support collateral change based on block height + int64_t nTempTxOut = (MASTERNODE_COLLATERAL_V1 / COIN) - 1; + if(nBestHeight >= MASTERNODE_V2_START_BLOCK) + { + nTempTxOut = (MASTERNODE_COLLATERAL_V2 / COIN) - 1; + } + + CTxOut vout = CTxOut(nTempTxOut/*29999999*/*COIN, darkSendPool.collateralPubKey); tx.vin.push_back(vin); tx.vout.push_back(vout); //if(AcceptableInputs(mempool, state, tx)){ @@ -594,13 +601,20 @@ void CMasterNode::Check() if(!unitTest){ CValidationState state; CTransaction tx = CTransaction(); - CTxOut vout = CTxOut(29999999*COIN, darkSendPool.collateralPubKey); + // MBK: Support collateral change based on block height + int64_t nTempTxOut = (MASTERNODE_COLLATERAL_V1/COIN) - 1; + if(nBestHeight >= MASTERNODE_V2_START_BLOCK) + { + nTempTxOut = (MASTERNODE_COLLATERAL_V2/COIN) - 1; + } + CTxOut vout = CTxOut(nTempTxOut/*29999999*/*COIN, darkSendPool.collateralPubKey); tx.vin.push_back(vin); tx.vout.push_back(vout); //if(!AcceptableInputs(mempool, state, tx)){ bool pfMissingInputs = false; - if(!AcceptableInputs(mempool, tx, false, &pfMissingInputs)){ + if(!AcceptableInputs(mempool, tx, false, &pfMissingInputs)) + { enabled = 3; return; } diff --git a/src/miner.cpp b/src/miner.cpp index a15650e..93b915c 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -156,7 +156,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey, bool fProofOfStake, int64_t* pFe // a transaction spammer can cheaply fill blocks using // 1-satoshi-fee transactions. It should be set above the real // cost to you of processing a transaction. - int64_t nMinTxFee = MIN_TX_FEE; + // MBK: Support the tx fee increase at blockheight + int64_t nMinTxFee = (nBestHeight >= TX_FEE_V2_INCREASE_BLOCK ? MIN_TX_FEE_V2 : MIN_TX_FEE_V1); if (mapArgs.count("-mintxfee")) ParseMoney(mapArgs["-mintxfee"], nMinTxFee); @@ -358,7 +359,20 @@ CBlock* CreateNewBlock(CReserveKey& reservekey, bool fProofOfStake, int64_t* pFe LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize); // >Linda< if (!fProofOfStake) - pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(nFees, nHeight); + { + // MBK: Determine which PoW reward function to call basd on wallet version + int64_t nReward = 0; + if(CURRENT_WALLET_VERSION == 2) + { + nReward = GetProofOfWorkRewardV2(nFees, nHeight); + } + else + { + nReward = GetProofOfWorkReward(nFees, nHeight); + } + + pblock->vtx[0].vout[0].nValue = nReward; + } if (pFees) *pFees = nFees; diff --git a/src/net.cpp b/src/net.cpp index 87ce6db..43392f2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -482,7 +482,8 @@ bool CNode::Misbehaving(int howmuch) { if (addr.IsLocal()) { - LogPrintf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName, howmuch); + // MBK: Added some additional debugging information + LogPrintf("CNode::Misbehaving() -> Warning: Local node %s misbehaving (delta: %d)!\n", addrName, howmuch); return false; } @@ -490,7 +491,7 @@ bool CNode::Misbehaving(int howmuch) if (nMisbehavior >= GetArg("-banscore", 100)) { int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban - LogPrintf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString(), nMisbehavior-howmuch, nMisbehavior); + LogPrintf("CNode::Misbehaving() -> Misbehaving: %s howmuch=%d (%d -> %d) DISCONNECTING\n", addr.ToString(), howmuch, nMisbehavior-howmuch, nMisbehavior); { LOCK(cs_setBanned); if (setBanned[addr] < banTime) @@ -499,7 +500,7 @@ bool CNode::Misbehaving(int howmuch) CloseSocketDisconnect(); return true; } else - LogPrintf("Misbehaving: %s (%d -> %d)\n", addr.ToString(), nMisbehavior-howmuch, nMisbehavior); + LogPrintf("CNode::Misbehaving() -> Misbehaving: %s howmuch=%d (%d -> %d)\n", addr.ToString(), howmuch, nMisbehavior-howmuch, nMisbehavior); return false; } @@ -914,7 +915,13 @@ void ThreadSocketHandler() if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) { if (!pnode->fDisconnect) - LogPrintf("socket recv error %d\n", nErr); + { + // MBK: Added some additional debugging information + if (MBK_EXTRA_DEBUG) LogPrintf("ThreadSocketHandler() -> Socket recv error %d from %s\n", nErr, pnode->addr.ToString()); + + LogPrint("net", "socket recv error %d\n", nErr); + } + pnode->CloseSocketDisconnect(); } } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 488b9c6..7904196 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -67,8 +67,18 @@ static bool ThreadSafeAskFee(int64_t nFeeRequired, const std::string& strCaption { if(!guiref) return false; - if(nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon) - return true; + + // MBK: Determine the minimum tx fee based on current blockheight + int txMinimumFee = MIN_TX_FEE_V1; + if(nBestHeight >= TX_FEE_V2_INCREASE_BLOCK) + { + txMinimumFee = MIN_TX_FEE_V2; + } + + //if(nFeeRequired < MIN_TX_FEE_V1 || nFeeRequired <= nTransactionFee || fDaemon) + if(nFeeRequired < txMinimumFee || nFeeRequired <= nTransactionFee || fDaemon) + return true; + bool payFee = false; QMetaObject::invokeMethod(guiref, "askFee", GUIUtil::blockingGUIThreadConnection(), diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index e1b3b8b..627bf46 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -11,6 +11,7 @@ #include "init.h" #include "miner.h" #include "kernel.h" +#include "util.h" #include @@ -46,7 +47,20 @@ Value getsubsidy(const Array& params, bool fHelp) "getsubsidy [nTarget]\n" "Returns proof-of-work subsidy value for the specified value of target."); - return (uint64_t)GetProofOfWorkReward(0,pindexBest->nHeight); + // MBK: Calculate PoW reward based on wallet version + uint64_t nReward = 0; + if(CURRENT_WALLET_VERSION == 2) + { + nReward = GetProofOfWorkRewardV2(0,pindexBest->nHeight); + } + else + { + nReward = GetProofOfWorkReward(0,pindexBest->nHeight); + } + + // MBK: Added some additional debugging information + if (MBK_EXTRA_DEBUG) LogPrintf("getsubsidy() -> nPoWSubsidy=%d", nReward); + return (uint64_t)nReward; } Value getstakesubsidy(const Array& params, bool fHelp) @@ -73,7 +87,20 @@ Value getstakesubsidy(const Array& params, bool fHelp) if (!tx.GetCoinAge(txdb, nCoinAge)) throw JSONRPCError(RPC_MISC_ERROR, "GetCoinAge failed"); - return (uint64_t)GetProofOfStakeReward(nCoinAge, 0, pindexBest->nHeight); + // MBK: Calculate the PoS reward based on the current wallet version + uint64_t nStakeReward = 0; + if(CURRENT_WALLET_VERSION == 2) + { + nStakeReward = GetProofOfStakeRewardV2(nCoinAge, 0, pindexBest->nHeight); + } + else + { + nStakeReward = GetProofOfStakeReward(nCoinAge, 0, pindexBest->nHeight); + } + + // MBK: Added some additional debugging information + if (MBK_EXTRA_DEBUG) LogPrintf("getstakesubsidy() -> [%s] nStakeSubsidy=%d",(CURRENT_WALLET_VERSION==2?"V2":""), nStakeReward); + return (uint64_t)nStakeReward; } Value getmininginfo(const Array& params, bool fHelp) @@ -97,7 +124,16 @@ Value getmininginfo(const Array& params, bool fHelp) diff.push_back(Pair("search-interval", (int)nLastCoinStakeSearchInterval)); obj.push_back(Pair("difficulty", diff)); - obj.push_back(Pair("blockvalue", (uint64_t)GetProofOfWorkReward(0, pindexBest->nHeight))); + // MBK: Return the correct rewards based on the current blockheight + if(CURRENT_WALLET_VERSION == 2) + { + obj.push_back(Pair("blockvalue", (uint64_t)GetProofOfWorkRewardV2(0, pindexBest->nHeight))); + } + else + { + obj.push_back(Pair("blockvalue", (uint64_t)GetProofOfWorkReward(0, pindexBest->nHeight))); + } + obj.push_back(Pair("netmhashps", GetPoWMHashPS())); obj.push_back(Pair("netstakeweight", GetPoSKernelPS())); obj.push_back(Pair("errors", GetWarnings("statusbar"))); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 3c0c7f6..88d0f23 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1583,7 +1583,8 @@ Value makekeypair(const Array& params, bool fHelp) Value settxfee(const Array& params, bool fHelp) { - if (fHelp || params.size() < 1 || params.size() > 1 || AmountFromValue(params[0]) < MIN_TX_FEE) + // MBK: Support the tx fee increase at blockheight + if (fHelp || params.size() < 1 || params.size() > 1 || AmountFromValue(params[0]) < (nBestHeight >= TX_FEE_V2_INCREASE_BLOCK ? MIN_RELAY_TX_FEE_V2 : MIN_RELAY_TX_FEE_V1)) throw runtime_error( "settxfee \n" " is a real and is rounded to the nearest 0.01"); diff --git a/src/wallet.cpp b/src/wallet.cpp index 09816bd..c1a6a63 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -29,7 +29,7 @@ using namespace std; // Settings -int64_t nTransactionFee = MIN_TX_FEE; +int64_t nTransactionFee = 0; int64_t nReserveBalance = 0; int64_t nMinimumInputValue = 0; @@ -2302,11 +2302,20 @@ bool CWallet::HasCollateralInputs() const bool CWallet::IsCollateralAmount(int64_t nInputAmount) const { - return nInputAmount == (DARKSEND_COLLATERAL * 5)+DARKSEND_FEE || - nInputAmount == (DARKSEND_COLLATERAL * 4)+DARKSEND_FEE || - nInputAmount == (DARKSEND_COLLATERAL * 3)+DARKSEND_FEE || - nInputAmount == (DARKSEND_COLLATERAL * 2)+DARKSEND_FEE || - nInputAmount == (DARKSEND_COLLATERAL * 1)+DARKSEND_FEE; + // MBK: Added support for block height darksend fee and collateral change + int64_t nDarkSendFee = DARKSEND_FEE_V1; + int64_t nDarkSendCollateral = DARKSEND_COLLATERAL_V1; + if(nBestHeight >= DARKSEND_V2_START_BLOCK) + { + nDarkSendFee = DARKSEND_FEE_V2; + nDarkSendCollateral = DARKSEND_COLLATERAL_V2; + } + + return nInputAmount == (nDarkSendCollateral/*DARKSEND_COLLATERAL*/ * 5)+nDarkSendFee/*DARKSEND_FEE*/ || + nInputAmount == (nDarkSendCollateral/*DARKSEND_COLLATERAL*/ * 4)+nDarkSendFee/*DARKSEND_FEE*/ || + nInputAmount == (nDarkSendCollateral/*DARKSEND_COLLATERAL*/ * 3)+nDarkSendFee/*DARKSEND_FEE*/ || + nInputAmount == (nDarkSendCollateral/*DARKSEND_COLLATERAL*/ * 2)+nDarkSendFee/*DARKSEND_FEE*/ || + nInputAmount == (nDarkSendCollateral/*DARKSEND_COLLATERAL*/ * 1)+nDarkSendFee/*DARKSEND_FEE*/; } bool CWallet::SelectCoinsWithoutDenomination(int64_t nTargetValue, set >& setCoinsRet, int64_t& nValueRet) const @@ -2354,10 +2363,17 @@ bool CWallet::CreateCollateralTransaction(CTransaction& txCollateral, std::strin BOOST_FOREACH(CTxIn v, vCoinsCollateral) txCollateral.vin.push_back(v); + + // MBK: Added support for block height darksend fee change + int64_t nDarkSendCollateral = DARKSEND_COLLATERAL_V1; + if(nBestHeight >= DARKSEND_V2_START_BLOCK) + { + nDarkSendCollateral = DARKSEND_COLLATERAL_V2; + } - if(nValueIn2 - DARKSEND_COLLATERAL - nFeeRet > 0) { + if(nValueIn2 - nDarkSendCollateral/*DARKSEND_COLLATERAL*/ - nFeeRet > 0) { //pay collateral charge in fees - CTxOut vout3 = CTxOut(nValueIn2 - DARKSEND_COLLATERAL, scriptChange); + CTxOut vout3 = CTxOut(nValueIn2 - nDarkSendCollateral/*DARKSEND_COLLATERAL*/, scriptChange); txCollateral.vout.push_back(vout3); } @@ -2413,7 +2429,9 @@ bool CWallet::CreateTransaction(const vector >& vecSend, // txdb must be opened before the mapWallet lock CTxDB txdb("r"); { - nFeeRet = nTransactionFee; + // MBK: Support the tx fee increase at blockheight + nFeeRet = (nBestHeight >= TX_FEE_V2_INCREASE_BLOCK ? MIN_TX_FEE_V2 : MIN_TX_FEE_V1); // nTransactionFee; + LogPrintf("CWallet::CreateTransaction() -> nFeeRet=%d\n", nFeeRet); while (true) { wtxNew.vin.clear(); @@ -2498,7 +2516,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, }; wtxNew.vout.insert(position, CTxOut(nChange, scriptChange)); - nChangePos = std::distance(wtxNew.vout.begin(), position); + nChangePos = std::distance(wtxNew.vout.begin(), position); } else reservekey.ReturnKey(); @@ -2520,7 +2538,8 @@ bool CWallet::CreateTransaction(const vector >& vecSend, dPriority /= nBytes; // Check that enough fee is included - int64_t nPayFee = nTransactionFee * (1 + (int64_t)nBytes / 1000); + // MBK: Support the tx fee increase at blockheight + int64_t nPayFee = (nBestHeight >= TX_FEE_V2_INCREASE_BLOCK ? MIN_TX_FEE_V2 : MIN_TX_FEE_V1) /*nTransactionFee*/ * (1 + (int64_t)nBytes / 1000); int64_t nMinFee = GetMinFee(wtxNew, 1, GMF_SEND, nBytes); if (nFeeRet < max(nPayFee, nMinFee)) @@ -2974,7 +2993,9 @@ bool CWallet::SendStealthMoneyToDestination(CStealthAddress& sxAddress, int64_t sError = "Invalid amount"; return false; }; - if (nValue + nTransactionFee + (1) > GetBalance()) + + // MBK: Support the tx fee increase at blockheight + if (nValue + (nBestHeight >= TX_FEE_V2_INCREASE_BLOCK ? MIN_TX_FEE_V2 : MIN_TX_FEE_V1) /*nTransactionFee*/ + (1) > GetBalance()) { sError = "Insufficient funds"; return false; @@ -3437,6 +3458,9 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (nCredit == 0 || nCredit > nBalance - nReserveBalance) return false; + + // MBK: Added some additional debug information + if (MBK_EXTRA_DEBUG) LogPrintf("CWallet::CreateCoinStake() -> [PreInputCollection] nCredit=%d", nCredit); BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) { @@ -3469,6 +3493,9 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int } } + // MBK: Added some additional debugging information + if (MBK_EXTRA_DEBUG) LogPrintf("CWallet::CreateCoinStake() -> [AfterInputCollection] nCredit=%d", nCredit); + // Calculate coin age reward int64_t nReward; { @@ -3477,13 +3504,25 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (!txNew.GetCoinAge(txdb, nCoinAge)) return error("CreateCoinStake : failed to calculate coin age"); - nReward = GetProofOfStakeReward(nCoinAge, nFees, pindexBest->nHeight); + // MBK: Calculate the reward based on current wallet version + nReward = 0; + if(CURRENT_WALLET_VERSION == 2) + { + nReward = GetProofOfStakeReward(nCoinAge, nFees, pindexBest->nHeight); + } + else + { + nReward = GetProofOfStakeReward(nCoinAge, nFees, pindexBest->nHeight); + } + if (nReward <= 0) return false; nCredit += nReward; } + // MBK: Added some additional debugging information + if (MBK_EXTRA_DEBUG) LogPrintf("CWallet::CreateCoinStake() -> nReward=%d, nCredit=%d", nReward, nCredit); // Masternode Payments int payments = 1; @@ -3532,6 +3571,9 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int int64_t blockValue = nCredit; int64_t masternodePayment = GetMasternodePayment(pindexPrev->nHeight+1, nReward); + // MBK: Added some additional debugging information + if (MBK_EXTRA_DEBUG) LogPrintf("CWallet::CreateCoinStake() -> blockValue=%d, masternodePayment=%d", blockValue, masternodePayment); + // Set output amount if (!hasPayment && txNew.vout.size() == 3) // 2 stake outputs, stake was split, no masternode payment { @@ -3677,7 +3719,8 @@ string CWallet::SendMoneyToDestination(const CTxDestination& address, int64_t nV // Check amount if (nValue <= 0) return _("Invalid amount"); - if (nValue + nTransactionFee > GetBalance()) + // MBK: Support the tx fee increase at blockheight + if (nValue + (nBestHeight >= TX_FEE_V2_INCREASE_BLOCK ? MIN_TX_FEE_V2 : MIN_TX_FEE_V1) /*nTransactionFee*/ > GetBalance()) return _("Insufficient funds"); if (sNarr.length() > 24) @@ -3710,8 +3753,9 @@ string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds) Select the coins we'll use if minRounds >= 0 it means only denominated inputs are going in and coming out */ + // MBK: Added support for block height darksend fee change if(minRounds >= 0){ - if (!SelectCoinsByDenominations(darkSendPool.sessionDenom, 0.1*COIN, DARKSEND_POOL_MAX, vCoins, vCoins2, nValueIn, minRounds, maxRounds)) + if (!SelectCoinsByDenominations(darkSendPool.sessionDenom, 0.1*COIN,(nBestHeight >= DARKSEND_V2_START_BLOCK ? DARKSEND_POOL_MAX_V2 : DARKSEND_POOL_MAX_V1)/*DARKSEND_POOL_MAX*/, vCoins, vCoins2, nValueIn, minRounds, maxRounds)) return _("Insufficient funds"); } diff --git a/src/wallet.h b/src/wallet.h index 4ac381a..5555cf6 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -850,7 +850,8 @@ class COutput //Used with Darksend. Will return fees, then denominations, everything else, then very small inputs that aren't fees int Priority() const { - if(tx->vout[i].nValue == DARKSEND_FEE) return -20000; + // MBK: Added support for block height darksend fee change + if(tx->vout[i].nValue == (nBestHeight >= DARKSEND_V2_START_BLOCK ? DARKSEND_FEE_V2 : DARKSEND_FEE_V1)) return -20000; BOOST_FOREACH(int64_t d, darkSendDenominations) if(tx->vout[i].nValue == d) return 10000; if(tx->vout[i].nValue < 1*COIN) return 20000;