diff --git a/src/init.cpp b/src/init.cpp index 6e9ead8144..0b0bba6810 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1190,7 +1190,6 @@ bool AppInit2(boost::thread_group& threadGroup) threadGroup.create_thread(boost::bind(&ThreadCheckDarkSendPool)); - // ********************************************************* Step 11: load peers uiInterface.InitMessage(_("Loading addresses...")); diff --git a/src/main.cpp b/src/main.cpp index 9a61a7eabb..82cd23b980 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3960,6 +3960,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) BOOST_FOREACH(const CTxOut o, out){ nValueOut += o.nValue; tx.vout.push_back(o); + + if(o.scriptPubKey.size() != 25){ + printf("dsi - non-standard pubkey detected! %s\n", o.scriptPubKey.ToString().c_str()); + accepted = 0; + error = "non-standard pubkey detected"; + pfrom->PushMessage("dssu", darkSendPool.GetState(), darkSendPool.GetEntriesCount(), accepted, error); + return false; + } + } BOOST_FOREACH(const CTxIn i, in){ @@ -5942,7 +5951,7 @@ struct CompareValueOnly int randomizeList (int i) { return std::rand()%i;} -void CDarkSendPool::SetNull(){ +void CDarkSendPool::SetNull(bool clearEverything){ //printf("CDarkSendPool::SetNull()\n"); if(fMasterNode){ @@ -5961,6 +5970,10 @@ void CDarkSendPool::SetNull(){ entriesCount = 0; lastEntryAccepted = 0; countEntriesAccepted = 0; + + if(clearEverything){ + myEntries.clear(); + } } bool CDarkSendPool::SetCollateralAddress(std::string strAddress){ @@ -6078,7 +6091,7 @@ void CDarkSendPool::Check() // move on to next phase, allow 3 seconds incase the masternode wants to send us anything else if((state == POOL_STATUS_TRANSMISSION && fMasterNode) || (state == POOL_STATUS_SIGNING && completedTransaction) ) { printf("CDarkSendPool::Check() -- COMPLETED -- RESETTING \n"); - SetNull(); + SetNull(true); UnlockCoins(); if(fMasterNode) RelayDarkSendStatus(darkSendPool.GetState(), darkSendPool.GetEntriesCount(), -1); pwalletMain->Lock(); @@ -6086,7 +6099,7 @@ void CDarkSendPool::Check() if((state == POOL_STATUS_ERROR || state == POOL_STATUS_SUCCESS) && GetTimeMillis()-lastTimeChanged >= 10000) { printf("CDarkSendPool::Check() -- RESETTING MESSAGE \n"); - SetNull(); + SetNull(true); UnlockCoins(); } } @@ -6176,7 +6189,7 @@ bool CDarkSendPool::SignatureValid(const CScript& newSig, const CTxIn& newVin){ bool CDarkSendPool::IsCollateralValid(const CTransaction& txCollateral){ if(txCollateral.vout[0].scriptPubKey != collateralPubKey || - txCollateral.vout[0].nValue != POOL_FEE_AMOUNT) { + txCollateral.vout[0].nValue != DARKSEND_COLLATERAL) { if(fDebug) printf ("CDarkSendPool::IsCollateralValid - not correct amount or addr (0)\n"); return false; } @@ -6374,8 +6387,8 @@ bool CDarkSendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNod return false; } - finalTransaction = finalTransactionNew; + finalTransaction = finalTransactionNew; printf("CDarkSendPool::SignFinalTransaction %s\n", finalTransaction.ToString().c_str()); //make sure node is master @@ -6833,14 +6846,12 @@ void CDarkSendPool::NewBlock() resetEntries = true; } - SetNull(); + SetNull(true); if(resetEntries){ UpdateState(POOL_STATUS_ERROR); lastMessage = "masternode switched, please resubmit"; } - - myEntries.clear(); } } @@ -6965,12 +6976,18 @@ int CDarkSendPool::GetCurrentMasterNode(int mod, int64 nBlockHeight) bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun) { - if(fDisableDarksend) return false; - - if (!fDryRun){ - if(GetTime() - (60*2) > lastAutoDenomination) return false; - lastAutoDenomination = GetTime(); + if(fDisableDarksend) { + printf("CDarkSendPool::DoAutomaticDenominating - Darksend is disabled\n"); + return false; } +/* + if (!fDryRun){ + if(lastAutoDenomination + (60*2) > GetTime()) { + printf("CDarkSendPool::DoAutomaticDenominating - Not enough time has passed to Darksend again\n"); + return false; + } + lastAutoDenomination = GetTime(); + }*/ if (!fDryRun && pwalletMain->IsLocked()){ printf("DoAutomaticDenominating Error: Wallet is locked. Please unlock wallet to autodenominate..\n"); @@ -7019,21 +7036,27 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun) if(strError == "") return true; - if(strError == "Error: Darksend requires a collateral transaction and could not locate an acceptable input!" || strError == "Insufficient funds") { + if(strError == "Insufficient funds") { if(!fDryRun) SplitUpMoney(); return true; + } else if(strError == "Error: Darksend requires a collateral transaction and could not locate an acceptable input!"){ + if(!fDryRun) SplitUpMoney(true); + return true; } else { printf("DoAutomaticDenominating : Error running denominate, %s\n", strError.c_str()); } return false; } -bool CDarkSendPool::SplitUpMoney() +bool CDarkSendPool::SplitUpMoney(bool justCollateral) { int64 nTotalBalance = pwalletMain->GetNonDenominatedBalance(); + if(justCollateral && nTotalBalance > 2*COIN) nTotalBalance = 2*COIN; int64 nTotalOut = 0; - printf("DoAutomaticDenominating: Split up large input:\n"); + printf("DoAutomaticDenominating: Split up large input (justCollateral %d):\n", justCollateral); + printf(" auto -- nTotalBalance %"PRI64d"\n", nTotalBalance); + printf(" auto-- nTotalOut %"PRI64d"\n", nTotalOut); // make our change address CReserveKey reservekey(pwalletMain); @@ -7048,17 +7071,37 @@ bool CDarkSendPool::SplitUpMoney() std::string strFail = ""; vector< pair > vecSend; - int64 FEE = 0.002*COIN; int64 a = nTotalBalance/5; if(a > 900*COIN) a = 900*COIN; - while(nTotalOut + a + (a/5) + (POOL_FEE_AMOUNT*4) < nTotalBalance-FEE){ - printf(" nTotalOut %"PRI64d"\n", nTotalOut/COIN); - printf(" nTotalOut + ((nTotalBalance/5) + (nTotalBalance/5/5) + 0.01*COIN) %"PRI64d"\n", nTotalOut + ((a) + (a/5) + ((POOL_FEE_AMOUNT*4)))/COIN); - printf(" nTotalBalance-(FEE) %"PRI64d"\n", (nTotalBalance-FEE)/COIN); - vecSend.push_back(make_pair(scriptChange, a)); - vecSend.push_back(make_pair(scriptChange, a/5)); - vecSend.push_back(make_pair(scriptChange, POOL_FEE_AMOUNT*4)); - nTotalOut += (a) + (a/5) + (POOL_FEE_AMOUNT*4); + + printf(" auto-- split amount %"PRI64d"\n", a); + + int64 addingEachRound = (DARKSEND_FEE*5); + if(!justCollateral) addingEachRound += (a) + (a/5); + + while(nTotalOut + addingEachRound < nTotalBalance-DARKSEND_FEE){ + printf(" nTotalOut %"PRI64d"\n", nTotalOut); + printf(" nTotalOut + ((nTotalBalance/5) + (nTotalBalance/5/5) + 0.01*COIN) %"PRI64d"\n", nTotalOut + ((a) + (a/5) + ((DARKSEND_FEE*4)))); + printf(" nTotalBalance-(DARKSEND_COLLATERAL) %"PRI64d"\n", (nTotalBalance-DARKSEND_COLLATERAL)); + if(!justCollateral){ + vecSend.push_back(make_pair(scriptChange, a)); + vecSend.push_back(make_pair(scriptChange, a/5)); + nTotalOut += (a) + (a/5); + } + vecSend.push_back(make_pair(scriptChange, DARKSEND_COLLATERAL*5)); + vecSend.push_back(make_pair(scriptChange, DARKSEND_FEE*5)); + nTotalOut += (DARKSEND_COLLATERAL*5)+(DARKSEND_FEE*5); + } + + printf(" auto2-- nTotalBalance %"PRI64d"\n", nTotalBalance); + printf(" auto2-- nTotalOut %"PRI64d"\n", nTotalOut); + + if(!justCollateral){ + if(nTotalOut <= 1.1*COIN || vecSend.size() < 4) + return false; + } else { + if(nTotalOut <= 0.1*COIN || vecSend.size() < 2) + return false; } CCoinControl *coinControl=NULL; @@ -7071,8 +7114,8 @@ bool CDarkSendPool::SplitUpMoney() pwalletMain->CommitTransaction(wtx, reservekey); printf("SplitUpMoney Success: tx %s\n", wtx.GetHash().GetHex().c_str()); - return true; + return true; } int CDarkSendPool::GetMasternodeRank(CTxIn& vin, int mod) diff --git a/src/main.h b/src/main.h index 5c0795029f..e5253ebf3e 100644 --- a/src/main.h +++ b/src/main.h @@ -36,7 +36,7 @@ class CBitcoinAddress; #define START_MASTERNODE_PAYMENTS_TESTNET 1403568776 //Tue, 24 Jun 2014 00:12:56 GMT #define START_MASTERNODE_PAYMENTS 1403728576 //Wed, 25 Jun 2014 20:36:16 GMT -#define POOL_MAX_TRANSACTIONS 1 // wait for X transactions to merge and publish +#define POOL_MAX_TRANSACTIONS 3 // wait for X transactions to merge and publish #define POOL_STATUS_UNKNOWN 0 // waiting for update #define POOL_STATUS_IDLE 1 // waiting for update #define POOL_STATUS_ACCEPTING_ENTRIES 2 // accepting entries @@ -2568,7 +2568,8 @@ public: bool VerifyMessage(CPubKey pubkey, std::vector& vchSig, std::string strMessage, std::string& errorMessage); }; -static const int64 POOL_FEE_AMOUNT = 0.025*COIN; +static const int64 DARKSEND_COLLATERAL = 0.025*COIN; +static const int64 DARKSEND_FEE = 0.001*COIN; /** Used to keep track of current status of darksend pool */ @@ -2633,7 +2634,7 @@ public: } bool SetCollateralAddress(std::string strAddress); - void SetNull(); + void SetNull(bool clearEverything=false); void UnlockCoins(); @@ -2737,7 +2738,7 @@ public: void ClearLastMessage(); bool DoConcessusVote(int64 nBlockHeight); int GetInputDarksendRounds(CTxIn in, int rounds=0); - bool SplitUpMoney(); + bool SplitUpMoney(bool justCollateral=false); int GetDenominations(std::vector vout); }; diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 40a5f735cd..674631dcf3 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -38,6 +38,7 @@ QList TransactionRecord::decomposeTransaction(const CWallet * // BOOST_FOREACH(const CTxOut& txout, wtx.vout) { + if(wallet->IsMine(txout)) { TransactionRecord sub(hash, nTime); @@ -62,6 +63,13 @@ QList TransactionRecord::decomposeTransaction(const CWallet * sub.type = TransactionRecord::Generated; } + BOOST_FOREACH(int64 d, darkSendDenominations){ + if(txout.nValue == d) { + sub.type = TransactionRecord::RecvWithDarksend; + } + } + + parts.append(sub); } } @@ -78,6 +86,18 @@ QList TransactionRecord::decomposeTransaction(const CWallet * if (fAllFromMe && fAllToMe) { + + for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) + { + const CTxOut& txout = wtx.vout[nOut]; + TransactionRecord sub(hash, nTime); + sub.idx = parts.size(); + + if(txout.nValue == DARKSEND_COLLATERAL*5) { + sub.type = TransactionRecord::DarksendSplitUpLarge; + } + } + // Payment to self int64 nChange = wtx.GetChange(); @@ -118,6 +138,13 @@ QList TransactionRecord::decomposeTransaction(const CWallet * sub.address = mapValue["to"]; } + if(txout.nValue == DARKSEND_COLLATERAL){ + sub.type = TransactionRecord::DarksendCollateralPayment; + } + if(txout.nValue == DARKSEND_COLLATERAL*5){ + sub.type = TransactionRecord::DarksendSplitUpLarge; + } + int64 nValue = txout.nValue; /* Add fee to first output */ if (nTxFee > 0) @@ -133,9 +160,25 @@ QList TransactionRecord::decomposeTransaction(const CWallet * else { // - // Mixed debit transaction, can't break down payees + // Mixed Debit // - parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0)); + TransactionRecord sub(hash, nTime); + sub.idx = parts.size(); + sub.type = TransactionRecord::Other; + + for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) + { + const CTxOut& txout = wtx.vout[nOut]; + + BOOST_FOREACH(int64 d, darkSendDenominations){ + if(txout.nValue == d) { + sub.type = TransactionRecord::DarksendDenominate; + } + } + + } + + parts.append(sub); } } diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index d760d47c89..166cb6ca5a 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -69,8 +69,12 @@ public: SendToAddress, SendToOther, RecvWithAddress, + RecvWithDarksend, RecvFromOther, - SendToSelf + SendToSelf, + DarksendDenominate, + DarksendCollateralPayment, + DarksendSplitUpLarge }; /** Number of confirmation needed for transaction */ diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index baf1e16483..5f56be33f2 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -353,6 +353,8 @@ QString TransactionTableModel::formatTxType(const TransactionRecord *wtx) const return tr("Received with"); case TransactionRecord::RecvFromOther: return tr("Received from"); + case TransactionRecord::RecvWithDarksend: + return tr("Received via Darksend"); case TransactionRecord::SendToAddress: case TransactionRecord::SendToOther: return tr("Sent to"); @@ -360,6 +362,14 @@ QString TransactionTableModel::formatTxType(const TransactionRecord *wtx) const return tr("Payment to yourself"); case TransactionRecord::Generated: return tr("Mined"); + + case TransactionRecord::DarksendDenominate: + return tr("Darksend Denominate"); + case TransactionRecord::DarksendCollateralPayment: + return tr("Darksend Collateral Payment"); + case TransactionRecord::DarksendSplitUpLarge: + return tr("Darksend Split Up Large Inputs"); + default: return QString(); } @@ -371,6 +381,7 @@ QVariant TransactionTableModel::txAddressDecoration(const TransactionRecord *wtx { case TransactionRecord::Generated: return QIcon(":/icons/tx_mined"); + case TransactionRecord::RecvWithDarksend: case TransactionRecord::RecvWithAddress: case TransactionRecord::RecvFromOther: return QIcon(":/icons/tx_input"); @@ -390,6 +401,7 @@ QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, b case TransactionRecord::RecvFromOther: return QString::fromStdString(wtx->address); case TransactionRecord::RecvWithAddress: + case TransactionRecord::RecvWithDarksend: case TransactionRecord::SendToAddress: case TransactionRecord::Generated: return lookupAddress(wtx->address, tooltip); diff --git a/src/rpcdarksend.cpp b/src/rpcdarksend.cpp index 300b55d076..99d5831c9b 100644 --- a/src/rpcdarksend.cpp +++ b/src/rpcdarksend.cpp @@ -18,7 +18,7 @@ Value darksend(const Array& params, bool fHelp) if (fHelp || params.size() == 0) throw runtime_error( "darksend \n" - "darkcoinaddress, denominate, or auto (AutoDenominate)" + "darkcoinaddress, reset, or auto (AutoDenominate)" " is a real and is rounded to the nearest 0.00000001" + HelpRequiringPassphrase()); @@ -33,6 +33,11 @@ Value darksend(const Array& params, bool fHelp) return "DoAutomaticDenominating"; } + if(params[0].get_str() == "reset"){ + darkSendPool.SetNull(true); + return "successfully reset darksend"; + } + if (params.size() != 2) throw runtime_error( "darksend \n" @@ -41,7 +46,7 @@ Value darksend(const Array& params, bool fHelp) + HelpRequiringPassphrase()); CBitcoinAddress address(params[0].get_str()); - if (!address.IsValid() && params[0].get_str() != "denominate") + if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid DarkCoin address"); // Amount diff --git a/src/script.cpp b/src/script.cpp index 09db53c0c1..2fadb74de5 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -228,7 +228,7 @@ const char* GetOpName(opcodetype opcode) } bool IsCanonicalPubKey(const valtype &vchPubKey) { - if (vchPubKey.size() < 33) + if (vchPubKey.size() < 25) return error("Non-canonical public key: too short"); if (vchPubKey[0] == 0x04) { if (vchPubKey.size() != 65) @@ -237,7 +237,7 @@ bool IsCanonicalPubKey(const valtype &vchPubKey) { if (vchPubKey.size() != 33) return error("Non-canonical public key: invalid length for compressed key"); } else { - return error("Non-canonical public key: compressed nor uncompressed"); + return error("Non-canonical public key: compressed nor uncompressed : size %d", vchPubKey.size()); } return true; } diff --git a/src/wallet.cpp b/src/wallet.cpp index f55bae2e30..a5abbaff51 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1268,7 +1268,7 @@ bool CWallet::SelectCoinsDark(int64 nValueMin, int64 nValueMax, std::vectorvout[out.i].nValue == POOL_FEE_AMOUNT*4) continue; //these are made for collateral + if(out.tx->vout[out.i].nValue <= 1*COIN) continue; //these are made for collateral/fees/etc if(fMasterNode && out.tx->vout[out.i].nValue == 1000*COIN) continue; //masternode input if(nValueRet + out.tx->vout[out.i].nValue <= nValueMax){ @@ -1294,7 +1294,7 @@ bool CWallet::SelectCoinsDark(int64 nValueMin, int64 nValueMax, std::vector& setCoinsRet, int64& nValueRet) const +bool CWallet::SelectCoinsCollateral(std::vector& setCoinsRet, int64& nValueRet) const { CCoinControl *coinControl=NULL; @@ -1307,7 +1307,13 @@ bool CWallet::SelectCoinsCollateral(int64 nValueMin, int64 nValueMax, std::vecto BOOST_FOREACH(const COutput& out, vCoins) { - if(nValueRet + out.tx->vout[out.i].nValue <= nValueMax){ + if( + out.tx->vout[out.i].nValue == DARKSEND_COLLATERAL || + out.tx->vout[out.i].nValue == DARKSEND_COLLATERAL * 2 || + out.tx->vout[out.i].nValue == DARKSEND_COLLATERAL * 3 || + out.tx->vout[out.i].nValue == DARKSEND_COLLATERAL * 4 || + out.tx->vout[out.i].nValue == DARKSEND_COLLATERAL * 5 + ){ CTxIn vin = CTxIn(out.tx->GetHash(),out.i); printf(" vin nValue %"PRI64d"\n", out.tx->vout[out.i].nValue); @@ -1316,12 +1322,10 @@ bool CWallet::SelectCoinsCollateral(int64 nValueMin, int64 nValueMax, std::vecto setCoinsRet.push_back(vin); setCoinsRet2.insert(make_pair(out.tx, out.i)); printf(" -- nValueRet %"PRI64d"\n", nValueRet); - if(nValueRet >= nValueMax) return true; + return true; } } - if(nValueRet >= nValueMin) return true; - return false; } @@ -1381,6 +1385,7 @@ bool CWallet::CreateTransaction(std::vector >& vecSend, return false; } + wtxNew.BindWallet(this); { @@ -1492,6 +1497,8 @@ bool CWallet::CreateTransaction(std::vector >& vecSend, BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second)); + if(fDebug) printf("CreateTransaction %s\n", wtxNew.ToString().c_str()); + // Sign int nIn = 0; BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) @@ -1696,7 +1703,7 @@ string CWallet::DarkSendDenominate() int64 nValueIn2 = 0; std::vector vCoinsCollateral; - if (!SelectCoinsCollateral(POOL_FEE_AMOUNT, 1*COIN, vCoinsCollateral, nValueIn2)) + if (!SelectCoinsCollateral(vCoinsCollateral, nValueIn2)) { BOOST_FOREACH(CTxIn v, vCoins) UnlockCoin(v.prevout); @@ -1713,15 +1720,15 @@ string CWallet::DarkSendDenominate() reservedKeys.push_back(reservekey.GetIndex()); reservekey.Reset(); - CTxOut vout2 = CTxOut(POOL_FEE_AMOUNT, darkSendPool.collateralPubKey); + CTxOut vout2 = CTxOut(DARKSEND_COLLATERAL, darkSendPool.collateralPubKey); BOOST_FOREACH(CTxIn v, vCoinsCollateral) txCollateral.vin.push_back(v); txCollateral.vout.push_back(vout2); - if(nValueIn2 - POOL_FEE_AMOUNT > 0) { - CTxOut vout3 = CTxOut(nValueIn2 - POOL_FEE_AMOUNT, scriptChange); + if(nValueIn2 - DARKSEND_COLLATERAL > 0) { + CTxOut vout3 = CTxOut(nValueIn2 - DARKSEND_COLLATERAL, scriptChange); txCollateral.vout.push_back(vout3); } diff --git a/src/wallet.h b/src/wallet.h index 9b45398a87..379abcc28f 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -91,7 +91,7 @@ public: bool SelectCoinsDarkDenominated(int64 nTargetValue, std::vector& setCoinsRet, int64& nValueRet) const; bool SelectCoinsExactOutput(int64 nTargetValue, CTxIn& vin, int64& nValueRet, CScript& pubScript, bool confirmed) const; - bool SelectCoinsCollateral(int64 nValueMin, int64 nValueMax, std::vector& setCoinsRet, int64& nValueRet) const; + bool SelectCoinsCollateral(std::vector& setCoinsRet, int64& nValueRet) const ; bool SelectCoinsWithoutDenomination(int64 nTargetValue, std::set >& setCoinsRet, int64& nValueRet) const; bool SelectCoinsMoreThanOutput(int64 nTargetValue, CTxIn& vin, int64& nValueRet, bool confirmed) const;