From 304ab6c7ab8468330c30f471359326a71f7f0b3e Mon Sep 17 00:00:00 2001 From: Evan Duffield Date: Sun, 12 Jul 2015 14:02:39 -0700 Subject: [PATCH] Various improvements to the proposal system - Proposal scripts are now checked correctly - Fee transactions are created correctly for IX and non-IX types --- src/instantx.cpp | 4 ++- src/masternode-budget.cpp | 53 ++++++------------------------------ src/masternode-budget.h | 2 +- src/rpcmasternode-budget.cpp | 33 ++++++---------------- src/script/script.cpp | 1 - 5 files changed, 22 insertions(+), 71 deletions(-) diff --git a/src/instantx.cpp b/src/instantx.cpp index 6c0c6206d..33b2249aa 100644 --- a/src/instantx.cpp +++ b/src/instantx.cpp @@ -57,7 +57,9 @@ void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream& } BOOST_FOREACH(const CTxOut o, tx.vout){ - if(!o.scriptPubKey.IsNormalPaymentScript()){ + // IX supports normal scripts and unspendable scripts (used in DS collateral and Budget collateral). + // TODO: Look into other script types that are normal and can be included + if(!o.scriptPubKey.IsNormalPaymentScript() && !o.scriptPubKey.IsUnspendable()){ LogPrintf("ProcessMessageInstantX::ix - Invalid Script %s\n", tx.ToString().c_str()); return; } diff --git a/src/masternode-budget.cpp b/src/masternode-budget.cpp index 0d2013014..c01d977dc 100644 --- a/src/masternode-budget.cpp +++ b/src/masternode-budget.cpp @@ -32,10 +32,8 @@ int GetBudgetPaymentCycleBlocks(){ return 50; } -bool IsBudgetCollateralValid(uint256 nTxCollateralHash, std::string& strError) +bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError) { - return true; - CTransaction txCollateral; uint256 hash; if(!GetTransaction(nTxCollateralHash, txCollateral, hash, true)){ @@ -46,56 +44,23 @@ bool IsBudgetCollateralValid(uint256 nTxCollateralHash, std::string& strError) if(txCollateral.vout.size() < 1) return false; if(txCollateral.nLockTime != 0) return false; - int64_t nValueIn = 0; - int64_t nValueOut = 0; - bool missingTx = false; + CScript findScript; + findScript << OP_RETURN << ToByteVector(nExpectedHash); + bool foundOpReturn = false; BOOST_FOREACH(const CTxOut o, txCollateral.vout){ - nValueOut += o.nValue; - - if(!o.scriptPubKey.IsNormalPaymentScript()){ + if(!o.scriptPubKey.IsNormalPaymentScript() && !o.scriptPubKey.IsUnspendable()){ LogPrintf ("CBudgetProposalBroadcast::FeeTXValid - Invalid Script %s\n", txCollateral.ToString().c_str()); return false; } - } + if(o.scriptPubKey == findScript && o.nValue >= BUDGET_FEE_TX) foundOpReturn = true; - bool foundOpReturn = false; - BOOST_FOREACH(const CTxIn i, txCollateral.vin){ - CTransaction tx2; - uint256 hash; - if(GetTransaction(i.prevout.hash, tx2, hash, true)){ - if(tx2.vout.size() > i.prevout.n) { - nValueIn += tx2.vout[i.prevout.n].nValue; - } - } else{ - missingTx = true; - } } - if(!foundOpReturn){ - - } - - if(missingTx){ - if(fDebug) LogPrintf ("CBudgetProposalBroadcast::FeeTXValid - Unknown inputs in collateral transaction - %s\n", txCollateral.ToString().c_str()); + LogPrintf ("CBudgetProposalBroadcast::IsBudgetCollateralValid - Couldn't find opReturn %s\n", txCollateral.ToString().c_str()); return false; } - //collateral transactions are required to pay out BUDGET_FEE_TX as a fee to the miners - if(nValueIn - nValueOut < BUDGET_FEE_TX) { - if(fDebug) LogPrintf ("CBudgetProposalBroadcast::FeeTXValid - did not include enough fees in transaction %d\n%s\n", nValueOut-nValueIn, txCollateral.ToString().c_str()); - return false; - } - - if(fDebug) LogPrintf("CBudgetProposalBroadcast::FeeTXValid %s\n", txCollateral.ToString().c_str()); - - CValidationState state; - if(!AcceptableInputs(mempool, state, txCollateral, true, NULL)){ - if(fDebug) LogPrintf ("CBudgetProposalBroadcast::FeeTXValid - didn't pass IsAcceptable\n"); - return false; - } - - return true; return true; } @@ -734,7 +699,7 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData budgetProposalBroadcast.nTime = GetAdjustedTime(); std::string strError = ""; - if(!IsBudgetCollateralValid(budgetProposalBroadcast.nFeeTXHash, strError)){ + if(!IsBudgetCollateralValid(budgetProposalBroadcast.nFeeTXHash, budgetProposalBroadcast.GetHash(), strError)){ LogPrintf("Proposal FeeTX is not valid - %s - %s\n", budgetProposalBroadcast.nFeeTXHash.ToString(), strError); return; } @@ -794,7 +759,7 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData } std::string strError = ""; - if(!IsBudgetCollateralValid(finalizedBudgetBroadcast.nFeeTXHash, strError)){ + if(!IsBudgetCollateralValid(finalizedBudgetBroadcast.nFeeTXHash, finalizedBudgetBroadcast.GetHash(), strError)){ LogPrintf("Finalized Budget FeeTX is not valid - %s - %s\n", finalizedBudgetBroadcast.nFeeTXHash.ToString(), strError); return; } diff --git a/src/masternode-budget.h b/src/masternode-budget.h index 40d95f518..d7690d727 100644 --- a/src/masternode-budget.h +++ b/src/masternode-budget.h @@ -44,7 +44,7 @@ void DumpBudgets(); int GetBudgetPaymentCycleBlocks(); //Check the collateral transaction for the budget proposal/finalized budget -bool IsBudgetCollateralValid(uint256 nTxCollateralHash, std::string& strError); +bool IsBudgetCollateralValid(uint256 nTxCollateralHash, uint256 nExpectedHash, std::string& strError); /** Save Budget Manager (budget.dat) */ diff --git a/src/rpcmasternode-budget.cpp b/src/rpcmasternode-budget.cpp index c748b849f..824f339c6 100644 --- a/src/rpcmasternode-budget.cpp +++ b/src/rpcmasternode-budget.cpp @@ -88,27 +88,21 @@ Value mnbudget(const Array& params, bool fHelp) // Parse Dash address CScript scriptPubKey = GetScriptForDestination(address.Get()); - CAmount nAmount = AmountFromValue(params[6]); - CPubKey pubKeyMasternode; - CKey keyMasternode; - std::string errorMessage; - - if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) - return(" Error upon calling SetKey"); - //************************************************************************* CBudgetProposalBroadcast budgetProposalBroadcast(strProposalName, strURL, nPaymentCount, scriptPubKey, nAmount, nBlockStart, 0); - std::string strCommand = "tx"; + std::string cmd = "tx"; bool useIX = true; - if (params.size() > 7) + + if (params.size() > 7){ useIX = (params[7].get_str() == "true" ? true : false); + } if(useIX) { - strCommand = "ix"; + cmd = "ix"; } CWalletTx wtx; @@ -117,7 +111,7 @@ Value mnbudget(const Array& params, bool fHelp) // make our change address CReserveKey reservekey(pwalletMain); //send the tx to the network - pwalletMain->CommitTransaction(wtx, reservekey, strCommand); + pwalletMain->CommitTransaction(wtx, reservekey, cmd); return wtx.GetHash().ToString().c_str(); @@ -172,23 +166,14 @@ Value mnbudget(const Array& params, bool fHelp) // Parse Dash address CScript scriptPubKey = GetScriptForDestination(address.Get()); - CAmount nAmount = AmountFromValue(params[6]); - - CPubKey pubKeyMasternode; - CKey keyMasternode; - std::string errorMessage; - - if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) - return(" Error upon calling SetKey"); - uint256 hash = ParseHashV(params[7], "parameter 1"); //create the proposal incase we're the first to make it CBudgetProposalBroadcast budgetProposalBroadcast(strProposalName, strURL, nPaymentCount, scriptPubKey, nAmount, nBlockStart, hash); std::string strError = ""; - if(!IsBudgetCollateralValid(hash ,strError)){ + if(!IsBudgetCollateralValid(hash, budgetProposalBroadcast.GetHash(), strError)){ return "Proposal FeeTX is not valid - " + hash.ToString() + " - " + strError; } @@ -500,7 +485,7 @@ Value mnfinalbudget(const Array& params, bool fHelp) std::string errorMessage; if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) - return(" Error upon calling SetKey"); + return("Masternode signing error, could not set key correctly"); //create transaction uint256 hash = 0; @@ -555,7 +540,7 @@ Value mnfinalbudget(const Array& params, bool fHelp) CKey keyMasternode; if(!darkSendSigner.SetKey(mne.getPrivKey(), errorMessage, keyMasternode, pubKeyMasternode)){ - printf(" Error upon calling SetKey for %s\n", mne.getAlias().c_str()); + printf(" Masternode signing error, could not set key correctly %s\n", mne.getAlias().c_str()); failed++; continue; } diff --git a/src/script/script.cpp b/src/script/script.cpp index 63ed94269..d283977e4 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -4,7 +4,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "script.h" - #include "tinyformat.h" #include "utilstrencodings.h"