diff --git a/denarius-qt.pro b/denarius-qt.pro index f79f16b2..e8374ffc 100644 --- a/denarius-qt.pro +++ b/denarius-qt.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = Denarius -VERSION = 3.3.9.7 +VERSION = 3.3.9.8 INCLUDEPATH += src src/json src/qt src/qt/plugins/mrichtexteditor DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE CURL_STATICLIB CONFIG += no_include_pwd diff --git a/snapcraft.yaml b/snapcraft.yaml index 82d38d54..b1faf37e 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -3,7 +3,7 @@ # https://github.com/carsenk/denarius # By Carsen Klock name: denarius -version: '3.3.9.7' +version: '3.3.9.8' summary: Denarius description: | An open source hybrid cryptocurrency called Denarius, which features Fortuna Stakes (Masternodes), Staking, Mining, Multisig, and much more! diff --git a/src/activefortunastake.cpp b/src/activefortunastake.cpp index 50f93825..f1459e6d 100644 --- a/src/activefortunastake.cpp +++ b/src/activefortunastake.cpp @@ -75,7 +75,7 @@ void CActiveFortunastake::ManageStatus() // return; //} - printf("CActiveFortunastake::ManageStatus() - Is capable master node!\n"); + printf("CActiveFortunastake::ManageStatus() - Is a capable FortunaStake!\n"); status = FORTUNASTAKE_IS_CAPABLE; notCapableReason = ""; diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index cd87d862..f433bd7d 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -56,12 +56,13 @@ namespace Checkpoints ( 1469647, uint256("0x000000000035f3c2c5e21ea1d4ccd83fe1b59d37659bb3302bd9edfab67da312") ) ( 1701516, uint256("0x000000000021e83d2818325042fc528a63027de9ff7612bca0efcdda688c9672") ) ( 2487883, uint256("0x00000000000c66f7f18969f44c28509c7a3948da5155d6f3d1c674d458a0948b") ) + ( 3692415, uint256("0x0000000028605ffbf22ef461ba8a867fc3beaabf34dacb6d1737209eb7f70ed5") ) // ; static const CCheckpointData data = { &mapCheckpoints, - 1570646530, // * UNIX timestamp of last checkpoint block above ^^ + 1599322010, // * UNIX timestamp of last checkpoint block above ^^ 5033897, // * total number of transactions between genesis and last checkpoint // (the tx=... number in the SetBestChain debug.log lines) 5000.0 // * estimated number of transactions per day after checkpoint diff --git a/src/clientversion.h b/src/clientversion.h index f52e41c2..32efad7f 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -10,7 +10,7 @@ #define CLIENT_VERSION_MAJOR 3 #define CLIENT_VERSION_MINOR 3 #define CLIENT_VERSION_REVISION 9 -#define CLIENT_VERSION_BUILD 7 +#define CLIENT_VERSION_BUILD 8 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/denariusrpc.cpp b/src/denariusrpc.cpp index 62ee4179..8b27c57f 100644 --- a/src/denariusrpc.cpp +++ b/src/denariusrpc.cpp @@ -349,6 +349,7 @@ static const CRPCCommand vRPCCommands[] = { "sendalert", &sendalert, false, false}, { "gettxout", &gettxout, true, false }, { "importaddress", &importaddress, false, false }, + { "burn", &burn, false, false }, { "getnewstealthaddress", &getnewstealthaddress, false, false}, { "liststealthaddresses", &liststealthaddresses, false, false}, @@ -1333,6 +1334,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 0) ConvertTo(params[0]); if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "burn" && n > 0) ConvertTo(params[0]); if (strMethod == "settxfee" && n > 0) ConvertTo(params[0]); if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo(params[1]); if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo(params[1]); @@ -1345,7 +1347,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 1) ConvertTo(params[1]); if (strMethod == "getbalance" && n > 2) ConvertTo(params[2]); if (strMethod == "getblock" && n > 1) ConvertTo(params[1]); - if (strMethod == "getblockheader" && n > 1) ConvertTo(params[1]); + if (strMethod == "getblockheader" && n > 1) ConvertTo(params[1]); if (strMethod == "getblock_old" && n > 1) ConvertTo(params[1]); if (strMethod == "getblockbynumber" && n > 0) ConvertTo(params[0]); if (strMethod == "getblockbynumber" && n > 1) ConvertTo(params[1]); diff --git a/src/denariusrpc.h b/src/denariusrpc.h index db713aef..f48acb71 100644 --- a/src/denariusrpc.h +++ b/src/denariusrpc.h @@ -251,6 +251,7 @@ extern json_spirit::Value getblockbynumber(const json_spirit::Array& params, boo extern json_spirit::Value getcheckpoint(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value importaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value burn(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value proofofdata(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp extern json_spirit::Value jupiterversion(const json_spirit::Array& params, bool fHelp); // in rpcjupiter.cpp Denarius Jupiter diff --git a/src/fortuna.cpp b/src/fortuna.cpp index 8b278141..93fa51a3 100644 --- a/src/fortuna.cpp +++ b/src/fortuna.cpp @@ -40,12 +40,12 @@ CActiveFortunastake activeFortunastake; int RequestedFortunaStakeList = 0; //MIN_MN_PROTO_VERSION -int MIN_MN_PROTO_VERSION = 33900; // D v3.3.9.2 - Proto - 33900 +int MIN_MN_PROTO_VERSION = 33933; // D v3.3.9.8 - Proto - 33933 /* *** BEGIN FORTUNA MAGIC ********** Copyright 2014, Darkcoin Developers eduffield - evan@darkcoin.io - Copyright 2018-2019, Denarius Developers + Copyright 2018-2020, Denarius Developers carsenk - admin@denarius.io enkayz - enkayz@denarius.io */ diff --git a/src/fortuna.h b/src/fortuna.h index 52b46374..f960ef34 100644 --- a/src/fortuna.h +++ b/src/fortuna.h @@ -224,7 +224,7 @@ class CFortunaSession class CForTunaPool { public: - static const int PROTOCOL_VERSION = 33900; //33900, D v3.3.9.2 + static const int PROTOCOL_VERSION = 33933; //33933, D v3.3.9.8 // clients entries std::vector myEntries; diff --git a/src/fortunastake.cpp b/src/fortunastake.cpp index 5b751021..3141889e 100644 --- a/src/fortunastake.cpp +++ b/src/fortunastake.cpp @@ -40,6 +40,7 @@ std::map mapCacheBlockHashes; CMedianFilter mnMedianCount(10, 0); unsigned int mnCount = 0; int64_t nAverageFSIncome; +int64_t nAveragePayCount; // manage the fortunastake connections void ProcessFortunastakeConnections(){ @@ -618,6 +619,9 @@ int GetFortunastakeRank(CFortunaStake &tmn, CBlockIndex* pindex, int minProtocol bool CheckFSPayment(CBlockIndex* pindex, int64_t value, CFortunaStake &mn) { if (mn.nBlockLastPaid == 0) return true; // if we didn't find a payment for this MN, let it through regardless of rate + + //if (mn.nBlockLastPaid - vFortunastakes.count()) return false; + // find height // calculate average payment across all FS // check if value is > 25% higher @@ -627,11 +631,29 @@ bool CheckFSPayment(CBlockIndex* pindex, int64_t value, CFortunaStake &mn) { if (value > max) { return false; } + + CScript pubScript; + pubScript = GetScriptForDestination(mn.pubkey.GetID()); + CTxDestination address1; + ExtractDestination(pubScript, address1); + CBitcoinAddress address2(address1); + + // calculate pay count average across FS + // check if pay count is > 50% higher than the avg + nAveragePayCount = avgCount(vecFortunastakeScoresList); + if (nAveragePayCount < 1) return true; // if the pay count is less than 1 just let it through + int64_t maxed = nAveragePayCount * 12 / 8; + if (mn.payCount > maxed) { + printf("CheckFSPayment() Current payCount of %s FS is %d - payCount Overall Average %d\n", address2.ToString().c_str(), mn.payCount, nAveragePayCount); + return false; + } + return true; } bool CheckPoSFSPayment(CBlockIndex* pindex, int64_t value, CFortunaStake &mn) { if (mn.nBlockLastPaid == 0) return true; // if we didn't find a payment for this MN, let it through regardless of rate + // find height // calculate average payment across all FS // check if value is > 25% higher @@ -643,6 +665,22 @@ bool CheckPoSFSPayment(CBlockIndex* pindex, int64_t value, CFortunaStake &mn) { return false; } */ + CScript pubScript; + pubScript = GetScriptForDestination(mn.pubkey.GetID()); + CTxDestination address1; + ExtractDestination(pubScript, address1); + CBitcoinAddress address2(address1); + + // calculate pay count average across FS + // check if pay count is > 50% higher than the avg + nAveragePayCount = avgCount(vecFortunastakeScoresList); + if (nAveragePayCount < 1) return true; // if the pay count is less than 1 just let it through + int64_t maxed = nAveragePayCount * 12 / 8; + if (mn.payCount > maxed) { + printf("CheckPoSFSPayment() Current payCount of %s is %d - payCount Overall Average %d\n", address2.ToString().c_str(), mn.payCount, nAveragePayCount); + return false; + } + return true; } @@ -660,6 +698,19 @@ int64_t avg2(std::vector const& v) { return mean; } +int64_t avgCount(std::vector const& v) { + int n = 0; + int64_t mean = 0; + for (int i = 0; i < v.size(); i++) { + int64_t x = v[i].payCount; + int64_t delta = x - mean; + //TODO: implement in mandatory update, will reduce average & lead to rejections + if (v[i].payCount < 1) { continue; } // don't consider payees below 1 payment (pos only / new payees) + mean += delta/++n; + } + return mean; +} + int GetFortunastakeByRank(int findRank, int64_t nBlockHeight, int minProtocol) { if (IsInitialBlockDownload()) return 0; @@ -998,7 +1049,7 @@ void CFortunaStake::UpdateLastPaidBlock(const CBlockIndex *pindex, int nMaxBlock // TODO HERE: Scan the block for fortunastake payment amount BOOST_FOREACH(CTxOut txout, block.vtx[1].vout) if(mnpayee == txout.scriptPubKey) { - nBlockLastPaid = BlockReading->nHeight;\ + nBlockLastPaid = BlockReading->nHeight; int lastPay = pindexBest->nHeight - nBlockLastPaid; int value = txout.nValue; // TODO HERE: Check the nValue for the fortunastake payment amount @@ -1019,7 +1070,7 @@ void CFortunaStake::UpdateLastPaidBlock(const CBlockIndex *pindex, int nMaxBlock } // -// Deterministically calculate a given "score" for a fortunastake depending on how close it's hash is to +// Deterministically calculate a given "score" for a fortunastake with tribus depending on how close it's hash is to // the proof of work for that block. The further away they are the better, the furthest will win the election // and get paid this block // diff --git a/src/fortunastake.h b/src/fortunastake.h index 5ff2fe92..b9e61b44 100644 --- a/src/fortunastake.h +++ b/src/fortunastake.h @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018 The Denarius developers +// Copyright (c) 2017-2020 The Denarius developers // Copyright (c) 2009-2012 The Darkcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -264,6 +264,7 @@ int GetCurrentFortunaStake(int mod=1, int64_t nBlockHeight=0, int minProtocol=CF bool CheckFSPayment(CBlockIndex* pindex, int64_t value, CFortunaStake &mn); bool CheckPoSFSPayment(CBlockIndex* pindex, int64_t value, CFortunaStake &mn); int64_t avg2(std::vector const& v); +int64_t avgCount(std::vector const& v); int GetFortunastakeByVin(CTxIn& vin); int GetFortunastakeRank(CFortunaStake& tmn, CBlockIndex* pindex, int minProtocol=CFortunaStake::minProtoVersion); int GetFortunastakeByRank(int findRank, int64_t nBlockHeight=0, int minProtocol=CFortunaStake::minProtoVersion); diff --git a/src/kernel.cpp b/src/kernel.cpp index 4d3000dc..59bd56da 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Peercoin developers -// Copyright (c) 2017-2018 The Denarius developers +// Copyright (c) 2017-2020 The Denarius developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -20,6 +20,7 @@ static std::map mapStakeModifierCheckpoints = ( 1000000, 0x0164bdb4 ) ( 1701527, 0xb64daf99 ) ( 2487918, 0x518704f3 ) + ( 3692427, 0x20a869c0 ) //( 640106, 0x491697be ) Example of bad modifier checkpoint, must have proof-of-stake flag ; diff --git a/src/main.cpp b/src/main.cpp index 8000051c..5a3adc36 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1723,7 +1723,7 @@ bool IsInitialBlockDownload() GetFortunastakeRanks(pindexBest); } return state; - + } void static InvalidChainFound(CBlockIndex* pindexNew) @@ -2438,6 +2438,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) int64_t nFees = 0; int64_t nValueIn = 0; int64_t nValueOut = 0; + int64_t nAmountBurned = 0; int64_t nStakeReward = 0; unsigned int nSigOps = 0; BOOST_FOREACH(CTransaction& tx, vtx) @@ -2505,6 +2506,10 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) nValueIn += nTxValueIn; nValueOut += nTxValueOut; + for (const CTxOut& out : tx.vout) { + if(out.scriptPubKey.IsUnspendable()) + nAmountBurned += out.nValue; + } if (!tx.IsCoinStake()) nFees += nTxValueIn - nTxValueOut; if (tx.IsCoinStake()) @@ -2658,11 +2663,11 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (!CheckPoSFSPayment(pindex, vtx[1].vout[i].nValue, mn)) // CheckPoSFSPayment() { if (pindexBest->nHeight >= MN_ENFORCEMENT_ACTIVE_HEIGHT) { //Update PoS FS Payments to not go out of sync - printf("CheckBlock-POS() : Out-of-cycle fortunastake payment detected, rejecting block."); + //printf("CheckBlock-POS() : Out-of-cycle fortunastake payment detected, rejecting block."); + printf("CheckBlock-POS() : Out-of-cycle FortunaStake payment detected, rejecting block. rank:%d value:%s avg:%s payRate:%s payCount:%d\n",mn.nRank,FormatMoney(mn.payValue).c_str(),FormatMoney(nAverageFSIncome).c_str(),FormatMoney(mn.payRate).c_str(), mn.payCount); } else { printf("CheckBlock-POS(): This fortunastake payment is too aggressive and will be accepted after block %d\n", MN_ENFORCEMENT_ACTIVE_HEIGHT); } - //break; } else { if (fDebug) printf("CheckBlock-POS() : Payment meets rate requirement: payee has earnt %s against average %s\n",FormatMoney(mn.payValue).c_str(),FormatMoney(nAverageFSIncome).c_str()); } @@ -2784,9 +2789,9 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) { if (pindexBest->nHeight >= MN_ENFORCEMENT_ACTIVE_HEIGHT) { - return error("CheckBlock-POW() : Fortunastake overpayment detected, rejecting block. rank:%d value:%s avg:%s payRate:%s",mn.nRank,FormatMoney(mn.payValue).c_str(),FormatMoney(nAverageFSIncome).c_str(),FormatMoney(mn.payRate).c_str()); + printf("CheckBlock-POW() : Fortunastake overpayment detected, rejecting block. rank:%d value:%s avg:%s payRate:%s payCount:%d\n",mn.nRank,FormatMoney(mn.payValue).c_str(),FormatMoney(nAverageFSIncome).c_str(),FormatMoney(mn.payRate).c_str(), mn.payCount); } else { - if (fDebug) printf("WARNING: This fortunastake payment is too aggressive and will not be accepted after block %d\n", MN_ENFORCEMENT_ACTIVE_HEIGHT); + printf("WARNING: This fortunastake payment is too aggressive and will not be accepted after block %d\n", MN_ENFORCEMENT_ACTIVE_HEIGHT); } } else { if (fDebug) printf("CheckBlock-POW() : Payment meets rate requirement: payee has earnt %s against average %s\n",FormatMoney(mn.payValue).c_str(),FormatMoney(nAverageFSIncome).c_str()); @@ -2876,6 +2881,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) // ppcoin: track money supply and mint amount info pindex->nMint = nValueOut - nValueIn + nFees; pindex->nMoneySupply = (pindex->pprev? pindex->pprev->nMoneySupply : 0) + nValueOut - nValueIn; + pindex->nMoneySupply -= nAmountBurned; + assert(pindex->nMoneySupply >= 0); if (!txdb.WriteBlockIndex(CDiskBlockIndex(pindex))) return error("Connect() : WriteBlockIndex for pindex failed"); @@ -3702,7 +3709,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) //After block 1.5m, The Minimum FortunaStake Protocol Version is 31005 if(nBestHeight >= 1500000) { - MIN_MN_PROTO_VERSION = 33900; + MIN_MN_PROTO_VERSION = 33933; } // ppcoin: if responsible for sync-checkpoint send it @@ -5400,4 +5407,4 @@ int64_t GetFortunastakePayment(int nHeight, int64_t blockValue) int64_t ret = static_cast(blockValue * 1/3); //33% return ret; -} \ No newline at end of file +} diff --git a/src/qt/marketbrowser.cpp b/src/qt/marketbrowser.cpp index faffe53d..e0496479 100644 --- a/src/qt/marketbrowser.cpp +++ b/src/qt/marketbrowser.cpp @@ -29,6 +29,7 @@ QString bitcoing; QString dnrnewsfeed; QString dnrmarket; QString dollarg; +QString eurog; int mode=1; int o = 0; @@ -84,7 +85,7 @@ void MarketBrowser::parseNetworkResponse(QNetworkReply *finished ) emit networkError( finished->error() ); return; } - + if (what == kBaseUrl) // Denarius Price { @@ -92,7 +93,7 @@ if (what == kBaseUrl) // Denarius Price QString denarius = finished->readAll(); denarius2 = (denarius.toDouble()); denarius = QString::number(denarius2, 'f', 2); - + if(denarius > denariusp) { ui->denarius->setText("$" + denarius + ""); @@ -132,7 +133,7 @@ if (what == kBaseUrl2) // Denarius Market Cap QString dnrmc = finished->readAll(); dnrmc2 = (dnrmc.toDouble()); dnrmc = QString::number(dnrmc2, 'f', 2); - + if(dnrmc > dnrmcp) { ui->dnrmc->setText("$" + dnrmc + ""); @@ -153,7 +154,7 @@ if (what == kBaseUrl3) // Denarius BTC Price QString dnrbtc = finished->readAll(); dnrbtc2 = (dnrbtc.toDouble()); dnrbtc = QString::number(dnrbtc2, 'f', 8); - + if(dnrbtc > dnrbtcp) { ui->dnrbtc->setText("" + dnrbtc + " BTC"); diff --git a/src/qt/marketbrowser.h b/src/qt/marketbrowser.h index 566d9fe0..84d6e226 100644 --- a/src/qt/marketbrowser.h +++ b/src/qt/marketbrowser.h @@ -13,6 +13,7 @@ extern QString bitcoing; extern QString dollarg; +extern QString eurog; extern QString dnrmarket; extern QString dnrnewsfeed; @@ -29,7 +30,7 @@ class MarketBrowser : public QWidget public: explicit MarketBrowser(QWidget *parent = 0); ~MarketBrowser(); - + void setModel(ClientModel *model); private: diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 42dca310..9bb12688 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -23,7 +23,9 @@ const QString BaseURL = "http://denarius.io/dnrusd.php"; const QString BaseURL2 = "http://denarius.io/dnrbtc.php"; const QString BaseURL3 = "http://denarius.io/newsfeed.php"; +const QString BaseURL4 = "http://denarius.io/dnreur.php"; double denariusx; +double dnreurx; double dnrbtcx; class TxViewDelegate : public QAbstractItemDelegate @@ -112,13 +114,13 @@ OverviewPage::OverviewPage(QWidget *parent) : filter(0) { ui->setupUi(this); - - + + PriceRequest(); QObject::connect(&m_nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(parseNetworkResponse(QNetworkReply*))); connect(ui->refreshButton, SIGNAL(pressed()), this, SLOT( PriceRequest())); - + //Refresh the Est. Balances and News automatically refreshbtnTimer = new QTimer(this); connect(refreshbtnTimer, SIGNAL(timeout()), this, SLOT( PriceRequest())); @@ -150,6 +152,7 @@ void OverviewPage::PriceRequest() getRequest(BaseURL); getRequest(BaseURL2); getRequest(BaseURL3); + getRequest(BaseURL4); //updateDisplayUnit(); //Segfault Fix } @@ -203,6 +206,16 @@ if (what == BaseURL3) // Denarius News Feed dnrnewsfeed = dnewsfeed; } +if (what == BaseURL4) // Denarius EUR Price +{ + + // QNetworkReply is a QIODevice. So we read from it just like it was a file + QString dnreur = finished->readAll(); + dnreurx = (dnreur.toDouble()); + dnreur = QString::number(dnreurx, 'f', 4); + + eurog = dnreur; +} finished->deleteLater(); } @@ -251,20 +264,20 @@ void OverviewPage::setBalance(qint64 balance, qint64 lockedbalance, qint64 stake double dollarg2 = (dollarg.toDouble() * totalBalance / 100000000); total = QString::number(dollarg2, 'f', 2); ui->labelUSDTotal->setText("$" + total + " USD"); - - QString eurtotal; - double dollarg1 = (dollarg.toDouble() * totalBalance * 0.886 / 100000000); - eurtotal = QString::number(dollarg1, 'f', 2); - ui->labelEURTotal->setText("€" + eurtotal + " EUR"); - ui->labelBTCTotal->setText(BitcoinUnits::formatWithUnit(unitdBTC, bitcoing.toDouble() * totalBalance)); + QString eurtotal; + double eurog1 = (eurog.toDouble() * totalBalance / 100000000); + eurtotal = QString::number(eurog1, 'f', 4); + ui->labelEURTotal->setText("€" + eurtotal + " EUR"); + + ui->labelBTCTotal->setText("₿" + BitcoinUnits::formatWithUnit(unitdBTC, bitcoing.toDouble() * totalBalance)); ui->labelTradeLink->setTextFormat(Qt::RichText); ui->labelTradeLink->setTextInteractionFlags(Qt::TextBrowserInteraction); ui->labelTradeLink->setOpenExternalLinks(true); - + QString news; news = dnrnewsfeed; - ui->labelNewsFeed->setText(news); + ui->labelNewsFeed->setText(news); // only show immature (newly mined) balance if it's non-zero, so as not to complicate things // for the non-mining users @@ -292,7 +305,7 @@ void OverviewPage::updateWatchOnlyLabels(bool showWatchOnly) ui->labelWatchAvailable->setVisible(showWatchOnly); // show watch-only available balance ui->labelWatchPending->setVisible(showWatchOnly); // show watch-only pending balance ui->labelWatchTotal->setVisible(showWatchOnly); // show watch-only total balance - + ui->watch1->setVisible(showWatchOnly); ui->watch2->setVisible(showWatchOnly); ui->labelWatchImmatureText->setVisible(showWatchOnly); diff --git a/src/rpcfortuna.cpp b/src/rpcfortuna.cpp index 214c1b8e..f066648f 100644 --- a/src/rpcfortuna.cpp +++ b/src/rpcfortuna.cpp @@ -291,7 +291,7 @@ Value fortunastake(const Array& params, bool fHelp) if (strCommand == "start") { - if(!fFortunaStake) return "you must set fortunastake=1 in the configuration"; + if(!fFortunaStake) return "You must set fortunastake=1 in your denarius.conf"; if(pwalletMain->IsLocked()) { SecureString strWalletPass; @@ -305,7 +305,7 @@ Value fortunastake(const Array& params, bool fHelp) } if(!pwalletMain->Unlock(strWalletPass)){ - return "incorrect passphrase"; + return "Incorrect passphrase"; } } diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index e4778e2c..1c809e82 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -67,7 +67,7 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry) entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); entry.push_back(Pair("blockindex", wtx.nIndex)); int64_t nTime = 0; - nTime = mapBlockIndex[wtx.hashBlock]->nTime; + nTime = mapBlockIndex[wtx.hashBlock]->nTime; entry.push_back(Pair("blocktime", nTime)); }; @@ -96,7 +96,7 @@ Value getinfo(const Array& params, bool fHelp) proxyType proxy; GetProxy(NET_IPV4, proxy); - + uint64_t nMinWeight = 0, nMaxWeight = 0, nWeight = 0; pwalletMain->GetStakeWeight(*pwalletMain, nMinWeight, nMaxWeight, nWeight); @@ -113,7 +113,7 @@ Value getinfo(const Array& params, bool fHelp) obj.push_back(Pair("immature", ValueFromAmount(pwalletMain->GetImmatureBalance()))); obj.push_back(Pair("blocks", (int)nBestHeight)); obj.push_back(Pair("timeoffset", (int64_t)GetTimeOffset())); - obj.push_back(Pair("moneysupply", ValueFromAmount(pindexBest->nMoneySupply))); + obj.push_back(Pair("moneysupply", ValueFromAmount(pindexBest->nMoneySupply))); obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("datareceived", bytesReadable(CNode::GetTotalBytesRecv()))); obj.push_back(Pair("datasent", bytesReadable(CNode::GetTotalBytesSent()))); @@ -136,11 +136,11 @@ Value getinfo(const Array& params, bool fHelp) diff.push_back(Pair("proof-of-work", GetDifficulty())); diff.push_back(Pair("proof-of-stake", GetDifficulty(GetLastBlockIndex(pindexBest, true)))); - + obj.push_back(Pair("difficulty", diff)); obj.push_back(Pair("netmhashps", GetPoWMHashPS())); obj.push_back(Pair("netstakeweight", GetPoSKernelPS())); - + obj.push_back(Pair("weight", (uint64_t)nWeight)); obj.push_back(Pair("testnet", fTestNet)); @@ -153,7 +153,7 @@ Value getinfo(const Array& params, bool fHelp) obj.push_back(Pair("mininput", ValueFromAmount(nMinimumInputValue))); obj.push_back(Pair("datadir", GetDataDir().string())); obj.push_back(Pair("initialblockdownload", IsInitialBlockDownload())); - if(fDebug) + if(fDebug) { obj.push_back(Pair("debug", fDebug)); obj.push_back(Pair("debugnet", fDebugNet)); @@ -184,7 +184,7 @@ Value walletstatus(const Array& params, bool fHelp) throw runtime_error( "walletstatus\n" "Returns the current wallet lock and encryption status."); - + Object obj; if (pwalletMain->IsCrypted()) obj.push_back(Pair("unlocked_until", (int64_t)nWalletUnlockTime / 1000)); @@ -196,7 +196,7 @@ Value walletstatus(const Array& params, bool fHelp) obj.push_back(Pair("wallet_status", "stakingonly")); if (pwalletMain->IsLocked() && pwalletMain->IsCrypted()) obj.push_back(Pair("wallet_status", "locked")); - + return obj; } @@ -394,7 +394,7 @@ Value sendtoaddress(const Array& params, bool fHelp) + HelpRequiringPassphrase()); EnsureWalletIsUnlocked(); - + /* if (params[0].get_str().length() > 75 && IsStealthAddress(params[0].get_str())) @@ -437,6 +437,61 @@ Value sendtoaddress(const Array& params, bool fHelp) return wtx.GetHash().GetHex(); } +Value burn(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw std::runtime_error( + "burn amount ( \"comment\" )\n" + "\nBurn an amount of coins. The amount is a real and is rounded to the nearest 0.00000001\n" + + HelpRequiringPassphrase() + "\n" + + "\nArguments:\n" + "1. \"amount\" (numeric, required) The amount in D to burn. eg 0.1\n" + "2. \"comment\" (string, optional) A comment embedded in the transaction on the blockchain.\n" + + "\nResult:\n" + "\"transactionid\" (string) The transaction id.\n" + + "\nExamples:\n" + + ("burn", "0.1") + + ("burn", "0.1 \"hello world\"") + + ("burn", "0.1, \"hello world\"")); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Amount + CAmount nAmount = AmountFromValue(params[0]); + if (nAmount > pwalletMain->GetBalance()) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + + // Comment + CWalletTx wtx; + CScript burnScript = CScript() << OP_RETURN; + if (params.size() > 1 && !params[1].is_null() && !params[1].get_str().empty()) { + if (params[1].get_str().length() > MAX_OP_RETURN_RELAY - 3) + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Comment cannot be longer than %u characters", MAX_OP_RETURN_RELAY - 3)); + burnScript << ToByteVector(params[1].get_str()); + } + + EnsureWalletIsUnlocked(); + CReserveKey reservekey(pwalletMain); + int64_t nFeeRequired; + std::string strError = "CreateTransaction() failed."; + std::string sNarr = ""; + + if (!pwalletMain->CreateTransaction(burnScript, nAmount, sNarr, wtx, reservekey, nFeeRequired, nullptr)) { + if (nAmount + nFeeRequired > pwalletMain->GetBalance()) + strError = "Error: This transaction requires a transaction fee of at least " + FormatMoney(nFeeRequired) + " because of its amount, complexity, or use of recently received funds!"; + LogPrintf("BurnCoins() : %s\n", strError); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + if (!pwalletMain->CommitTransaction(wtx, reservekey)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); + + return wtx.GetHash().GetHex(); +} + + Value listaddressgroupings(const Array& params, bool fHelp) { if (fHelp) @@ -486,10 +541,10 @@ Value listaddressgroups(const Array& params, bool fHelp) BOOST_FOREACH(CTxDestination address, grouping) { obj.push_back(Pair("address", CBitcoinAddress(address).ToString())); - obj.push_back(Pair("amount", ValueFromAmount(balances[address]))); + obj.push_back(Pair("amount", ValueFromAmount(balances[address]))); } } - ret.push_back(obj); + ret.push_back(obj); return ret; } @@ -1717,7 +1772,7 @@ Value walletpassphrase(const Array& params, bool fHelp) if (!pwalletMain->IsLocked()) throw JSONRPCError(RPC_WALLET_ALREADY_UNLOCKED, "Error: Wallet is already unlocked, use walletlock first if need to change unlock settings."); - + // Note that the walletpassphrase is stored in params[0] which is not mlock()ed SecureString strWalletPass; strWalletPass.reserve(100); @@ -1740,9 +1795,9 @@ Value walletpassphrase(const Array& params, bool fHelp) //LOCK(cs_nWalletUnlockTime); //nWalletUnlockTime = GetTime() + pnSleepTime; NewThread(ThreadCleanWalletPassphrase, pnSleepTime); - + //fWalletUnlockStakingOnly = false; - + // Denarius: if user OS account compromised prevent trivial sendmoney commands // if (params.size() > 2 && params[2].get_bool() == true) // fWalletUnlockStakingOnly = true; @@ -2400,7 +2455,7 @@ Value scanforalltxns(const Array& params, bool fHelp) throw runtime_error( "scanforalltxns [fromHeight]\n" "Scan blockchain for owned transactions."); - + Object result; int32_t nFromHeight = 0; diff --git a/src/script.h b/src/script.h index e2615364..098c67a0 100644 --- a/src/script.h +++ b/src/script.h @@ -839,7 +839,12 @@ class CScript : public std::vector void SetDestination(const CTxDestination& address); void SetMultisig(int nRequired, const std::vector& keys); - void SetMultisigpub(int nRequired, const std::vector& keys); + void SetMultisigpub(int nRequired, const std::vector& keys); + + bool IsUnspendable() const + { + return (size() > 0 && *begin() == OP_RETURN); + } std::string ToString(bool fShort=false) const { diff --git a/src/version.h b/src/version.h index 4de8509d..ba828b99 100644 --- a/src/version.h +++ b/src/version.h @@ -30,20 +30,20 @@ static const int DATABASE_VERSION = 21212; // network protocol versioning // -static const int PROTOCOL_VERSION = 33900; //Protocol is now 33900 as of D v3.3.9.2 +static const int PROTOCOL_VERSION = 33933; //Protocol is now 33933 as of D v3.3.9.8 // intial proto version, to be increased after version/verack negotiation -static const int INIT_PROTO_VERSION = 33900; // Bumped up from 21212 to 33900 v3.3.9.2 +static const int INIT_PROTO_VERSION = 33933; // Bumped up from 21212 to 33933 v3.3.9.8 // disconnect from peers older than this proto version -static const int MIN_PEER_PROTO_VERSION = 33900; +static const int MIN_PEER_PROTO_VERSION = 33933; // Don't forget to change proto in FORTUNA.h as well!! On Block 1.5m this will be 31005 extern int MIN_MN_PROTO_VERSION; // nTime field added to CAddress, starting with this version; // if possible, avoid requesting addresses nodes older than this -static const int CADDR_TIME_VERSION = 33900; // start sharing node timeinfo with this proto version 33500 +static const int CADDR_TIME_VERSION = 33933; // start sharing node timeinfo with this proto version 33500 // only request blocks from nodes outside this range of versions static const int NOBLKS_VERSION_START = 70002;