Dash Core  0.12.2.1
P2P Digital Currency
privatesend-client.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2017 The Dash Core developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 #include "privatesend-client.h"
5 
6 #include "coincontrol.h"
7 #include "consensus/validation.h"
8 #include "core_io.h"
9 #include "init.h"
10 #include "masternode-sync.h"
11 #include "masternodeman.h"
12 #include "script/sign.h"
13 #include "txmempool.h"
14 #include "util.h"
15 #include "utilmoneystr.h"
16 
17 #include <memory>
18 
20 
21 void CPrivateSendClient::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv, CConnman& connman)
22 {
23  if(fMasterNode) return;
24  if(fLiteMode) return; // ignore all Dash related functionality
25  if(!masternodeSync.IsBlockchainSynced()) return;
26 
27  if(strCommand == NetMsgType::DSQUEUE) {
28  TRY_LOCK(cs_darksend, lockRecv);
29  if(!lockRecv) return;
30 
32  LogPrint("privatesend", "DSQUEUE -- incompatible version! nVersion: %d\n", pfrom->nVersion);
33  return;
34  }
35 
36  CDarksendQueue dsq;
37  vRecv >> dsq;
38 
39  // process every dsq only once
40  BOOST_FOREACH(CDarksendQueue q, vecDarksendQueue) {
41  if(q == dsq) {
42  // LogPrint("privatesend", "DSQUEUE -- %s seen\n", dsq.ToString());
43  return;
44  }
45  }
46 
47  LogPrint("privatesend", "DSQUEUE -- %s new\n", dsq.ToString());
48 
49  if(dsq.IsExpired()) return;
50 
51  masternode_info_t infoMn;
52  if(!mnodeman.GetMasternodeInfo(dsq.vin.prevout, infoMn)) return;
53 
54  if(!dsq.CheckSignature(infoMn.pubKeyMasternode)) {
55  // we probably have outdated info
56  mnodeman.AskForMN(pfrom, dsq.vin.prevout, connman);
57  return;
58  }
59 
60  // if the queue is ready, submit if we can
61  if(dsq.fReady) {
62  if(!infoMixingMasternode.fInfoValid) return;
63  if(infoMixingMasternode.addr != infoMn.addr) {
64  LogPrintf("DSQUEUE -- message doesn't match current Masternode: infoMixingMasternode=%s, addr=%s\n", infoMixingMasternode.addr.ToString(), infoMn.addr.ToString());
65  return;
66  }
67 
68  if(nState == POOL_STATE_QUEUE) {
69  LogPrint("privatesend", "DSQUEUE -- PrivateSend queue (%s) is ready on masternode %s\n", dsq.ToString(), infoMn.addr.ToString());
70  SubmitDenominate(connman);
71  }
72  } else {
73  BOOST_FOREACH(CDarksendQueue q, vecDarksendQueue) {
74  if(q.vin == dsq.vin) {
75  // no way same mn can send another "not yet ready" dsq this soon
76  LogPrint("privatesend", "DSQUEUE -- Masternode %s is sending WAY too many dsq messages\n", infoMn.addr.ToString());
77  return;
78  }
79  }
80 
82  LogPrint("privatesend", "DSQUEUE -- nLastDsq: %d threshold: %d nDsqCount: %d\n", infoMn.nLastDsq, nThreshold, mnodeman.nDsqCount);
83  //don't allow a few nodes to dominate the queuing process
84  if(infoMn.nLastDsq != 0 && nThreshold > mnodeman.nDsqCount) {
85  LogPrint("privatesend", "DSQUEUE -- Masternode %s is sending too many dsq messages\n", infoMn.addr.ToString());
86  return;
87  }
88 
89  if(!mnodeman.AllowMixing(dsq.vin.prevout)) return;
90 
91  LogPrint("privatesend", "DSQUEUE -- new PrivateSend queue (%s) from masternode %s\n", dsq.ToString(), infoMn.addr.ToString());
93  dsq.fTried = true;
94  }
95  vecDarksendQueue.push_back(dsq);
96  dsq.Relay(connman);
97  }
98 
99  } else if(strCommand == NetMsgType::DSSTATUSUPDATE) {
100 
102  LogPrintf("DSSTATUSUPDATE -- incompatible version! nVersion: %d\n", pfrom->nVersion);
103  return;
104  }
105 
106  if(!infoMixingMasternode.fInfoValid) return;
107  if(infoMixingMasternode.addr != pfrom->addr) {
108  //LogPrintf("DSSTATUSUPDATE -- message doesn't match current Masternode: infoMixingMasternode %s addr %s\n", infoMixingMasternode.addr.ToString(), pfrom->addr.ToString());
109  return;
110  }
111 
112  int nMsgSessionID;
113  int nMsgState;
114  int nMsgEntriesCount;
115  int nMsgStatusUpdate;
116  int nMsgMessageID;
117  vRecv >> nMsgSessionID >> nMsgState >> nMsgEntriesCount >> nMsgStatusUpdate >> nMsgMessageID;
118 
119  LogPrint("privatesend", "DSSTATUSUPDATE -- nMsgSessionID %d nMsgState: %d nEntriesCount: %d nMsgStatusUpdate: %d nMsgMessageID %d\n",
120  nMsgSessionID, nMsgState, nEntriesCount, nMsgStatusUpdate, nMsgMessageID);
121 
122  if(nMsgState < POOL_STATE_MIN || nMsgState > POOL_STATE_MAX) {
123  LogPrint("privatesend", "DSSTATUSUPDATE -- nMsgState is out of bounds: %d\n", nMsgState);
124  return;
125  }
126 
127  if(nMsgStatusUpdate < STATUS_REJECTED || nMsgStatusUpdate > STATUS_ACCEPTED) {
128  LogPrint("privatesend", "DSSTATUSUPDATE -- nMsgStatusUpdate is out of bounds: %d\n", nMsgStatusUpdate);
129  return;
130  }
131 
132  if(nMsgMessageID < MSG_POOL_MIN || nMsgMessageID > MSG_POOL_MAX) {
133  LogPrint("privatesend", "DSSTATUSUPDATE -- nMsgMessageID is out of bounds: %d\n", nMsgMessageID);
134  return;
135  }
136 
137  LogPrint("privatesend", "DSSTATUSUPDATE -- GetMessageByID: %s\n", CPrivateSend::GetMessageByID(PoolMessage(nMsgMessageID)));
138 
139  if(!CheckPoolStateUpdate(PoolState(nMsgState), nMsgEntriesCount, PoolStatusUpdate(nMsgStatusUpdate), PoolMessage(nMsgMessageID), nMsgSessionID)) {
140  LogPrint("privatesend", "DSSTATUSUPDATE -- CheckPoolStateUpdate failed\n");
141  }
142 
143  } else if(strCommand == NetMsgType::DSFINALTX) {
144 
146  LogPrintf("DSFINALTX -- incompatible version! nVersion: %d\n", pfrom->nVersion);
147  return;
148  }
149 
150  if(!infoMixingMasternode.fInfoValid) return;
151  if(infoMixingMasternode.addr != pfrom->addr) {
152  //LogPrintf("DSFINALTX -- message doesn't match current Masternode: infoMixingMasternode %s addr %s\n", infoMixingMasternode.addr.ToString(), pfrom->addr.ToString());
153  return;
154  }
155 
156  int nMsgSessionID;
157  CTransaction txNew;
158  vRecv >> nMsgSessionID >> txNew;
159 
160  if(nSessionID != nMsgSessionID) {
161  LogPrint("privatesend", "DSFINALTX -- message doesn't match current PrivateSend session: nSessionID: %d nMsgSessionID: %d\n", nSessionID, nMsgSessionID);
162  return;
163  }
164 
165  LogPrint("privatesend", "DSFINALTX -- txNew %s", txNew.ToString());
166 
167  //check to see if input is spent already? (and probably not confirmed)
168  SignFinalTransaction(txNew, pfrom, connman);
169 
170  } else if(strCommand == NetMsgType::DSCOMPLETE) {
171 
173  LogPrintf("DSCOMPLETE -- incompatible version! nVersion: %d\n", pfrom->nVersion);
174  return;
175  }
176 
177  if(!infoMixingMasternode.fInfoValid) return;
178  if(infoMixingMasternode.addr != pfrom->addr) {
179  LogPrint("privatesend", "DSCOMPLETE -- message doesn't match current Masternode: infoMixingMasternode=%s addr=%s\n", infoMixingMasternode.addr.ToString(), pfrom->addr.ToString());
180  return;
181  }
182 
183  int nMsgSessionID;
184  int nMsgMessageID;
185  vRecv >> nMsgSessionID >> nMsgMessageID;
186 
187  if(nMsgMessageID < MSG_POOL_MIN || nMsgMessageID > MSG_POOL_MAX) {
188  LogPrint("privatesend", "DSCOMPLETE -- nMsgMessageID is out of bounds: %d\n", nMsgMessageID);
189  return;
190  }
191 
192  if(nSessionID != nMsgSessionID) {
193  LogPrint("privatesend", "DSCOMPLETE -- message doesn't match current PrivateSend session: nSessionID: %d nMsgSessionID: %d\n", nSessionID, nMsgSessionID);
194  return;
195  }
196 
197  LogPrint("privatesend", "DSCOMPLETE -- nMsgSessionID %d nMsgMessageID %d (%s)\n", nMsgSessionID, nMsgMessageID, CPrivateSend::GetMessageByID(PoolMessage(nMsgMessageID)));
198 
199  CompletedTransaction(PoolMessage(nMsgMessageID));
200  }
201 }
202 
204 {
207  vecMasternodesUsed.clear();
208  UnlockCoins();
210  SetNull();
211 }
212 
214 {
215  // Client side
216  nEntriesCount = 0;
217  fLastEntryAccepted = false;
219 
221 }
222 
223 //
224 // Unlock coins after mixing fails or succeeds
225 //
227 {
228  while(true) {
229  TRY_LOCK(pwalletMain->cs_wallet, lockWallet);
230  if(!lockWallet) {MilliSleep(50); continue;}
231  BOOST_FOREACH(COutPoint outpoint, vecOutPointLocked)
232  pwalletMain->UnlockCoin(outpoint);
233  break;
234  }
235 
236  vecOutPointLocked.clear();
237 }
238 
240 {
241  static int nStatusMessageProgress = 0;
242  nStatusMessageProgress += 10;
243  std::string strSuffix = "";
244 
246  return strAutoDenomResult;
247 
248  switch(nState) {
249  case POOL_STATE_IDLE:
250  return _("PrivateSend is idle.");
251  case POOL_STATE_QUEUE:
252  if( nStatusMessageProgress % 70 <= 30) strSuffix = ".";
253  else if(nStatusMessageProgress % 70 <= 50) strSuffix = "..";
254  else if(nStatusMessageProgress % 70 <= 70) strSuffix = "...";
255  return strprintf(_("Submitted to masternode, waiting in queue %s"), strSuffix);;
257  if(nEntriesCount == 0) {
258  nStatusMessageProgress = 0;
259  return strAutoDenomResult;
260  } else if(fLastEntryAccepted) {
261  if(nStatusMessageProgress % 10 > 8) {
262  fLastEntryAccepted = false;
263  nStatusMessageProgress = 0;
264  }
265  return _("PrivateSend request complete:") + " " + _("Your transaction was accepted into the pool!");
266  } else {
267  if( nStatusMessageProgress % 70 <= 40) return strprintf(_("Submitted following entries to masternode: %u / %d"), nEntriesCount, CPrivateSend::GetMaxPoolTransactions());
268  else if(nStatusMessageProgress % 70 <= 50) strSuffix = ".";
269  else if(nStatusMessageProgress % 70 <= 60) strSuffix = "..";
270  else if(nStatusMessageProgress % 70 <= 70) strSuffix = "...";
271  return strprintf(_("Submitted to masternode, waiting for more entries ( %u / %d ) %s"), nEntriesCount, CPrivateSend::GetMaxPoolTransactions(), strSuffix);
272  }
273  case POOL_STATE_SIGNING:
274  if( nStatusMessageProgress % 70 <= 40) return _("Found enough users, signing ...");
275  else if(nStatusMessageProgress % 70 <= 50) strSuffix = ".";
276  else if(nStatusMessageProgress % 70 <= 60) strSuffix = "..";
277  else if(nStatusMessageProgress % 70 <= 70) strSuffix = "...";
278  return strprintf(_("Found enough users, signing ( waiting %s )"), strSuffix);
279  case POOL_STATE_ERROR:
280  return _("PrivateSend request incomplete:") + " " + strLastMessage + " " + _("Will retry...");
281  case POOL_STATE_SUCCESS:
282  return _("PrivateSend request complete:") + " " + strLastMessage;
283  default:
284  return strprintf(_("Unknown state: id = %u"), nState);
285  }
286 }
287 
288 //
289 // Check the mixing progress and send client updates if a Masternode
290 //
292 {
293  // reset if we're here for 10 seconds
295  LogPrint("privatesend", "CPrivateSendClient::CheckPool -- timeout, RESETTING\n");
296  UnlockCoins();
297  if (nState == POOL_STATE_ERROR) {
299  } else {
301  }
302  SetNull();
303  }
304 }
305 
306 //
307 // Check for various timeouts (queue objects, mixing, etc)
308 //
310 {
311  {
312  TRY_LOCK(cs_darksend, lockDS);
313  if(!lockDS) return; // it's ok to fail here, we run this quite frequently
314 
315  // check mixing queue objects for timeouts
316  std::vector<CDarksendQueue>::iterator it = vecDarksendQueue.begin();
317  while(it != vecDarksendQueue.end()) {
318  if((*it).IsExpired()) {
319  LogPrint("privatesend", "CPrivateSendClient::CheckTimeout -- Removing expired queue (%s)\n", (*it).ToString());
320  it = vecDarksendQueue.erase(it);
321  } else ++it;
322  }
323  }
324 
325  if(!fEnablePrivateSend && !fMasterNode) return;
326 
327  // catching hanging sessions
328  if(!fMasterNode) {
329  switch(nState) {
330  case POOL_STATE_ERROR:
331  LogPrint("privatesend", "CPrivateSendClient::CheckTimeout -- Pool error -- Running CheckPool\n");
332  CheckPool();
333  break;
334  case POOL_STATE_SUCCESS:
335  LogPrint("privatesend", "CPrivateSendClient::CheckTimeout -- Pool success -- Running CheckPool\n");
336  CheckPool();
337  break;
338  default:
339  break;
340  }
341  }
342 
343  int nLagTime = fMasterNode ? 0 : 10000; // if we're the client, give the server a few extra seconds before resetting.
345  bool fTimeout = GetTimeMillis() - nTimeLastSuccessfulStep >= nTimeout*1000 + nLagTime;
346 
347  if(nState != POOL_STATE_IDLE && fTimeout) {
348  LogPrint("privatesend", "CPrivateSendClient::CheckTimeout -- %s timed out (%ds) -- restting\n",
349  (nState == POOL_STATE_SIGNING) ? "Signing" : "Session", nTimeout);
350  UnlockCoins();
352  SetNull();
354  strLastMessage = _("Session timed out.");
355  }
356 }
357 
358 //
359 // Execute a mixing denomination via a Masternode.
360 // This is only ran from clients
361 //
362 bool CPrivateSendClient::SendDenominate(const std::vector<CTxIn>& vecTxIn, const std::vector<CTxOut>& vecTxOut, CConnman& connman)
363 {
364  if(fMasterNode) {
365  LogPrintf("CPrivateSendClient::SendDenominate -- PrivateSend from a Masternode is not supported currently.\n");
366  return false;
367  }
368 
370  LogPrintf("CPrivateSendClient:SendDenominate -- PrivateSend collateral not set\n");
371  return false;
372  }
373 
374  // lock the funds we're going to use
375  BOOST_FOREACH(CTxIn txin, txMyCollateral.vin)
376  vecOutPointLocked.push_back(txin.prevout);
377 
378  BOOST_FOREACH(CTxIn txin, vecTxIn)
379  vecOutPointLocked.push_back(txin.prevout);
380 
381  // we should already be connected to a Masternode
382  if(!nSessionID) {
383  LogPrintf("CPrivateSendClient::SendDenominate -- No Masternode has been selected yet.\n");
384  UnlockCoins();
386  SetNull();
387  return false;
388  }
389 
390  if(!CheckDiskSpace()) {
391  UnlockCoins();
393  SetNull();
394  fEnablePrivateSend = false;
395  LogPrintf("CPrivateSendClient::SendDenominate -- Not enough disk space, disabling PrivateSend.\n");
396  return false;
397  }
398 
400  strLastMessage = "";
401 
402  LogPrintf("CPrivateSendClient::SendDenominate -- Added transaction to pool.\n");
403 
404  //check it against the memory pool to make sure it's valid
405  {
406  CValidationState validationState;
408 
409  BOOST_FOREACH(const CTxIn& txin, vecTxIn) {
410  LogPrint("privatesend", "CPrivateSendClient::SendDenominate -- txin=%s\n", txin.ToString());
411  tx.vin.push_back(txin);
412  }
413 
414  BOOST_FOREACH(const CTxOut& txout, vecTxOut) {
415  LogPrint("privatesend", "CPrivateSendClient::SendDenominate -- txout=%s\n", txout.ToString());
416  tx.vout.push_back(txout);
417  }
418 
419  LogPrintf("CPrivateSendClient::SendDenominate -- Submitting partial tx %s", tx.ToString());
420 
421  mempool.PrioritiseTransaction(tx.GetHash(), tx.GetHash().ToString(), 1000, 0.1*COIN);
422  TRY_LOCK(cs_main, lockMain);
423  if(!lockMain || !AcceptToMemoryPool(mempool, validationState, CTransaction(tx), false, NULL, false, true, true)) {
424  LogPrintf("CPrivateSendClient::SendDenominate -- AcceptToMemoryPool() failed! tx=%s", tx.ToString());
425  UnlockCoins();
427  SetNull();
428  return false;
429  }
430  }
431 
432  // store our entry for later use
433  CDarkSendEntry entry(vecTxIn, vecTxOut, txMyCollateral);
434  vecEntries.push_back(entry);
435  RelayIn(entry, connman);
437 
438  return true;
439 }
440 
441 // Incoming message from Masternode updating the progress of mixing
442 bool CPrivateSendClient::CheckPoolStateUpdate(PoolState nStateNew, int nEntriesCountNew, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID, int nSessionIDNew)
443 {
444  if(fMasterNode) return false;
445 
446  // do not update state when mixing client state is one of these
447  if(nState == POOL_STATE_IDLE || nState == POOL_STATE_ERROR || nState == POOL_STATE_SUCCESS) return false;
448 
449  strAutoDenomResult = _("Masternode:") + " " + CPrivateSend::GetMessageByID(nMessageID);
450 
451  // if rejected at any state
452  if(nStatusUpdate == STATUS_REJECTED) {
453  LogPrintf("CPrivateSendClient::CheckPoolStateUpdate -- entry is rejected by Masternode\n");
454  UnlockCoins();
456  SetNull();
459  return true;
460  }
461 
462  if(nStatusUpdate == STATUS_ACCEPTED && nState == nStateNew) {
463  if(nStateNew == POOL_STATE_QUEUE && nSessionID == 0 && nSessionIDNew != 0) {
464  // new session id should be set only in POOL_STATE_QUEUE state
465  nSessionID = nSessionIDNew;
467  LogPrintf("CPrivateSendClient::CheckPoolStateUpdate -- set nSessionID to %d\n", nSessionID);
468  return true;
469  }
470  else if(nStateNew == POOL_STATE_ACCEPTING_ENTRIES && nEntriesCount != nEntriesCountNew) {
471  nEntriesCount = nEntriesCountNew;
473  fLastEntryAccepted = true;
474  LogPrintf("CPrivateSendClient::CheckPoolStateUpdate -- new entry accepted!\n");
475  return true;
476  }
477  }
478 
479  // only situations above are allowed, fail in any other case
480  return false;
481 }
482 
483 //
484 // After we receive the finalized transaction from the Masternode, we must
485 // check it to make sure it's what we want, then sign it if we agree.
486 // If we refuse to sign, it's possible we'll be charged collateral
487 //
488 bool CPrivateSendClient::SignFinalTransaction(const CTransaction& finalTransactionNew, CNode* pnode, CConnman& connman)
489 {
490  if(fMasterNode || pnode == NULL) return false;
491 
492  finalMutableTransaction = finalTransactionNew;
493  LogPrintf("CPrivateSendClient::SignFinalTransaction -- finalMutableTransaction=%s", finalMutableTransaction.ToString());
494 
495  // Make sure it's BIP69 compliant
498 
499  if(finalMutableTransaction.GetHash() != finalTransactionNew.GetHash()) {
500  LogPrintf("CPrivateSendClient::SignFinalTransaction -- WARNING! Masternode %s is not BIP69 compliant!\n", infoMixingMasternode.vin.prevout.ToStringShort());
501  UnlockCoins();
503  SetNull();
504  return false;
505  }
506 
507  std::vector<CTxIn> sigs;
508 
509  //make sure my inputs/outputs are present, otherwise refuse to sign
510  BOOST_FOREACH(const CDarkSendEntry entry, vecEntries) {
511  BOOST_FOREACH(const CTxDSIn txdsin, entry.vecTxDSIn) {
512  /* Sign my transaction and all outputs */
513  int nMyInputIndex = -1;
514  CScript prevPubKey = CScript();
515  CTxIn txin = CTxIn();
516 
517  for(unsigned int i = 0; i < finalMutableTransaction.vin.size(); i++) {
518  if(finalMutableTransaction.vin[i] == txdsin) {
519  nMyInputIndex = i;
520  prevPubKey = txdsin.prevPubKey;
521  txin = txdsin;
522  }
523  }
524 
525  if(nMyInputIndex >= 0) { //might have to do this one input at a time?
526  int nFoundOutputsCount = 0;
527  CAmount nValue1 = 0;
528  CAmount nValue2 = 0;
529 
530  for(unsigned int i = 0; i < finalMutableTransaction.vout.size(); i++) {
531  BOOST_FOREACH(const CTxOut& txout, entry.vecTxDSOut) {
532  if(finalMutableTransaction.vout[i] == txout) {
533  nFoundOutputsCount++;
534  nValue1 += finalMutableTransaction.vout[i].nValue;
535  }
536  }
537  }
538 
539  BOOST_FOREACH(const CTxOut txout, entry.vecTxDSOut)
540  nValue2 += txout.nValue;
541 
542  int nTargetOuputsCount = entry.vecTxDSOut.size();
543  if(nFoundOutputsCount < nTargetOuputsCount || nValue1 != nValue2) {
544  // in this case, something went wrong and we'll refuse to sign. It's possible we'll be charged collateral. But that's
545  // better then signing if the transaction doesn't look like what we wanted.
546  LogPrintf("CPrivateSendClient::SignFinalTransaction -- My entries are not correct! Refusing to sign: nFoundOutputsCount: %d, nTargetOuputsCount: %d\n", nFoundOutputsCount, nTargetOuputsCount);
547  UnlockCoins();
549  SetNull();
550 
551  return false;
552  }
553 
554  const CKeyStore& keystore = *pwalletMain;
555 
556  LogPrint("privatesend", "CPrivateSendClient::SignFinalTransaction -- Signing my input %i\n", nMyInputIndex);
557  if(!SignSignature(keystore, prevPubKey, finalMutableTransaction, nMyInputIndex, int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))) { // changes scriptSig
558  LogPrint("privatesend", "CPrivateSendClient::SignFinalTransaction -- Unable to sign my own transaction!\n");
559  // not sure what to do here, it will timeout...?
560  }
561 
562  sigs.push_back(finalMutableTransaction.vin[nMyInputIndex]);
563  LogPrint("privatesend", "CPrivateSendClient::SignFinalTransaction -- nMyInputIndex: %d, sigs.size(): %d, scriptSig=%s\n", nMyInputIndex, (int)sigs.size(), ScriptToAsmStr(finalMutableTransaction.vin[nMyInputIndex].scriptSig));
564  }
565  }
566  }
567 
568  if(sigs.empty()) {
569  LogPrintf("CPrivateSendClient::SignFinalTransaction -- can't sign anything!\n");
570  UnlockCoins();
572  SetNull();
573 
574  return false;
575  }
576 
577  // push all of our signatures to the Masternode
578  LogPrintf("CPrivateSendClient::SignFinalTransaction -- pushing sigs to the masternode, finalMutableTransaction=%s", finalMutableTransaction.ToString());
579  connman.PushMessage(pnode, NetMsgType::DSSIGNFINALTX, sigs);
582 
583  return true;
584 }
585 
587 {
588  static int64_t nTimeNewBlockReceived = 0;
589 
590  //we we're processing lots of blocks, we'll just leave
591  if(GetTime() - nTimeNewBlockReceived < 10) return;
592  nTimeNewBlockReceived = GetTime();
593  LogPrint("privatesend", "CPrivateSendClient::NewBlock\n");
594 
595  CheckTimeout();
596 }
597 
598 // mixing transaction was completed (failed or successful)
600 {
601  if(fMasterNode) return;
602 
603  if(nMessageID == MSG_SUCCESS) {
604  LogPrintf("CompletedTransaction -- success\n");
607  } else {
608  LogPrintf("CompletedTransaction -- error\n");
610  }
611  UnlockCoins();
612  SetNull();
614 }
615 
617 {
619  return true;
620 
622  return false;
623 
625 }
626 
628 {
629  switch(nWalletBackups) {
630  case 0:
631  LogPrint("privatesend", "CPrivateSendClient::CheckAutomaticBackup -- Automatic backups disabled, no mixing available.\n");
632  strAutoDenomResult = _("Automatic backups disabled") + ", " + _("no mixing available.");
633  fEnablePrivateSend = false; // stop mixing
634  pwalletMain->nKeysLeftSinceAutoBackup = 0; // no backup, no "keys since last backup"
635  return false;
636  case -1:
637  // Automatic backup failed, nothing else we can do until user fixes the issue manually.
638  // There is no way to bring user attention in daemon mode so we just update status and
639  // keep spaming if debug is on.
640  LogPrint("privatesend", "CPrivateSendClient::CheckAutomaticBackup -- ERROR! Failed to create automatic backup.\n");
641  strAutoDenomResult = _("ERROR! Failed to create automatic backup") + ", " + _("see debug.log for details.");
642  return false;
643  case -2:
644  // We were able to create automatic backup but keypool was not replenished because wallet is locked.
645  // There is no way to bring user attention in daemon mode so we just update status and
646  // keep spaming if debug is on.
647  LogPrint("privatesend", "CPrivateSendClient::CheckAutomaticBackup -- WARNING! Failed to create replenish keypool, please unlock your wallet to do so.\n");
648  strAutoDenomResult = _("WARNING! Failed to replenish keypool, please unlock your wallet to do so.") + ", " + _("see debug.log for details.");
649  return false;
650  }
651 
653  // We should never get here via mixing itself but probably smth else is still actively using keypool
654  LogPrint("privatesend", "CPrivateSendClient::CheckAutomaticBackup -- Very low number of keys left: %d, no mixing available.\n", pwalletMain->nKeysLeftSinceAutoBackup);
655  strAutoDenomResult = strprintf(_("Very low number of keys left: %d") + ", " + _("no mixing available."), pwalletMain->nKeysLeftSinceAutoBackup);
656  // It's getting really dangerous, stop mixing
657  fEnablePrivateSend = false;
658  return false;
660  // Low number of keys left but it's still more or less safe to continue
661  LogPrint("privatesend", "CPrivateSendClient::CheckAutomaticBackup -- Very low number of keys left: %d\n", pwalletMain->nKeysLeftSinceAutoBackup);
662  strAutoDenomResult = strprintf(_("Very low number of keys left: %d"), pwalletMain->nKeysLeftSinceAutoBackup);
663 
664  if(fCreateAutoBackups) {
665  LogPrint("privatesend", "CPrivateSendClient::CheckAutomaticBackup -- Trying to create new backup.\n");
666  std::string warningString;
667  std::string errorString;
668 
669  if(!AutoBackupWallet(pwalletMain, "", warningString, errorString)) {
670  if(!warningString.empty()) {
671  // There were some issues saving backup but yet more or less safe to continue
672  LogPrintf("CPrivateSendClient::CheckAutomaticBackup -- WARNING! Something went wrong on automatic backup: %s\n", warningString);
673  }
674  if(!errorString.empty()) {
675  // Things are really broken
676  LogPrintf("CPrivateSendClient::CheckAutomaticBackup -- ERROR! Failed to create automatic backup: %s\n", errorString);
677  strAutoDenomResult = strprintf(_("ERROR! Failed to create automatic backup") + ": %s", errorString);
678  return false;
679  }
680  }
681  } else {
682  // Wait for smth else (e.g. GUI action) to create automatic backup for us
683  return false;
684  }
685  }
686 
687  LogPrint("privatesend", "CPrivateSendClient::CheckAutomaticBackup -- Keys left since latest backup: %d\n", pwalletMain->nKeysLeftSinceAutoBackup);
688 
689  return true;
690 }
691 
692 //
693 // Passively run mixing in the background to anonymize funds based on the given configuration.
694 //
696 {
697  if(fMasterNode) return false; // no client-side mixing on masternodes
698  if(!fEnablePrivateSend) return false;
699  if(!pwalletMain || pwalletMain->IsLocked(true)) return false;
700  if(nState != POOL_STATE_IDLE) return false;
701 
703  strAutoDenomResult = _("Can't mix while sync in progress.");
704  return false;
705  }
706 
707  if(!CheckAutomaticBackup())
708  return false;
709 
710  if(GetEntriesCount() > 0) {
711  strAutoDenomResult = _("Mixing in progress...");
712  return false;
713  }
714 
715  TRY_LOCK(cs_darksend, lockDS);
716  if(!lockDS) {
717  strAutoDenomResult = _("Lock is already in place.");
718  return false;
719  }
720 
721  if(!fDryRun && pwalletMain->IsLocked(true)) {
722  strAutoDenomResult = _("Wallet is locked.");
723  return false;
724  }
725 
726  if(WaitForAnotherBlock()) {
727  LogPrintf("CPrivateSendClient::DoAutomaticDenominating -- Last successful PrivateSend action was too recent\n");
728  strAutoDenomResult = _("Last successful PrivateSend action was too recent.");
729  return false;
730  }
731 
732  if(mnodeman.size() == 0) {
733  LogPrint("privatesend", "CPrivateSendClient::DoAutomaticDenominating -- No Masternodes detected\n");
734  strAutoDenomResult = _("No Masternodes detected.");
735  return false;
736  }
737 
739 
740  // if there are no confirmed DS collateral inputs yet
742  // should have some additional amount for them
744  }
745 
746  // including denoms but applying some restrictions
747  CAmount nBalanceNeedsAnonymized = pwalletMain->GetNeedsToBeAnonymizedBalance(nValueMin);
748 
749  // anonymizable balance is way too small
750  if(nBalanceNeedsAnonymized < nValueMin) {
751  LogPrintf("CPrivateSendClient::DoAutomaticDenominating -- Not enough funds to anonymize\n");
752  strAutoDenomResult = _("Not enough funds to anonymize.");
753  return false;
754  }
755 
756  // excluding denoms
757  CAmount nBalanceAnonimizableNonDenom = pwalletMain->GetAnonymizableBalance(true);
758  // denoms
759  CAmount nBalanceDenominatedConf = pwalletMain->GetDenominatedBalance();
760  CAmount nBalanceDenominatedUnconf = pwalletMain->GetDenominatedBalance(true);
761  CAmount nBalanceDenominated = nBalanceDenominatedConf + nBalanceDenominatedUnconf;
762 
763  LogPrint("privatesend", "CPrivateSendClient::DoAutomaticDenominating -- nValueMin: %f, nBalanceNeedsAnonymized: %f, nBalanceAnonimizableNonDenom: %f, nBalanceDenominatedConf: %f, nBalanceDenominatedUnconf: %f, nBalanceDenominated: %f\n",
764  (float)nValueMin/COIN,
765  (float)nBalanceNeedsAnonymized/COIN,
766  (float)nBalanceAnonimizableNonDenom/COIN,
767  (float)nBalanceDenominatedConf/COIN,
768  (float)nBalanceDenominatedUnconf/COIN,
769  (float)nBalanceDenominated/COIN);
770 
771  if(fDryRun) return true;
772 
773  // Check if we have should create more denominated inputs i.e.
774  // there are funds to denominate and denominated balance does not exceed
775  // max amount to mix yet.
776  if(nBalanceAnonimizableNonDenom >= nValueMin + CPrivateSend::GetCollateralAmount() && nBalanceDenominated < nPrivateSendAmount*COIN)
777  return CreateDenominated(connman);
778 
779  //check if we have the collateral sized inputs
781  return !pwalletMain->HasCollateralInputs(false) && MakeCollateralAmounts(connman);
782 
783  if(nSessionID) {
784  strAutoDenomResult = _("Mixing in progress...");
785  return false;
786  }
787 
788  // Initial phase, find a Masternode
789  // Clean if there is anything left from previous session
790  UnlockCoins();
792  SetNull();
793 
794  // should be no unconfirmed denoms in non-multi-session mode
795  if(!fPrivateSendMultiSession && nBalanceDenominatedUnconf > 0) {
796  LogPrintf("CPrivateSendClient::DoAutomaticDenominating -- Found unconfirmed denominated outputs, will wait till they confirm to continue.\n");
797  strAutoDenomResult = _("Found unconfirmed denominated outputs, will wait till they confirm to continue.");
798  return false;
799  }
800 
801  //check our collateral and create new if needed
802  std::string strReason;
805  LogPrintf("CPrivateSendClient::DoAutomaticDenominating -- create collateral error:%s\n", strReason);
806  return false;
807  }
808  } else {
810  LogPrintf("CPrivateSendClient::DoAutomaticDenominating -- invalid collateral, recreating...\n");
812  LogPrintf("CPrivateSendClient::DoAutomaticDenominating -- create collateral error: %s\n", strReason);
813  return false;
814  }
815  }
816  }
817 
819 
820  // If we've used 90% of the Masternode list then drop the oldest first ~30%
821  int nThreshold_high = nMnCountEnabled * 0.9;
822  int nThreshold_low = nThreshold_high * 0.7;
823  LogPrint("privatesend", "Checking vecMasternodesUsed: size: %d, threshold: %d\n", (int)vecMasternodesUsed.size(), nThreshold_high);
824 
825  if((int)vecMasternodesUsed.size() > nThreshold_high) {
826  vecMasternodesUsed.erase(vecMasternodesUsed.begin(), vecMasternodesUsed.begin() + vecMasternodesUsed.size() - nThreshold_low);
827  LogPrint("privatesend", " vecMasternodesUsed: new size: %d, threshold: %d\n", (int)vecMasternodesUsed.size(), nThreshold_high);
828  }
829 
830  bool fUseQueue = GetRandInt(100) > 33;
831  // don't use the queues all of the time for mixing unless we are a liquidity provider
832  if((nLiquidityProvider || fUseQueue) && JoinExistingQueue(nBalanceNeedsAnonymized, connman))
833  return true;
834 
835  // do not initiate queue if we are a liquidity provider to avoid useless inter-mixing
836  if(nLiquidityProvider) return false;
837 
838  if(StartNewQueue(nValueMin, nBalanceNeedsAnonymized, connman))
839  return true;
840 
841  strAutoDenomResult = _("No compatible Masternode found.");
842  return false;
843 }
844 
845 bool CPrivateSendClient::JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CConnman& connman)
846 {
847  std::vector<CAmount> vecStandardDenoms = CPrivateSend::GetStandardDenominations();
848  // Look through the queues and see if anything matches
849  BOOST_FOREACH(CDarksendQueue& dsq, vecDarksendQueue) {
850  // only try each queue once
851  if(dsq.fTried) continue;
852  dsq.fTried = true;
853 
854  if(dsq.IsExpired()) continue;
855 
856  masternode_info_t infoMn;
857 
858  if(!mnodeman.GetMasternodeInfo(dsq.vin.prevout, infoMn)) {
859  LogPrintf("CPrivateSendClient::JoinExistingQueue -- dsq masternode is not in masternode list, masternode=%s\n", dsq.vin.prevout.ToStringShort());
860  continue;
861  }
862 
864 
865  std::vector<int> vecBits;
866  if(!CPrivateSend::GetDenominationsBits(dsq.nDenom, vecBits)) {
867  // incompatible denom
868  continue;
869  }
870 
871  // mixing rate limit i.e. nLastDsq check should already pass in DSQUEUE ProcessMessage
872  // in order for dsq to get into vecDarksendQueue, so we should be safe to mix already,
873  // no need for additional verification here
874 
875  LogPrint("privatesend", "CPrivateSendClient::JoinExistingQueue -- found valid queue: %s\n", dsq.ToString());
876 
877  CAmount nValueInTmp = 0;
878  std::vector<CTxIn> vecTxInTmp;
879  std::vector<COutput> vCoinsTmp;
880 
881  // Try to match their denominations if possible, select at least 1 denominations
882  if(!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, vecStandardDenoms[vecBits.front()], nBalanceNeedsAnonymized, vecTxInTmp, vCoinsTmp, nValueInTmp, 0, nPrivateSendRounds)) {
883  LogPrintf("CPrivateSendClient::JoinExistingQueue -- Couldn't match denominations %d %d (%s)\n", vecBits.front(), dsq.nDenom, CPrivateSend::GetDenominationsToString(dsq.nDenom));
884  continue;
885  }
886 
887  vecMasternodesUsed.push_back(dsq.vin.prevout);
888 
889  CNode* pnodeFound = NULL;
890  bool fDisconnect = false;
891  connman.ForNode(infoMn.addr, CConnman::AllNodes, [&pnodeFound, &fDisconnect](CNode* pnode) {
892  pnodeFound = pnode;
893  if(pnodeFound->fDisconnect) {
894  fDisconnect = true;
895  } else {
896  pnodeFound->AddRef();
897  }
898  return true;
899  });
900  if (fDisconnect)
901  continue;
902 
903  LogPrintf("CPrivateSendClient::JoinExistingQueue -- attempt to connect to masternode from queue, addr=%s\n", infoMn.addr.ToString());
904  // connect to Masternode and submit the queue request
905  CNode* pnode = (pnodeFound && pnodeFound->fMasternode) ? pnodeFound : connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, true);
906  if(pnode) {
907  infoMixingMasternode = infoMn;
908  nSessionDenom = dsq.nDenom;
909 
911  LogPrintf("CPrivateSendClient::JoinExistingQueue -- connected (from queue), sending DSACCEPT: nSessionDenom: %d (%s), addr=%s\n",
913  strAutoDenomResult = _("Mixing in progress...");
916  if(pnodeFound) {
917  pnodeFound->Release();
918  }
919  return true;
920  } else {
921  LogPrintf("CPrivateSendClient::JoinExistingQueue -- can't connect, addr=%s\n", infoMn.addr.ToString());
922  strAutoDenomResult = _("Error connecting to Masternode.");
923  continue;
924  }
925  }
926  return false;
927 }
928 
929 bool CPrivateSendClient::StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsAnonymized, CConnman& connman)
930 {
931  int nTries = 0;
933 
934  // ** find the coins we'll use
935  std::vector<CTxIn> vecTxIn;
936  CAmount nValueInTmp = 0;
937  if(!pwalletMain->SelectCoinsDark(nValueMin, nBalanceNeedsAnonymized, vecTxIn, nValueInTmp, 0, nPrivateSendRounds)) {
938  // this should never happen
939  LogPrintf("CPrivateSendClient::StartNewQueue -- Can't mix: no compatible inputs found!\n");
940  strAutoDenomResult = _("Can't mix: no compatible inputs found!");
941  return false;
942  }
943 
944  // otherwise, try one randomly
945  while(nTries < 10) {
947  if(!infoMn.fInfoValid) {
948  LogPrintf("CPrivateSendClient::StartNewQueue -- Can't find random masternode!\n");
949  strAutoDenomResult = _("Can't find random Masternode.");
950  return false;
951  }
952  vecMasternodesUsed.push_back(infoMn.vin.prevout);
953 
954  if(infoMn.nLastDsq != 0 && infoMn.nLastDsq + nMnCountEnabled/5 > mnodeman.nDsqCount) {
955  LogPrintf("CPrivateSendClient::StartNewQueue -- Too early to mix on this masternode!"
956  " masternode=%s addr=%s nLastDsq=%d CountEnabled/5=%d nDsqCount=%d\n",
957  infoMn.vin.prevout.ToStringShort(), infoMn.addr.ToString(), infoMn.nLastDsq,
958  nMnCountEnabled/5, mnodeman.nDsqCount);
959  nTries++;
960  continue;
961  }
962 
963  CNode* pnodeFound = NULL;
964  bool fDisconnect = false;
965  connman.ForNode(infoMn.addr, CConnman::AllNodes, [&pnodeFound, &fDisconnect](CNode* pnode) {
966  pnodeFound = pnode;
967  if(pnodeFound->fDisconnect) {
968  fDisconnect = true;
969  } else {
970  pnodeFound->AddRef();
971  }
972  return true;
973  });
974  if (fDisconnect) {
975  nTries++;
976  continue;
977  }
978 
979  LogPrintf("CPrivateSendClient::StartNewQueue -- attempt %d connection to Masternode %s\n", nTries, infoMn.addr.ToString());
980  CNode* pnode = (pnodeFound && pnodeFound->fMasternode) ? pnodeFound : connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, true);
981  if(pnode) {
982  LogPrintf("CPrivateSendClient::StartNewQueue -- connected, addr=%s\n", infoMn.addr.ToString());
983  infoMixingMasternode = infoMn;
984 
985  std::vector<CAmount> vecAmounts;
986  pwalletMain->ConvertList(vecTxIn, vecAmounts);
987  // try to get a single random denom out of vecAmounts
988  while(nSessionDenom == 0) {
990  }
991 
993  LogPrintf("CPrivateSendClient::StartNewQueue -- connected, sending DSACCEPT, nSessionDenom: %d (%s)\n",
995  strAutoDenomResult = _("Mixing in progress...");
998  if(pnodeFound) {
999  pnodeFound->Release();
1000  }
1001  return true;
1002  } else {
1003  LogPrintf("CPrivateSendClient::StartNewQueue -- can't connect, addr=%s\n", infoMn.addr.ToString());
1004  nTries++;
1005  continue;
1006  }
1007  }
1008  return false;
1009 }
1010 
1012 {
1013  std::string strError;
1014  std::vector<CTxIn> vecTxInRet;
1015  std::vector<CTxOut> vecTxOutRet;
1016 
1017  // Submit transaction to the pool if we get here
1018  // Try to use only inputs with the same number of rounds starting from the highest number of rounds possible
1019  for(int i = nPrivateSendRounds; i > 0; i--) {
1020  if(PrepareDenominate(i - 1, i, strError, vecTxInRet, vecTxOutRet)) {
1021  LogPrintf("CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, success\n", i);
1022  return SendDenominate(vecTxInRet, vecTxOutRet, connman);
1023  }
1024  LogPrint("privatesend", "CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, error: %s\n", i, strError);
1025  }
1026 
1027  // We failed? That's strange but let's just make final attempt and try to mix everything
1028  if(PrepareDenominate(0, nPrivateSendRounds, strError, vecTxInRet, vecTxOutRet)) {
1029  LogPrintf("CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for all rounds, success\n");
1030  return SendDenominate(vecTxInRet, vecTxOutRet, connman);
1031  }
1032 
1033  // Should never actually get here but just in case
1034  LogPrintf("CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for all rounds, error: %s\n", strError);
1035  strAutoDenomResult = strError;
1036  return false;
1037 }
1038 
1039 bool CPrivateSendClient::PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, std::vector<CTxIn>& vecTxInRet, std::vector<CTxOut>& vecTxOutRet)
1040 {
1041  if(!pwalletMain) {
1042  strErrorRet = "Wallet is not initialized";
1043  return false;
1044  }
1045 
1046  if (pwalletMain->IsLocked(true)) {
1047  strErrorRet = "Wallet locked, unable to create transaction!";
1048  return false;
1049  }
1050 
1051  if (GetEntriesCount() > 0) {
1052  strErrorRet = "Already have pending entries in the PrivateSend pool";
1053  return false;
1054  }
1055 
1056  // make sure returning vectors are empty before filling them up
1057  vecTxInRet.clear();
1058  vecTxOutRet.clear();
1059 
1060  // ** find the coins we'll use
1061  std::vector<CTxIn> vecTxIn;
1062  std::vector<COutput> vCoins;
1063  CAmount nValueIn = 0;
1064 
1065  /*
1066  Select the coins we'll use
1067 
1068  if nMinRounds >= 0 it means only denominated inputs are going in and coming out
1069  */
1070  std::vector<int> vecBits;
1072  strErrorRet = "Incorrect session denom";
1073  return false;
1074  }
1075  std::vector<CAmount> vecStandardDenoms = CPrivateSend::GetStandardDenominations();
1076  bool fSelected = pwalletMain->SelectCoinsByDenominations(nSessionDenom, vecStandardDenoms[vecBits.front()], CPrivateSend::GetMaxPoolAmount(), vecTxIn, vCoins, nValueIn, nMinRounds, nMaxRounds);
1077  if (nMinRounds >= 0 && !fSelected) {
1078  strErrorRet = "Can't select current denominated inputs";
1079  return false;
1080  }
1081 
1082  LogPrintf("CPrivateSendClient::PrepareDenominate -- max value: %f\n", (double)nValueIn/COIN);
1083 
1084  {
1086  BOOST_FOREACH(CTxIn txin, vecTxIn) {
1087  pwalletMain->LockCoin(txin.prevout);
1088  }
1089  }
1090 
1091  CAmount nValueLeft = nValueIn;
1092 
1093  // Try to add every needed denomination, repeat up to 5-PRIVATESEND_ENTRY_MAX_SIZE times.
1094  // NOTE: No need to randomize order of inputs because they were
1095  // initially shuffled in CWallet::SelectCoinsByDenominations already.
1096  int nStep = 0;
1097  int nStepsMax = 5 + GetRandInt(PRIVATESEND_ENTRY_MAX_SIZE-5+1);
1098 
1099  while (nStep < nStepsMax) {
1100  BOOST_FOREACH(int nBit, vecBits) {
1101  CAmount nValueDenom = vecStandardDenoms[nBit];
1102  if (nValueLeft - nValueDenom < 0) continue;
1103 
1104  // Note: this relies on a fact that both vectors MUST have same size
1105  std::vector<CTxIn>::iterator it = vecTxIn.begin();
1106  std::vector<COutput>::iterator it2 = vCoins.begin();
1107  while (it2 != vCoins.end()) {
1108  // we have matching inputs
1109  if ((*it2).tx->vout[(*it2).i].nValue == nValueDenom) {
1110  // add new input in resulting vector
1111  vecTxInRet.push_back(*it);
1112  // remove corresponting items from initial vectors
1113  vecTxIn.erase(it);
1114  vCoins.erase(it2);
1115 
1117 
1118  // add new output
1119  CTxOut txout(nValueDenom, scriptDenom);
1120  vecTxOutRet.push_back(txout);
1121 
1122  // subtract denomination amount
1123  nValueLeft -= nValueDenom;
1124 
1125  // step is complete
1126  break;
1127  }
1128  ++it;
1129  ++it2;
1130  }
1131  }
1132  if(nValueLeft == 0) break;
1133  nStep++;
1134  }
1135 
1136  {
1137  // unlock unused coins
1139  BOOST_FOREACH(CTxIn txin, vecTxIn) {
1141  }
1142  }
1143 
1144  if (CPrivateSend::GetDenominations(vecTxOutRet) != nSessionDenom) {
1145  // unlock used coins on failure
1147  BOOST_FOREACH(CTxIn txin, vecTxInRet) {
1149  }
1151  strErrorRet = "Can't make current denominated outputs";
1152  return false;
1153  }
1154 
1155  // We also do not care about full amount as long as we have right denominations
1156  return true;
1157 }
1158 
1159 // Create collaterals by looping through inputs grouped by addresses
1161 {
1162  std::vector<CompactTallyItem> vecTally;
1163  if(!pwalletMain->SelectCoinsGrouppedByAddresses(vecTally, false)) {
1164  LogPrint("privatesend", "CPrivateSendClient::MakeCollateralAmounts -- SelectCoinsGrouppedByAddresses can't find any inputs!\n");
1165  return false;
1166  }
1167 
1168  // First try to use only non-denominated funds
1169  BOOST_FOREACH(CompactTallyItem& item, vecTally) {
1170  if(!MakeCollateralAmounts(item, false, connman)) continue;
1171  return true;
1172  }
1173 
1174  // There should be at least some denominated funds we should be able to break in pieces to continue mixing
1175  BOOST_FOREACH(CompactTallyItem& item, vecTally) {
1176  if(!MakeCollateralAmounts(item, true, connman)) continue;
1177  return true;
1178  }
1179 
1180  // If we got here then smth is terribly broken actually
1181  LogPrintf("CPrivateSendClient::MakeCollateralAmounts -- ERROR: Can't make collaterals!\n");
1182  return false;
1183 }
1184 
1185 // Split up large inputs or create fee sized inputs
1186 bool CPrivateSendClient::MakeCollateralAmounts(const CompactTallyItem& tallyItem, bool fTryDenominated, CConnman& connman)
1187 {
1189 
1190  // denominated input is always a single one, so we can check its amount directly and return early
1191  if(!fTryDenominated && tallyItem.vecTxIn.size() == 1 && pwalletMain->IsDenominatedAmount(tallyItem.nAmount))
1192  return false;
1193 
1194  CWalletTx wtx;
1195  CAmount nFeeRet = 0;
1196  int nChangePosRet = -1;
1197  std::string strFail = "";
1198  std::vector<CRecipient> vecSend;
1199 
1200  // make our collateral address
1201  CReserveKey reservekeyCollateral(pwalletMain);
1202  // make our change address
1203  CReserveKey reservekeyChange(pwalletMain);
1204 
1205  CScript scriptCollateral;
1206  CPubKey vchPubKey;
1207  assert(reservekeyCollateral.GetReservedKey(vchPubKey, false)); // should never fail, as we just unlocked
1208  scriptCollateral = GetScriptForDestination(vchPubKey.GetID());
1209 
1210  vecSend.push_back((CRecipient){scriptCollateral, CPrivateSend::GetMaxCollateralAmount(), false});
1211 
1212  // try to use non-denominated and not mn-like funds first, select them explicitly
1213  CCoinControl coinControl;
1214  coinControl.fAllowOtherInputs = false;
1215  coinControl.fAllowWatchOnly = false;
1216  // send change to the same address so that we were able create more denoms out of it later
1217  coinControl.destChange = tallyItem.txdest;
1218  BOOST_FOREACH(const CTxIn& txin, tallyItem.vecTxIn)
1219  coinControl.Select(txin.prevout);
1220 
1221  bool fSuccess = pwalletMain->CreateTransaction(vecSend, wtx, reservekeyChange,
1222  nFeeRet, nChangePosRet, strFail, &coinControl, true, ONLY_NONDENOMINATED_NOT1000IFMN);
1223  if(!fSuccess) {
1224  LogPrintf("CPrivateSendClient::MakeCollateralAmounts -- ONLY_NONDENOMINATED_NOT1000IFMN Error: %s\n", strFail);
1225  // If we failed then most likeky there are not enough funds on this address.
1226  if(fTryDenominated) {
1227  // Try to also use denominated coins (we can't mix denominated without collaterals anyway).
1228  // MN-like funds should not be touched in any case.
1229  if(!pwalletMain->CreateTransaction(vecSend, wtx, reservekeyChange,
1230  nFeeRet, nChangePosRet, strFail, &coinControl, true, ONLY_NOT1000IFMN)) {
1231  LogPrintf("CPrivateSendClient::MakeCollateralAmounts -- ONLY_NOT1000IFMN Error: %s\n", strFail);
1232  reservekeyCollateral.ReturnKey();
1233  return false;
1234  }
1235  } else {
1236  // Nothing else we can do.
1237  reservekeyCollateral.ReturnKey();
1238  return false;
1239  }
1240  }
1241 
1242  reservekeyCollateral.KeepKey();
1243 
1244  LogPrintf("CPrivateSendClient::MakeCollateralAmounts -- txid=%s\n", wtx.GetHash().GetHex());
1245 
1246  // use the same nCachedLastSuccessBlock as for DS mixinx to prevent race
1247  if(!pwalletMain->CommitTransaction(wtx, reservekeyChange, &connman)) {
1248  LogPrintf("CPrivateSendClient::MakeCollateralAmounts -- CommitTransaction failed!\n");
1249  return false;
1250  }
1251 
1253 
1254  return true;
1255 }
1256 
1257 // Create denominations by looping through inputs grouped by addresses
1259 {
1261 
1262  std::vector<CompactTallyItem> vecTally;
1264  LogPrint("privatesend", "CPrivateSendClient::CreateDenominated -- SelectCoinsGrouppedByAddresses can't find any inputs!\n");
1265  return false;
1266  }
1267 
1268  bool fCreateMixingCollaterals = !pwalletMain->HasCollateralInputs();
1269 
1270  BOOST_FOREACH(CompactTallyItem& item, vecTally) {
1271  if(!CreateDenominated(item, fCreateMixingCollaterals, connman)) continue;
1272  return true;
1273  }
1274 
1275  LogPrintf("CPrivateSendClient::CreateDenominated -- failed!\n");
1276  return false;
1277 }
1278 
1279 // Create denominations
1280 bool CPrivateSendClient::CreateDenominated(const CompactTallyItem& tallyItem, bool fCreateMixingCollaterals, CConnman& connman)
1281 {
1282  std::vector<CRecipient> vecSend;
1283  CKeyHolderStorage keyHolderStorageDenom;
1284 
1285  CAmount nValueLeft = tallyItem.nAmount;
1286  nValueLeft -= CPrivateSend::GetCollateralAmount(); // leave some room for fees
1287 
1288  LogPrintf("CreateDenominated0 nValueLeft: %f\n", (float)nValueLeft/COIN);
1289 
1290  // ****** Add an output for mixing collaterals ************ /
1291 
1292  if(fCreateMixingCollaterals) {
1293  CScript scriptCollateral = keyHolderStorageDenom.AddKey(pwalletMain).GetScriptForDestination();
1294  vecSend.push_back((CRecipient){ scriptCollateral, CPrivateSend::GetMaxCollateralAmount(), false });
1295  nValueLeft -= CPrivateSend::GetMaxCollateralAmount();
1296  }
1297 
1298  // ****** Add outputs for denoms ************ /
1299 
1300  // try few times - skipping smallest denoms first if there are too many of them already, if failed - use them too
1301  int nOutputsTotal = 0;
1302  bool fSkip = true;
1303  do {
1304  std::vector<CAmount> vecStandardDenoms = CPrivateSend::GetStandardDenominations();
1305 
1306  BOOST_REVERSE_FOREACH(CAmount nDenomValue, vecStandardDenoms) {
1307 
1308  if(fSkip) {
1309  // Note: denoms are skipped if there are already DENOMS_COUNT_MAX of them
1310  // and there are still larger denoms which can be used for mixing
1311 
1312  // check skipped denoms
1313  if(IsDenomSkipped(nDenomValue)) continue;
1314 
1315  // find new denoms to skip if any (ignore the largest one)
1316  if(nDenomValue != vecStandardDenoms.front() && pwalletMain->CountInputsWithAmount(nDenomValue) > DENOMS_COUNT_MAX) {
1317  strAutoDenomResult = strprintf(_("Too many %f denominations, removing."), (float)nDenomValue/COIN);
1318  LogPrintf("CPrivateSendClient::CreateDenominated -- %s\n", strAutoDenomResult);
1319  vecDenominationsSkipped.push_back(nDenomValue);
1320  continue;
1321  }
1322  }
1323 
1324  int nOutputs = 0;
1325 
1326  // add each output up to 11 times until it can't be added again
1327  while(nValueLeft - nDenomValue >= 0 && nOutputs <= 10) {
1328  CScript scriptDenom = keyHolderStorageDenom.AddKey(pwalletMain).GetScriptForDestination();
1329 
1330  vecSend.push_back((CRecipient){ scriptDenom, nDenomValue, false });
1331 
1332  //increment outputs and subtract denomination amount
1333  nOutputs++;
1334  nValueLeft -= nDenomValue;
1335  LogPrintf("CreateDenominated1: totalOutputs: %d, nOutputsTotal: %d, nOutputs: %d, nValueLeft: %f\n", nOutputsTotal + nOutputs, nOutputsTotal, nOutputs, (float)nValueLeft/COIN);
1336  }
1337 
1338  nOutputsTotal += nOutputs;
1339  if(nValueLeft == 0) break;
1340  }
1341  LogPrintf("CreateDenominated2: nOutputsTotal: %d, nValueLeft: %f\n", nOutputsTotal, (float)nValueLeft/COIN);
1342  // if there were no outputs added, start over without skipping
1343  fSkip = !fSkip;
1344  } while (nOutputsTotal == 0 && !fSkip);
1345  LogPrintf("CreateDenominated3: nOutputsTotal: %d, nValueLeft: %f\n", nOutputsTotal, (float)nValueLeft/COIN);
1346 
1347  // if we have anything left over, it will be automatically send back as change - there is no need to send it manually
1348 
1349  CCoinControl coinControl;
1350  coinControl.fAllowOtherInputs = false;
1351  coinControl.fAllowWatchOnly = false;
1352  // send change to the same address so that we were able create more denoms out of it later
1353  coinControl.destChange = tallyItem.txdest;
1354  BOOST_FOREACH(const CTxIn& txin, tallyItem.vecTxIn)
1355  coinControl.Select(txin.prevout);
1356 
1357  CWalletTx wtx;
1358  CAmount nFeeRet = 0;
1359  int nChangePosRet = -1;
1360  std::string strFail = "";
1361  // make our change address
1362  CReserveKey reservekeyChange(pwalletMain);
1363 
1364  bool fSuccess = pwalletMain->CreateTransaction(vecSend, wtx, reservekeyChange,
1365  nFeeRet, nChangePosRet, strFail, &coinControl, true, ONLY_NONDENOMINATED_NOT1000IFMN);
1366  if(!fSuccess) {
1367  LogPrintf("CPrivateSendClient::CreateDenominated -- Error: %s\n", strFail);
1368  keyHolderStorageDenom.ReturnAll();
1369  return false;
1370  }
1371 
1372  keyHolderStorageDenom.KeepAll();
1373 
1374  if(!pwalletMain->CommitTransaction(wtx, reservekeyChange, &connman)) {
1375  LogPrintf("CPrivateSendClient::CreateDenominated -- CommitTransaction failed!\n");
1376  return false;
1377  }
1378 
1379  // use the same nCachedLastSuccessBlock as for DS mixing to prevent race
1381  LogPrintf("CPrivateSendClient::CreateDenominated -- txid=%s\n", wtx.GetHash().GetHex());
1382 
1383  return true;
1384 }
1385 
1387 {
1388  if(!infoMixingMasternode.fInfoValid) return;
1389 
1390  connman.ForNode(infoMixingMasternode.addr, [&entry, &connman](CNode* pnode) {
1391  LogPrintf("CPrivateSendClient::RelayIn -- found master, relaying message to %s\n", pnode->addr.ToString());
1392  connman.PushMessage(pnode, NetMsgType::DSVIN, entry);
1393  return true;
1394  });
1395 }
1396 
1398 {
1399  LogPrintf("CPrivateSendClient::SetState -- nState: %d, nStateNew: %d\n", nState, nStateNew);
1400  nState = nStateNew;
1401 }
1402 
1404 {
1405  nCachedBlockHeight = pindex->nHeight;
1406  LogPrint("privatesend", "CPrivateSendClient::UpdatedBlockTip -- nCachedBlockHeight: %d\n", nCachedBlockHeight);
1407 
1409  NewBlock();
1410  }
1411 
1413 }
1414 
1415 //TODO: Rename/move to core
1417 {
1418  if(fLiteMode) return; // disable all Dash specific functionality
1419 
1420  static bool fOneThread;
1421  if(fOneThread) return;
1422  fOneThread = true;
1423 
1424  // Make this thread recognisable as the PrivateSend thread
1425  RenameThread("dash-ps-client");
1426 
1427  unsigned int nTick = 0;
1428  unsigned int nDoAutoNextRun = nTick + PRIVATESEND_AUTO_TIMEOUT_MIN;
1429 
1430  while (true)
1431  {
1432  MilliSleep(1000);
1433 
1435  nTick++;
1437  if(nDoAutoNextRun == nTick) {
1440  }
1441  }
1442  }
1443 }
static CAmount GetMaxCollateralAmount()
Definition: privatesend.h:350
masternode_info_t FindRandomNotInVec(const std::vector< COutPoint > &vecToExclude, int nProtocolVersion=-1)
Find a random entry.
CTxDestination destChange
Definition: coincontrol.h:14
CNode * ConnectNode(CAddress addrConnect, const char *pszDest=NULL, bool fConnectToMasternode=false)
Definition: net.cpp:347
int CountInputsWithAmount(CAmount nInputAmount)
Definition: wallet.cpp:3044
int64_t nDsqCount
Definition: masternodeman.h:91
bool fAllowWatchOnly
Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria.
Definition: coincontrol.h:20
CMasternodeMan mnodeman
const CKeyHolder & AddKey(CWallet *pwalletIn)
std::string strAutoDenomResult
CMasternodeSync masternodeSync
const char * DSACCEPT
Definition: protocol.cpp:54
PoolState nState
Definition: privatesend.h:287
bool PrepareDenominate(int nMinRounds, int nMaxRounds, std::string &strErrorRet, std::vector< CTxIn > &vecTxInRet, std::vector< CTxOut > &vecTxOutRet)
step 1: prepare denominated inputs and outputs
void MilliSleep(int64_t n)
Definition: utiltime.cpp:63
std::vector< CTxIn > vecTxIn
Definition: wallet.h:115
int GetRandInt(int nMax)
Definition: random.cpp:109
#define TRY_LOCK(cs, name)
Definition: sync.h:170
const char * DSQUEUE
Definition: protocol.cpp:61
bool SelectCoinsDark(CAmount nValueMin, CAmount nValueMax, std::vector< CTxIn > &vecTxInRet, CAmount &nValueRet, int nPrivateSendRoundsMin, int nPrivateSendRoundsMax) const
Definition: wallet.cpp:2930
static const int DENOMS_COUNT_MAX
CMutableTransaction txMyCollateral
bool ShutdownRequested()
Definition: init.cpp:168
#define strprintf
Definition: tinyformat.h:1011
bool JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CConnman &connman)
CCriticalSection cs_wallet
Definition: wallet.h:672
static const CAmount COIN
Definition: amount.h:16
void RelayIn(const CDarkSendEntry &entry, CConnman &connman)
CKeyHolderStorage keyHolderStorage
CAmount nAmount
Definition: wallet.h:114
static std::string GetDenominationsToString(int nDenom)
std::vector< CAmount > vecDenominationsSkipped
void SetState(PoolState nStateNew)
CCriticalSection cs_main
Definition: validation.cpp:62
bool SelectCoinsByDenominations(int nDenom, CAmount nValueMin, CAmount nValueMax, std::vector< CTxIn > &vecTxInRet, std::vector< COutput > &vCoinsRet, CAmount &nValueRet, int nPrivateSendRoundsMin, int nPrivateSendRoundsMax)
Definition: wallet.cpp:2762
CAmount nValue
Definition: transaction.h:136
const char * DSFINALTX
Definition: protocol.cpp:56
static const int PRIVATESEND_KEYS_THRESHOLD_WARNING
CAddress addr
Definition: net.h:688
bool SubmitDenominate(CConnman &connman)
As a client, submit part of a future mixing transaction to a Masternode to start the process...
Definition: net.h:108
bool ForNode(NodeId id, std::function< bool(const CNode *pnode)> cond, std::function< bool(CNode *pnode)> func)
Definition: net.cpp:2879
static CAmount GetCollateralAmount()
Definition: privatesend.h:349
void Select(const COutPoint &output)
Definition: coincontrol.h:50
bool HasCollateralInputs(bool fOnlyConfirmed=true) const
Definition: wallet.cpp:3072
std::string ToString() const
Definition: transaction.cpp:76
static CAmount GetSmallestDenomination()
Definition: privatesend.h:329
CWallet * pwalletMain
std::vector< CTxIn > vin
Definition: transaction.h:306
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool *pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee, bool fDryRun)
CPubKey pubKeyMasternode
Definition: masternode.h:117
void CompletedTransaction(PoolMessage nMessageID)
static const int PRIVATESEND_QUEUE_TIMEOUT
Definition: privatesend.h:21
masternode_info_t infoMixingMasternode
std::string ToString(bool fUseGetnameinfo=true) const
Definition: netaddress.cpp:568
void AskForMN(CNode *pnode, const COutPoint &outpoint, CConnman &connman)
Ask (source) node for mnb.
bool CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey, CConnman *connman, std::string strCommand="tx")
Definition: wallet.cpp:3527
CAmount GetNeedsToBeAnonymizedBalance(CAmount nMinBalance=0) const
Definition: wallet.cpp:2244
CAmount GetAnonymizableBalance(bool fSkipDenominated=false, bool fSkipUnconfirmed=true) const
Definition: wallet.cpp:2155
void RenameThread(const char *name)
Definition: util.cpp:873
PoolMessage
Definition: privatesend.h:30
static int GetDenominations(const std::vector< CTxOut > &vecTxOut, bool fSingleRandomDenom=false)
Get the denominations for a list of outputs (returns a bitshifted integer)
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:144
std::vector< CTxDSIn > vecTxDSIn
Definition: privatesend.h:118
bool fMasterNode
Definition: util.cpp:108
int64_t CAmount
Definition: amount.h:14
bool CheckDiskSpace(uint64_t nAdditionalBytes)
bool fLiteMode
Definition: util.cpp:109
#define LOCK2(cs1, cs2)
Definition: sync.h:169
void push_back(const T &value)
Definition: prevector.h:381
int nWalletBackups
Definition: util.cpp:117
#define LogPrintf(...)
Definition: util.h:98
bool CreateTransaction(const std::vector< CRecipient > &vecSend, CWalletTx &wtxNew, CReserveKey &reservekey, CAmount &nFeeRet, int &nChangePosRet, std::string &strFailReason, const CCoinControl *coinControl=NULL, bool sign=true, AvailableCoinsType nCoinType=ALL_COINS, bool fUseInstantSend=false)
Definition: wallet.cpp:3173
std::string ToString()
Definition: privatesend.h:205
static const CAmount PRIVATESEND_ENTRY_MAX_SIZE
Definition: privatesend.h:27
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Definition: core_write.cpp:75
bool CreateDenominated(CConnman &connman)
Create denominations.
COutPoint prevout
Definition: transaction.h:61
Definition: net.h:661
void UnlockCoin(COutPoint &output)
Definition: wallet.cpp:4204
static int LogPrint(const char *category, const char *format)
Definition: util.h:126
#define LOCK(cs)
Definition: sync.h:168
std::string ToString() const
Definition: transaction.cpp:36
bool fAllowOtherInputs
If false, allows unselected inputs, but requires all selected inputs be used.
Definition: coincontrol.h:18
bool GetMasternodeInfo(const COutPoint &outpoint, masternode_info_t &mnInfoRet)
std::string strLastMessage
std::vector< COutPoint > vecOutPointLocked
int64_t nTimeLastSuccessfulStep
Definition: privatesend.h:288
bool ConvertList(std::vector< CTxIn > vecTxIn, std::vector< CAmount > &vecAmounts)
Definition: wallet.cpp:3158
void CheckPool()
Check for process.
bool IsLocked(bool fForMixing=false) const
Definition: crypter.h:166
static std::string GetMessageByID(PoolMessage nMessageID)
std::string ToString() const
Definition: uint256.cpp:65
static bool GetDenominationsBits(int nDenom, std::vector< int > &vecBitsRet)
CScript GetScriptForDestination(const CTxDestination &dest)
Definition: standard.cpp:262
void KeepKey()
Definition: wallet.cpp:4120
CMutableTransaction finalMutableTransaction
Definition: privatesend.h:292
int size()
Return the number of (unique) Masternodes.
bool IsDenominatedAmount(CAmount nInputAmount) const
Definition: wallet.cpp:1343
bool CreateCollateralTransaction(CMutableTransaction &txCollateral, std::string &strReason)
Definition: wallet.cpp:3088
static const int PRIVATESEND_SIGNING_TIMEOUT
Definition: privatesend.h:22
bool SendDenominate(const std::vector< CTxIn > &vecTxIn, const std::vector< CTxOut > &vecTxOut, CConnman &connman)
step 2: send denominated inputs and outputs prepared in step 1
std::vector< CTxOut > vout
Definition: transaction.h:307
bool SelectCoinsGrouppedByAddresses(std::vector< CompactTallyItem > &vecTallyRet, bool fSkipDenominated=true, bool fAnonymizable=true, bool fSkipUnconfirmed=true) const
Definition: wallet.cpp:2831
const char * DSSIGNFINALTX
Definition: protocol.cpp:57
void ReturnKey()
Definition: wallet.cpp:4129
CPrivateSendClient privateSendClient
bool GetReservedKey(CPubKey &pubkey, bool fInternalIn)
Definition: wallet.cpp:4101
static vector< COutput > vCoins
std::vector< CDarkSendEntry > vecEntries
Definition: privatesend.h:285
PoolStatusUpdate
Definition: privatesend.h:70
CTxMemPool mempool
int CountEnabled(int nProtocolVersion=-1)
static std::vector< CAmount > GetStandardDenominations()
Definition: privatesend.h:328
uint256 GetHash() const
Definition: transaction.cpp:71
int GetEntriesCount() const
Definition: privatesend.h:305
static CAmount GetMaxPoolAmount()
Definition: privatesend.h:345
bool AllowMixing(const COutPoint &outpoint)
std::string ToString() const
Definition: transaction.cpp:63
CAmount GetDenominatedBalance(bool unconfirmed=false) const
Definition: wallet.cpp:2268
CTxDestination txdest
Definition: wallet.h:113
int64_t GetTimeMillis()
Definition: utiltime.cpp:34
const uint256 & GetHash() const
Definition: transaction.h:262
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CConnman &connman)
static int GetMaxPoolTransactions()
Get the maximum number of transactions for the pool.
Definition: privatesend.h:343
std::vector< COutPoint > vecMasternodesUsed
PoolState
Definition: privatesend.h:58
static const int PRIVATESEND_AUTO_TIMEOUT_MAX
Definition: privatesend.h:20
bool CheckPoolStateUpdate(PoolState nStateNew, int nEntriesCountNew, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID, int nSessionIDNew=0)
Get Masternode updates about the progress of mixing.
bool IsBlockchainSynced()
static const int MIN_PRIVATESEND_PEER_PROTO_VERSION
minimum peer version accepted by mixing pool
Definition: privatesend.h:25
bool IsDenomSkipped(CAmount nDenomValue)
std::string GetHex() const
Definition: uint256.cpp:21
bool IsExpired()
Is this queue expired?
Definition: privatesend.h:203
static const int PRIVATESEND_AUTO_TIMEOUT_MIN
Definition: privatesend.h:19
static const int PRIVATESEND_KEYS_THRESHOLD_STOP
static bool IsCollateralValid(const CTransaction &txCollateral)
If the collateral is valid given by a client.
Definition: pubkey.h:37
CCriticalSection cs_darksend
void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, const CAmount &nFeeDelta)
Definition: txmempool.cpp:934
void ThreadCheckPrivateSendClient(CConnman &connman)
int64_t GetTime()
For unit testing.
Definition: utiltime.cpp:20
bool SignFinalTransaction(const CTransaction &finalTransactionNew, CNode *pnode, CConnman &connman)
As a client, check and sign the final transaction.
void LockCoin(COutPoint &output)
Definition: wallet.cpp:4193
const char * DSCOMPLETE
Definition: protocol.cpp:58
static constexpr const CAllNodes AllNodes
Definition: net.h:160
bool MakeCollateralAmounts(CConnman &connman)
Split up large inputs or make fee sized inputs.
bool DoAutomaticDenominating(CConnman &connman, bool fDryRun=false)
Passively run mixing in the background according to the configuration in settings.
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:113
const char * DSSTATUSUPDATE
Definition: protocol.cpp:59
std::string ToStringShort() const
Definition: transaction.cpp:17
void UpdatedBlockTip(const CBlockIndex *pindex)
bool SignSignature(const CKeyStore &keystore, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, int nHashType)
Definition: sign.cpp:129
bool IsMasternodeListSynced()
static int GetDenominationsByAmounts(const std::vector< CAmount > &vecAmount)
Get the denominations for a specific amount of dash.
int64_t nKeysLeftSinceAutoBackup
Definition: wallet.h:755
static void CheckDSTXes(int nHeight)
bool AutoBackupWallet(CWallet *wallet, std::string strWalletFile, std::string &strBackupWarning, std::string &strBackupError)
Definition: walletdb.cpp:946
void PushMessage(CNode *pnode, const std::string &sCommand, Args &&... args)
Definition: net.h:199
std::atomic< int > nVersion
Definition: net.h:692
std::string _(const char *psz)
Definition: util.h:84
std::vector< CTxDSOut > vecTxDSOut
Definition: privatesend.h:119
CScript prevPubKey
Definition: transaction.h:64
CScript GetScriptForDestination() const
bool StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsAnonymized, CConnman &connman)
std::vector< CDarksendQueue > vecDarksendQueue
Definition: privatesend.h:283
void NewBlock()
Process a new block.