From 62b7b4d1e52268a03bc45f37681618b49304489b Mon Sep 17 00:00:00 2001 From: cygnus Date: Wed, 27 Sep 2017 19:03:31 -0400 Subject: [PATCH] 1.9.4.1 Updates --- src/alert.cpp | 4 +- src/alert.h | 4 +- src/curecoinrpc.h | 1 + src/init.cpp | 6 ++ src/kernel.cpp | 9 +++ src/kernel.h | 3 + src/main.cpp | 4 +- src/main.h | 3 + src/qt/curecoin.qrc | 2 + src/qt/curecoingui.cpp | 71 +++++++++++++++++- src/qt/curecoingui.h | 3 + src/qt/res/icons/staking_off.png | Bin 0 -> 978 bytes src/qt/res/icons/staking_on.png | Bin 0 -> 888 bytes src/rpcblockchain.cpp | 25 +++++++ src/rpcmining.cpp | 37 +++++++++ src/wallet.cpp | 124 +++++++++++++++++++++++++++++++ src/wallet.h | 10 +++ 17 files changed, 297 insertions(+), 9 deletions(-) create mode 100755 src/qt/res/icons/staking_off.png create mode 100755 src/qt/res/icons/staking_on.png diff --git a/src/alert.cpp b/src/alert.cpp index 1b7f41a..a463c0c 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -16,8 +16,8 @@ using namespace std; map mapAlerts; CCriticalSection cs_mapAlerts; -//static const char* pszMainKey = "043fa441fd4203d03f5df2b75ea14e36f20d39f43e7a61aa7552ab9bcd7ecb0e77a3be4585b13fcdaa22ef6e51f1ff6f2929bec2494385b086fb86610e33193195"; -//static const char* pszTestKey = "0471dc165db490094d35cde15b1f5d755fa6ad6f2b5ed0f340e3f17f57389c3c2af113a8cbcc885bde73305a553b5640c83021128008ddf882e856336269080496"; +static const char* pszMainKey = "043fa441fd4203d03f5df2b75ea14e36f20d39f43e7a61aa7552ab9bcd7ecb0e77a3be4585b13fcdaa22ef6e51f1ff6f2929bec2494385b086fb86610e33193195"; +static const char* pszTestKey = "0471dc165db490094d35cde15b1f5d755fa6ad6f2b5ed0f340e3f17f57389c3c2af113a8cbcc885bde73305a553b5640c83021128008ddf882e856336269080496"; // TestNet alerts private key // "308201130201010420b665cff1884e53da26376fd1b433812c9a5a8a4d5221533b15b9629789bb7e42a081a53081a2020101302c06072a8648ce3d0101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f300604010004010704410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101a1440342000471dc165db490094d35cde15b1f5d755fa6ad6f2b5ed0f340e3f17f57389c3c2af113a8cbcc885bde73305a553b5640c83021128008ddf882e856336269080496" diff --git a/src/alert.h b/src/alert.h index 9da1b21..ed9f4d1 100644 --- a/src/alert.h +++ b/src/alert.h @@ -13,10 +13,10 @@ #include "util.h" -static const char* pszMainKey = "0407c78740e67ab033220e1ca3a9e5dc0d0c19d631e211d6dbdef5c9f0df2761859d79b851ef65b1dd2596c8db15c3b0f79765804e66d2f62896f4b1351ce8840c"; +// static const char* pszMainKey = "0407c78740e67ab033220e1ca3a9e5dc0d0c19d631e211d6dbdef5c9f0df2761859d79b851ef65b1dd2596c8db15c3b0f79765804e66d2f62896f4b1351ce8840c"; // TestNet alerts pubKey -static const char* pszTestKey = "0471dc165db490094d35cde15b1f5d755fa6ad6f2b5ed0f340e3f17f57389c3c2af113a8cbcc885bde73305a553b5640c83021128008ddf882e856336269080496"; +// static const char* pszTestKey = "0471dc165db490094d35cde15b1f5d755fa6ad6f2b5ed0f340e3f17f57389c3c2af113a8cbcc885bde73305a553b5640c83021128008ddf882e856336269080496"; class CNode; diff --git a/src/curecoinrpc.h b/src/curecoinrpc.h index b3e2232..d13554c 100644 --- a/src/curecoinrpc.h +++ b/src/curecoinrpc.h @@ -131,6 +131,7 @@ extern std::string HexBits(unsigned int nBits); extern std::string HelpRequiringPassphrase(); extern void EnsureWalletIsUnlocked(); +extern double GetPoSKernelPS(); extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp); diff --git a/src/init.cpp b/src/init.cpp index fe06883..8520d61 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -440,6 +440,12 @@ bool AppInit2() InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); } + if (mapArgs.count("-mininput")) + { + if (!ParseMoney(mapArgs["-mininput"], nMinimumInputValue)) + return InitError(strprintf(_("Invalid amount for -mininput=: '%s'"), mapArgs["-mininput"].c_str())); + } + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log std::string strDataDir = GetDataDir().string(); diff --git a/src/kernel.cpp b/src/kernel.cpp index 762414c..dfa9d93 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -27,6 +27,15 @@ static std::map mapStakeModifierCheckpoints = ( 180646, 0xb85b7dd1u ) ; +// Get time weight +int64 GetWeight(int64 nIntervalBeginning, int64 nIntervalEnd) +{ + // Kernel hash weight starts from 0 at the min age + // this change increases active coins participating the hash and helps + // to secure the network when proof-of-stake difficulty is low + + return min(nIntervalEnd - nIntervalBeginning - nStakeMinAge, (int64)nStakeMaxAge); +} // Get the last stake modifier and its generation time from a given block static bool GetLastStakeModifier(const CBlockIndex* pindex, uint64& nStakeModifier, int64& nModifierTime) diff --git a/src/kernel.h b/src/kernel.h index 9241173..412deb3 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -34,4 +34,7 @@ unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex); // Check stake modifier hard checkpoints bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierChecksum); +// Get time weight using supplied timestamps +int64 GetWeight(int64 nIntervalBeginning, int64 nIntervalEnd); + #endif // PPCOIN_KERNEL_H diff --git a/src/main.cpp b/src/main.cpp index 9edec78..a8dea27 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ #include "init.h" #include "ui_interface.h" #include "kernel.h" +#include "wallet.h" #include #include #include @@ -76,7 +77,8 @@ int64 nHPSTimerStart; // Settings int64 nTransactionFee = MIN_TX_FEE; - +int64 nReserveBalance = 0; +int64 nMinimumInputValue = 0; diff --git a/src/main.h b/src/main.h index e86c66d..4ea33c0 100644 --- a/src/main.h +++ b/src/main.h @@ -81,7 +81,10 @@ extern unsigned char pchMessageStart[4]; extern std::map mapOrphanBlocks; // Settings +//extern int64 nTransactionFee; extern int64 nTransactionFee; +extern int64 nReserveBalance; +extern int64 nMinimumInputValue; // Minimum disk space required - used in CheckDiskSpace() static const uint64 nMinDiskSpace = 52428800; diff --git a/src/qt/curecoin.qrc b/src/qt/curecoin.qrc index c1e859e..819ad34 100644 --- a/src/qt/curecoin.qrc +++ b/src/qt/curecoin.qrc @@ -40,6 +40,8 @@ res/icons/filesave.png res/icons/qrcode.png res/icons/debugwindow.png + res/icons/staking_off.png + res/icons/staking_on.png res/images/about.png diff --git a/src/qt/curecoingui.cpp b/src/qt/curecoingui.cpp index 74d6f5b..c07f118 100644 --- a/src/qt/curecoingui.cpp +++ b/src/qt/curecoingui.cpp @@ -25,6 +25,7 @@ #include "notificator.h" #include "guiutil.h" #include "rpcconsole.h" +#include "wallet.h" #ifdef Q_OS_MAC #include "macdockiconhandler.h" @@ -58,6 +59,11 @@ #include +extern CWallet* pwalletMain; +extern int64 nLastCoinStakeSearchInterval; +extern unsigned int nStakeTargetSpacing; +double GetPoSKernelPS(); + curecoinGUI::curecoinGUI(QWidget *parent): QMainWindow(parent), clientModel(0), @@ -126,22 +132,33 @@ curecoinGUI::curecoinGUI(QWidget *parent): // Status bar notification icons QFrame *frameBlocks = new QFrame(); frameBlocks->setContentsMargins(0,0,0,0); - frameBlocks->setMinimumWidth(56); - frameBlocks->setMaximumWidth(56); + // frameBlocks->setMinimumWidth(56); + // frameBlocks->setMaximumWidth(56); + frameBlocks->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks); frameBlocksLayout->setContentsMargins(3,0,3,0); frameBlocksLayout->setSpacing(3); labelEncryptionIcon = new QLabel(); labelConnectionsIcon = new QLabel(); labelBlocksIcon = new QLabel(); + labelStakingIcon = new QLabel(); frameBlocksLayout->addStretch(); frameBlocksLayout->addWidget(labelEncryptionIcon); frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelStakingIcon); + frameBlocksLayout->addStretch(); frameBlocksLayout->addWidget(labelConnectionsIcon); frameBlocksLayout->addStretch(); frameBlocksLayout->addWidget(labelBlocksIcon); frameBlocksLayout->addStretch(); + + QTimer *timerStakingIcon = new QTimer(labelStakingIcon); + connect(timerStakingIcon, SIGNAL(timeout()), this, SLOT(updateStakingIcon())); + timerStakingIcon->start(30 * 1000); + updateStakingIcon(); + + // Progress bar and label for blocks download progressBarLabel = new QLabel(); progressBarLabel->setVisible(false); @@ -409,7 +426,7 @@ void curecoinGUI::createTrayIcon() trayIcon = new QSystemTrayIcon(this); trayIconMenu = new QMenu(this); trayIcon->setContextMenu(trayIconMenu); - trayIcon->setToolTip(tr("curecoin client")); + trayIcon->setToolTip(tr("Curecoin client")); trayIcon->setIcon(QIcon(":/icons/toolbar")); connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); @@ -478,7 +495,7 @@ void curecoinGUI::setNumConnections(int count) default: icon = ":/icons/connect_4"; break; } labelConnectionsIcon->setPixmap(QIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); - labelConnectionsIcon->setToolTip(tr("%n active connection(s) to curecoin network", "", count)); + labelConnectionsIcon->setToolTip(tr("%n active connection(s) to the Curecoin network", "", count)); } void curecoinGUI::setNumBlocks(int count, int nTotalBlocks) @@ -588,6 +605,52 @@ void curecoinGUI::setNumBlocks(int count, int nTotalBlocks) progressBar->setToolTip(tooltip); } +void curecoinGUI::updateStakingIcon() +{ +uint64 nMinWeight = 0, nMaxWeight = 0, nWeight = 0; +if (pwalletMain) + pwalletMain->GetStakeWeight(*pwalletMain, nMinWeight, nMaxWeight, nWeight); + +if (nLastCoinStakeSearchInterval && nWeight) +{ + uint64 nNetworkWeight = GetPoSKernelPS(); + unsigned nEstimateTime = nStakeTargetSpacing * nNetworkWeight / nWeight; + + QString text; + if (nEstimateTime < 60) + { + text = tr("%n second(s)", "", nEstimateTime); + } + else if (nEstimateTime < 60*60) + { + text = tr("%n minute(s)", "", nEstimateTime/60); + } + else if (nEstimateTime < 24*60*60) + { + text = tr("%n hour(s)", "", nEstimateTime/(60*60)); + } + else + { + text = tr("%n day(s)", "", nEstimateTime/(60*60*24)); + } + // labelStakingIcon->show(); + labelStakingIcon->setPixmap(QIcon(":/icons/staking_on").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelStakingIcon->setToolTip(tr("Staking.
Your weight is %1
Network weight is %2
Estimated time to earn your next staking installment is %3").arg(nWeight).arg(nNetworkWeight).arg(text)); + } else { + labelStakingIcon->setPixmap(QIcon(":/icons/staking_off").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + if (pwalletMain && pwalletMain->IsLocked()) + labelStakingIcon->setToolTip(tr("Not staking because wallet is locked")); + else if (vNodes.empty()) + labelStakingIcon->setToolTip(tr("Not staking because wallet is offline")); + else if (IsInitialBlockDownload()) + labelStakingIcon->setToolTip(tr("Not staking because wallet is syncing")); + else if (!nWeight) + labelStakingIcon->setToolTip(tr("Not staking because you don't have mature coins 1:%1 2: %2").arg(nLastCoinStakeSearchInterval).arg(nWeight)); + else + labelStakingIcon->setToolTip(tr("Not staking")); } +} + + void curecoinGUI::error(const QString &title, const QString &message, bool modal) { // Report errors from network/worker thread diff --git a/src/qt/curecoingui.h b/src/qt/curecoingui.h index a8d7892..37a3d85 100644 --- a/src/qt/curecoingui.h +++ b/src/qt/curecoingui.h @@ -69,6 +69,7 @@ private: QLabel *labelEncryptionIcon; QLabel *labelConnectionsIcon; QLabel *labelBlocksIcon; + QLabel *labelStakingIcon; QLabel *progressBarLabel; QProgressBar *progressBar; @@ -177,6 +178,8 @@ private slots: void showNormalIfMinimized(bool fToggleHidden = false); /** simply calls showNormalIfMinimized(true) for use in SLOT() macro */ void toggleHidden(); + + void updateStakingIcon(); }; #endif diff --git a/src/qt/res/icons/staking_off.png b/src/qt/res/icons/staking_off.png new file mode 100755 index 0000000000000000000000000000000000000000..91e570e1a7f54e22f1eaf86fbd82245b1d95b5ae GIT binary patch literal 978 zcmV;@11Al{zp+N*54QB?bhllt_ihBmOG^v7t^*JbM-;!mCK?C?zV7Mi{@myDMWvLy zeS7ssCX;!3eSP(KXJ_Zn^Ye@H%*+gni;D=}6^%yyJv}`S2L?X+ZgB7(Znq1E!-13% zAq2%@k&TTFlF8qGSY2KFF`vKqdvbCT`EITq9v=Q_WMt%mV96I)wbS27xnDzVtz@9*FL?5kj~0Yy=`zP?7+vkVLjVB0pw z$635yFNz}Y`FzyX)!orFO--dz>oODyMTdune~v`LNGZ9zykviWp9c>nh(y9PHa3#a z=Q%hy!0!)W+cqAL2g5Kw1Xg8NSJ%VQ(a}$Y5aja(c6L%sPk&2O)BD)AjSzxxI6^j? zWp{U%+S*zy%R)-Ud3JX8T4`@@AD2>cetypO_BK;f(=;_TVVXB6io~)i6pOcvkAFc! zLj&vUFE9*)>gsAVO^YiYkEhe+a*@qu85)rvOwc7E4P@9334I3^rmICIB}# zMQpo*Vi?Bnsw#;@B6z)CQmGW7P>9>xTL4O>GQnUYCnq^JH#h0;??+0BWm(uZN%ipX z@R!@$Qn%kXCNE!B{xgQEs)WPg|54etO`%YrQmOo^luD&1$z&3TL&NQM z<8-=kx!ly(*HbQ+Fin%HswzAl51OVSgg^*EE|3`U4^13fZ*cdg1x=HCo3x}^U^fUN}*7AC4{(JUtfR6=X(#Q z(@7xUr@OnGj*br8ZZ`myRUwzlkxr*q=I7@h0he-WYKlZ6ag$D`pKF>XP4lMP;cz(J zZWlr*R4O*bVv%h2m~=Y*Pdc4`JU2J@2*~yJ_99waTNxS}VsUX1z!{In2b!Ck;~tME z4h-71ZCjT0s#q+p>ALMbD>liSb zPOlccmi(ISu~E{~odA?0ukzHE?Dm^>p?zt(_^X$7iYg6=+K#}%_=_!X-qB715Drez zXAH47x(9#RPc(RfKW=vcaGgGOJUpHlpPkgIx9kyB?XGL9+w4DbUrPpnjgiyDZ-3AJ zp7+@tO|WrYGv?ePVc$<&HXj9G%I%}sIF+24xbcfnH02HB@c;n2aRu$KVGccgka#$b z>$wOac)p{bgqGmh&?l?og%aWVVCVWB0zrSR`ZMSmeA9z`)qj|HIEGazB7{oSmDrBW zE04WQQg5fd_H_VmYJ+J0nqDCcZ4*ue>~7xMI>1BCNwTv!J~;LDV4QsD$g19Pt7x9( zUIVtQkOy)*@A6(s3BWOHKUn|rrmq|6xoLs)PBc~atyvmn{`hj>Dfe8eO1_M{AkPS= zQXR^UTw5dX8g@~Y4yB5f~9RqC69zxNay@9yN(`Iopd|0f0I zxm8Z9*~6U+H>g}J4tb_Gyxd=mM!hvSoO&X)>-qyn`9Cz-d%1dP6!Y@japt^tysPCI zMSY|WnJz($^&;x~s4dawdi!|kzjAYALs?Pxt@z7os7A-a28XZQ*AXZ$L#9L8~6v?pEDE;4MVm7 O0000IsProofOfStake()) + { + dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0; + nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0; + pindexPrevStake = pindex; + nStakesHandled++; + } + + pindex = pindex->pprev; + } + + return nStakesTime ? dStakeKernelsTriedAvg / nStakesTime : 0; +} + Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPrintTransactionDetail) { diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 51dfaeb..6dab5e8 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -11,6 +11,8 @@ using namespace json_spirit; using namespace std; +extern unsigned int nStakeTargetSpacing; + Value getgenerate(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -108,6 +110,7 @@ Value getmininginfo(const Array& params, bool fHelp) obj.push_back(Pair("currentblocksize",(uint64_t)nLastBlockSize)); obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx)); obj.push_back(Pair("difficulty", (double)GetDifficulty())); +// obj.push_back(Pair("netstakeweight", GetPoSKernelPS())); obj.push_back(Pair("errors", GetWarnings("statusbar"))); obj.push_back(Pair("generate", GetBoolArg("-gen"))); obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); @@ -118,6 +121,40 @@ Value getmininginfo(const Array& params, bool fHelp) return obj; } +Value getstakinginfo(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getstakinginfo\n" + "Returns an object containing staking-related information."); + + uint64 nMinWeight = 0, nMaxWeight = 0, nWeight = 0; + pwalletMain->GetStakeWeight(*pwalletMain, nMinWeight, nMaxWeight, nWeight); + + uint64 nNetworkWeight = GetPoSKernelPS(); + bool staking = nLastCoinStakeSearchInterval && nWeight; + int nExpectedTime = staking ? (nStakeTargetSpacing * nNetworkWeight / nWeight) : -1; + + Object obj; + + obj.push_back(Pair("enabled", GetBoolArg("-staking", true))); + obj.push_back(Pair("staking", staking)); + obj.push_back(Pair("errors", GetWarnings("statusbar"))); + + obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize)); + obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); + obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); + + obj.push_back(Pair("difficulty", GetDifficulty(GetLastBlockIndex(pindexBest, true)))); + obj.push_back(Pair("search-interval", (int)nLastCoinStakeSearchInterval)); + + obj.push_back(Pair("weight", (uint64_t)nWeight)); + obj.push_back(Pair("netstakeweight", (uint64_t)nNetworkWeight)); + + obj.push_back(Pair("expectedtime", nExpectedTime)); + + return obj; +} Value getworkex(const Array& params, bool fHelp) { diff --git a/src/wallet.cpp b/src/wallet.cpp index 82e53c7..bfe4dd5 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1023,6 +1023,29 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed) const } } +void CWallet::AvailableCoinsMinConf(vector& vCoins, int nConf) const +{ + vCoins.clear(); + + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + + if (!pcoin->IsFinal()) + continue; + + if(pcoin->GetDepthInMainChain() < nConf) + continue; + + for (unsigned int i = 0; i < pcoin->vout.size(); i++) + if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue >= nMinimumInputValue) + vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain())); + } + } +} + static void ApproximateBestSubset(vector > >vValue, int64 nTotalLower, int64 nTargetValue, vector& vfBest, int64& nBest, int iterations = 1000) { @@ -1203,7 +1226,49 @@ bool CWallet::SelectCoins(int64 nTargetValue, unsigned int nSpendTime, set >& setCoinsRet, int64& nValueRet) const +{ + vector vCoins; + AvailableCoinsMinConf(vCoins, nMinConf); + setCoinsRet.clear(); + nValueRet = 0; + + BOOST_FOREACH(COutput output, vCoins) + { + const CWalletTx *pcoin = output.tx; + int i = output.i; + + // Stop if we've chosen enough inputs + if (nValueRet >= nTargetValue) + break; + + // Follow the timestamp rules + if (pcoin->nTime > nSpendTime) + continue; + + int64_t n = pcoin->vout[i].nValue; + + pair > coin = make_pair(n,make_pair(pcoin, i)); + + if (n >= nTargetValue) + { + // If input value is greater or equal to target then simply insert + // it into the current subset and exit + setCoinsRet.insert(coin.second); + nValueRet += coin.first; + break; + } + else if (n < nTargetValue + CENT) + { + setCoinsRet.insert(coin.second); + nValueRet += coin.first; + } + } + + return true; +} bool CWallet::CreateTransaction(const vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment) @@ -1343,6 +1408,65 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strTxComment); } +// NovaCoin: get current stake weight +bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight) +{ + // Choose coins to use + int64 nBalance = GetBalance(); + int64 nReserveBalance = 0; + if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) + return error("GetStakeWeight : invalid reserve balance amount"); + if (nBalance <= nReserveBalance) + return false; + + vector vwtxPrev; + + set > setCoins; + int64 nValueIn = 0; + + if (!SelectCoinsSimple(nBalance - nReserveBalance, GetTime(), nCoinbaseMaturity + 10, setCoins, nValueIn)) + return false; + + if (setCoins.empty()) + return false; + + nMinWeight = nMaxWeight = nWeight =0; + + CTxDB txdb("r"); + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + CTxIndex txindex; + { + LOCK2(cs_main, cs_wallet); + if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) + continue; + } + + int64_t nTimeWeight = GetWeight((int64_t)pcoin.first->nTime, (int64_t)GetTime()); + CBigNum bnCoinDayWeight = CBigNum(pcoin.first->vout[pcoin.second].nValue) * nTimeWeight / COIN / (24 * 60 * 60); + + // Weight is greater than zero + if (nTimeWeight > 0) + { + nWeight += bnCoinDayWeight.getuint64(); + } + + // Weight is greater than zero, but the maximum value isn't reached yet + if (nTimeWeight > 0 && nTimeWeight < nStakeMaxAge) + { + nMinWeight += bnCoinDayWeight.getuint64(); + } + + // Maximum weight was reached + if (nTimeWeight == nStakeMaxAge) + { + nMaxWeight += bnCoinDayWeight.getuint64(); + } + } + + return true; +} + // ppcoin: create coin stake transaction bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew) { diff --git a/src/wallet.h b/src/wallet.h index 78b2b09..d48a747 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -69,6 +69,7 @@ public: class CWallet : public CCryptoKeyStore { private: + bool SelectCoinsSimple(int64 nTargetValue, unsigned int nSpendTime, int nMinConf, std::set >& setCoinsRet, int64& nValueRet) const; bool SelectCoins(int64 nTargetValue, unsigned int nSpendTime, std::set >& setCoinsRet, int64& nValueRet) const; CWalletDB *pwalletdbEncryption; @@ -123,6 +124,7 @@ public: // check whether we are allowed to upgrade (or already support) to the named feature bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; } + void AvailableCoinsMinConf(std::vector& vCoins, int nConf) const; void AvailableCoins(std::vector& vCoins, bool fOnlyConfirmed=true) const; bool SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, int64& nValueRet) const; // keystore implementation @@ -177,6 +179,7 @@ public: bool CreateTransaction(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment); bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); + bool GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight); bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew); std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false, std::string strTxComment = ""); std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false, std::string strTxComment = ""); @@ -201,6 +204,13 @@ public: { return ::IsMine(*this, txout.scriptPubKey); } + /* bool IsMine(const CTransaction& tx) const + { + BOOST_FOREACH(const CTxOut& txout, tx.vout) + if (IsMine(txout) && txout.nValue >= nMinimumInputValue) + return true; + return false; + } */ int64 GetCredit(const CTxOut& txout) const { if (!MoneyRange(txout.nValue))