diff --git a/src/darksend.cpp b/src/darksend.cpp index ba14fd5f44a2..0d74ce9990c1 100644 --- a/src/darksend.cpp +++ b/src/darksend.cpp @@ -27,30 +27,30 @@ using namespace boost; CCriticalSection cs_darksend; -/** The main object for accessing darksend */ +// The main object for accessing DarkSend CDarkSendPool darkSendPool; -/** A helper object for signing messages from masternodes */ +// A helper object for signing messages from masternodes CDarkSendSigner darkSendSigner; -/** The current darksends in progress on the network */ +// The current DarkSends in progress on the network std::vector vecDarksendQueue; -/** Keep track of the used masternodes */ +// Keep track of the used masternodes std::vector vecMasternodesUsed; -// keep track of the scanning errors I've seen +// Keep track of the scanning errors I've seen map mapDarksendBroadcastTxes; -// +// Keep track of the active masternode CActiveMasternode activeMasternode; -// count peers we've requested the list from +// Count peers we've requested the list from int RequestedMasterNodeList = 0; /* *** BEGIN DARKSEND MAGIC - DARKCOIN ********** - Copyright 2014, Darkcoin Developers + Copyright 2014-2015 Darkcoin Developers eduffield - evan@darkcoin.io */ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) { - if(fLiteMode) return; //disable all darksend/masternode related functionality + if(fLiteMode) return; //disable all DarkSend/masternode related functionality if(IsInitialBlockDownload()) return; if (strCommand == "dsf") { //DarkSend Final tx @@ -394,7 +394,7 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream& int randomizeList (int i) { return std::rand()%i;} -// Recursively determine the rounds of a given input (How deep is the darksend chain for a given input) +// Recursively determine the rounds of a given input (How deep is the DarkSend chain for a given input) int GetInputDarksendRounds(CTxIn in, int rounds) { static std::map mDenomWtxes; @@ -486,7 +486,7 @@ int GetInputDarksendRounds(CTxIn in, int rounds) return rounds-1; } -// manage the masternode connections +/// Manage the masternode connections void CDarkSendPool::ProcessMasternodeConnections() { LOCK(cs_vNodes); @@ -503,6 +503,7 @@ void CDarkSendPool::ProcessMasternodeConnections() } } +/// Reset the the DarkSend pool void CDarkSendPool::Reset(){ cachedLastSuccess = 0; vecMasternodesUsed.clear(); @@ -559,7 +560,7 @@ bool CDarkSendPool::SetCollateralAddress(std::string strAddress){ } // -// Unlock coins after Darksend fails or succeeds +// Unlock coins after DarkSend fails or succeeds // void CDarkSendPool::UnlockCoins(){ BOOST_FOREACH(CTxIn v, lockedCoins) @@ -569,7 +570,7 @@ void CDarkSendPool::UnlockCoins(){ } // -// Check the Darksend progress and send client updates if a masternode +// Check the DarkSend progress and send client updates if a masternode // void CDarkSendPool::Check() { @@ -708,8 +709,8 @@ void CDarkSendPool::Check() // // Charge clients a fee if they're abusive // -// Why bother? Darksend uses collateral to ensure abuse to the process is kept to a minimum. -// The submission and signing stages in darksend are completely separate. In the cases where +// Why bother? DarkSend uses collateral to ensure abuse to the process is kept to a minimum. +// The submission and signing stages in DarkSend are completely separate. In the cases where // a client submits a transaction then refused to sign, there must be a cost. Otherwise they // would be able to do this over and over again and bring the mixing to a hault. // @@ -820,7 +821,7 @@ void CDarkSendPool::ChargeFees(){ } // charge the collateral randomly -// - Darksend is completely free, to pay miners we randomly pay the collateral of users. +// - DarkSend is completely free, to pay miners we randomly pay the collateral of users. void CDarkSendPool::ChargeRandomFees(){ if(fMasterNode) { int i = 0; @@ -856,7 +857,7 @@ void CDarkSendPool::ChargeRandomFees(){ } // -// Check for various timeouts (queue objects, darksend, etc) +// Check for various timeouts (queue objects, DarkSend, etc) // void CDarkSendPool::CheckTimeout(){ if(!fEnableDarksend && !fMasterNode) return; @@ -869,7 +870,7 @@ void CDarkSendPool::CheckTimeout(){ } } - // check darksend queue objects for timeouts + // check DarkSend queue objects for timeouts int c = 0; vector::iterator it; for(it=vecDarksendQueue.begin();it& vin, std::vector& vout, int64_t amount){ @@ -1233,7 +1235,7 @@ void CDarkSendPool::SendDarksendDenominate(std::vector& vin, std::vector< Check(); } -// Incoming message from masternode updating the progress of darksend +// Incoming message from masternode updating the progress of DarkSend // newAccepted: -1 mean's it'n not a "transaction accepted/not accepted" message, just a standard update // 0 means transaction was not accepted // 1 means transaction was accepted @@ -1379,7 +1381,7 @@ void CDarkSendPool::NewBlock() } } -// Darksend transaction was completed (failed or successed) +// DarkSend transaction was completed (failed or successful) void CDarkSendPool::CompletedTransaction(bool error, std::string lastMessageNew) { if(fMasterNode) return; @@ -1409,7 +1411,7 @@ void CDarkSendPool::ClearLastMessage() } // -// Passively run Darksend in the background to anonymize funds based on the given configuration. +// Passively run DarkSend in the background to anonymize funds based on the given configuration. // // This does NOT run by default for daemons, only for QT. // @@ -2158,7 +2160,7 @@ bool CDarksendQueue::CheckSignature() //TODO: Rename/move to core void ThreadCheckDarkSendPool() { - if(fLiteMode) return; //disable all darksend/masternode related functionality + if(fLiteMode) return; //disable all DarkSend/masternode related functionality // Make this thread recognisable as the wallet flushing thread RenameThread("darkcoin-darksend"); diff --git a/src/darksend.h b/src/darksend.h index 70a879fff077..64db10f77a88 100644 --- a/src/darksend.h +++ b/src/darksend.h @@ -35,8 +35,8 @@ class CActiveMasternode; #define MASTERNODE_REJECTED 0 #define MASTERNODE_RESET -1 -#define DARKSEND_QUEUE_TIMEOUT 120 -#define DARKSEND_SIGNING_TIMEOUT 30 +#define DARKSEND_QUEUE_TIMEOUT 120 // in seconds +#define DARKSEND_SIGNING_TIMEOUT 30 // in seconds static const int MIN_POOL_PEER_PROTO_VERSION = 70067; // minimum peer version accepted by DarkSendPool @@ -47,18 +47,37 @@ extern std::string strMasterNodePrivKey; extern map mapDarksendBroadcastTxes; extern CActiveMasternode activeMasternode; -//specific messages for the Darksend protocol +/** Process a DarkSend message using the DarkSend protocol + * \param pfrom + * \param strCommand lower case command string; valid values are: + * Command | Description + * -------- | ----------------- + * dsa | DarkSend Acceptable + * dsc | DarkSend Complete + * dsf | DarkSend Final tx + * dsi | DarkSend vIn + * dsq | DarkSend Queue + * dss | DarkSend Signal Final Tx + * dssu | DarkSend status update + * dssub | DarkSend Subscribe To + * \param vRecv + */ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream& vRecv); -// get the darksend chain depth for a given input +/// Get the DarkSend chain depth for a given input int GetInputDarksendRounds(CTxIn in, int rounds=0); -// An input in the darksend pool +/** An input in the DarkSend pool + */ class CDarkSendEntryVin { public: + + // Returns true if Signature is set bool isSigSet; + + // Instance of an Inbound Transaction CTxIn vin; CDarkSendEntryVin() @@ -68,7 +87,8 @@ class CDarkSendEntryVin } }; -// A clients transaction in the darksend pool +/** A client's transaction in the DarkSend pool + */ class CDarkSendEntry { public: @@ -78,7 +98,7 @@ class CDarkSendEntry CTransaction collateral; std::vector vout; CTransaction txSupporting; - int64_t addedTime; + int64_t addedTime; // time in UTC milliseconds CDarkSendEntry() { @@ -87,6 +107,7 @@ class CDarkSendEntry amount = 0; } + /// Add entries to use for DarkSend bool Add(const std::vector vinIn, int64_t amountIn, const CTransaction collateralIn, const std::vector voutIn) { if(isSet){return false;} @@ -105,6 +126,7 @@ class CDarkSendEntry return true; } + /// Add Signature bool AddSig(const CTxIn& vin) { BOOST_FOREACH(CDarkSendEntryVin& s, sev) { @@ -121,15 +143,15 @@ class CDarkSendEntry return false; } + /// Is this DarkSend expired? bool IsExpired() { return (GetTime() - addedTime) > DARKSEND_QUEUE_TIMEOUT;// 120 seconds } }; -// -// A currently inprogress darksend merge and denomination information -// +/** A currently in-progress DarkSend merge and denomination information + */ class CDarksendQueue { public: @@ -157,6 +179,7 @@ class CDarksendQueue READWRITE(vchSig); ) + /// Check if there is an address bool GetAddress(CService &addr) { CMasternode* pmn = mnodeman.Find(vin); @@ -168,6 +191,7 @@ class CDarksendQueue return false; } + /// Get the protocol version bool GetProtocolVersion(int &protocolVersion) { CMasternode* pmn = mnodeman.Find(vin); @@ -179,19 +203,30 @@ class CDarksendQueue return false; } + /** Sign this DarkSend transaction + * \return true if all conditions are met: + * 1) we have an active MasterNode, + * 2) we have a valid MasterNode private key, + * 3) we signed the message successfully, and + * 4) we verified the message successfully + */ bool Sign(); + bool Relay(); + /// Is this DarkSend expired? bool IsExpired() { return (GetTime() - time) > DARKSEND_QUEUE_TIMEOUT;// 120 seconds } + /// check if we have a valid MasterNode address bool CheckSignature(); }; -// store darksend tx signature information +/** Helper class to store DarkSend transaction (tx) information. + */ class CDarksendBroadcastTx { public: @@ -201,9 +236,8 @@ class CDarksendBroadcastTx int64_t sigTime; }; -// -// Helper object for signing and checking signatures -// +/** Helper object for signing and checking signatures + */ class CDarkSendSigner { public: @@ -213,14 +247,15 @@ class CDarkSendSigner bool VerifyMessage(CPubKey pubkey, std::vector& vchSig, std::string strMessage, std::string& errorMessage); }; +/** Empty class - not used (TODO: Delete?) + */ class CDarksendSession { }; -// -// Used to keep track of current status of darksend pool -// +/** Used to keep track of current status of DarkSend pool + */ class CDarkSendPool { public: @@ -232,8 +267,8 @@ class CDarkSendPool // the finalized transaction ready for signing CTransaction finalTransaction; - int64_t lastTimeChanged; - int64_t lastAutoDenomination; + int64_t lastTimeChanged; /// time in UTC milliseconds + int64_t lastAutoDenomination; // Note: possibly not used TODO: Delete? unsigned int state; unsigned int entriesCount; @@ -288,6 +323,7 @@ class CDarkSendPool SetNull(); } + /// Manage the masternode connections void ProcessMasternodeConnections(); void InitCollateralAddress(){ @@ -305,9 +341,11 @@ class CDarkSendPool } bool SetCollateralAddress(std::string strAddress); + /// Reset the DarkSend pool void Reset(); void SetNull(bool clearEverything=false); + /// Unlock coins after DarkSend fails or succceeds void UnlockCoins(); bool IsNull() const @@ -370,61 +408,63 @@ class CDarkSendPool return POOL_MAX_TRANSACTIONS; } - //Do we have enough users to take entries? + /// Do we have enough users to take entries? bool IsSessionReady(){ return sessionUsers >= GetMaxPoolTransactions(); } - // Are these outputs compatible with other client in the pool? + /// Are these outputs compatible with other client in the pool? bool IsCompatibleWithEntries(std::vector vout); - // Is this amount compatible with other client in the pool? + /// Is this amount compatible with other client in the pool? bool IsCompatibleWithSession(int64_t nAmount, CTransaction txCollateral, std::string& strReason); - // Passively run Darksend in the background according to the configuration in settings (only for QT) + /// Passively run DarkSend in the background according to the configuration in settings (only for QT) bool DoAutomaticDenominating(bool fDryRun=false, bool ready=false); bool PrepareDarksendDenominate(); - // check for process in Darksend + /// Check the Darksend progress and send client updates if a masternode void Check(); - // charge fees to bad actors + /// Charge fees to bad actors (Charge clients a fee if they're abusive) void ChargeFees(); - // rarely charge fees to pay miners + /// Rarely charge fees to pay miners void ChargeRandomFees(); + /// Check for various timeouts (queue objects, DarkSend, etc) void CheckTimeout(); - // check to make sure a signature matches an input in the pool + /// Check to make sure a signature matches an input in the pool bool SignatureValid(const CScript& newSig, const CTxIn& newVin); - // if the collateral is valid given by a client + /// If the collateral is valid given by a client bool IsCollateralValid(const CTransaction& txCollateral); - // add a clients entry to the pool + /// Add a clients entry to the pool bool AddEntry(const std::vector& newInput, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector& newOutput, std::string& error); - // add signature to a vin + /// Add signature to a vin bool AddScriptSig(const CTxIn& newVin); - // are all inputs signed? + /// Check that all inputs are signed. (Are all inputs signed?) bool SignaturesComplete(); - // as a client, send a transaction to a masternode to start the denomination process + /// As a client, send a transaction to a masternode to start the denomination process void SendDarksendDenominate(std::vector& vin, std::vector& vout, int64_t amount); - // get masternode updates about the progress of darksend + /// Get masternode updates about the progress of DarkSend bool StatusUpdate(int newState, int newEntriesCount, int newAccepted, std::string& error, int newSessionID=0); - // as a client, check and sign the final transaction + /// As a client, check and sign the final transaction bool SignFinalTransaction(CTransaction& finalTransactionNew, CNode* node); - // get the last valid block hash for a given modulus + /// Get the last valid block hash for a given modulus bool GetLastValidBlockHash(uint256& hash, int mod=1, int nBlockHeight=0); - // process a new block + /// Process a new block void NewBlock(); + /// DarkSend transaction was completed (failed or successful) void CompletedTransaction(bool error, std::string lastMessageNew); void ClearLastMessage(); - // used for liquidity providers + /// Used for liquidity providers bool SendRandomPaymentToSelf(); - // split up large inputs or make fee sized inputs + /// Split up large inputs or make fee sized inputs bool MakeCollateralAmounts(); bool CreateDenominated(int64_t nTotalValue); - // get the denominations for a list of outputs (returns a bitshifted integer) + /// Get the denominations for a list of outputs (returns a bitshifted integer) int GetDenominations(const std::vector& vout); void GetDenominationsToString(int nDenom, std::string& strDenom); - // get the denominations for a specific amount of darkcoin. + /// Get the denominations for a specific amount of darkcoin. int GetDenominationsByAmount(int64_t nAmount, int nDenomTarget=0); int GetDenominationsByAmounts(std::vector& vecAmount); diff --git a/src/util.h b/src/util.h index c11176911d7f..ea0e68a31262 100644 --- a/src/util.h +++ b/src/util.h @@ -326,12 +326,14 @@ inline int64_t GetPerformanceCounter() return nCounter; } +/// returns the current time as UTC milliseconds inline int64_t GetTimeMillis() { return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) - boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds(); } +/// returns the current time as UTC microseconds inline int64_t GetTimeMicros() { return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) - diff --git a/src/wallet.h b/src/wallet.h index c8a79d4fd1af..eb1b9d6f4d70 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -781,7 +781,7 @@ class COutput return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString().c_str(), i, nDepth, FormatMoney(tx->vout[i].nValue).c_str()); } - //Used with Darksend. Will return largest nondenom, then denominations, then very small inputs + //Used with DarkSend. Will return largest nondenom, then denominations, then very small inputs int Priority() const { BOOST_FOREACH(int64_t d, darkSendDenominations)