From 0b4cc80c9c6c152d6d45b180840296a4606c48aa Mon Sep 17 00:00:00 2001 From: awitherow Date: Wed, 10 Jan 2018 15:41:54 -0500 Subject: [PATCH] add ability to burn via rpc --- README.md | 2 +- share/setup.nsi | 6 +++--- src/clientversion.h | 2 +- src/main.cpp | 36 +++++++++++++++++++++++++++++------- src/main.h | 4 +++- src/miner.cpp | 3 ++- src/rpcwallet.cpp | 26 ++++++++++++++++++++++++++ src/script.cpp | 1 + src/script.h | 3 ++- 9 files changed, 68 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index d0e5e4f..7ee2d8b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -BuzzCoin v3.0 +BuzzCoin v3.0.1 Copyright (c) 2013 NovaCoin Developers Copyright (c) 2011-2012 PPCoin Developers Copyright (c) 2017 BUZZ Developers Distributed under the MIT/X11 software diff --git a/share/setup.nsi b/share/setup.nsi index 3454e24..036f8a9 100644 --- a/share/setup.nsi +++ b/share/setup.nsi @@ -5,7 +5,7 @@ SetCompressor /SOLID lzma # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" -!define VERSION 0.3.0 +!define VERSION 0.3.0.1 !define COMPANY "NovaCoin project" !define URL http://www.novacoin.ru/ @@ -45,13 +45,13 @@ Var StartMenuGroup !insertmacro MUI_LANGUAGE English # Installer attributes -OutFile novacoin-0.3.0-win32-setup.exe +OutFile novacoin-0.3.0.1-win32-setup.exe InstallDir $PROGRAMFILES\NovaCoin CRCCheck on XPStyle on BrandingText " " ShowInstDetails show -VIProductVersion 0.3.0.0 +VIProductVersion 0.3.0.1.0 VIAddVersionKey ProductName NovaCoin VIAddVersionKey ProductVersion "${VERSION}" VIAddVersionKey CompanyName "${COMPANY}" diff --git a/src/clientversion.h b/src/clientversion.h index 9275c66..63abca6 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -8,7 +8,7 @@ // These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 3 #define CLIENT_VERSION_MINOR 0 -#define CLIENT_VERSION_REVISION 0 +#define CLIENT_VERSION_REVISION 1 #define CLIENT_VERSION_BUILD 0 // Set to true for release, false for prerelease or test build diff --git a/src/main.cpp b/src/main.cpp index 3cd5971..5d52827 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -787,13 +787,16 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool fLimitFree, boo // At default rate it would take over a month to fill 1GB if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000) return error("AcceptToMemoryPool : free transaction rejected by rate limiter"); + LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); dFreeCount += nSize; } + uint64_t nBurnCoins = 0; + // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. - if (!tx.ConnectInputs(txdb, mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false, STANDARD_SCRIPT_VERIFY_FLAGS)) + if (!tx.ConnectInputs(txdb, mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, nBurnCoins, false, false, STANDARD_SCRIPT_VERIFY_FLAGS)) { return error("AcceptToMemoryPool : ConnectInputs failed %s", hash.ToString()); } @@ -807,7 +810,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CTransaction &tx, bool fLimitFree, boo // There is a similar check in CreateNewBlock() to prevent creating // invalid blocks, however allowing such transactions into the mempool // can be exploited as a DoS attack. - if (!tx.ConnectInputs(txdb, mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false, MANDATORY_SCRIPT_VERIFY_FLAGS)) + if (!tx.ConnectInputs(txdb, mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, nBurnCoins, false, false, MANDATORY_SCRIPT_VERIFY_FLAGS)) { return error("AcceptToMemoryPool: : BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString()); } @@ -1383,7 +1386,7 @@ int64_t CTransaction::GetValueIn(const MapPrevTx& inputs) const } bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, map& mapTestPool, const CDiskTxPos& posThisTx, - const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, unsigned int flags) + const CBlockIndex* pindexBlock, uint64_t &nBurnCoins, bool fBlock, bool fMiner, unsigned int flags) { // Take over previous transactions' spent pointers // fBlock is true when this is called from AcceptBlock when a new best-block is added to the blockchain @@ -1403,6 +1406,16 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, map= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %u %u prev tx %s\n%s", GetHash().ToString(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString(), txPrev.ToString())); + // Coins Burning + // if OP_BURN is set, destroy selected coins. + for (unsigned int i = 0; i < vout.size(); i++) { + if (vout[i].scriptPubKey[1] == OP_BURN) { + nBurnCoins += vout[i].nValue; + if (fDebug) + LogPrintf("ConnectInputs() : burning coins %ld\n", vout[i].nValue); + } + } + // If prev is coinbase or coinstake, check that it's matured if (txPrev.IsCoinBase() || txPrev.IsCoinStake()) for (const CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < nCoinbaseMaturity; pindex = pindex->pprev) @@ -1543,6 +1556,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) int64_t nFees = 0; int64_t nValueIn = 0; int64_t nValueOut = 0; + int64_t nBurnCoins = 0; int64_t nStakeReward = 0; unsigned int nSigOps = 0; BOOST_FOREACH(CTransaction& tx, vtx) @@ -1601,13 +1615,18 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (tx.IsCoinStake()) nStakeReward = nTxValueOut - nTxValueIn; - if (!tx.ConnectInputs(txdb, mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, flags)) + if (!tx.ConnectInputs(txdb, mapInputs, mapQueuedChanges, posThisTx, pindex, nBurnCoins, true, false, flags)) return false; } mapQueuedChanges[hashTx] = CTxIndex(posThisTx, tx.vout.size()); } + if (nBurnCoins > 0 && fDebug) { + LogPrintf("ConnectBlock() : burning coins %s\n", FormatMoney(nBurnCoins)); + } + + if (IsProofOfWork()) { int64_t nReward = GetProofOfWorkReward(nFees, pindex); @@ -1632,7 +1651,7 @@ 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 = ((pindex->pprev ? pindex->pprev->nMoneySupply : 0) + nValueOut - nValueIn) - nBurnCoins; if (!txdb.WriteBlockIndex(CDiskBlockIndex(pindex))) return error("Connect() : WriteBlockIndex for pindex failed"); @@ -1935,10 +1954,13 @@ bool CTransaction::GetCoinAge(CTxDB& txdb, uint64_t& nCoinAge, CBlockIndex* pind // Read block header CBlock block; - if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) { return false; // unable to read block of previous transaction - if (block.GetBlockTime() + GetMinStakeAge(pindex) > nTime) + } + + if (block.GetBlockTime() + GetMinStakeAge(pindex) > nTime){ continue; // only count coins meeting min age requirement + } int64_t nValueIn = txPrev.vout[txin.prevout.n].nValue; bnCentSecond += CBigNum(nValueIn) * (nTime-txPrev.nTime) / CENT; diff --git a/src/main.h b/src/main.h index a229c12..ba64f74 100644 --- a/src/main.h +++ b/src/main.h @@ -391,7 +391,9 @@ class CTransaction */ bool ConnectInputs(CTxDB& txdb, MapPrevTx inputs, std::map& mapTestPool, const CDiskTxPos& posThisTx, - const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, unsigned int flags = STANDARD_SCRIPT_VERIFY_FLAGS); + const CBlockIndex* pindexBlock, uint64_t &nBurnCoins, bool fBlock, bool fMiner, + unsigned int flags = STANDARD_SCRIPT_VERIFY_FLAGS); + bool CheckTransaction() const; bool GetCoinAge(CTxDB& txdb, uint64_t& nCoinAge, CBlockIndex* pindex) const; // ppcoin: get transaction coin age diff --git a/src/miner.cpp b/src/miner.cpp index 510757c..cf4ed9b 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -311,7 +311,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey, bool fProofOfStake, int64_t* pFe // Note that flags: we don't want to set mempool/IsStandard() // policy here, but we still have to ensure that the block we // create only contains transactions that are valid in new blocks. - if (!tx.ConnectInputs(txdb, mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, false, true, MANDATORY_SCRIPT_VERIFY_FLAGS)) + uint64_t nBurnCoins = 0; + if (!tx.ConnectInputs(txdb, mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nBurnCoins, false, true, MANDATORY_SCRIPT_VERIFY_FLAGS)) continue; mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(1,1,1), tx.vout.size()); swap(mapTestPool, mapTestPoolTmp); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index ec56f76..7084714 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -76,6 +76,32 @@ string AccountFromValue(const Value& value) return strAccount; } +Value burn(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 1) + throw runtime_error( + "burn \n" + " is a real and is rounded to the nearest 0.00000001" + + HelpRequiringPassphrase()); + + CScript scriptPubKey; + scriptPubKey = CScript() << OP_RETURN << OP_BURN; + + // Amount + int64_t nAmount = AmountFromValue(params[0]); + + if (pwalletMain->IsLocked()) + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); + + CWalletTx wtx; + string strError = pwalletMain->SendMoney(scriptPubKey, nAmount, wtx); + if (strError != "") { + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + + return wtx.GetHash().GetHex(); +} + Value getnewpubkey(const Array& params, bool fHelp) { diff --git a/src/script.cpp b/src/script.cpp index 239c61e..c48c72c 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -149,6 +149,7 @@ const char* GetOpName(opcodetype opcode) case OP_ENDIF : return "OP_ENDIF"; case OP_VERIFY : return "OP_VERIFY"; case OP_RETURN : return "OP_RETURN"; + case OP_BURN : return "OP_BURN"; // stack ops case OP_TOALTSTACK : return "OP_TOALTSTACK"; diff --git a/src/script.h b/src/script.h index 0ff6966..e05cb4f 100644 --- a/src/script.h +++ b/src/script.h @@ -234,7 +234,8 @@ enum opcodetype OP_NOP9 = 0xb8, OP_NOP10 = 0xb9, - + // extra control funcion + OP_BURN = 0xd0, // template matching params OP_SMALLDATA = 0xf9,