Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ot_utility_ot.cpp
Go to the documentation of this file.
1 /************************************************************
2 *
3 * ot_utility_ot.cpp
4 *
5 */
6 
7 /************************************************************
8  -----BEGIN PGP SIGNED MESSAGE-----
9  Hash: SHA1
10 
11  * OPEN TRANSACTIONS
12  *
13  * Financial Cryptography and Digital Cash
14  * Library, Protocol, API, Server, CLI, GUI
15  *
16  * -- Anonymous Numbered Accounts.
17  * -- Untraceable Digital Cash.
18  * -- Triple-Signed Receipts.
19  * -- Cheques, Vouchers, Transfers, Inboxes.
20  * -- Basket Currencies, Markets, Payment Plans.
21  * -- Signed, XML, Ricardian-style Contracts.
22  * -- Scripted smart contracts.
23  *
24  * Copyright (C) 2010-2013 by "Fellow Traveler" (A pseudonym)
25  *
26  * EMAIL:
28  *
29  * BITCOIN: 1NtTPVVjDsUfDWybS4BwvHpG2pdS9RnYyQ
30  *
31  * KEY FINGERPRINT (PGP Key in license file):
32  * 9DD5 90EB 9292 4B48 0484 7910 0308 00ED F951 BB8E
33  *
34  * OFFICIAL PROJECT WIKI(s):
35  * https://github.com/FellowTraveler/Moneychanger
36  * https://github.com/FellowTraveler/Open-Transactions/wiki
37  *
38  * WEBSITE:
39  * http://www.OpenTransactions.org/
40  *
41  * Components and licensing:
42  * -- Moneychanger..A Java client GUI.....LICENSE:.....GPLv3
43  * -- otlib.........A class library.......LICENSE:...LAGPLv3
44  * -- otapi.........A client API..........LICENSE:...LAGPLv3
45  * -- opentxs/ot....Command-line client...LICENSE:...LAGPLv3
46  * -- otserver......Server Application....LICENSE:....AGPLv3
47  * Github.com/FellowTraveler/Open-Transactions/wiki/Components
48  *
49  * All of the above OT components were designed and written by
50  * Fellow Traveler, with the exception of Moneychanger, which
51  * was contracted out to Vicky C ([email protected]).
52  * The open-source community has since actively contributed.
53  *
54  * -----------------------------------------------------
55  *
56  * LICENSE:
57  * This program is free software: you can redistribute it
58  * and/or modify it under the terms of the GNU Affero
59  * General Public License as published by the Free Software
60  * Foundation, either version 3 of the License, or (at your
61  * option) any later version.
62  *
63  * ADDITIONAL PERMISSION under the GNU Affero GPL version 3
64  * section 7: (This paragraph applies only to the LAGPLv3
65  * components listed above.) If you modify this Program, or
66  * any covered work, by linking or combining it with other
67  * code, such other code is not for that reason alone subject
68  * to any of the requirements of the GNU Affero GPL version 3.
69  * (==> This means if you are only using the OT API, then you
70  * don't have to open-source your code--only your changes to
71  * Open-Transactions itself must be open source. Similar to
72  * LGPLv3, except it applies to software-as-a-service, not
73  * just to distributing binaries.)
74  *
75  * Extra WAIVER for OpenSSL, Lucre, and all other libraries
76  * used by Open Transactions: This program is released under
77  * the AGPL with the additional exemption that compiling,
78  * linking, and/or using OpenSSL is allowed. The same is true
79  * for any other open source libraries included in this
80  * project: complete waiver from the AGPL is hereby granted to
81  * compile, link, and/or use them with Open-Transactions,
82  * according to their own terms, as long as the rest of the
83  * Open-Transactions terms remain respected, with regard to
84  * the Open-Transactions code itself.
85  *
86  * Lucre License:
87  * This code is also "dual-license", meaning that Ben Lau-
88  * rie's license must also be included and respected, since
89  * the code for Lucre is also included with Open Transactions.
90  * See Open-Transactions/src/otlib/lucre/LUCRE_LICENSE.txt
91  * The Laurie requirements are light, but if there is any
92  * problem with his license, simply remove the Lucre code.
93  * Although there are no other blind token algorithms in Open
94  * Transactions (yet. credlib is coming), the other functions
95  * will continue to operate.
96  * See Lucre on Github: https://github.com/benlaurie/lucre
97  * -----------------------------------------------------
98  * You should have received a copy of the GNU Affero General
99  * Public License along with this program. If not, see:
100  * http://www.gnu.org/licenses/
101  *
102  * If you would like to use this software outside of the free
103  * software license, please contact FellowTraveler.
104  * (Unfortunately many will run anonymously and untraceably,
105  * so who could really stop them?)
106  *
107  * DISCLAIMER:
108  * This program is distributed in the hope that it will be
109  * useful, but WITHOUT ANY WARRANTY; without even the implied
110  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
111  * PURPOSE. See the GNU Affero General Public License for
112  * more details.
113 
114  -----BEGIN PGP SIGNATURE-----
115  Version: GnuPG v1.4.9 (Darwin)
116 
117  iQIcBAEBAgAGBQJRSsfJAAoJEAMIAO35UbuOQT8P/RJbka8etf7wbxdHQNAY+2cC
118  vDf8J3X8VI+pwMqv6wgTVy17venMZJa4I4ikXD/MRyWV1XbTG0mBXk/7AZk7Rexk
119  KTvL/U1kWiez6+8XXLye+k2JNM6v7eej8xMrqEcO0ZArh/DsLoIn1y8p8qjBI7+m
120  aE7lhstDiD0z8mwRRLKFLN2IH5rAFaZZUvj5ERJaoYUKdn4c+RcQVei2YOl4T0FU
121  LWND3YLoH8naqJXkaOKEN4UfJINCwxhe5Ke9wyfLWLUO7NamRkWD2T7CJ0xocnD1
122  sjAzlVGNgaFDRflfIF4QhBx1Ddl6wwhJfw+d08bjqblSq8aXDkmFA7HeunSFKkdn
123  oIEOEgyj+veuOMRJC5pnBJ9vV+7qRdDKQWaCKotynt4sWJDGQ9kWGWm74SsNaduN
124  TPMyr9kNmGsfR69Q2Zq/FLcLX/j8ESxU+HYUB4vaARw2xEOu2xwDDv6jt0j3Vqsg
125  x7rWv4S/Eh18FDNDkVRChiNoOIilLYLL6c38uMf1pnItBuxP3uhgY6COm59kVaRh
126  nyGTYCDYD2TK+fI9o89F1297uDCwEJ62U0Q7iTDp5QuXCoxkPfv8/kX6lS6T3y9G
127  M9mqIoLbIQ1EDntFv7/t6fUTS2+46uCrdZWbQ5RjYXdrzjij02nDmJAm2BngnZvd
128  kamH0Y/n11lCvo1oQxM+
129  =uSzz
130  -----END PGP SIGNATURE-----
131  **************************************************************/
132 
133 #include "ot_utility_ot.hpp"
134 #include "ot_otapi_ot.hpp"
135 #include "../core/OTLog.hpp"
136 
137 #include <locale>
138 
139 namespace opentxs
140 {
141 
142 using namespace std;
143 
144 OT_UTILITY_OT bool VerifyExists(const string& theObjectNameAsStr)
145 {
146  return VerifyExists(theObjectNameAsStr, true);
147 }
148 
149 OT_UTILITY_OT bool VerifyExists(const string& theObjectNameAsStr,
150  bool bDisplayError)
151 {
152  if (OT_ME::FindVariable2(theObjectNameAsStr) == nullptr) {
153  if (bDisplayError) {
154  otOut << "Missing parameter: --";
155  locale loc;
156  for (auto elem : theObjectNameAsStr) {
157  otOut << tolower(elem, loc);
158  }
159  otOut << "\n";
160  }
161  return false;
162  }
163 
164  return true;
165 }
166 
168 // OT_UTILITY_OT bool VerifyOTIntegerRef(nValue) // used for OTInteger
169 //{
170 // if (nValue.is_var_null() || nValue.is_var_undef() ||
171 // !nValue.is_type("OTInteger"))
172 // {
173 // return false;
174 // }
175 // else { return true; }
176 //}
177 //
179 // OT_UTILITY_OT bool VerifyOTBoolRef(bValue) // used for OTBool class
180 //{
181 // if (bValue.is_var_null() || bValue.is_var_undef() ||
182 // !bValue.is_type("OTBool"))
183 // {
184 // return false;
185 // }
186 // else { return true; }
187 //}
189 
190 OT_UTILITY_OT bool VerifyMessage(const string& strMessage)
191 {
192  if (10 > strMessage.length()) {
193  otWarn << "VerifyMessage: Error strMessage is: Too Short:" << strMessage
194  << "\n";
195  return false;
196  }
197  return true;
198 }
199 
200 OT_UTILITY_OT int32_t VerifyMessageSuccess(const string& strMessage)
201 {
202  if (!VerifyMessage(strMessage)) {
203  return -1;
204  }
205 
206  int32_t nStatus = OTAPI_Wrap::Message_GetSuccess(strMessage);
207  switch (nStatus) {
208  case -1:
209  otOut << "VerifyMessageSuccess: Error calling "
210  "OT_API_Message_GetSuccess, for message:\n\n" << strMessage
211  << "\n";
212  break;
213  case 0:
214  otWarn << "VerifyMessageSuccess: Reply received: success == FALSE. "
215  "Reply message:\n\n" << strMessage << "\n";
216  break;
217  case 1:
218  otWarn << "VerifyMessageSuccess: Reply received: success == TRUE.\n";
219  break;
220  default:
221  otOut << "VerifyMessageSuccess: Error. (This should never happen!) "
222  "nStatus: " << nStatus << ", Input: " << strMessage << "\n";
223  nStatus = -1;
224  break;
225  }
226 
227  return nStatus;
228 }
229 
231  const string& SERVER_ID, const string& USER_ID, const string& ACCOUNT_ID,
232  const string& strMessage) // For when an OTMessage is the input.
233 {
234  if (!VerifyMessage(strMessage)) {
235  return -1;
236  }
237 
239  SERVER_ID, USER_ID, ACCOUNT_ID, strMessage);
240  switch (nSuccess) {
241  case -1:
242  otOut << "VerifyMsgBalanceAgrmntSuccess: Error calling "
243  "OT_API_Msg_GetBlnceAgrmntSuccess, for message:\n\n"
244  << strMessage << "\n";
245  break;
246  case 0:
247  otWarn << "VerifyMsgBalanceAgrmntSuccess: Reply received: success == "
248  "FALSE. Reply message:\n\n" << strMessage << "\n";
249  break;
250  case 1:
251  otWarn << "VerifyMsgBalanceAgrmntSuccess: Reply received: success == "
252  "TRUE.\n";
253  break;
254  default:
255  otOut << "VerifyMsgBalanceAgrmntSuccess: Error. (This should never "
256  "happen!) Input: " << strMessage << "\n";
257  nSuccess = -1;
258  break;
259  }
260 
261  return nSuccess;
262 }
263 
264 OT_UTILITY_OT int32_t
265  VerifyMsgTrnxSuccess(const string& SERVER_ID, const string& USER_ID,
266  const string& ACCOUNT_ID, const string& strMessage)
267 {
268  if (!VerifyMessage(strMessage)) {
269  return -1;
270  }
271 
273  SERVER_ID, USER_ID, ACCOUNT_ID, strMessage);
274  switch (nSuccess) {
275  case -1:
276  otOut << "VerifyMsgTrnxSuccess: Error calling "
277  "OT_API_Message_GetSuccess, for message:\n\n" << strMessage
278  << "\n";
279  break;
280  case 0:
281  otWarn << "VerifyMsgTrnxSuccess: Reply received: success == FALSE. "
282  "Reply message:\n\n" << strMessage << "\n";
283  break;
284  case 1:
285  otWarn << "VerifyMsgTrnxSuccess: Reply received: success == TRUE.\n";
286  break;
287  default:
288  otOut << "VerifyMsgTrnxSuccess: Error. (This should never happen!) "
289  "Input: " << strMessage << "\n";
290  nSuccess = -1;
291  break;
292  }
293 
294  return nSuccess;
295 }
296 
297 //
298 // This code was repeating a lot, so I just added a function for it.
299 //
300 OT_UTILITY_OT int32_t InterpretTransactionMsgReply(const string& SERVER_ID,
301  const string& USER_ID,
302  const string& ACCOUNT_ID,
303  const string& strAttempt,
304  const string& strResponse)
305 {
306  int32_t nMessageSuccess = VerifyMessageSuccess(strResponse);
307  if (-1 == nMessageSuccess) {
308  otOut << "Message error: " << strAttempt << ".\n";
309  return -1;
310  }
311  if (0 == nMessageSuccess) {
312  otOut << "Server reply (" << strAttempt << "): Message failure.\n";
313 
314  return 0;
315  }
316 
317  int32_t nBalanceSuccess = VerifyMsgBalanceAgrmntSuccess(
318  SERVER_ID, USER_ID, ACCOUNT_ID, strResponse);
319  if (-1 == nBalanceSuccess) {
320  otOut << "Balance agreement error: " << strAttempt << ".\n";
321  return -1;
322  }
323  if (0 == nBalanceSuccess) {
324  otOut << "Server reply (" << strAttempt
325  << "): Balance agreement failure.\n";
326  return 0;
327  }
328 
329  int32_t nTransSuccess =
330  VerifyMsgTrnxSuccess(SERVER_ID, USER_ID, ACCOUNT_ID, strResponse);
331  if (-1 == nTransSuccess) {
332  otOut << "Transaction error: " << strAttempt << ".\n";
333  return -1;
334  }
335  if (0 == nTransSuccess) {
336  otOut << "Server reply (" << strAttempt << "): Transaction failure.\n";
337  return 0;
338  }
339 
340  return 1;
341 }
342 
345 //
346 // OT_UTILITY_OT int32_t ifB(the_expression, X, Y)
347 //{
348 // var theReturnValue
349 //
350 // if (the_expression)
351 // {
352 // theReturnValue = X;
353 // }
354 // else
355 // {
356 // theReturnValue = Y;
357 // }
358 //
359 // // Returning...
360 // //
361 //
362 // return theReturnValue;
363 //
364 //}
365 
368 //
369 // attr OTBool::value
370 // attr OTBool::value2
371 //
373 // OT_UTILITY_OT int32_t OTBool::OTBool()
374 //{
375 // value = false;
376 // value2 = false;
377 //}
379 // OT_UTILITY_OT int32_t OTBool::OTBool(param_value)
380 //{
381 // value = param_value;
382 // value2 = false;
383 //}
385 // OT_UTILITY_OT int32_t OTBool::getBooleanValue()
386 //{
387 //
388 // return value;
389 //
390 //}
392 // OT_UTILITY_OT int32_t OTBool::setBooleanValue(param_value)
393 //{
394 // value = param_value;
395 //}
397 // OT_UTILITY_OT int32_t OTBool::getSecondValue()
398 //{
399 //
400 // return value2;
401 //
402 //}
404 // OT_UTILITY_OT int32_t OTBool::setSecondValue(param_value)
405 //{
406 // value2 = param_value;
407 //}
408 //
411 //
412 // attr OTInteger::value
413 //
415 // OT_UTILITY_OT int32_t OTInteger::OTInteger()
416 //{
417 // value = 0;
418 //}
420 // OT_UTILITY_OT int32_t OTInteger::OTInteger(param_value)
421 //{
422 // value = param_value;
423 //}
425 // OT_UTILITY_OT int32_t OTInteger::getIntegerValue()
426 //{
427 // // Returning...
428 // //
429 //
430 // return value;
431 //
432 //}
434 // OT_UTILITY_OT int32_t OTInteger::setIntegerValue(param_value)
435 //{
436 // value = param_value;
437 //}
440 
442 {
443  strLastReplyReceived = "";
444  delay_ms = 50;
445  max_trans_dl = 10; // Number of transactions I download when I'm low. (Also,
446  // when I'm low is when I'm below this number.)
447 }
448 
450 {
451 }
452 
454 {
455  OTAPI_Wrap::Sleep(delay_ms);
456 }
457 
459 {
460  OTAPI_Wrap::Sleep(delay_ms + 200);
461 }
462 
464 {
465  return max_trans_dl;
466 }
467 
469 {
470  max_trans_dl = new_trans_dl;
471 }
472 
474 {
475  return strLastReplyReceived;
476 }
477 
478 OT_UTILITY_OT void Utility::setLastReplyReceived(const string& strReply)
479 {
480  strLastReplyReceived = strReply;
481 }
482 
483 OT_UTILITY_OT int32_t
484  Utility::getNymboxLowLevel(const string& serverID, const string& nymID)
485 {
486  bool bWasSent = false;
487  return getNymboxLowLevel(serverID, nymID, bWasSent);
488 }
489 
490 // This returns -1 if error, or a positive request number if it was sent.
491 // (It cannot return 0;
492 // Called by getAndProcessNymbox.
493 //
494 OT_UTILITY_OT int32_t Utility::getNymboxLowLevel(const string& serverID,
495  const string& nymID,
496  bool& bWasSent)
497 {
498  string strLocation = "Utility::getNymboxLowLevel";
499 
501  bWasSent = false;
502 
503  int32_t nRequestNum = OTAPI_Wrap::getNymbox(
504  serverID, nymID); // <===== ATTEMPT TO SEND THE MESSAGE HERE...;
505  if (-2 == nRequestNum) {
506  otOut << strLocation << ": ERROR, not supported. (-2 was returned.)\n";
507  return -1; // -2 is also possible at some future date. (If the request
508  // number won't fit in an int32_t, this is returned and then
509  // you can retrieve the actual number via a separate call.);
510  }
511  if (-1 == nRequestNum) {
512  otOut << strLocation
513  << ": Failed to send getNymbox message due to error.\n";
514  return -1;
515  }
516  if (0 == nRequestNum) {
517  otOut << strLocation << ": Unexpectedly returned 0. Didn't send "
518  "getNymbox message, but NO error occurred, "
519  "either. (In this case, SHOULD NEVER HAPPEN. "
520  "Treating as Error.)\n";
521  return -1; // Even though '0' MEANS "didn't send, but no error" by
522  // convention in many places, it is actually an impossible
523  // return value;
524  }
525  if (nRequestNum < 0) {
526  otOut << strLocation << ": Unexpected request number: " << nRequestNum
527  << "\n";
528  return -1;
529  }
530 
531  bWasSent = true;
532 
533  //
534  int32_t nResult =
535  receiveReplySuccessLowLevel(serverID, nymID, nRequestNum, strLocation);
536 
537  // otOut << strLocation << ": receiveReplySuccessLowLevel:
538  // " << nResult << "\n";
539 
540  // BY this point, we definitely have the request number in nResult, which
541  // means
542  // the message was actually SENT. (At least.) This also means we can use
543  // nResult
544  // later to query for a copy of that sent message.
545  // Let's go ahead, in this case, and remove that now:
546  //
547  // THE REMOVE SENT MESSAGE BELOW FAILS, LIKE IT'S ALREADY GONE.
548  //
549  // THIS MUST BE DUE TO THE PROCESS SERVER REPLY THAT OCCURS **IMMEDIATELY**
550  // after the message was originally sent!
551  // (The reply came in and was sent to OT's "ProcessServerReply", INSIDE the
552  // call to getNymbox.)
553  // Our subsequent "receive" (above) is nothing of the sort, but actually
554  // pops the incoming message buffer where
555  // the server's reply was ALREADY SITTING, since it was put there in OT's
556  // "ProcessServerReply", WHICH REMOVED THE
557  // SENT MESSAGE ALREADY (that's why the below call to RemoveSentMessage
558  // fails.)
559  //
560  // RETHINK any logic that doesn't take this into account,.
561  // Either we REMOVE this call wherever this happens, OR... we call Get first
562  // and make sure whether it's
563  // there, THEN remove it. But we can't be lumping "Failure because it's
564  // gone" versus "Error state" by mixing
565  // 0 and -1 here. We need to differentiate.
566  //
567  // Bottom line: if the reply WAS received, then the original sent message
568  // has ALREADY been removed
569  // from the sent buffer. Whereas if the reply was NOT received, then the
570  // sent message is still there,
571  // but in that case, we do NOT want to remove it -- we want it to STAY in
572  // the sent buffer, so that
573  // when we get the Nymbox later and we DO have the reply from that, THEN we
574  // can remove the sent msg from
575  // the sent buffer. Until then, we don't want OT to think it's already been
576  // processed (which it will, if
577  // it's already been removed from the sent buffer. So we leave it there for
578  // now.)
579  //
580 
581  // int32_t nRemovedSentMsg =
582  // OTAPI_Wrap::RemoveSentMessage(to_string(nRequestNum), serverID, nymID);
583  //
584  // if (nRemovedSentMsg < 1)
585  // {
586  // otOut << strLocation << ": ERROR:
587  // OT_API_RemoveSentMessage returned: " << nRemovedSentMsg << "\n";
588  // }
589 
590  if (1 == nResult) {
591  return nRequestNum;
592  }
593 
594  return nResult;
595 }
596 
597 OT_UTILITY_OT int32_t
598  Utility::getNymbox(const string& serverID, const string& nymID)
599 {
600  bool bForceDownload = false;
601  return getNymbox(serverID, nymID, bForceDownload);
602 }
603 
604 OT_UTILITY_OT int32_t Utility::getNymbox(const string& serverID,
605  const string& nymID,
606  bool bForceDownload)
607 {
608  string strLocation = "Utility::getNymbox";
609 
610  string strRecentHash = OTAPI_Wrap::GetNym_RecentHash(serverID, nymID);
611  bool bRecentHash = VerifyStringVal(strRecentHash);
612  if (!bRecentHash) {
613  otOut << strLocation << ": Warning: Unable to retrieve recent cached "
614  "copy of server-side NymboxHash from "
615  "client-side nym (perhaps he's never "
616  "downloaded it before?)\n\n";
617  }
618 
619  string strLocalHash = OTAPI_Wrap::GetNym_NymboxHash(serverID, nymID);
620  bool bLocalHash = VerifyStringVal(strLocalHash);
621  if (!bLocalHash) {
622  otOut << strLocation << ": Warning: Unable to retrieve client-side "
623  "NymboxHash for:\n serverID: " << serverID
624  << "\n nymID: " << nymID << "\n";
625  }
626 
627  if (!bForceDownload) {
628  if (bLocalHash && bRecentHash &&
629  (strRecentHash == strLocalHash)) // the hashes match -- no need to
630  // download anything.
631  {
632  otWarn
633  << strLocation
634  << ": The hashes already match (skipping Nymbox download.)\n";
635  return 1;
636  }
637  }
638 
639  // -- SECTION 1: "GET NYMBOX"
640  //
641  bool bWasMsgSent = false;
642  int32_t nGetNymbox = getNymboxLowLevel(
643  serverID, nymID, bWasMsgSent); // bWasMsgSent is output from this call.;
644  if (bWasMsgSent) {
645  otWarn << strLocation
646  << ": FYI: we just sent a getNymboxLowLevel msg. RequestNum: "
647  << nGetNymbox << "\n";
648  }
649 
650  if (!(bWasMsgSent) || ((nGetNymbox <= 0) && (-1 != nGetNymbox))) {
651  otOut << strLocation
652  << ": Failure: this.getNymboxLowLevel returned unexpected value: "
653  << nGetNymbox << "\n";
654  return -1;
655  } // NOTE: for getNymbox, there is no '0' return value;
656 
657  if (-1 ==
658  nGetNymbox) // we'll try re-syncing the request number, then try again.
659  {
660  otOut << strLocation
661  << ": FYI: this.getNymboxLowLevel returned -1. (Re-trying...)\n";
662 
663  int32_t nGetRequest = getRequestNumber(serverID, nymID);
664  if (1 != nGetRequest) {
665  otOut << strLocation << ": Failure: this.getNymboxLowLevel failed, "
666  "then I tried to resync with "
667  "this.getRequestNumber and then that "
668  "failed too. (I give up.)\n";
669  return -1;
670  }
671 
672  string strLastReplyReceived = getLastReplyReceived();
673  // I had to do this bit because getRequestNumber doesn't return the
674  // reply itself. But in this case, I needed it.
675  if (!VerifyStringVal(strLastReplyReceived)) // THIS SHOULD NEVER HAPPEN.
676  {
677  otOut << strLocation << ": ERROR in getLastReplyReceived(): why "
678  "was this string not set, when "
679  "this.getRequestNumber was otherwise an "
680  "apparent success?\n";
681  return -1; // (SHOULD NEVER HAPPEN. This string is set in the
682  // getRequestNumber function.)
683  }
684 
685  // BY THIS POINT, we have received a server reply: @getRequest
686  // (Unless it is malformed.) It's definitely not null, nor empty.
687 
688  // Grab the NymboxHash on the @getRequest reply, and also the one I
689  // already had on my client-side Nym... (So we can compare them.)
690  //
691  // If the hashes do NOT match, then I DO need to download nymbox
692  // and box receipts.
693  /*
694  * ===> If the NymboxHash is changed from what I expected, then I
695  *need to re-download the
696  * nymbox (and any box receipts I don't already have.)
697  *
698  * Then I need to process the Nymbox. But first, see if my missing
699  *server reply is in there.
700  * If it is, then I have the server reply! (As if we had succeeded
701  *in the first place!!)
702  * Next, process the Nymbox (which processes that reply) and then
703  *return strReply;
704  *
705  * (Clearly this is just going to be a normal part of the getRequest
706  *syncronization.)
707  *
708  * By the time that much is done, I will KNOW the request number,
709  *the nymbox, the box receipts,
710  * etc are ALL syncronized properly, and that I THEN processed the
711  *Nymbox successfully.
712  *
713  *
714  * NOTICE: In this example I do NOT want to pull out my sent message
715  *from the outbuffer (using
716  * the request number) and try to harvest all the transaction
717  *numbers. Why not? Because possibly the
718  * server DID reply! And if I processed that reply properly, it
719  *would sync my transaction numbers
720  * properly just from that! ===>
721  *
722  * ===> Therefore, I need to see FIRST if the old message has a
723  *reply WAITING in the Nymbox. THEN
724  * I need to process the Nymbox. ONLY if the reply wasn't there, can
725  *I THEN pull out the message
726  * from my outbuffer and harvest it. (Which I am reticent to do,
727  *until I am SURE the server
728  * really never saw that message in the first place.)
729  *
730  * However, as long as my NymboxHash hasn't changed, then I'm safe!
731  *But if it HAS changed,
732  * then I HAVE to A. download it B. SEE if the reply is there for
733  *the request number, then
734  * C. process it. ... If the reply wasn't there, THEN Harvest the
735  *transaction #s (for transaction
736  * messages) and then re-try.
737  */
738 
739  // Grabbing again in case it's changed.
740  string strServerHash =
741  OTAPI_Wrap::Message_GetNymboxHash(strLastReplyReceived);
742  bool bServerHash = VerifyStringVal(strServerHash);
743  if (!bServerHash) {
744  otOut << strLocation
745  << ": Warning: Unable to retrieve server-side NymboxHash "
746  "from server @getRequest reply:\n\n"
747  << strLastReplyReceived << "\n";
748  }
749 
750  strLocalHash = OTAPI_Wrap::GetNym_NymboxHash(serverID, nymID);
751  bLocalHash = VerifyStringVal(strLocalHash);
752  if (!bLocalHash) {
753  otOut << strLocation
754  << ": Warning(2): Unable to retrieve client-side NymboxHash "
755  "for:\n serverID: " << serverID << "\n nymID: " << nymID
756  << "\n";
757  }
758 
759  // The hashes don't match -- so let's definitely re-try to download the
760  // latest nymbox.
761  if (bForceDownload || !bLocalHash || !bServerHash ||
762  (bServerHash && bLocalHash && !(strServerHash == strLocalHash))) {
763  // the getRequest worked, and the server hashes don't match,
764  // so let's try the call again...
765 
766  nGetNymbox = getNymboxLowLevel(serverID, nymID, bWasMsgSent);
767 
768  if (!(bWasMsgSent) || ((nGetNymbox <= 0) && (-1 != nGetNymbox))) {
769  otOut << strLocation
770  << ": Failure(2): this.getNymboxLowLevel returned "
771  "unexpected value: " << nGetNymbox << "\n";
772  return -1;
773  }
774 
775  if (-1 == nGetNymbox) // we'll try re-syncing the request number,
776  // then try again.
777  {
778  otOut << strLocation << ": Failure: this.getNymboxLowLevel "
779  "returned -1, even after syncing the "
780  "request number successfully. (Giving "
781  "up.)\n";
782  return -1;
783  }
784  }
785  }
786 
787  // By this point, we DEFINITELY know that the Nymbox was retrieved
788  // successfully.
789  // (With request number nGetNymbox.) This is because the getNymboxLowLevel()
790  // call
791  // also tries to receive the reply, so we already know by now whether the
792  // reply
793  // was successfully received.
794  //
795 
796  return nGetNymbox;
797 }
798 
799 // NEW ONES:
800 
801 // public static int32_t getAndProcessNymbox(String serverID, String nymID,
802 // OTBool bWasMsgSent, boolean bForceDownload,
803 // var nRequestNumber, // nRequestNumber
804 // refers to a PREVIOUS msg (like a cash withdrawal) that had an error and then
805 // called this while trying to resync. (The caller will want to know whether it
806 // was found in the Nymbox.)
807 // OTBool bFoundNymboxItem, //
808 // bFoundNymboxItem is OUTPUT bool, telling caller whether it was found.
809 // boolean bHarvestingForRetry, //
810 // bHarvestingForRetry is INPUT, in the case nRequestNumber needs to be
811 // harvested before a flush occurs.
812 // boolean bMsgReplySuccess, //
813 // bMsgReplySuccess is INPUT, and is in case nRequestNumber needs to be
814 // HARVESTED before a FLUSH happens.
815 // boolean bMsgReplyFailure, //
816 // bMsgReplyFailure is INPUT, and is in case nRequestNumber needs to be
817 // HARVESTED before a FLUSH happens.
818 // boolean bMsgTransSuccess, //
819 // bMsgTransSuccess is INPUT, and is in case nRequestNumber needs to be
820 // HARVESTED before a FLUSH happens.
821 // boolean bMsgTransFailure) //
822 // bMsgTransFailure is INPUT, and is in case nRequestNumber needs to be
823 // HARVESTED before a FLUSH happens.
824 
825 // def Utility::getAndProcessNymbox_8(serverID, nymID, bWasMsgSent, //
826 // bWasMsgSent is OUTPUT.
827 // bForceDownload, // INPUT
828 // nRequestNumber, // nRequestNumber
829 // refers to a PREVIOUS msg (like a cash withdrawal) that had an error and then
830 // called this while trying to resync. (The caller will want to know whether it
831 // was found in the Nymbox.)
832 // bFoundNymboxItem, // bFoundNymboxItem
833 // is OUTPUT bool, telling caller whether it was found.
834 // bHarvestingForRetry, //
835 // bHarvestingForRetry is INPUT, in the case nRequestNumber needs to be
836 // harvested before a flush occurs.
837 // bMsgFoursome) // OTfourbool class, used to
838 // reduce the number of parameters here, which I am suspicious that ChaiScript
839 // cannot handle.
840 
841 // Returns:
842 // -1 ERROR.
843 // 0 Nymbox was empty -- nothing done. (bWasMsgSent = false)
844 // 0 Transactionstatus = = server reply received (bWasMsgSent = true), but;
845 // the server reply hasstatus = = FAILED. (All harvesting was subsequently
846 // successful for processNymbox).;
847 // 1 If the ProcessNymbox Transaction status (from the server reply) is
848 // SUCCESS,
849 // then this function returns 1.
850 // >1 If the ProcessNymbox Transaction status (from the server reply) is >1,
851 // then this function returns the
852 // REQUEST NUMBER from when it was originally sent. (Harvesting was NOT
853 // performed, which is why the request
854 // number is being returned, so the caller can choose what to do next.)
855 
856 // def Utility::getAndProcessNymbox_8(serverID, nymID, bWasMsgSent,
857 // bForceDownload, nRequestNumber, bFoundNymboxItem, bHarvestingForRetry,
858 // bMsgFoursome)
859 //{
860 // cout << "Here's the dead version!\n";
861 //}
862 
863 // var nGetAndProcessNymbox = getAndProcessNymbox_8(serverID, nymID,
864 // bWasMsgSent, bForceDownload, nRequestNumber, bFoundNymboxItem,
865 // bHarvestingForRetry, the_foursome);
866 
868  const string& serverID, const string& nymID, bool& bWasMsgSent,
869  bool bForceDownload, int32_t nRequestNumber, bool& bFoundNymboxItem,
870  bool bHarvestingForRetry, const OTfourbool& bMsgFoursome)
871 {
872  string strLocation = "Utility::getAndProcessNymbox";
873 
874  bool bMsgReplySuccess = bMsgFoursome[0];
875  bool bMsgReplyFailure = bMsgFoursome[1];
876  bool bMsgTransSuccess = bMsgFoursome[2];
877  bool bMsgTransFailure = bMsgFoursome[3];
878 
879  if (0 > nRequestNumber) {
880  otOut << "\n\n\n\n Failed verifying nRequestNumber as an integer. "
881  "\n\n\n\n\n";
882  return -1;
883  }
884 
885  if (1 == nRequestNumber) {
886  otOut << strLocation
887  << ": WARNING: Request Num of '1' was just passed in here.\n";
888  }
889 
890  bWasMsgSent = false;
891 
892  // what is nRequestNumber?
893  //
894  // Let's say a message, say for a cash withdrawal with request number 5, has
895  // FAILED.
896  // Since the message failed, perhaps the request number was out of sync, or
897  // Nymbox hash
898  // was old? So, let's say that it then sent a getRequest message, in order
899  // to resync,
900  // and discovered that the Nymbox hash has changed. Therefore the Nymbox is
901  // now being
902  // re-downloaded and processed, so that the cash withdrawal can be attempted
903  // again.
904  //
905  // HOWEVER, before we PROCESS the Nymbox, we need to see if the withdrawal
906  // reply is already
907  // sitting in it. Why, you ask, if the withdrawal failed, would I expect a
908  // reply to be in
909  // the Nymbox? In case 1, the message was dropped, so I don't know if the
910  // reply is there
911  // until I check the Nymbox. In case 2, the message may have failed OR
912  // SUCCEEDED, with the
913  // successful message containing a FAILED TRANSACTION.
914  // Thus, we just want to check the Nymbox for nRequestNumber, and make sure
915  // whether it's
916  // there or not, before we PROCESS the nymbox, because once we do THAT, it
917  // will be empty.
918  //
919  // We will return a;
920  // was already in the Nymbox. We can also harvest the transaction numbers
921  // from the reply
922  // message, if it's a transaction, so that everything is set for the re-try.
923  // (Possibly pass
924  // a bool parameter dictating whether the harvesting is being done for a
925  // re-try or not.)
926  //
927 
928  // -- SECTION 1: "GET NYMBOX"
929  //
930  // This call is sufficiently high-level enough that it already has re-tries
931  // built into it. That's why you don't see me re-trying the getNymbox if it
932  // fails.
933  //
934 
935  int32_t nGetNymbox = getNymbox(serverID, nymID, bForceDownload);
936  if (nGetNymbox < 1) {
937  otOut << strLocation
938  << ": Failure: this.getNymbox returned: " << nGetNymbox << "\n";
939  return -1;
940  }
941 
942  // By this point, we DEFINITELY know that the Nymbox was retrieved
943  // successfully.
944  // (With request number nGetNymbox.) This is because the getNymboxLowLevel()
945  // call
946  // also tries to receive the reply, so we already know by now whether the
947  // reply
948  // was successfully received.
949  //
950  /*
951  * FYI: nRequestNumber is the request number, if >0, for whatever command
952  * is causing this getAndProcessNymbox to occur (like a cash withdrawal, or
953  * a cheque deposit, etc.) We pass it in here so we can verify whether it's
954  *on
955  * the Nymbox, before we process it out (so the caller knows whether to
956  *clawback.)
957  *
958  * FYI: nGetNymbox is the request number from getNymboxLowLevel() (above.) We
959  * know for a FACT, by this point, this number is >0.
960  *
961  * FYI: nProcess (just below) is the request number for the PROCESS NYMBOX
962  *message.
963  * Below the switch block just down there, we know for a fact this number is
964  *>0.
965  */
966 
967  // -- SECTION 2: "SEND PROCESS NYMBOX"
968  //
969 
970  // Next, we have to make sure we have all the BOX RECEIPTS downloaded
971  // for this Nymbox.
972 
973  // If the caller wanted to know whether a certain reply (by request number)
974  // was in the Nymbox, then bFoundNymboxItem
975  // will be set true in this call, if it was there. That way he can Harvest
976  // his own msg if he needs to. (Just like I
977  // harvest my own processNymbox call below, if necessary.)
978  //
979  // nBoxType = 0 aka nymbox;
980  //
981 
982  int32_t nBoxType = 0;
983 
984  bool bInsured = insureHaveAllBoxReceipts(
985  serverID, nymID, nymID, nBoxType, nRequestNumber,
986  bFoundNymboxItem); // ***************************;
987  if (bInsured) {
988  // If the caller was on about a specific request number...
989  //
990  if (nRequestNumber > 0) {
991  // ...And if we DID NOT find that request number in the Nymbox
992  // (along with the server's reply), then harvest it!!
993  // (If we HAD found it, then we'd know it didn't NEED harvesting,
994  // since the server clearly REPLIED to it already.)
995 
996  // FOUND it in the nymbox! Therefore we can remove without
997  // harvesting.
998  // (Server definitely processed it, so nothing to harvest.)
999  //
1000  if (bFoundNymboxItem) {
1001  // Notice, if the above call to insureHaveAllBoxReceipts had any
1002  // network hiccups, then
1003  // it may have had to get and processNymbox, meaning the below
1004  // Remove would fail, since
1005  // the sent message was already removed. Therefore, might want
1006  // to update this to call getSent
1007  // FIRST, before trying to remove.
1008  // (Might want different messages in either case.)
1009  //
1010  bool nRemovedMsg = OTAPI_Wrap::RemoveSentMessage(
1011  int64_t(nRequestNumber), serverID, nymID);
1012  otInfo << strLocation
1013  << ": OT_API_RemoveSentMessage: (Found server reply in "
1014  "Nymbox. Removing local sent msg.) Request number: "
1015  << nRemovedMsg << "\n";
1016  }
1017  else // We DIDN'T find it in the nymbox, so we can harvest it:
1018  {
1019  // NOTE: This may always fail,
1020 
1021  otLog3 << strLocation
1022  << ": FYI: Calling OT_API_GetSentMessage...\n";
1023 
1024  string strSentMsg = OTAPI_Wrap::GetSentMessage(
1025  int64_t(nRequestNumber), serverID, nymID);
1026 
1027  if (!VerifyStringVal(strSentMsg)) {
1028  otInfo << strLocation
1029  << ": (1) OT_API_GetSentMessage returned nullptr "
1030  "for clawback. (Must have already been cleared. "
1031  "OT uses deliberate redundancy, though optimizes "
1032  "this wherever possible.) Request number: "
1033  << nRequestNumber << "\n";
1034  }
1035  else // OTAPI_Wrap::GetSentMessage success.
1036  {
1037  otOut << strLocation << ": FYI: Harvesting transaction "
1038  "numbers from failed Msg "
1039  "attempt...\n";
1040 
1042  strSentMsg, nymID,
1043  bHarvestingForRetry, // bHarvestingForRetry.
1044  bMsgReplySuccess, // bReplyWasSuccess, // RECEIVED
1045  // server reply: explicit success.
1046  bMsgReplyFailure, // bReplyWasFailure, // RECEIVED
1047  // server reply: explicit failure.
1048  bMsgTransSuccess, // bTransactionWasSuccess, // MESSAGE
1049  // success, Transaction success.
1050  // (Explicit.)
1051  bMsgTransFailure); // bTransactionWasFailure // MESSAGE
1052  // success, Transaction failure.
1053  // (Explicit.)
1054  otOut << strLocation
1055  << ": OT_API_Msg_HarvestTransactionNumbers: "
1056  << nHarvested << "\n";
1057 
1058  bool nRemovedMsg = OTAPI_Wrap::RemoveSentMessage(
1059  int64_t(nRequestNumber), serverID, nymID);
1060  otInfo << strLocation
1061  << ": OT_API_RemoveSentMessage: " << nRemovedMsg
1062  << "\n";
1063  } // strSentMsg NOT null!
1064  }
1065  }
1066 
1067  // (flush): LOOP THROUGH ALL "SENT" messages, and see if ANY of them has
1068  // a reply
1069  // sitting in my Nymbox. If so, REMOVE IT from "Sent" queue, (since
1070  // clearly the server
1071  // DID respond already.) And if it's NOT in my nymbox, that means I
1072  // DEFINITELY need to
1073  // harvest it back since the server definitely rejected it or never
1074  // received it.
1075  //
1076  // The Nym actually SAVES the sent messages PER SERVER, so that this
1077  // will continue to work in every possible case!!
1078  // NOTE: Also now storing, on the client nym, a copy of the server's
1079  // latest nymbox hash
1080  // for that nym, in addition to the nym's copy (which only updates when
1081  // he gets his Nymbox.)
1082  // That way the Nym, even before syncing the nymboxes, and even before
1083  // sending a new message
1084  // to find out if they are out of sync, ALREADY KNOWS if they're in sync
1085  // or not. (That's why
1086  // all those other server messages send a copy of that hash back, not
1087  // just the getNymbox msg.)
1088  //
1089  //
1090  // void OTAPI_Wrap::FlushSentMessages( int32_t //
1091  // bHarvestingForRetry, // bHarvestingForRetry is actually OT_BOOL
1092  // const char * SERVER_ID,
1093  // const char * USER_ID,
1094  // const char * THE_NYMBOX);
1095  // NoVerify means don't load up all the box receipts.
1096  // Especially in this case--we only care about whether a box receipt is
1097  // THERE, not
1098  // what it contains. FlushSentMessages will work just fine WITHOUT
1099  // loading those
1100  // box receipts (because the Nymbox contains enough of an abbreviated
1101  // record already
1102  // for each one, that we will have the info we need already.)
1103  //
1104  string strNymbox = OTAPI_Wrap::LoadNymboxNoVerify(
1105  serverID, nymID); // FLUSH SENT MESSAGES!!!! (AND HARVEST.);
1106 
1107  if (VerifyStringVal(strNymbox)) {
1108 
1110  false, // harvesting for retry = = OT_FALSE. None of the things
1111  // are being re-tried by the time they are being flushed.
1112  // They were already old news.;
1113  serverID, nymID, strNymbox);
1114  }
1115  // Flushing removes all the messages from the "sent messages" queue,
1116  // and harvests any transaction numbers to be had. How do I know for
1117  // sure
1118  // that I can get away with this? How do I know whether the server has
1119  // processed those messages or not? How can I harvest them as though
1120  // they
1121  // were dropped on the network somewhere? The answer is because I JUST
1122  // called GetNymbox and downloaded the latest one. I can SEE which
1123  // replies
1124  // are in there -- and which ones aren't. I pass that Nymbox into the
1125  // flush
1126  // call, so that flush can be careful to remove all sent messages that
1127  // have
1128  // nymbox replies, and only harvest the others.
1129  else {
1130  otOut << strLocation
1131  << ": Error while trying to flush sent messages: Failed "
1132  "loading Nymbox for nym: " << nymID << "\n";
1133  }
1134 
1135  int32_t nMsgSentRequestNumOut = -1;
1136  int32_t nReplySuccessOut = -1;
1137  int32_t nBalanceSuccessOut = -1;
1138  int32_t nTransSuccessOut = -1;
1139 
1140  // PROCESS NYMBOX
1141  //
1142  // Returns:
1143  // -1 Error.
1144  // 0 Nymbox was empty -- nothing done. (bWasMsgSent = false)
1145  // 0 Transactionstatus = = server reply received (bWasMsgSent = true),;
1146  // but the server reply saysstatus = =failed.;
1147  // >0 If the Transaction status (from the server reply) is SUCCESS, then
1148  // this function
1149  // returns the REQUEST NUMBER from when it was originally sent.
1150 
1151  int32_t nProcess = processNymbox(
1152  serverID, nymID, bWasMsgSent, nMsgSentRequestNumOut,
1153  nReplySuccessOut, nBalanceSuccessOut, nTransSuccessOut);
1154 
1155  if (-1 == nProcess) {
1156  // Todo: might want to remove the sent message here, IF bMsgWasSent
1157  // is true.
1158  // (Just like case 0.)
1159  //
1160  otOut << strLocation << ": Failure: processNymbox: error (-1). (It "
1161  "couldn't send. I give up.)\n";
1162 
1163  return -1; // (It didn't even send.)
1164  }
1165  else if (0 == nProcess) {
1166  // Nymbox was empty. (So we didn't send any process message because
1167  // there was nothing to process.)
1168  if (!bWasMsgSent) {
1169  return 0; // success. done. (box was empty already.)
1170  }
1171  // else: the message WAS sent, (the Nymbox was NOT empty)
1172  // and then the server replied "success==FALSE"
1173  // in its REPLY to that message! Thus we continue and DROP
1174  // THROUGH...
1175  }
1176  else if (nProcess < 0) {
1177  otOut << strLocation
1178  << ": Failure: processNymbox: unexpected: " << nProcess
1179  << ". (I give up.)\n";
1180 
1181  return -1;
1182  }
1183  // bWasMsgSent = true; // unnecessary -- set already by processNymbox
1184  // call above.
1185 
1186  // By this point, we definitely have a >0 request number from the
1187  // sendProcessNymbox()
1188  // call, stored in nProcess (meaning the message WAS sent.) (Except in
1189  // case of 0, see next line which fixes this:)
1190  //
1191 
1192  nProcess = nMsgSentRequestNumOut; // Sometimes this could be 0 still, so
1193  // we fix it here.;
1194  int32_t nReplySuccess = nReplySuccessOut;
1195  int32_t nTransSuccess = nTransSuccessOut;
1196  int32_t nBalanceSuccess = nBalanceSuccessOut;
1197 
1198  /*
1199 
1200  return const;
1201 
1202  char * OTAPI_Wrap::GetSentMessage(const char* REQUEST_NUMBER)
1203  OT_BOOL OTAPI_Wrap::RemoveSentMessage(const char* REQUEST_NUMBER)
1204 
1205  */
1206  // All of these booleans (except "error") represent RECEIVED ANSWERS
1207  // from the server.
1208  // In other words, "false" does not mean "failed to find message."
1209  // Rather, it means "DEFINITELY got a reply, and that reply sayssuccess
1210  // = =false.";
1211 
1212  // SHOULD NEVER HAPPEN (processNymbox call just above was successful,
1213  // therefore the sent message SHOULD be here in my cache.)
1214  //
1215  string strReplyProcess = getLastReplyReceived();
1216  // I had to do this bit because getRequestNumber doesn't return the;
1217  // reply itself. But in this case, I needed it.
1218  if (!VerifyStringVal(strReplyProcess)) // THIS SHOULD NEVER HAPPEN.
1219  {
1220  otOut << strLocation << ": ERROR in getLastReplyReceived(): why "
1221  "was this string not set, when "
1222  "getRequestNumber was otherwise an "
1223  "apparent success?\n";
1224 
1225  return -1; // (SHOULD NEVER HAPPEN. This string is set in the
1226  // getRequestNumber function.)
1227  }
1228 
1229  bool bProcessNymboxReplyError =
1230  (!VerifyStringVal(strReplyProcess) || (nReplySuccess < 0));
1231  bool bProcessNymboxBalanceError =
1232  (!VerifyStringVal(strReplyProcess) || (nBalanceSuccess < 0));
1233  bool bProcessNymboxTransError =
1234  (!VerifyStringVal(strReplyProcess) || (nTransSuccess < 0));
1235 
1236  bool bProcessNymboxReplySuccess =
1237  (!bProcessNymboxReplyError && (nReplySuccess > 0));
1238  bool bProcessNymboxReplyFailure =
1239  (!bProcessNymboxReplyError && (nReplySuccess == 0));
1240 
1241  bool bProcessNymboxBalanceSuccess =
1242  (!bProcessNymboxReplyError && !bProcessNymboxBalanceError &&
1243  (nBalanceSuccess > 0));
1244  bool bProcessNymboxBalanceFailure =
1245  (!bProcessNymboxReplyError && !bProcessNymboxBalanceError &&
1246  (nBalanceSuccess == 0));
1247 
1248  bool bProcessNymboxTransSuccess =
1249  (!bProcessNymboxReplyError && !bProcessNymboxBalanceError &&
1250  !bProcessNymboxTransError && (nTransSuccess > 0));
1251  bool bProcessNymboxTransFailure =
1252  (!bProcessNymboxReplyError && !bProcessNymboxBalanceError &&
1253  !bProcessNymboxTransError && (nTransSuccess == 0));
1254 
1255  bool bProcessAnyError =
1256  (bProcessNymboxReplyError || bProcessNymboxBalanceError ||
1257  bProcessNymboxTransError);
1258  bool bProcessAnyFailure =
1259  (bProcessNymboxReplyFailure || bProcessNymboxBalanceFailure ||
1260  bProcessNymboxTransFailure);
1261  bool bProcessAllSuccess =
1262  (bProcessNymboxReplySuccess && bProcessNymboxBalanceSuccess &&
1263  bProcessNymboxTransSuccess);
1264 
1265  // Note: we LEAVE the sent message in the "sent queue" until we are
1266  // certain that it processed.
1267  // If we are NOT certain that it processed, then we try to download the
1268  // Nymbox and see if there's
1269  // a reply there (for the sent message.) If we are able to confirm THAT,
1270  // AFTER SUCCESSFULLY downloading
1271  // the Nymbox, then then we don't have to do anything because we know
1272  // for sure it was processed.
1273  // Similarly, if we DEFINITELY download the Nymbox and do NOT find the
1274  // reply, then we know the server
1275  // DEFINITELY did not receive (or at least process) that message, which
1276  // is what allows us to HARVEST
1277  // the transaction numbers back from the sent message, and remove the
1278  // sent message from the sent queue.
1279  //
1280  // However, if we are NOT able to Verify any of these things, NOR are we
1281  // able to download the Nymbox to
1282  // see, then we DO leave the message in the sent queue. This is
1283  // deliberate, since it gives us the opportunity
1284  // in the future to clear those sent messages NEXT time we successfully
1285  // DO download the Nymbox, and in the
1286  // meantime, it allows us to store a record of EXACTLY which messages
1287  // were MISSED.
1288  //
1289 
1290  int32_t nHarvested = -1;
1291 
1292  if (bProcessAllSuccess) {
1293  // the processNymbox was a complete success, including the message
1294  // AND the transaction AND the transaction statement.
1295  // Therefore, there's DEFINITELY nothing to clawback.
1296  //
1297  // (Thus I RemoveSentMessage for the processNymbox message, since
1298  // I'm totally done with it now.)
1299  //
1300  // int32_t nRemoved =
1301  // OTAPI_Wrap::RemoveSentMessage(Integer.toString(nProcess),
1302  // serverID, nymID);
1303 
1304  // NOTE: The above call is unnecessary, since a successful process
1305  // means
1306  // we already received the successful server reply, and OT's
1307  // "ProcessServerReply"
1308  // already removed the sent message from the sent buffer (so no need
1309  // to do that here.)
1310  //
1311  }
1312  else if (bProcessAnyError ||
1313  bProcessAnyFailure) // let's resync, and clawback whatever
1314  // transaction numbers we might have used
1315  // on the processNymbox request...
1316  {
1317  nGetNymbox = getNymbox(serverID, nymID,
1318  true); // bForceDownload=true - NOTE: could
1319  // maybe change this to false and have
1320  // it still work.;
1321 
1322  if (nGetNymbox < 1) {
1323  otOut << strLocation
1324  << ": Failure: this.getNymbox returned: " << nGetNymbox
1325  << "\n";
1326 
1327  return -1;
1328  }
1329 
1330  bool bWasFound = false;
1331  nBoxType =
1332  0; // I think it was already zero, but since i'm using it here;
1333  // PURELY to be a '0', I feel safer setting it again. (Nymbox is 0.)
1334  // bool bInsured = insureHaveAllBoxReceipts(serverID, nymID,
1335  // nymID, nBoxType, nRequestNumber, bFoundNymboxItem); //
1336  // ***************************;
1337  if (insureHaveAllBoxReceipts(serverID, nymID, nymID, nBoxType,
1338  nProcess, bWasFound)) // This will tell
1339  // us whether the
1340  // processNymbox
1341  // reply was
1342  // found in the
1343  // Nymbox
1344  {
1345  // we FOUND the processNymbox reply in the Nymbox!
1346  //
1347  if (bWasFound) {
1348  // Thus, no need to clawback any transaction numbers,
1349  // since the server clearly already processed this
1350  // processNymbox
1351  // transaction, since I have a reply to it already sitting
1352  // in my Nymbox.
1353  //
1354  // int32_t nRemoved =
1355  // OTAPI_Wrap::RemoveSentMessage(Integer.toString(nProcess),
1356  // serverID, nymID);
1357  //
1358  // NOTE: The above call is unnecessary, since a successful
1359  // process means
1360  // we already received the successful server reply, and OT's
1361  // "ProcessServerReply"
1362  // already removed the sent message from the sent buffer (so
1363  // no need to do that here.)
1364 
1365  otOut << strLocation << ": FYI: I *did* find the "
1366  "@processNymbox reply in my "
1367  "Nymbox, so NO NEED to clawback "
1368  "any transaction numbers.\n";
1369  }
1370  else // was NOT found... we need to clawback.
1371  {
1372  // This means the server's reply was definitely NOT found in
1373  // the
1374  // Nymbox, even after successfully DOWNLOADING that Nymbox.
1375  // Which
1376  // means the server never got it in the first place, or
1377  // rejected it
1378  // at the message level before the transaction portion had a
1379  // chance
1380  // to run. Either way, we need to claw back any relevant
1381  // transaction
1382  // numbers...
1383 
1384  // HARVEST the processNymbox message from outgoing messages.
1385 
1386  otLog3 << strLocation
1387  << ": FYI: Calling OT_API_GetSentMessage...\n";
1388 
1389  string strSentProcessNymboxMsg = OTAPI_Wrap::GetSentMessage(
1390  int64_t(nProcess), serverID, nymID);
1391 
1392  if (!VerifyStringVal(strSentProcessNymboxMsg)) {
1393  otInfo << strLocation
1394  << ": (2) OT_API_GetSentMessage returned "
1395  "nullptr for clawback. (Must have already "
1396  "been cleared. OT uses deliberate "
1397  "redundancy, though optimizes this wherever "
1398  "possible.) Request number: " << nProcess
1399  << "\n";
1400  }
1401  else // strSentProcessNymboxMsg NOT null!
1402  {
1403  otOut << strLocation << ": FYI: Harvesting transaction "
1404  "numbers from failed "
1405  "processNymbox attempt...\n";
1406 
1408  strSentProcessNymboxMsg, nymID,
1409  false, // bHarvestingForRetry = = false;
1410  bProcessNymboxReplySuccess, // bReplyWasSuccess,
1411  // // RECEIVED server
1412  // reply: explicit
1413  // success.
1414  bProcessNymboxReplyFailure, // bReplyWasFailure,
1415  // // RECEIVED server
1416  // reply: explicit
1417  // failure.
1418  bProcessNymboxTransSuccess, // bTransactionWasSuccess,
1419  // // MESSAGE success,
1420  // Transaction success.
1421  // (Explicit.)
1422  bProcessNymboxTransFailure); // bTransactionWasFailure
1423  // // MESSAGE success,
1424  // Transaction failure.
1425  // (Explicit.)
1426 
1427  otOut << strLocation
1428  << ": OT_API_Msg_HarvestTransactionNumbers: "
1429  << nHarvested << "\n";
1430 
1431  bool nRemovedProcessNymboxMsg =
1432  OTAPI_Wrap::RemoveSentMessage(int64_t(nProcess),
1433  serverID, nymID);
1434 
1435  otInfo << strLocation << ": OT_API_RemoveSentMessage: "
1436  << nRemovedProcessNymboxMsg << "\n";
1437  } // strSentProcessNymboxMsg NOT null!
1438  } // a specific receipt was not found in the nymbox (need to
1439  // clawback the transaction numbers on that receipt.)
1440 
1441  strNymbox = OTAPI_Wrap::LoadNymboxNoVerify(
1442  serverID,
1443  nymID); // FLUSH SENT MESSAGES!!!! (AND HARVEST.);
1444  if (VerifyStringVal(strNymbox)) {
1446  false, // harvesting for retry = = OT_FALSE
1447  serverID, nymID, strNymbox);
1448  }
1449  // Flushing removes all the messages from the "sent messages"
1450  // queue,
1451  // and harvests any transaction numbers to be had. How do I know
1452  // for sure
1453  // that I can get away with this? How do I know whether the
1454  // server has
1455  // processed those messages or not? How can I harvest them as
1456  // though they
1457  // were dropped on the network somewhere? The answer is because
1458  // I JUST
1459  // called getNymbox and downloaded the latest one. I can SEE
1460  // which replies
1461  // are in there -- and which ones aren't. I pass that Nymbox
1462  // into the flush
1463  // call, so that flush can be careful to remove all sent
1464  // messages that have
1465  // nymbox replies, and only harvest the others.
1466  else {
1467  otOut << strLocation << ": Error while trying to flush "
1468  "sent messages: Failed loading "
1469  "Nymbox for nym: " << nymID << "\n";
1470  }
1471  } // if insureHaveAllBoxReceipts()
1472  else // we do NOT have all the box receipts.
1473  {
1474  otOut << strLocation << ": Error: insureHaveAllBoxReceipts "
1475  "failed. (I give up.)\n";
1476  return -1;
1477  }
1478  } // else if (bProcessAnyError || bProcessAnyFailure)
1479 
1480  // Return the request number, if potentially needed by caller.
1481  // If explicit success, the request number is returned as a positive
1482  // number (though already removed from sent queue.) Whereas if explicit
1483  // failure (replystatus = failed) then we harvest the numbers;
1484  //
1485  if (bProcessAllSuccess)
1486  // return getNymbox(serverID, nymID, true);
1487  // //bForceDownload = true. Since we DID process it successfully,
1488  // then we grab it again.
1489  {
1490  return 1;
1491  } // We don't need the sent message after this, and we've already
1492  // removed it from sent queue.
1493 
1494  if (bProcessAnyFailure || bProcessAnyError) {
1495  if (nHarvested < 1) // If the message failed, and the harvesting
1496  // failed, then we return the
1497  {
1498  return nProcess;
1499  } // number for the process nymbox, so the caller has a choice of
1500  // what to do next.
1501 
1502  if (bProcessAnyFailure) {
1503  return 0;
1504  } // by this point, we've definitely harvested, AND removed sent
1505  // message from sent queue. So we just return 0;
1506  }
1507 
1508  return -1; // must've been an error.
1509  } // if insureAllBoxReceipts()
1510  else {
1511  otOut << strLocation
1512  << ": insureHaveAllBoxReceipts failed. (I give up.)\n";
1513  }
1514 
1515  return -1;
1516 }
1517 
1518 // def Utility::getAndProcessNymbox(String serverID, String nymID, OTBool
1519 // bWasMsgSent, boolean bForceDownload)
1520 //
1521 OT_UTILITY_OT int32_t
1522  Utility::getAndProcessNymbox_4(const string& serverID, const string& nymID,
1523  bool& bWasMsgSent, bool bForceDownload)
1524 {
1525  string strLocation = "Utility::getAndProcessNymbox_4";
1526 
1527  if (!VerifyStringVal(serverID) || !VerifyStringVal(nymID)) {
1528  otOut << strLocation << ": SHOULD NEVER HAPPEN!!! ASSERT!! ERROR!! "
1529  "FAILURE!!! PROBLEM!!!!!\n";
1530  return -1;
1531  }
1532  // bool bMsgReplySuccess5 = false;
1533  // bool bMsgReplyFailure5 = false;
1534  // bool bMsgTransSuccess5 = false;
1535  // bool bMsgTransFailure5 = false;
1536 
1537  int32_t nRequestNumber = 0;
1538  bool bHarvestingForRetry = false;
1539  OTfourbool the_foursome = {false, false, false, false};
1540  bool bFoundNymboxItem = false; // bFoundNymboxItem is output bool, telling
1541  // caller whether it was found.;
1542 
1543  return getAndProcessNymbox_8(serverID, nymID, bWasMsgSent, bForceDownload,
1544  nRequestNumber, bFoundNymboxItem,
1545  bHarvestingForRetry, the_foursome);
1546 }
1547 
1548 // public static int32_t getNymboxLowLevel(String serverID, String nymID)
1549 // public static int32_t receiveNymboxLowLevel(String serverID, String nymID,
1550 // var nRequestNum)
1551 // public static int32_t processNymboxLowLevel(String serverID, String nymID) {
1552 
1553 // def Utility::getAndProcessNymbox(String serverID, String nymID, OTBool
1554 // bWasMsgSent)
1555 OT_UTILITY_OT int32_t Utility::getAndProcessNymbox_3(const string& serverID,
1556  const string& nymID,
1557  bool& bWasMsgSent)
1558 {
1559  bool bForceDownload = false;
1560  return getAndProcessNymbox_4(serverID, nymID, bWasMsgSent, bForceDownload);
1561 }
1562 
1563 // NEW VERSION:
1564 
1565 // PROCESS NYMBOX
1566 //
1567 // Returns:
1568 // -1 Error.
1569 // 0 Nymbox was empty -- nothing done. (bWasMsgSent = false)
1570 // 0 server reply received, but it sayssuccess = =false on that msg.
1571 // (bWasMsgSent = true);
1572 // >0 If the Transaction status (from the server reply) is SUCCESS, then this
1573 // function
1574 // returns the REQUEST NUMBER from when it was originally sent.
1575 //
1576 // public static int32_t processNymbox(String serverID, String nymID,
1577 // OTBool bWasMsgSent,
1578 //
1579 // OTInteger nMsgSentRequestNumOut,
1580 // OTInteger nReplySuccessOut,
1581 // OTInteger nBalanceSuccessOut,
1582 // OTInteger nTransSuccessOut)
1583 
1584 OT_UTILITY_OT int32_t
1585  Utility::processNymbox(const string& serverID, const string& nymID,
1586  bool& bWasMsgSent, int32_t& nMsgSentRequestNumOut,
1587  int32_t& nReplySuccessOut,
1588  int32_t& nBalanceSuccessOut,
1589  int32_t& nTransSuccessOut)
1590 {
1591  bWasMsgSent = false;
1592  string strLocation = "Utility::processNymbox";
1593 
1594  // if (!VerifyOTBoolRef(bWasMsgSent) ||
1595  // !VerifyOTIntegerRef(nReplySuccessOut) ||
1596  // !VerifyOTIntegerRef(nBalanceSuccessOut) ||
1597  // !VerifyOTIntegerRef(nTransSuccessOut))
1598  //{
1599  // otOut << strLocation << ": SHOULD NEVER HAPPEN: has null
1600  // values passed in...\n";
1601  // exit(-1)
1602  //}
1603 
1604  nMsgSentRequestNumOut = -1;
1605  nReplySuccessOut = -1;
1606  nBalanceSuccessOut = -1;
1607  nTransSuccessOut = -1;
1608 
1609  // -- SECTION 2: "SEND PROCESS NYMBOX"
1610 
1611  // Next, we have to make sure we have all the BOX RECEIPTS downloaded
1612  // for this Nymbox.
1613 
1614  int32_t nProcess = sendProcessNymboxLowLevel(
1615  serverID, nymID); // <===================== SEND PROCESS NYMBOX!!;
1616  if (-1 == nProcess) {
1617  otOut << strLocation << "(2): error (-1), when calling "
1618  "sendProcessNymboxLowLevel. (It couldn't send. "
1619  "I give up.)\n";
1620  return -1; // (It didn't even send.)
1621  }
1622  // Nymbox was empty. (So we didn't send any process message because there
1623  // was nothing to process.)
1624  if (0 == nProcess) {
1625  return 0; // success. done.
1626  }
1627  if (nProcess < 0) {
1628  otOut << strLocation << ": unexpected: " << nProcess
1629  << ", when calling sendProcessNymboxLowLevel. (I give up.)\n";
1630  return -1;
1631  }
1632 
1633  bWasMsgSent = true;
1634  nMsgSentRequestNumOut = nProcess;
1635 
1636  // By this point, we definitely have a >0 request number from the
1637  // sendProcessNymbox()
1638  // call, stored in ** nProcess ** (meaning the message WAS sent.)
1639  //
1640  // But was it received?
1641  //
1642  string strReplyProcess =
1643  ReceiveReplyLowLevel(serverID, nymID, nProcess,
1644  "processNymbox / sendProcessNymboxLowLevel / "
1645  "ReceiveReplyLowLevel"); // <=============== Here
1646  // we RECEIVE the REPLY...
1647 
1648  // getLastReplyReceived() will also contain the same as strReplyProcess.
1649  // So if the CALLER of this function (that we're in, receiveNymboxLowLevel)
1650  // wants to see the contents, he can.
1651 
1652  // ReceiveReplyLowLevel returns null unless there was a string returned.
1653  // So we can directly check it for success...
1654 
1655  int32_t nReplySuccess =
1656  VerifyMessageSuccess(strReplyProcess); // sendProcessNymboxLowLevel;
1657  int32_t nTransSuccess = -1;
1658  int32_t nBalanceSuccess = -1;
1659  ;
1660  if (nReplySuccess > 0) // If message was success, then let's see if the
1661  // transaction was, too.
1662  {
1664  serverID, nymID, nymID,
1665  strReplyProcess); // the processNymbox transaction.;
1666  if (nBalanceSuccess > 0) {
1668  serverID, nymID, nymID,
1669  strReplyProcess); // the processNymbox transaction.;
1670  }
1671  }
1672 
1673  nReplySuccessOut = nReplySuccess;
1674  nBalanceSuccessOut = nBalanceSuccess;
1675  nTransSuccessOut = nTransSuccess;
1676 
1677  // NOTE: The caller MUST have a call to OTAPI_Wrap::RemoveSentMessage
1678  // to correspond to THIS function's call of sendProcessNymboxLowLevel().
1679  //
1680  if (nTransSuccess > 0) {
1681  return nProcess; // <=========================
1682  }
1683 
1684  return nTransSuccess;
1685 }
1686 
1687 // No need to deal with getRequest here when failure, since the calling
1688 // function already goes through that crap before we get here.
1689 // Returns: the request number for the process Nymbox request.
1690 // OR returns 0 if the Nymbox was empty (and no message was sent.)
1691 // OR returns -1 if there was an error.
1692 //
1693 // DONE
1695  const string& serverID, const string& nymID) const // bWasSent is an output
1696  // param allowing to
1697  // return whether;
1698 {
1699  string strLocation = "Utility::sendProcessNymboxLowLevel";
1700 
1701  // Send message..
1703 
1704  int32_t nRequestNum = OTAPI_Wrap::processNymbox(serverID, nymID);
1705  if (-1 == nRequestNum) {
1706  otOut << strLocation
1707  << ": Failure sending. OT_API_processNymbox() returned -1. \n";
1708  return -1; // no need to check for any reply.
1709  }
1710  if (nRequestNum < 0) {
1711  otOut << strLocation
1712  << ": Failure: OT_API_processNymbox() returned unexpected value: "
1713  << nRequestNum << "\n";
1714  return -1; // no need to check for any reply.
1715  }
1716  if (0 == nRequestNum) {
1717  otOut << strLocation << ": Nymbox was empty; no need to process it. \n";
1718  return 0; // Nymbox is empty, thus no need to process it.
1719  }
1720 
1721  // Note: I do NOT call RemoveSentMessage for processNymbox, at least, not
1722  // here.
1723  // Instead, the place that CALLS this function, will actually use that
1724  // because
1725  // it has to be able to harvest the transaction numbers in certain failure
1726  // cases.
1727 
1728  return nRequestNum;
1729 }
1730 
1731 // returns:
1732 // -1 for error,
1733 // 0 for server reply of failure,
1734 // 1 for server reply of success
1735 //
1736 OT_UTILITY_OT int32_t
1737  Utility::receiveReplySuccessLowLevel(const string& serverID18,
1738  const string& nymID,
1739  int32_t nRequestNumber7,
1740  const string& IN_FUNCTION)
1741 {
1742  string strReply = ReceiveReplyLowLevel(
1743  serverID18, nymID, nRequestNumber7,
1744  "receiveReplySuccessLowLevel: " +
1745  IN_FUNCTION); // <=============== Here we RECEIVE the REPLY...
1746 
1747  // getLastReplyReceived() will also contain the same as strReply.
1748  // So if the CALLER of this function (that we're in, receiveNymboxLowLevel)
1749  // wants to see the contents, he can.
1750 
1751  // ReceiveReplyLowLevel returns null unless there was a string returned.
1752  // So we can directly check it for success...
1753 
1754  return VerifyMessageSuccess(strReply);
1755 }
1756 
1757 // Tries to receive a server reply
1758 // (for a message that you presumably just sent.)
1759 // If successful, returns the server reply. Otherwise returns null.
1760 // (Successful meaning, a valid-formed message was received. Whether that is a
1761 // "success=true" or "success=false" message, the caller will have to figure
1762 // that out for himself.)
1763 //
1764 OT_UTILITY_OT string Utility::ReceiveReplyLowLevel(const string& serverID17,
1765  const string& nymID,
1766  int32_t nRequestNumber8,
1767  const string& IN_FUNCTION)
1768 {
1769  delay();
1770  setLastReplyReceived("");
1771 
1772  if (0 > nRequestNumber8) {
1773  otOut << "ReceiveReplyLowLevel (" << IN_FUNCTION
1774  << "): nRequestNumber isn't a valid number.\n";
1775  return "";
1776  }
1777 
1778  string strResponseMessage = OTAPI_Wrap::PopMessageBuffer(
1779  int64_t(nRequestNumber8), serverID17, nymID);
1780  if (!VerifyStringVal(strResponseMessage)) {
1781  otOut << "ReceiveReplyLowLevel (" << IN_FUNCTION
1782  << "): null server reply!\n";
1783  return "";
1784  }
1785  setLastReplyReceived(strResponseMessage);
1786 
1787  return strResponseMessage;
1788 }
1789 
1790 OT_UTILITY_OT int32_t
1791  Utility::getRequestNumber(const string& serverID, const string& nymID)
1792 {
1793  bool bWasSent = false;
1794  return getRequestNumber(serverID, nymID, bWasSent);
1795 }
1796 
1797 // -1 == error (couldn't send, or couldn't receive)
1798 // 0 = = success false (received reply from server);
1799 // 1 = = success true (received reply from server);
1800 //
1801 // To distinguish between error where message wasn't sent,
1802 // and error where message WAS sent, but reply never received,
1803 // bWasSent will be set to TRUE once this function is sure that
1804 // it was sent out. (which you only care about if -1 was the
1805 // return value;
1806 // server reply, AND its status.
1807 // DONE
1808 OT_UTILITY_OT int32_t
1809  Utility::getRequestNumber(const string& serverID, const string& nymID,
1810  bool& bWasSent) // bWasSent is an output param
1811  // allowing to return whether;
1812 {
1813  string strLocation = "Utility::getRequestNumber";
1814 
1816 
1817  int32_t nResult = OTAPI_Wrap::getRequest(serverID, nymID);
1818  if (-1 == nResult) // if error -1, that means it DIDN'T SEND (error)
1819  {
1820  otOut << strLocation
1821  << ": Failed to send getRequest message due to error.\n";
1822  return -1;
1823  }
1824  if (0 == nResult) // if 0 is returned, that also means it DIDN'T SEND (but
1825  // there was NO error...)
1826  { // I don't know if this case can actually even HAPPEN... but if it does,
1827  // I'll log it.
1828  otOut << strLocation << ": Didn't send this getRequest message, but NO "
1829  "error occurred, either. (Should never "
1830  "happen.)\n";
1831  return -1; // Since the 0 case should never happen, I'm returning it as
1832  // an ERROR (-1).
1833  // Note: I could never return 0;
1834  // and that the server's reply said "success == 0". But that's not what
1835  // happened here. Here,
1836  // we couldn't even SEND our request, which is an error
1837  }
1838  //
1839  // else it's >0 == successfully sent! (I BELIEVE this is 1, in this case,
1840  // every time, since you don't NEED a request number to CALL getRequestNum
1841  // since you are only calling it in the first place because it must have
1842  // gotten out of sync.)
1843  //
1844  bWasSent = true;
1845  //
1846  int32_t nReturn =
1847  receiveReplySuccessLowLevel(serverID, nymID, nResult, strLocation);
1848  // otOut << "IN getRequestNumber " <<
1849  // getLastReplyReceived());
1850 
1851  // BY this point, we definitely have the request number in nResult, which
1852  // means
1853  // the message was actually SENT. (At least.) This also means we can use
1854  // nResult
1855  // later to query for a copy of that sent message.
1856  // Let's go ahead, in this case, and remove that now:
1857  //
1858  // var nRemovedGetRequest =
1859  // OTAPI_Wrap::RemoveSentMessage(Integer.toString(nResult), serverID,
1860  // nymID);
1861 
1862  // NOTE: The above call is unnecessary, since a successful reply means
1863  // we already received the successful server reply, and OT's
1864  // "ProcessServerReply"
1865  // already removed the sent message from the sent buffer (so no need to do
1866  // that here.)
1867 
1868  // if (nRemovedGetRequest < 1)
1869  // {
1870  // otOut << "getRequestNumber: ERROR:
1871  // OT_API_RemoveSentMessage returned: " << nRemovedGetRequest);
1872  // }
1873 
1874  return nReturn;
1875 }
1876 
1877 // called by getBoxReceiptWithErrorCorrection DONE
1879  const string& serverID, const string& nymID, const string& accountID,
1880  int32_t nBoxType, int64_t strTransactionNum,
1881  bool& bWasSent) // bWasSent is OTBool
1882 {
1883  string strLocation = "Utility::getBoxReceiptLowLevel";
1884 
1885  bWasSent = false;
1886 
1888 
1889  int32_t nRequestNum = OTAPI_Wrap::getBoxReceipt(
1890  serverID, nymID, accountID, nBoxType,
1891  strTransactionNum); // <===== ATTEMPT TO SEND THE MESSAGE HERE...;
1892  if (-2 == nRequestNum) {
1893  otOut << strLocation << ": ERROR, not supported. (-2 was returned.)\n";
1894  return false; // -2 is also possible at some future date. (If the
1895  // request number won't fit in an int32_t, this is
1896  // returned and then you can retrieve the actual number
1897  // via a separate call.);
1898  }
1899  if (-1 == nRequestNum) {
1900  otOut << strLocation
1901  << ": Failed to send getNymbox message due to error.\n";
1902  return false;
1903  }
1904  if (0 == nRequestNum) {
1905  otOut << strLocation << ": Didn't send getNymbox message, but NO error "
1906  "occurred, either. (In this case, SHOULD NEVER "
1907  "HAPPEN. Treating as Error.)\n";
1908  return false; // Even though '0' MEANS "didn't send, but no error" by
1909  // convention in many places, it is actually an impossible
1910  // return value;
1911  }
1912  if (nRequestNum < 0) {
1913  otOut << strLocation << ": Unexpected request number: " << nRequestNum
1914  << "\n";
1915  return false;
1916  }
1917 
1918  bWasSent = true;
1919 
1920  // BY this point, we definitely have the request number, which means the
1921  // message was actually SENT. (At least.) This also means we can use
1922  // nRequestNum
1923  // later to query for a copy of that sent message.
1924  //
1925  //
1926  int32_t nReturn =
1927  receiveReplySuccessLowLevel(serverID, nymID, nRequestNum, strLocation);
1928  otWarn << strLocation << ": nRequestNum: " << nRequestNum
1929  << " / nReturn: " << nReturn << "\n";
1930 
1931  // int32_t nRemovedGetBoxReceipt =
1932  // OTAPI_Wrap::RemoveSentMessage(Integer.toString(nRequestNum), serverID,
1933  // nymID);
1934  //
1935  // // NOTE: The above call is unnecessary, since a successful reply
1936  // means
1937  // // we already received the successful server reply, and OT's
1938  // "ProcessServerReply"
1939  // // already removed the sent message from the sent buffer (so no need
1940  // to do that here.)
1941  //
1942  // if (nRemovedGetBoxReceipt < 1)
1943  // {
1944  // otOut << "getBoxReceiptLowLevel: ERROR:
1945  // OT_API_RemoveSentMessage returned: " << nRemovedGetBoxReceipt);
1946  // }
1947 
1948  if (nReturn > 0) {
1949  return true;
1950  }
1951 
1952  otOut << strLocation << ": Failure: Response from server:\n"
1953  << getLastReplyReceived() << "\n";
1954 
1955  return false;
1956 }
1957 
1958 // called by insureHaveAllBoxReceipts DONE
1960  const string& serverID, const string& nymID, const string& accountID,
1961  int32_t nBoxType, int64_t strTransactionNum) // nBoxType is int32_t
1962 {
1963  string strLocation = "Utility::getBoxReceiptWithErrorCorrection";
1964 
1965  bool bWasSent = false;
1966  bool bWasRequestSent = false;
1967 
1968  if (getBoxReceiptLowLevel(serverID, nymID, accountID, nBoxType,
1969  strTransactionNum, bWasSent)) {
1970  return true;
1971  }
1972  if (bWasSent && (1 == getRequestNumber(serverID, nymID,
1973  bWasRequestSent))) // this might be
1974  // out of sync, if
1975  // it failed...
1976  // we'll re-sync,
1977  // and re-try.
1978  {
1979  if (bWasRequestSent &&
1980  getBoxReceiptLowLevel(serverID, nymID, accountID, nBoxType,
1981  strTransactionNum, bWasSent)) {
1982  return true;
1983  }
1984  otOut << strLocation << ": getBoxReceiptLowLevel failed, then "
1985  "getRequestNumber succeeded, then "
1986  "getBoxReceiptLowLevel failed again. (I give "
1987  "up.)\n";
1988  }
1989  else {
1990  otOut << strLocation << ": getBoxReceiptLowLevel failed, then "
1991  "getRequestNumber failed. (I give up.) Was "
1992  "getRequest message sent: " << bWasRequestSent
1993  << "\n";
1994  }
1995  return false;
1996 }
1997 
1998 // This function assumes you just downloaded the latest version of the box
1999 // (inbox, outbox, or nymbox)
2000 // and its job is to make sure all the related box receipts are downloaded as
2001 // well and available, though
2002 // not necessarily loaded into memory. (Yet.)
2003 // NOTE: If nBoxType is 0 (nymbox) then pass nymID as the accountID as well!
2004 //
2006  const string& serverID, const string& nymID, const string& accountID,
2007  int32_t nBoxType) // nBoxType is int32_t
2008 {
2009  bool bFoundIt = false;
2010  int32_t nRequestSeeking = 0;
2011  return insureHaveAllBoxReceipts(serverID, nymID, accountID, nBoxType,
2012  nRequestSeeking, bFoundIt);
2013 }
2014 
2016  const string& serverID, const string& nymID, const string& accountID,
2017  int32_t nBoxType, int32_t nRequestSeeking, bool& bFoundIt)
2018 {
2019  string strLocation = "Utility::insureHaveAllBoxReceipts";
2020 
2021  string ledger = "";
2022 
2023  if (0 == nBoxType) {
2024  ledger = OTAPI_Wrap::LoadNymboxNoVerify(serverID, nymID);
2025  }
2026  else if (1 == nBoxType) {
2027  ledger = OTAPI_Wrap::LoadInboxNoVerify(serverID, nymID, accountID);
2028  }
2029  else if (2 == nBoxType) {
2030  ledger = OTAPI_Wrap::LoadOutboxNoVerify(serverID, nymID, accountID);
2031  }
2032  else {
2033  otOut << strLocation << ": Error. Expected nBoxType of 0,1,2 (nymbox, "
2034  "inbox, or outbox.)\n";
2035  return false;
2036  }
2037 
2038  // Unable to load or verify inbox/outbox/nymbox
2039  // Notice I don't call VerifyAccount() here (not that the API even exposes
2040  // that method) but why not? Because that method tries to load up all the
2041  // box receipts, in addition to verifying the signature. Therefore I call
2042  // "Load XXXX NoVerify()", avoiding all that, then I verify the Signature
2043  // itself. That's because this function's whole point is to find out what
2044  // the box receipts are, and download them from the server. No point trying
2045  // to load them before that time, when I know it will fail.
2046  //
2047  if (!VerifyStringVal(ledger) ||
2048  (!OTAPI_Wrap::VerifySignature(nymID, ledger))) {
2049  otOut << strLocation << ": Unable to load or verify signature on "
2050  "ledger. (Failure.) Contents:\n" << ledger
2051  << "\n";
2052  return false;
2053  }
2054 
2055  // At this point, the box is definitely loaded.
2056  // Next we'll iterate the receipts
2057  // within, and for each, verify that the Box Receipt already exists. If not,
2058  // then we'll download it using getBoxReceiptLowLevel(). If any download
2059  // fails,
2060  // then we break out of the loop (without continuing on to try the rest.)
2061  //
2062  bool bReturnValue = true; // Assuming an empty box, we return success;
2063 
2064  int32_t nReceiptCount =
2065  OTAPI_Wrap::Ledger_GetCount(serverID, nymID, accountID, ledger);
2066  if (nReceiptCount > 0) {
2067  for (int32_t i_loop = 0; i_loop < nReceiptCount; ++i_loop) {
2068  int64_t lTransactionNum =
2070  serverID, nymID, accountID, ledger, i_loop);
2071  if (lTransactionNum != -1) {
2072  if (lTransactionNum > 0) {
2073  string strTransaction =
2074  OTAPI_Wrap::Ledger_GetTransactionByID(serverID, nymID,
2075  accountID, ledger,
2076  lTransactionNum);
2077 
2078  // Note: OTAPI_Wrap::Ledger_GetTransactionByID tries to get
2079  // the full transaction from the ledger and
2080  // return it;
2081  // and pass the full version back to us. Failing that
2082  // (perhaps the box receipt hasn't been downloaded
2083  // yet) then it will try to re-sign / re-save the
2084  // abbreviated version and pass it back. So if, by this
2085  // point, it STILL has failed, that means it couldn't even
2086  // give us the abbreviated version either!
2087  //
2088  if (!VerifyStringVal(strTransaction)) {
2089  otOut << strLocation
2090  << ": Error: Null transaction somehow returned, "
2091  "(not even an abbreviated one!) even though I "
2092  "had a good ID " << lTransactionNum
2093  << " which came originally as lTransactionNum: "
2094  << lTransactionNum << " for index: " << i_loop
2095  << " with the contents:\n\n" << strTransaction
2096  << "\n\n";
2097  return false;
2098  }
2099 
2100  // This block might have a full version, OR an abbreviated
2101  // version of the box receipt in
2102  // question, in the strTransaction variable. It will attempt
2103  // to download the full box
2104  // receipt, if we don't already have it here on the client
2105  // side.
2106  {
2107  string strTransType = OTAPI_Wrap::Transaction_GetType(
2108  serverID, nymID, accountID, strTransaction);
2109  bool bIsReplyNotice = (VerifyStringVal(strTransType) &&
2110  (strTransType == "replyNotice"));
2111  int64_t lRequestNum = 0;
2112  if (bIsReplyNotice) {
2114  serverID, nymID, strTransaction);
2115  }
2116 
2117  bool bShouldDownload =
2118  (!bIsReplyNotice ||
2119  (bIsReplyNotice && (0 < lRequestNum) &&
2120  !OTAPI_Wrap::HaveAlreadySeenReply(serverID, nymID,
2121  lRequestNum)));
2122 
2123  if (bShouldDownload) // This block executes if we should
2124  // download it (assuming we haven't
2125  // already, which it also checks
2126  // for.)
2127  {
2128  bool bHaveBoxReceipt =
2130  serverID, nymID, accountID, nBoxType,
2131  lTransactionNum);
2132  if (!bHaveBoxReceipt) {
2133  otWarn << strLocation << ": Downloading box "
2134  "receipt to add to my "
2135  "collection...\n";
2136 
2137  bool bDownloaded =
2138  getBoxReceiptWithErrorCorrection(
2139  serverID, nymID, accountID, nBoxType,
2140  lTransactionNum);
2141  if (!bDownloaded) {
2142  otOut
2143  << strLocation
2144  << ": Failed downloading box receipt. "
2145  "(Skipping any others.) Transaction "
2146  "number: " << lTransactionNum
2147  << "\n";
2148 
2149  bReturnValue = false;
2150  break;
2151  // No point continuing to loop and fail 500
2152  // times, when
2153  // getBoxReceiptWithErrorCorrection()
2154  // already failed
2155  // even doing the getRequest() trick and
2156  // everything, and whatever retries are
2157  // inside OT, before it finally
2158  // gave up.
2159  }
2160  // else (Download success.)
2161  } // if (!bHaveBoxReceipt)
2162  }
2163 
2164  // else we already have the box receipt, no need to
2165  // download again.
2166  }
2167  } // if (lTransactionNum > 0)
2168  else {
2169  otOut
2170  << strLocation
2171  << ": Error: TransactionNum less-than-or-equal-to 0.\n";
2172  }
2173  }
2174  else {
2175  otOut << strLocation << ": Error: TransactionNum was null, "
2176  "when trying to read it based on the "
2177  "index (within bounds, too!)\n";
2178  }
2179  } // ************* FOR LOOP ******************
2180  } // if (nReceiptCount > 0)
2181 
2182  //
2183  // if nRequestSeeking is >0, that means the caller wants to know if there is
2184  // a receipt present for that request number.
2185  // (which is only a valid option ifnBoxType = = 0 for Nymbox.);
2186  // IF the receipt is found, then bFoundIt is set to true.
2187  //
2188  if ((nRequestSeeking > 0) && (0 == nBoxType)) {
2189  // NOTE: the below call to OTAPI_Wrap::Nymbox_GetReplyNotice will
2190  // succeed even if
2191  // only the abbreviated receipt is available, because the caller mainly
2192  // just
2193  // wants to know if it is there.
2194  // Technically the full receipt SHOULD always be there, with the above
2195  // loop,
2196  // but since the above loop can break in case of error, it's still
2197  // possible that
2198  // box receipts haven't been downloaded by the time you reach this code.
2199  // Nevertheless, we will see if the reply is there for the appropriate
2200  // request
2201  // number, whether abbreviated or not.
2202  //
2203  // UPDATE: I am now adding specific cases where the replyNotice is NOT
2204  // downloaded.
2205  // You still use it, through its abbreviated version -- and the actual
2206  // version
2207  // IS still available for download through the server's API. But with a
2208  // replyNotice,
2209  // just knowing that it exists is usually enough for the client, who
2210  // probably still
2211  // has a cached copy of the original sent message anyway. Only in cases
2212  // where he
2213  // doesn't, would he need to download it. (Why? So he can process the
2214  // server's reply.)
2215  // Therefore the cached sent message is useless, since it doesn't
2216  // contain the server's
2217  // reply! Hmm. So I need that reply BUT ONLY IN CASES where I didn't
2218  // already receive it
2219  // as a normal part of processing (and that is MOST of the time, meaning
2220  // most cases can
2221  // thus entirely eliminate the download.)
2222  //
2223  // PROTOCOL FOR NOT DOWNLOADING MOST OF THE BOX RECEIPTS
2224  //
2225  // Solution: User messages should contain a list of the last X number of
2226  // request numbers
2227  // that they have DEFINITELY seen the response to. The server,
2228  // meanwhile, since the user
2229  // has DEFINITELY seen the response, can now safely remove the
2230  // replyNotice from the Nymbox.
2231  // The only reason it was there in the first place was to make sure the
2232  // user got the reply.
2233  // Since the user is straight-up acknowledging that he received it, the
2234  // server no longer
2235  // needs to "make sure" and thus it can remove that reply from the
2236  // Nymbox, and mark the
2237  // box receipt for deletion. This will be MOST REPLIES! We'll eliminate
2238  // the step of having
2239  // to download the box receipt.
2240  // The above call to getBoxReceiptWithErrorCorrection should also be
2241  // smart enough not to
2242  // bother downloading any replyNotice Box Receipts if their request
2243  // number appears on that
2244  // list. Again: the list means I DEFINITELY already responded to it--if
2245  // the request # is on
2246  // that list, then NO NEED downloading the Box Receipt -- I DEFINITELY
2247  // already got that reply!
2248  //
2249  // Therefore, Something like OTAPI_Wrap::HaveAlreadySeenReply(serverID,
2250  // nymID, requestNum);
2251  //
2252  // Perhaps also, on the server side, send a list of request numbers for
2253  // that Nym that the
2254  // server KNOWS the Nym saw the reply to. This way, the Nym can remove
2255  // the number from his
2256  // list, and thus won't be continually causing the server to load up the
2257  // Nymbox and try
2258  // to remove the replyNotice (since it's already been removed.)
2259  //
2260  // The Nym doesn't have to keep a list of ALL request numbers he's seen
2261  // the reply to.
2262  // Rather, just the past X number of them, and with the number
2263  // explicitly removed once
2264  // he sees the server acknowledgment. (ServerAckOfAlreadyGotReply.)
2265  //
2266  // The server, meanwhile, is free to remove the ACK for any request #
2267  // once he sees that
2268  // the client has as well. Server also only needs to store a list of the
2269  // past X request #s.
2270  // Also: since both sides REMOVE the number, there need not necessarily
2271  // be a limit on the
2272  // size of the list, since it grows and shrinks as needed.
2273  //
2274  // Whenever Wallet processes a server reply, just see if it's on that
2275  // "replied to already"
2276  // list already on client side. If so, discard the reply.
2277  // OTClient::ProcessServerReply probably
2278  // best place to do (We replied to it already, so discard it.)
2279  // Also, for any server reply, look at the list of numbers on it. The
2280  // server is acknowledging
2281  // to us that it KNOWS we got those replies, and that it ALREADY has
2282  // removed them from the
2283  // Nymbox as a result. Therefore we can remove ALL of those numbers from
2284  // our own list
2285  // as well. No need for an API call to do this, since it will happen
2286  // internally to OT.
2287  //
2288  // On the server side, any numbers on its own list were only there to
2289  // acknowledge numbers
2290  // that had been on the client side list. Therefore, when those numbers
2291  // disappear from the
2292  // client side list, the server simply removes them. Again: ANY NUMBERS
2293  // on the server list,
2294  // which do NOT appear on the client list, are REMOVED From the server
2295  // list. After all, the
2296  // client has clearly now removed them, so the server doesn't have to
2297  // keep them around either.
2298  //
2299  // These are useful for synchronization but also there's a int64_t term
2300  // benefit, if we include
2301  // them in the signed receipt (which they will be already, if the
2302  // receipt contains the entire
2303  // message and not just the transaction.) That benefit is that we can
2304  // prove receipt of notice.
2305  // At least, notice of server replies. But for other notice types, such
2306  // as notice of upcoming
2307  // meeting. Or notice of upcoming election. Or notice of election
2308  // outcome. Or notice of petition
2309  // to put X issue on the next ballot, or to nominate Y Nym for some
2310  // corporate role. Sometimes
2311  // you want to be able to PROVE that notice was received. Does this
2312  // prove that?
2313  // Hmm, not necessarily. Currently I'm using this as an optimization
2314  // scheme, which is useful
2315  // even if not provable. How to make it provable?
2316  //
2317  // Back from tangent: Wait a sec! If I notice the server that I saw the
2318  // reply, the server will
2319  // remove that reply from my Nymbox -- but it's still in my Nymbox on
2320  // the client side! Until
2321  // I download the latest Nymbox. Thus if I try to PROCESS MY NYMBOX, I
2322  // will be attempting to
2323  // accept a receipt that's already gone! (And the processNymbox will
2324  // therefore FAIL!)
2325  // Solution: be smart enough, when processing Nymbox, to IGNORE any
2326  // replyNotices when the request
2327  // Number appears on the client's list! As the wallet processes the
2328  // Nymbox it should already
2329  // know to skip the ones that were already replied-to.
2330  // Meanwhile the server side will deliberately NOT update the Nymbox
2331  // hash just because the receipt
2332  // was removed. Otherwise it could trigger an unnecessary download of
2333  // the Nymbox, when the whole
2334  // point of this exercise was to prevent unnecessary downloads. It only
2335  // updates the Nymbox hash
2336  // when it WANTS me to download the Nymbox, and that certainly does NOT
2337  // apply to cases where the
2338  // only change involved the removal of some old receipt I already
2339  // acknowledged. (No need to force
2340  // any downloads based on THAT case, after all.)
2341  //
2342  string strReplyNotice = OTAPI_Wrap::Nymbox_GetReplyNotice(
2343  serverID, nymID, int64_t(nRequestSeeking));
2344 
2345  if (VerifyStringVal(strReplyNotice)) {
2346  bFoundIt = true;
2347  }
2348  }
2349 
2350  return bReturnValue;
2351 }
2352 
2353 /*
2354 static void getBoxReceipt( string SERVER_ID, string USER_ID, string ACCT_ID, //
2355 If for Nymbox (vs inbox/outbox) then pass USER_ID
2356 in this field also.
2357 int32_t nBoxType, // 0/nymbox, 1/inbox, 2/outbox
2358 const string TRANSACTION_NUMBER);
2359 
2360 static bool DoesBoxReceiptExist( string SERVER_ID, string USER_ID, string
2361 ACCT_ID, // If for Nymbox (vs inbox/outbox) then pass USER_ID
2362 in this field also.
2363 int32_t nBoxType, // 0/nymbox, 1/inbox, 2/outbox
2364 const string TRANSACTION_NUMBER);
2365 */
2366 // If the transaction number requests fail, this function will try to resync
2367 // the request number. But you still have to call getRequest() yourself if
2368 // you have a failure in your own function, since you might already have
2369 // enough transaction numbers, and thus this function will never get called,
2370 // even if your request number IS out of sync. Sorry :-)
2371 //
2372 
2373 OT_UTILITY_OT int32_t
2374  Utility::getTransactionNumLowLevel(const string& serverID,
2375  const string& nymID,
2376  bool& bWasSent) // bWasSent is OTBool
2377 {
2378  string strLocation = "Utility::getTransactionNumLowLevel";
2379 
2381  bWasSent = false;
2382 
2383  int32_t nRequestNum = OTAPI_Wrap::getTransactionNumber(
2384  serverID, nymID); // <===== ATTEMPT TO SEND THE MESSAGE HERE...;
2385  if (-2 == nRequestNum) {
2386  otOut << strLocation << ": ERROR, not supported. (-2 was returned.)\n";
2387  return -1; // -2 is also possible at some future date. (If the request
2388  // number won't fit in an int32_t, this is returned and then
2389  // you can retrieve the actual number via a separate call.)
2390  }
2391  if (-1 == nRequestNum) {
2392  otOut << strLocation
2393  << ": Failed to send getNymbox message due to error.\n";
2394  return -1;
2395  }
2396  if (0 == nRequestNum) {
2397  otOut << strLocation << ": Unexpectedly returned 0. Didn't send "
2398  "getTransactionNum message, but NO error "
2399  "occurred, either. (In this case, SHOULD NEVER "
2400  "HAPPEN. Treating as Error.)\n";
2401  return -1; // Even though '0' MEANS "didn't send, but no error" by
2402  // convention in many places, it is actually an impossible
2403  // return value;
2404  }
2405  if (nRequestNum < 0) {
2406  otOut << strLocation << ": Unexpected request number: " << nRequestNum
2407  << "\n";
2408  return -1;
2409  }
2410 
2411  bWasSent = true;
2412 
2413  //
2414  int32_t nReturn = receiveReplySuccessLowLevel(serverID, nymID, nRequestNum,
2415  "getTransactionNum");
2416  // otOut << "IN getTransactionNum " <<
2417  // getLastReplyReceived());
2418 
2419  // BY this point, we definitely have the request number in nResult, which
2420  // means
2421  // the message was actually SENT. (At least.) This also means we can use
2422  // nResult
2423  // later to query for a copy of that sent message.
2424  // Let's go ahead, in this case, and remove that now:
2425  //
2426 
2427  // THE REMOVE SENT MESSAGE BELOW FAILS, LIKE IT'S ALREADY GONE.
2428  //
2429  // THIS MUST BE DUE TO THE PROCESS SERVER REPLY THAT OCCURS **IMMEDIATELY**
2430  // after the message was originally sent!
2431  // (The reply came in and was sent to OT's "ProcessServerReply", INSIDE the
2432  // call to OTAPI_Wrap::getTransactionNumber.)
2433  // Our subsequent "receive" (above) is nothing of the sort, but actually
2434  // pops the incoming message buffer where
2435  // the server's reply was ALREADY SITTING, since it was put there in OT's
2436  // "ProcessServerReply", WHICH REMOVED THE
2437  // SENT MESSAGE ALREADY (that's why the below call to RemoveSentMessage
2438  // fails.)
2439  //
2440  // RETHINK any logic that doesn't take this into account,.
2441  // Either we REMOVE this call wherever this happens, OR... we call Get first
2442  // and make sure whether it's
2443  // there, THEN remove it. But we can't be lumping "Failure because it's
2444  // gone" versus "Error state" by mixing
2445  // 0 and -1 here. We need to differentiate.
2446  //
2447  // Bottom line: if the reply WAS received, then the original sent message
2448  // has ALREADY been removed
2449  // from the sent buffer. Whereas if the reply was NOT received, then the
2450  // sent message is still there,
2451  // but in that case, we do NOT want to remove it -- we want it to STAY in
2452  // the sent buffer, so that
2453  // when we get the Nymbox later and we DO have the reply from that, THEN we
2454  // can remove the sent msg from
2455  // the sent buffer. Until then, we don't want OT to think it's already been
2456  // processed (which it will, if
2457  // it's already been removed from the sent buffer. So we leave it there for
2458  // now.)
2459  //
2460  //
2461  //
2462  // int32_t nRemovedSentMsg =
2463  // OTAPI_Wrap::RemoveSentMessage(Integer.toString(nRequestNum), serverID,
2464  // nymID);
2465  //
2466  // if (nRemovedSentMsg < 1)
2467  // {
2468  // otOut << "getTransactionNum: ERROR:
2469  // OT_API_RemoveSentMessage returned: " << nRemovedSentMsg);
2470  // }
2471 
2472  if (1 == nReturn) {
2473  return nRequestNum;
2474  }
2475 
2476  return nReturn;
2477 }
2478 
2479 // DONE
2480 OT_UTILITY_OT bool Utility::getTransactionNumbers(const string& serverID,
2481  const string& nymID)
2482 {
2483  return getTransactionNumbers(serverID, nymID, true); // bForceFirstCall = =
2484  // true (by default)
2485  // but in special cases
2486  // you can override it
2487  // and set it to false.
2488 }
2489 
2491  const string& serverID, const string& nymID,
2492  bool bForceFirstCall) // boolean bForceFirstCall defaults to true.
2493 {
2494  string strLocation = "Utility::getTransactionNumbers";
2495 
2496  bool bWasSent = false;
2497  int32_t nGetNumbers = -1;
2498  if (bForceFirstCall) {
2499  nGetNumbers = getTransactionNumLowLevel(
2500  serverID, nymID, bWasSent); // <============ FIRST TRY;
2501  }
2502 
2503  // if the first call didn't happen, due to bForceFirstCall being false, that
2504  // means the caller wants the rest of this to happen as though it did.
2505  //
2506  if (!bForceFirstCall || (bWasSent && (nGetNumbers >= 1)) ||
2507  (!bWasSent && (nGetNumbers == 0))) {
2508  // Because it was successful, we have to now SIGN FOR those numbers we
2509  // requested.
2510  //
2511  bool bForceDownload = true;
2512  int32_t nProcess = getAndProcessNymbox_4(
2513  serverID, nymID, bWasSent, bForceDownload); // bForceDownload=true;
2514 
2515  if ((bWasSent && (1 == nProcess)) || (!bWasSent && (0 == nProcess))) {
2516  return true;
2517  }
2518  }
2519  // If value is LESS THAN -1 (which is an unexpected value)
2520  // or if the getTransactionNum message WASN'T EVEN SENT, then return.
2521  //
2522  else if ((nGetNumbers < -1) || !bWasSent) {
2523  otOut << strLocation << ": Failure: getTransactionNumLowLevel returned "
2524  "unexpected value: " << nGetNumbers << "\n";
2525  return false;
2526  }
2527 
2528  // Below this point, the message WAS sent. -1 is error, 0 is failure, >0 is
2529  // success.
2530  // Now it's just about whether a reply was successful, or was even received.
2531  //
2532  // else if ((-1 == nGetNumbers) || // Message sent, but then error
2533  // receiving or loading the reply.
2534  // (( 0) == nGetNumbers)) // Received a reply, butstatus =
2535  // = failure on that reply.;
2536  else if ((-1 == nGetNumbers) || (0 == nGetNumbers)) {
2537  if (-1 == nGetNumbers) {
2538  otOut << strLocation << ": FYI: getTransactionNumLowLevel did "
2539  "send, but returned error (-1). "
2540  "(Re-trying...)\n";
2541  }
2542  else if (0 == nGetNumbers) {
2543  otOut << strLocation << ": FYI: getTransactionNumLowLevel did "
2544  "send, but returned failure (0). "
2545  "(Re-trying...)\n";
2546  }
2547 
2548  int32_t nGetRequest = getRequestNumber(serverID, nymID);
2549  if (1 != nGetRequest) {
2550  otOut << strLocation << ": Failure: getTransactionNumLowLevel "
2551  "failed, then I tried to resync with "
2552  "getRequestNumber and then that failed "
2553  "too. (I give up.)\n";
2554  return false;
2555  }
2556 
2557  //
2558  bool bWasProcessSent = false;
2559  bool bForceDownload = true;
2560  int32_t nProcessNymbox = getAndProcessNymbox_4(
2561  serverID, nymID, bWasProcessSent,
2562  bForceDownload); // boolean bForceDownload=true;
2563 
2564  // if ( (!bWasProcessSent && ((nProcessNymbox < 0) ||
2565  // (nProcessNymbox > 1))) ||
2566  // ( bWasProcessSent && (nProcessNymbox != 1)) ) // -1
2567  // error, 0 failed (harvesting success), 1 success, >1 failed
2568  // (harvesting NOT done) RequestNum is returned.
2569 
2570  if ((!bWasProcessSent &&
2571  ((nProcessNymbox < 0) || (nProcessNymbox > 1))) ||
2572  (bWasProcessSent && (nProcessNymbox != 1))) {
2573  // todo: if request num is returned probably don't have to do
2574  // anything with it.
2575  // Why not? Because future processNymbox will iterate Nymbox and
2576  // search for all found
2577  // items in the sent message buffer, and REMOVE them from it (as
2578  // clearly they will be
2579  // processed already.)
2580  // The ones left over in the sent buffer, after this? Must be
2581  // harvested!
2582  // Hmm, solution: Use the "Flush Sent Messages" function, which is
2583  // already
2584  // there. Have it be smart enough to harvest all sent messages
2585  // before flushing,
2586  //
2587  //
2588  if (bWasProcessSent && (nProcessNymbox > 1)) {
2589  string strNymbox = OTAPI_Wrap::LoadNymboxNoVerify(
2590  serverID,
2591  nymID); // FLUSH SENT MESSAGES!!!! (AND HARVEST.);
2592 
2593  if (VerifyStringVal(strNymbox)) {
2595  false, // harvesting for retry = = OT_FALSE
2596  serverID, nymID, strNymbox);
2597  }
2598  }
2599 
2600  otOut << strLocation
2601  << ": Failure: getAndProcessNymbox. Returned value: "
2602  << nProcessNymbox << "\n";
2603 
2604  return false;
2605  }
2606 
2607  nGetNumbers = getTransactionNumLowLevel(
2608  serverID, nymID, bWasSent); // <================= SECOND TRY;
2609 
2610  // if ( ( bWasSent && (nGetNumbers >= 1)) || // if message was
2611  // sent, and was a success.
2612  // (!bWasSent && (nGetNumbers == 0)) ) // Or if message
2613  // wasn't sent due to "you already signed out too many numbers--you need
2614  // to process your Nymbox..."
2615 
2616  if ((bWasSent && (nGetNumbers >= 1)) ||
2617  (!bWasSent && (nGetNumbers == 0))) {
2618  bool bForceDownload = true;
2619  int32_t nProcess =
2620  getAndProcessNymbox_4(serverID, nymID, bWasSent,
2621  bForceDownload); // bForceDownload=true;
2622 
2623  // if ( ( bWasSent && (1 == nProcess)) ||
2624  // (!bWasSent && (0 == nProcess)) )
2625 
2626  if ((bWasSent && (1 == nProcess)) ||
2627  (!bWasSent && (0 == nProcess))) {
2628  return true;
2629  }
2630  }
2631  // else if (( nGetNumbers < -1) ||
2632  // (!bWasSent && nGetNumbers != 0))
2633  else if ((nGetNumbers < -1) || (!bWasSent && nGetNumbers != 0)) {
2634  otOut << strLocation << ": Failure: getTransactionNumLowLevel "
2635  "returned unexpected value: " << nGetNumbers
2636  << "\n";
2637  return false;
2638  }
2639  else if ((-1 == nGetNumbers) || (0 == nGetNumbers)) {
2640  if (-1 == nGetNumbers) {
2641  otOut << strLocation << ": Failure: getTransactionNumLowLevel "
2642  "did send, but returned error (-1), "
2643  "even after syncing the request number "
2644  "successfully. (Giving up.)\n";
2645  }
2646  else if (0 == nGetNumbers) {
2647  otOut << strLocation << ": Failure: getTransactionNumLowLevel "
2648  "did send, but returned failure (0), "
2649  "even after syncing the request number "
2650  "successfully. (Giving up.)\n";
2651  }
2652 
2653  bool bForceDownload = true;
2654 
2655  int32_t nLast = getAndProcessNymbox_4(
2656  serverID, nymID, bWasProcessSent,
2657  bForceDownload); // boolean bForceDownload=true;
2658  // if (
2659  // ((!bWasProcessSent) && ((nLast < 0) || (nLast
2660  // > 1))) ||
2661  // ((true == bWasProcessSent) && (nLast != 1))
2662  // ) // -1 error, 0 failed (harvesting success), 1
2663  // success, >1 failed (harvesting NOT done) RequestNum is returned.
2664 
2665  if (((!bWasProcessSent) && ((nLast < 0) || (nLast > 1))) ||
2666  ((true == bWasProcessSent) &&
2667  (nLast != 1))) // -1 error, 0 failed (harvesting success), 1
2668  // success, >1 failed (harvesting NOT done)
2669  // RequestNum is returned.
2670  {
2671  if (bWasProcessSent && (nLast > 1)) {
2672  string strNymbox = OTAPI_Wrap::LoadNymboxNoVerify(
2673  serverID,
2674  nymID); // FLUSH SENT MESSAGES!!!! (AND HARVEST.);
2675 
2676  if (VerifyStringVal(strNymbox)) {
2678  false, // harvesting for retry = = OT_FALSE
2679  serverID, nymID, strNymbox);
2680  }
2681  }
2682 
2683  otOut << strLocation
2684  << ": Failure: getAndProcessNymbox. Returned value: "
2685  << nLast << "\n";
2686  return false;
2687  }
2688 
2689  nGetNumbers = getTransactionNumLowLevel(
2690  serverID, nymID, bWasSent); // <============ FIRST TRY;
2691 
2692  // if ( (bWasSent && (nGetNumbers >= 1) )
2693  // ||
2694  // ((!bWasSent && (nGetNumbers == 0) ) )
2695  // )
2696 
2697  if ((bWasSent && (nGetNumbers >= 1)) ||
2698  ((!bWasSent && (nGetNumbers == 0)))) {
2699  bool bForceDownload = true;
2700  int32_t nProcess = getAndProcessNymbox_4(
2701  serverID, nymID, bWasSent,
2702  bForceDownload); // bForceDownload=true;
2703 
2704  // if ( ( bWasSent && (1 == nProcess)) ||
2705  // (!bWasSent && (0 == nProcess)) )
2706 
2707  if ((bWasSent && (1 == nProcess)) ||
2708  (!bWasSent && (0 == nProcess))) {
2709  return true;
2710  }
2711  }
2712 
2713  // if ((nGetNumbers < -1) || // If value is
2714  // LESS THAN -1 (which is an unexpected value)
2715  // !bWasSent) // or if the getTransactionNum
2716  // message WASN'T EVEN SENT, then return.
2717 
2718  if ((nGetNumbers < -1) || !bWasSent) {
2719  otOut << strLocation
2720  << ": Failure: getTransactionNumLowLevel returned "
2721  "unexpected value: " << nGetNumbers << "\n";
2722  return false;
2723  }
2724  }
2725  }
2726 
2727  // BY THIS POINT, we have SUCCESSFULLY sent the getTransactionNumLowLevel
2728  // message,
2729  // and nGetNumbers contains its request number.
2730 
2731  // No need to read the result, as getTransactionNumLowLevel() already read
2732  // it,
2733  // and and it's available anytime via getLastReplyReceived()
2734 
2735  string strLastReplyReceived = getLastReplyReceived();
2736 
2737  if (!VerifyStringVal(strLastReplyReceived)) {
2738  otOut << strLocation << ": ERROR in getLastReplyReceived(): why was "
2739  "this string not set, when getRequestNumber "
2740  "was otherwise an apparent success?\n";
2741  return false; // (SHOULD NEVER HAPPEN. This string is set in the
2742  // getRequestNumber function.);
2743  }
2744 
2745  // BY THIS POINT, we have received a server reply: @getTransactionNum
2746  // (Unless it is malformed.) It's definitely not null, nor empty.
2747 
2748  // Grab the NymboxHash on the @getTransactionNum reply, and also the one I
2749  // already had on my client-side Nym... (So we can compare them.)
2750  //
2751  string strServerHash =
2752  OTAPI_Wrap::Message_GetNymboxHash(strLastReplyReceived);
2753  bool bServerhash = VerifyStringVal(strServerHash);
2754  if (!bServerhash) {
2755  otOut << strLocation
2756  << ": Warning: Unable to retrieve server-side NymboxHash from "
2757  "OT, from server @getTransactionNum reply:\n\n"
2758  << strLastReplyReceived << "\n";
2759  // return false;
2760  }
2761 
2762  string strLocalHash = OTAPI_Wrap::GetNym_NymboxHash(serverID, nymID);
2763  bool bLocalhash = VerifyStringVal(strLocalHash);
2764  if (!bLocalhash) {
2765  otOut << strLocation
2766  << ": Warning: Unable to retrieve client-side NymboxHash from "
2767  "OT, for:\n serverID: " << serverID << "\n nymID: " << nymID
2768  << "\n";
2769  // return false;
2770  }
2771 
2772  // the hashes don't match -- so let's definitely re-try to download the
2773  // latest nymbox.
2774  //
2775  if (!bServerhash || !bLocalhash ||
2776  (bServerhash && bLocalhash && !(strServerHash == strLocalHash))) {
2777  // the getRequest worked, and the server hashes don't match,
2778  // so let's get and process the Nymbox...
2779  //
2780 
2781  bool bWasProcessSent = false;
2782  bool bForceDownload = true;
2783  int32_t nGetNymbox = getAndProcessNymbox_4(
2784  serverID, nymID, bWasProcessSent,
2785  bForceDownload); // boolean bForceDownload=true;
2786 
2787  // if ( ((!bWasProcessSent) && ((nGetNymbox < 0) ||
2788  // (nGetNymbox > 1))) ||
2789  // ((true == bWasProcessSent) && (nGetNymbox != 1)) ) //
2790  // -1 error, 0 failed (harvesting success), 1 success, >1 failed
2791  // (harvesting NOT done) RequestNum is returned.
2792 
2793  if (((!bWasProcessSent) && ((nGetNymbox < 0) || (nGetNymbox > 1))) ||
2794  ((true == bWasProcessSent) && (nGetNymbox != 1))) {
2795  if (nGetNymbox > 1) {
2796  string strNymbox = OTAPI_Wrap::LoadNymboxNoVerify(
2797  serverID,
2798  nymID); // FLUSH SENT MESSAGES!!!! (AND HARVEST.);
2799 
2800  if (VerifyStringVal(strNymbox)) {
2802  false, // harvesting for retry = = OT_FALSE
2803  serverID, nymID, strNymbox);
2804  }
2805  }
2806 
2807  otOut
2808  << strLocation
2809  << ": Failure: getAndProcessNymbox returned unexpected value: "
2810  << nGetNymbox << "\n";
2811  return false;
2812  }
2813  if (-1 == nGetNymbox) // we'll try re-syncing the request number, then
2814  // try again.
2815  {
2816  otOut << strLocation << ": Failure: getAndProcessNymbox returned "
2817  "-1, even after syncing the request number "
2818  "successfully. (Giving up.)\n";
2819  return false;
2820  }
2821  }
2822 
2823  return true;
2824 }
2825 
2826 OT_UTILITY_OT bool Utility::getIntermediaryFiles(const string& serverID,
2827  const string& nymID,
2828  const string& accountID)
2829 {
2830  bool bForceDownload = false;
2831  return getIntermediaryFiles(serverID, nymID, accountID, bForceDownload);
2832 }
2833 
2834 // DEPRECATED
2836  const string& serverID, const string& nymID, const string& accountID,
2837  bool bForceDownload) // booleanbForceDownload = false;
2838 {
2839  string strLocation = "Utility::getIntermediaryFiles_old";
2840 
2841  if (!VerifyStringVal(serverID) || serverID.size() < 10) {
2842  otOut << strLocation << ": nullptr or invalid serverID.\n";
2843  return false;
2844  }
2845  if (!VerifyStringVal(nymID) || nymID.size() < 10) {
2846  otOut << strLocation << ": nullptr or invalid nymID.\n";
2847  return false;
2848  }
2849  if (!VerifyStringVal(accountID) || accountID.size() < 10) {
2850  otOut << strLocation << ": nullptr or invalid accountID.\n";
2851  return false;
2852  }
2853 
2854  bool bWasSentInbox = false;
2855  bool bWasSentAccount = false;
2856 
2857  int32_t nGetInboxAcct =
2858  getInboxAccount_old(serverID, nymID, accountID, bWasSentInbox,
2859  bWasSentAccount, bForceDownload);
2860 
2861  // if we received an error state, and the "getAccount" message wasn't even
2862  // sent,
2863  // then no point doing a bunch of retries -- it failed.
2864  //
2865  if ((-1 == nGetInboxAcct) && !bWasSentAccount) {
2866  otOut << strLocation << ": getInboxAccount_old failed, without even "
2867  "sending getAccount. (Returning false.)\n";
2868  return false;
2869  }
2870 
2871  // If it wasn't sent, and 0 was returned, that means
2872  // no error: we already have the latest inbox. (Nothing done.)
2873  //
2874  if (!bWasSentInbox && (0 == nGetInboxAcct)) {
2875  // we don't return true;
2876  }
2877  else if (1 != nGetInboxAcct) {
2878  otOut << strLocation
2879  << ": getInboxAccount_old failed. (Trying one more time...)\n";
2880 
2881  int32_t nGetRequest = getRequestNumber(serverID, nymID);
2882  if (1 != nGetRequest) {
2883  otOut << strLocation << ": Failure: getInboxAccount_old failed, "
2884  "then I tried to resync with "
2885  "getRequestNumber and then that failed "
2886  "too. (I give up.)\n";
2887  return false;
2888  }
2889 
2890  int32_t nSecondtry =
2891  getInboxAccount_old(serverID, nymID, accountID, bWasSentInbox,
2892  bWasSentAccount, bForceDownload);
2893  if ((-1 == nSecondtry) && !bWasSentAccount) {
2894  // if we received an error state, and the "getAccount" message
2895  // wasn't even sent,
2896  // then no point doing a bunch of retries -- it failed.
2897  //
2898  otOut << strLocation << ": getInboxAccount_old failed a second "
2899  "time, without even sending getAccount. "
2900  "(Returning false.)\n";
2901  return false;
2902  }
2903  // If it wasn't sent, and 0 was returned, that means
2904  // no error: we already have the latest inbox. (Nothing done.)
2905  //
2906  if (!bWasSentInbox && (0 == nSecondtry)) {
2907  // we don't return true;
2908  }
2909  else if (1 != nSecondtry) {
2910  otOut << strLocation << ": getInboxAccount_old re-try failed. "
2911  "(That's twice now--Returning false.) "
2912  "Value: " << nSecondtry << "\n";
2913  return false;
2914  }
2915  otOut
2916  << strLocation
2917  << ": getInboxAccount_old second call succeeded. (Continuing...)\n";
2918  }
2919 
2920  bool bWasSentOutbox = false;
2921 
2922  int32_t nGetOutbox = getOutboxLowLevel(serverID, nymID, accountID,
2923  bWasSentOutbox, bForceDownload);
2924 
2925  if (-1 == nGetOutbox && !bWasSentOutbox) {
2926  // if we received an error state, and the "getOutbox" message wasn't
2927  // even sent,
2928  // then no point doing a bunch of retries -- it failed.
2929  //
2930  otOut << strLocation << ": getOutboxLowLevel failed, without even "
2931  "sending getOutbox. (Returning false.)\n";
2932  return false;
2933  }
2934  // If it wasn't sent, and 0 was returned, that means the
2935  // outbox we have is already the latest version.
2936  //
2937  if (!bWasSentOutbox && 0 == nGetOutbox) {
2938  return true;
2939  }
2940 
2941  if (1 != nGetOutbox) {
2942  otOut << strLocation
2943  << ": getOutboxLowLevel failed. (Trying one more time...)\n";
2944 
2945  int32_t nGetRequest = getRequestNumber(serverID, nymID);
2946  if (1 != nGetRequest) {
2947  otOut << strLocation << ": Failure: getOutboxLowLevel failed, then "
2948  "I tried to resync with getRequestNumber "
2949  "and then that failed too. (I give up.)\n";
2950  return false;
2951  }
2952 
2953  int32_t nSecondtry = getOutboxLowLevel(serverID, nymID, accountID,
2954  bWasSentOutbox, bForceDownload);
2955  if ((-1 == nSecondtry) && !bWasSentOutbox) {
2956  // if we received an error state, and the "getOutbox" message wasn't
2957  // even sent,
2958  // then no point doing a bunch of retries -- it failed.
2959  //
2960  otOut << strLocation << ": getOutboxLowLevel failed a second time, "
2961  "without even sending getOutbox. "
2962  "(Returning false.)\n";
2963  return false;
2964  }
2965  // If it wasn't sent, and 0 was returned, that means
2966  // no error: we already have the latest outbox. (Nothing done.)
2967  //
2968  if (!bWasSentOutbox && (0 == nSecondtry)) {
2969  return true;
2970  }
2971 
2972  if (1 != nSecondtry) {
2973  otOut << strLocation << ": getOutboxLowLevel re-try failed. "
2974  "(That's twice now--Returning false.) "
2975  "Value: " << nSecondtry << "\n";
2976  return false;
2977  }
2978  otOut << strLocation
2979  << ": getOutboxLowLevel second call succeeded. (Continuing...)\n";
2980  }
2981 
2982  return true;
2983 }
2984 
2985 // NOTE: This is a new version, that uses getInboxAccount new version, which
2986 // uses getAccountFiles instead of getAccount, getInbox, and getOutbox.
2988  const string& serverID, const string& nymID, const string& accountID,
2989  bool bForceDownload) // booleanbForceDownload = false;
2990 {
2991  string strLocation = "Utility::getIntermediaryFiles";
2992 
2993  if (!VerifyStringVal(serverID) || serverID.size() < 10) {
2994  otOut << strLocation << ": nullptr or invalid serverID.\n";
2995  return false;
2996  }
2997  if (!VerifyStringVal(nymID) || nymID.size() < 10) {
2998  otOut << strLocation << ": nullptr or invalid nymID.\n";
2999  return false;
3000  }
3001  if (!VerifyStringVal(accountID) || accountID.size() < 10) {
3002  otOut << strLocation << ": nullptr or invalid accountID.\n";
3003  return false;
3004  }
3005 
3006  bool bWasSentInbox = false;
3007  bool bWasSentAccount = false;
3008 
3009  // This is a new version of getInboxAccount that downloads ALL
3010  // THREE files (account/inbox/outbox) in a single server message.
3011  //
3012  int32_t nGetInboxAcct =
3013  getInboxAccount(serverID, nymID, accountID, bWasSentInbox,
3014  bWasSentAccount, bForceDownload);
3015 
3016  // if we received an error state, and the "getAccountFiles" message wasn't
3017  // even sent,
3018  // then no point doing a bunch of retries -- it failed.
3019  //
3020  if (-1 == nGetInboxAcct) {
3021  if (!bWasSentAccount) {
3022  otOut << strLocation << ": this.getInboxAccount failed, without "
3023  "even sending getAccountFiles. (Returning "
3024  "false.)\n";
3025  return false;
3026  }
3027  }
3028 
3029  // If it wasn't sent, and 0 was returned, that means
3030  // no error: we already have the latest inbox. (Nothing done.)
3031  //
3032  else if (!bWasSentInbox && (0 == nGetInboxAcct)) {
3033  // we don't return true;
3034  }
3035  else if (1 != nGetInboxAcct) {
3036  otOut << strLocation
3037  << ": getInboxAccount failed. (Trying one more time...)\n";
3038 
3039  int32_t nGetRequest = getRequestNumber(serverID, nymID);
3040  if (1 != nGetRequest) {
3041  otOut << strLocation << ": Failure: getInboxAccount failed, then I "
3042  "tried to resync with getRequestNumber and "
3043  "then that failed too. (I give up.)\n";
3044  return false;
3045  }
3046  else // TODO: REMOVE THIS BLOCK ONCE THE SERVERS ALL SUPPORT NEW
3047  // "getAccountFiles" message.
3048  {
3049  // Maybe the server doesn't support the new getAccountFiles
3050  // message yet -- so let's just call the old version of the function
3051  // we're currently in.
3052 
3053  // TODO: LONGER TERM, remove this call to _old entirely.
3054  // AND: remove this 'else' -- just let it fall through to the
3055  // getRequest / retry.
3056  //
3057  // UNTIL WE REMOVE THIS, any sync issue with the request number will
3058  // cause this
3059  // function to download the account/inbox/outbox individually, due
3060  // to this call
3061  // here to the old version.
3062 
3063  return getIntermediaryFiles_old(serverID, nymID, accountID,
3064  bForceDownload);
3065  }
3066 
3069 
3070  // We sync'd the request number, so now we try the function again...
3071  //
3072  int32_t nSecondtry =
3073  getInboxAccount(serverID, nymID, accountID, bWasSentInbox,
3074  bWasSentAccount, bForceDownload);
3075 
3076  if ((-1 == nSecondtry) && !bWasSentAccount) {
3077  // if we received an error state, and the "getAccountFiles" message
3078  // wasn't even sent,
3079  // then no point doing a bunch of retries -- it failed.
3080  //
3081  otOut << strLocation << ": getInboxAccount failed a second time, "
3082  "without even sending getAccountFiles. "
3083  "(Returning false.)\n";
3084  return false;
3085  }
3086  // If it wasn't sent, and 0 was returned, that means
3087  // no error: we already have the latest inbox. (Nothing done.)
3088  //
3089  if (!bWasSentInbox && (0 == nSecondtry)) {
3090  // we don't return true;
3091  }
3092  else if (1 != nSecondtry) {
3093  otOut << strLocation
3094  << ": getInboxAccount re-try failed. (That's twice "
3095  "now--Returning false.) Value: " << nSecondtry << "\n";
3096  return false;
3097  }
3098  otOut << strLocation
3099  << ": getInboxAccount second call succeeded. (Continuing...)\n";
3100  }
3101 
3102  return true;
3103 }
3104 
3105 // NOTE: This is a new version that uses the new server message, getAccountFiles
3106 // (Which combines getAccount, getInbox, and getOutbox into a single message.)
3107 OT_UTILITY_OT int32_t
3108  Utility::getInboxAccount(const string& serverID, const string& nymID,
3109  const string& accountID, bool& bWasSentInbox,
3110  bool& bWasSentAccount, const bool)
3111 {
3112  string strLocation = "Utility::getInboxAccount";
3113 
3114  bWasSentAccount = false;
3115  bWasSentInbox = false;
3116 
3117  //
3118  // (Success means both were downloaded, if necessary.)
3119  //
3120  // FIRST WE DO THE ACCOUNT...
3121  //
3122  // GET ACCOUNT
3123  //
3125 
3126  int32_t nRequestNum = OTAPI_Wrap::getAccountFiles(
3127  serverID, nymID, accountID); // <===== ATTEMPT TO SEND MESSAGE;
3128  if (-2 == nRequestNum) {
3129  otOut << strLocation << ": ERROR, not supported. (-2 was returned.)\n";
3130  return -1; // -2 is also possible at some future date. (If the request
3131  // number won't fit in an int32_t, this is returned and then
3132  // you can retrieve the actual number via a separate call.)
3133  }
3134  if (-1 == nRequestNum) {
3135  otOut << strLocation
3136  << ": Failed to send getAccountFiles message due to error.\n";
3137  return -1;
3138  }
3139  if (0 == nRequestNum) {
3140  otOut << strLocation << ": Didn't send getAccountFiles message, but NO "
3141  "error occurred, either. (In this case, SHOULD "
3142  "NEVER HAPPEN. Treating as Error.)\n";
3143  return -1;
3144  }
3145  if (nRequestNum < 0) {
3146  otOut
3147  << strLocation
3148  << ": Unexpected failure sending getAccountFiles. Request number: "
3149  << nRequestNum << "\n";
3150  return -1;
3151  }
3152 
3153  bWasSentAccount = true;
3154  bWasSentInbox = true;
3155 
3156  // -1 for error
3157  // 0 for reply: failure
3158  // 1 for reply: success
3159  //
3160  int32_t nReturn = receiveReplySuccessLowLevel(
3161  serverID, nymID, nRequestNum,
3162  "getInboxAccount"); // <============ RETURN VALUE;
3163  if (nReturn < 0) // error
3164  {
3165  otOut << strLocation << ": Error in getAccountFiles: " << nReturn
3166  << ". (I give up.)\n";
3167  return -1;
3168  }
3169 
3170  // otOut << "IN getInboxAccount " <<
3171  // getLastReplyReceived());
3172 
3173  // BY this point, we definitely have the request number, which means the
3174  // message was actually SENT. (At least.) This also means we can use
3175  // nRequestNum
3176  // later to query for a copy of that sent message.
3177  // Let's go ahead, in this case, and remove that now:
3178  //
3179 
3180  // int32_t nRemovedSentMsg =
3181  // OTAPI_Wrap::RemoveSentMessage(Integer.toString(nRequestNum), serverID,
3182  // nymID);
3183  //
3184  // // NOTE: The above call is unnecessary, since a successful process
3185  // means
3186  // // we already received the successful server reply, and OT's
3187  // "ProcessServerReply"
3188  // // already removed the sent message from the sent buffer (so no need
3189  // to do that here.)
3190  //
3191  // if (nRemovedSentMsg < 1) // (not success.)
3192  // {
3193  // otOut << "getInboxAccount: ERROR:
3194  // OT_API_RemoveSentMessage returned: " << nRemovedSentMsg);
3195  // }
3196 
3197  if (1 != nReturn) {
3198  otOut << strLocation
3199  << ": getAccountFiles failed, returning: " << nReturn << "\n";
3200  return nReturn;
3201  }
3202 
3203  // DOWNLOAD THE BOX RECEIPTS.
3204  if (!insureHaveAllBoxReceipts(serverID, nymID, accountID,
3205  1)) // <===== nBoxType = 1 aka INBOX;
3206  {
3207  otOut << strLocation << ": getAccountFiles succeeded, but then "
3208  "insureHaveAllBoxReceipts failed on the inbox. "
3209  "(I give up.)\n";
3210  return -1;
3211  }
3212 
3213  if (!insureHaveAllBoxReceipts(serverID, nymID, accountID,
3214  2)) // <===== nBoxType = 2 aka OUTBOX;
3215  {
3216  otOut << strLocation << ": getAccountFiles succeeded, but then "
3217  "insureHaveAllBoxReceipts failed on the "
3218  "outbox. (I give up.)\n";
3219  return -1;
3220  }
3221 
3222  return 1;
3223 }
3224 
3225 // Same as the above function, except you only have to pass the accountID.
3226 // (instead of 3 IDs...)
3227 //
3228 OT_UTILITY_OT bool Utility::getInboxOutboxAccount(const string& accountID)
3229 {
3230  bool bForceDownload = false;
3231  return getInboxOutboxAccount(accountID, bForceDownload);
3232 }
3233 
3235  const string& accountID,
3236  bool bForceDownload) // booleanbForceDownload = false;
3237 {
3238  string strLocation = "Utility::getInboxOutboxAccount";
3239 
3240  if (!VerifyStringVal(accountID) || accountID.size() < 10) {
3241  otOut << strLocation << ": invalid accountID: " << accountID << "\n";
3242  return false;
3243  }
3244 
3245  string serverID = OTAPI_Wrap::GetAccountWallet_ServerID(accountID);
3246  string nymID = OTAPI_Wrap::GetAccountWallet_NymID(accountID);
3247  if (!getIntermediaryFiles(serverID, nymID, accountID, bForceDownload)) {
3248  otOut << strLocation << ": getIntermediaryFiles failed. (Returning.)\n";
3249  return false;
3250  }
3251 
3252  return true;
3253 }
3254 
3255 // getInboxAccount()
3256 // Grabs the "Account", which is the intermediary file containing the current
3257 // balance, verified against
3258 // last signed receipt. Server must have your signature on the last balance
3259 // agreement plus, if applicable,
3260 // any inbox receipts (box receipts), also with your signature, in order to
3261 // justify the current balance.
3262 // Any inbox receipts, further, are only valid if they each contain a
3263 // transaction number that was previously
3264 // already signed out to you.
3265 // (As you can see, the "account" is not a list of transactions, as per the
3266 // classical understanding in
3267 // double-entry accounting, but instead it's just a signed balance agreement,
3268 // plus any as-yet-unclosed
3269 // transactions that have cleared since that balance was last signed, and are
3270 // still waiting in the inbox
3271 // for the next balance agreement to be signed when they can be removed.)
3272 
3273 // In addition to the "Account" there is also the Inbox itself, as well as all
3274 // of its box receipts.
3275 // The box receipts are stored in abbreviated form in the Inbox itself, with the
3276 // actual full
3277 // versions in separate files. These are retrieved individually from the server
3278 // after the inbox itself
3279 // is, and then each is verified against a hash kept inside its abbreviated
3280 // version.)
3281 // DONE
3282 OT_UTILITY_OT int32_t
3283  Utility::getInboxAccount(const string& serverID, const string& nymID,
3284  const string& accountID, bool& bWasSentInbox,
3285  bool& bWasSentAccount)
3286 {
3287  bool bForceDownload = false;
3288  return getInboxAccount(serverID, nymID, accountID, bWasSentInbox,
3289  bWasSentAccount, bForceDownload);
3290 }
3291 
3292 // DEPRECATED
3293 OT_UTILITY_OT int32_t
3294  Utility::getInboxAccount_old(const string& serverID, const string& nymID,
3295  const string& accountID, bool& bWasSentInbox,
3296  bool& bWasSentAccount,
3297  bool bForceDownload) // bForceDownload=false
3298 {
3299  string strLocation = "Utility::getInboxAccount_old";
3300 
3301  bWasSentAccount = false;
3302  bWasSentInbox = false;
3303 
3304  //
3305  // (Success means both were downloaded, if necessary.)
3306  //
3307  // FIRST WE DO THE ACCOUNT...
3308  //
3309  // GET ACCOUNT
3310  //
3312 
3313  int32_t nRequestNum = OTAPI_Wrap::getAccount(
3314  serverID, nymID,
3315  accountID); // <===== ATTEMPT TO SEND THE MESSAGE HERE...;
3316 
3317  if ((-2) == nRequestNum) {
3318  otOut << strLocation << ": ERROR, not supported. (-2 was returned.)\n";
3319  return -1; // -2 is also possible at some future date. (If the request
3320  // number won't fit in an int32_t, this is returned and then
3321  // you can retrieve the actual number via a separate call.)
3322  }
3323  if (-1 == nRequestNum) {
3324  otOut << strLocation
3325  << ": Failed to send getAccount message due to error.\n";
3326  return -1;
3327  }
3328  if (0 == nRequestNum) {
3329  otOut << strLocation << ": Didn't send getAccount message, but NO "
3330  "error occurred, either. (In this case, SHOULD "
3331  "NEVER HAPPEN. Treating as Error.)\n";
3332  return -1;
3333  }
3334  if (nRequestNum < 0) {
3335  otOut << strLocation
3336  << ": Unexpected failure sending getAccount(). Request number: "
3337  << nRequestNum << "\n";
3338  return -1;
3339  }
3340 
3341  bWasSentAccount = true;
3342 
3343  // -1 for error
3344  // 0 for reply: failure
3345  // 1 for reply: success
3346  //
3347  int32_t nReturn = receiveReplySuccessLowLevel(
3348  serverID, nymID, nRequestNum,
3349  "getInboxAccount"); // <============ RETURN VALUE;
3350 
3351  // otOut << "IN getInboxAccount " <<
3352  // getLastReplyReceived());
3353 
3354  bool bAccount = 1 == nReturn;
3355 
3356  // BY this point, we definitely have the request number, which means the
3357  // message was actually SENT. (At least.) This also means we can use
3358  // nRequestNum
3359  // later to query for a copy of that sent message.
3360  // Let's go ahead, in this case, and remove that now:
3361  //
3362 
3363  // int32_t nRemovedSentMsg =
3364  // OTAPI_Wrap::RemoveSentMessage(Integer.toString(nRequestNum), serverID,
3365  // nymID);
3366  //
3367  // // NOTE: The above call is unnecessary, since a successful process
3368  // means
3369  // // we already received the successful server reply, and OT's
3370  // "ProcessServerReply"
3371  // // already removed the sent message from the sent buffer (so no need
3372  // to do that here.)
3373  //
3374  // if (nRemovedSentMsg < 1) // (not success.)
3375  // {
3376  // otOut << "getInboxAccount: ERROR:
3377  // OT_API_RemoveSentMessage returned: " << nRemovedSentMsg);
3378  // }
3379 
3380  if (nReturn < 0) // error
3381  {
3382  otOut << strLocation << ": Error in getAccount: " << nReturn
3383  << ". (I give up.)\n";
3384  return -1;
3385  }
3386 
3387  if (!bAccount) {
3388  otOut << strLocation << ": getAccount failed, returning: " << nReturn
3389  << "\n";
3390  return nReturn;
3391  }
3392 
3393  int32_t nReturn2 = getInboxLowLevel(serverID, nymID, accountID,
3394  bWasSentInbox, bForceDownload);
3395 
3396  // If it wasn't sent, and 0 was returned, that means
3397  // no error: we already have the latest inbox. (Nothing done.)
3398  //
3399  if (!bWasSentInbox && (0 == nReturn2)) {
3400  return 0;
3401  }
3402 
3403  if (1 != nReturn2) {
3404  otOut << strLocation
3405  << ": getInboxLowLevel failed. Returning: " << nReturn2 << "\n";
3406  }
3407 
3408  return nReturn2;
3409 }
3410 
3411 // -1 error
3412 // 0 Request NOT sent: But NO error, since hash hasn't changed.
3413 // (bWasSent=false)
3414 // 0 Request WAS sent, reply WAS received:success = = false. (bWasSent=true);
3415 // 1 reply received:success = = true.;
3416 // bWasSent gets set to TRUE once the message is confirmed as sent.
3417 //
3418 // DEPRECATED
3419 OT_UTILITY_OT int32_t
3420  Utility::getInboxLowLevel(const string& serverID, const string& nymID,
3421  const string& accountID, bool& bWasSent)
3422 {
3423  bool bForceDownload = false;
3424  return getInboxLowLevel(serverID, nymID, accountID, bWasSent,
3425  bForceDownload);
3426 }
3427 
3428 // DEPRECATED
3429 OT_UTILITY_OT int32_t
3430  Utility::getInboxLowLevel(const string& serverID, const string& nymID,
3431  const string& accountID, bool& bWasSent,
3432  bool bForce) // bForce defaults to FALSE
3433 {
3434  string strLocation = "Utility::getInboxLowLevel";
3435 
3436  bWasSent = false;
3437 
3438  //
3439  // Use OTAPI_Wrap::GetAccountWallet_InboxHash(ACCT_ID) to see the server's
3440  // most recent inbox hash (on the OTAccount for that box)
3441 
3442  string strRecentHash = OTAPI_Wrap::GetAccountWallet_InboxHash(accountID);
3443  bool bRecentHash = VerifyStringVal(strRecentHash);
3444  if (!bRecentHash) {
3445  otOut << strLocation << ": Warning: Unable to retrieve recent cached "
3446  "copy of server-side InboxHash from "
3447  "client-side nym (perhaps he's never "
3448  "downloaded it before?)\n\n";
3449  }
3450 
3451  //
3452  // Use OTAPI_Wrap::GetNym_InboxHash(ACCT_ID, NYM_ID) to see the client's
3453  // copy of the inbox hash,
3454  // from whenever the client last actually downloaded the inbox.
3455 
3456  string strLocalHash = OTAPI_Wrap::GetNym_InboxHash(accountID, nymID);
3457  bool bLocalHash = VerifyStringVal(strLocalHash);
3458  if (!bLocalHash) {
3459  otOut << strLocation << ": Warning: Unable to retrieve client-side "
3460  "InboxHash for:\n accountID: " << accountID
3461  << "\n nymID: " << nymID << "\n";
3462  }
3463 
3464  if (!bForce) {
3465  // the hashes match -- no need to download anything.
3466  //
3467  if (bLocalHash && bRecentHash && (strRecentHash == strLocalHash)) {
3468  otWarn << strLocation
3469  << ": The hashes already match (skipping Inbox download.)\n";
3470  return 0;
3471  }
3472  }
3473  //
3474  // Now that we dealt with the Inbox Hash, let's do the download!!
3475  //
3477 
3478  int32_t nRequestNum = OTAPI_Wrap::getInbox(
3479  serverID, nymID,
3480  accountID); // <===== ATTEMPT TO SEND THE MESSAGE HERE...;
3481 
3482  if ((-2) == nRequestNum) {
3483  otOut << strLocation << ": ERROR, not supported. (-2 was returned.)\n";
3484  return -1; // -2 is also possible at some future date. (If the request
3485  // number won't fit in an int32_t, this is returned and then
3486  // you can retrieve the actual number via a separate call.)
3487  }
3488  if (-1 == nRequestNum) // if the requestNumber returned by the send-attempt
3489  // is -1, that means it DIDN'T SEND (error)
3490  {
3491  otOut << strLocation
3492  << ": Failed to send getInbox message due to error.\n";
3493  return -1;
3494  }
3495  if (0 == nRequestNum) {
3496  otOut << strLocation << ": Didn't send getInbox message, but NO error "
3497  "occurred, either. (In this case, SHOULD NEVER "
3498  "HAPPEN. Treating as Error.)\n";
3499  return -1; // Even though '0' MEANS "didn't send, but no error" by
3500  // convention in many places, it is actually an impossible
3501  // return value;
3502  }
3503  if (nRequestNum < 0) {
3504  otOut << strLocation << ": Unexpected request number: " << nRequestNum
3505  << "\n";
3506  return -1;
3507  }
3508 
3509  bWasSent = true;
3510 
3511  //
3512  //
3513  int32_t nReturn =
3514  receiveReplySuccessLowLevel(serverID, nymID, nRequestNum, strLocation);
3515  // otOut << "IN getInboxLowLevel " <<
3516  // getLastReplyReceived() << "\n";
3517 
3518  bool bInbox = 1 == nReturn;
3519 
3520  // BY this point, we definitely have the request number, which means the
3521  // message was actually SENT. (At least.) This also means we can use
3522  // nRequestNum
3523  // later to query for a copy of that sent message.
3524  // Let's go ahead, in this case, and remove that now:
3525  //
3526 
3527  // int32_t nRemovedSentMsg =
3528  // OTAPI_Wrap::RemoveSentMessage(Integer.toString(nRequestNum), serverID,
3529  // nymID);
3530  //
3531  // // NOTE: The above call is unnecessary, since a successful process
3532  // means
3533  // // we already received the successful server reply, and OT's
3534  // "ProcessServerReply"
3535  // // already removed the sent message from the sent buffer (so no need
3536  // to do that here.)
3537  //
3538  // if (nRemovedSentMsg < 1)
3539  // {
3540  // otOut << "getInboxLowLevel: ERROR:
3541  // OT_API_RemoveSentMessage returned: " << nRemovedSentMsg <<
3542  // "\n";
3543  // }
3544 
3545  // Now let's make sure we have all the box receipts for this outbox.
3546  // (They will be needed when it is used for something.)
3547  //
3548  int32_t nBoxType = 1;
3549  if (bInbox &&
3550  !insureHaveAllBoxReceipts(serverID, nymID, accountID,
3551  nBoxType)) // <===== nBoxType = 1 aka INBOX;
3552  {
3553  otOut << strLocation << ": getInbox succeeded, but then "
3554  "insureHaveAllBoxReceipts failed. (I give "
3555  "up.)\n";
3556  return -1;
3557  }
3558 
3559  return nReturn;
3560 }
3561 
3562 // -1 error
3563 // 0 Request NOT sent: But NO error, since hash hasn't changed.
3564 // (bWasSent=false)
3565 // 0 Request WAS sent, reply WAS received:success = = false. (bWasSent=true);
3566 // 1 reply received:success = = true.;
3567 // bWasSent gets set to TRUE once the message is confirmed as sent.
3568 //
3569 // DEPRECATED
3570 OT_UTILITY_OT int32_t
3571  Utility::getOutboxLowLevel(const string& serverID, const string& nymID,
3572  const string& accountID, bool& bWasSent)
3573 {
3574  bool bForceDownload = false;
3575  return getOutboxLowLevel(serverID, nymID, accountID, bWasSent,
3576  bForceDownload);
3577 }
3578 
3579 // DEPRECATED
3580 // public static int32_t getOutboxLowLevel(String serverID, String nymID, String
3581 // accountID, OTBool bWasSent, boolean bForce) // bForce defaults to FALSE
3582 OT_UTILITY_OT int32_t
3583  Utility::getOutboxLowLevel(const string& serverID, const string& nymID,
3584  const string& accountID, bool& bWasSent,
3585  bool bForce) // bForce defaults to FALSE
3586 {
3587  bWasSent = false;
3588 
3589  string strLocation = "Utility::getOutboxLowLevel";
3590 
3591  //
3592  // Use OTAPI_Wrap::GetAccountWallet_OutboxHash(ACCT_ID) to see the server's
3593  // most recent outbox hash (on the OTAccount for that box)
3594 
3595  string strRecentHash = OTAPI_Wrap::GetAccountWallet_OutboxHash(accountID);
3596  bool bRecentHash = VerifyStringVal(strRecentHash);
3597  if (!bRecentHash) {
3598  otOut << strLocation << ": Warning: Unable to retrieve recent cached "
3599  "copy of server-side OutboxHash from "
3600  "client-side nym (perhaps he's never "
3601  "downloaded it before?)\n\n";
3602  }
3603 
3604  //
3605  // Use OTAPI_Wrap::GetNym_OutboxHash(ACCT_ID, NYM_ID) to see the client's
3606  // copy of the outbox hash,
3607  // from whenever the client last actually downloaded the outbox.
3608 
3609  string strLocalHash = OTAPI_Wrap::GetNym_OutboxHash(accountID, nymID);
3610  bool bLocalHash = VerifyStringVal(strLocalHash);
3611  if (!bLocalHash) {
3612  otOut << strLocation << ": Warning: Unable to retrieve client-side "
3613  "OutboxHash for:\n accountID: " << accountID
3614  << "\n nymID: " << nymID << "\n";
3615  }
3616 
3617  if (!bForce) {
3618  if (bLocalHash && bRecentHash &&
3619  (strRecentHash == strLocalHash)) // the hashes match -- no need to
3620  // download anything.
3621  {
3622  otWarn
3623  << strLocation
3624  << ": The hashes already match (skipping Outbox download.)\n";
3625  return 0;
3626  }
3627  }
3628 
3629  // Now that we dealt with the Outbox Hash, let's do the download!!
3630  //
3632 
3633  int32_t nRequestNum = OTAPI_Wrap::getOutbox(
3634  serverID, nymID,
3635  accountID); // <===== ATTEMPT TO SEND THE MESSAGE HERE...;
3636  if (-2 == nRequestNum) {
3637  otOut << strLocation << ": ERROR, not supported. (-2 was returned.)\n";
3638  return -1; // -2 is also possible at some future date. (If the request
3639  // number won't fit in an int32_t, this is returned and then
3640  // you can retrieve the actual number via a separate call.)
3641  }
3642  if (-1 == nRequestNum) // if the requestNumber returned by the send-attempt
3643  // is -1, that means it DIDN'T SEND (error)
3644  {
3645  otOut << strLocation
3646  << ": Failed to send getOutbox message due to error.\n";
3647  return -1;
3648  }
3649  if (0 == nRequestNum) {
3650  otOut << strLocation << ": Didn't send getOutbox message, but NO error "
3651  "occurred, either. (In this case, SHOULD NEVER "
3652  "HAPPEN. Treating as Error.)\n";
3653  return -1; // Even though '0' MEANS "didn't send, but no error" by
3654  // convention in many places, it is actually an impossible
3655  // return value;
3656  }
3657  if (nRequestNum < 0) {
3658  otOut << strLocation << ": Unexpected request number: " << nRequestNum
3659  << "\n";
3660  return -1;
3661  }
3662 
3663  bWasSent = true;
3664 
3665  //
3666  //
3667  int32_t nReturn =
3668  receiveReplySuccessLowLevel(serverID, nymID, nRequestNum, strLocation);
3669  // otOut << "IN getOutboxLowLevel " <<
3670  // getLastReplyReceived());
3671 
3672  bool bOutbox = 1 == nReturn;
3673 
3674  // BY this point, we definitely have the request number, which means the
3675  // message was actually SENT. (At least.) This also means we can use
3676  // nRequestNum
3677  // later to query for a copy of that sent message.
3678  // Let's go ahead, in this case, and remove that now:
3679  //
3680 
3681  // int32_t nRemovedSentMsg =
3682  // OTAPI_Wrap::RemoveSentMessage(Integer.toString(nRequestNum), serverID,
3683  // nymID);
3684  //
3685  // // NOTE: The above call is unnecessary, since a successful process
3686  // means
3687  // // we already received the successful server reply, and OT's
3688  // "ProcessServerReply"
3689  // // already removed the sent message from the sent buffer (so no need
3690  // to do that here.)
3691  //
3692  // if (nRemovedSentMsg < 1)
3693  // {
3694  // otOut << "getOutboxLowLevel: ERROR: OT_API_RemoveSentMessage
3695  // returned: " << nRemovedSentMsg << "\n";
3696 
3697  // }
3698 
3699  // Now let's make sure we have all the box receipts for this outbox.
3700  // (They will be needed when it is used for something.)
3701  //
3702  int32_t nBoxType = 2;
3703  if (bOutbox &&
3704  !insureHaveAllBoxReceipts(serverID, nymID, accountID,
3705  nBoxType)) // <===== nBoxType = 2 aka OUTBOX;
3706  {
3707  otOut << strLocation << ": getOutbox succeeded, but then "
3708  "insureHaveAllBoxReceipts failed. (I give "
3709  "up.)\n";
3710  return -1;
3711  }
3712 
3713  return nReturn;
3714 }
3715 
3716 } // namespace opentxs
EXPORT OT_UTILITY_OT int32_t getAndProcessNymbox_3(const std::string &serverID, const std::string &nymID, bool &bWasMsgSent)
EXPORT OT_UTILITY_OT int32_t getNymbox(const std::string &serverID, const std::string &nymID)
static EXPORT std::string GetAccountWallet_NymID(const std::string &ACCOUNT_ID)
Definition: OTAPI.cpp:1052
static EXPORT std::string LoadOutboxNoVerify(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID)
Definition: OTAPI.cpp:1546
static EXPORT std::string GetNym_InboxHash(const std::string &ACCOUNT_ID, const std::string &NYM_ID)
Definition: OTAPI.cpp:676
static EXPORT std::string GetSentMessage(const int64_t &REQUEST_NUMBER, const std::string &SERVER_ID, const std::string &USER_ID)
Definition: OTAPI.cpp:2344
static EXPORT bool DoesBoxReceiptExist(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID, const int32_t &nBoxType, const int64_t &TRANSACTION_NUMBER)
Definition: OTAPI.cpp:566
EXPORT OT_UTILITY_OT int32_t getOutboxLowLevel(const std::string &serverID, const std::string &nymID, const std::string &accountID, bool &bWasSent)
EXPORT OT_UTILITY_OT int32_t getNbrTransactionCount() const
EXPORT OT_UTILITY_OT bool getBoxReceiptWithErrorCorrection(const std::string &serverID, const std::string &nymID, const std::string &accountID, int32_t nBoxType, int64_t strTransactionNum)
EXPORT OT_UTILITY_OT bool getBoxReceiptLowLevel(const std::string &serverID, const std::string &nymID, const std::string &accountID, int32_t nBoxType, int64_t strTransactionNum, bool &bWasSent)
EXPORT OT_UTILITY_OT int32_t getAndProcessNymbox_4(const std::string &serverID, const std::string &nymID, bool &bWasMsgSent, bool bForceDownload)
static EXPORT int32_t Message_GetSuccess(const std::string &THE_MESSAGE)
Definition: OTAPI.cpp:2423
static EXPORT int32_t processNymbox(const std::string &SERVER_ID, const std::string &USER_ID)
Definition: OTAPI.cpp:2230
static EXPORT void FlushMessageBuffer()
Definition: OTAPI.cpp:2339
static EXPORT int64_t ReplyNotice_GetRequestNum(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &THE_TRANSACTION)
Transactions do not have request numbers. However, if you have a.
Definition: OTAPI.cpp:1771
static EXPORT bool Msg_HarvestTransactionNumbers(const std::string &THE_MESSAGE, const std::string &USER_ID, const bool &bHarvestingForRetry, const bool &bReplyWasSuccess, const bool &bReplyWasFailure, const bool &bTransactionWasSuccess, const bool &bTransactionWasFailure)
Definition: OTAPI.cpp:1434
static EXPORT std::string GetNym_RecentHash(const std::string &SERVER_ID, const std::string &NYM_ID)
Definition: OTAPI.cpp:670
static EXPORT std::string GetNym_OutboxHash(const std::string &ACCOUNT_ID, const std::string &NYM_ID)
Definition: OTAPI.cpp:682
EXPORT OT_UTILITY_OT bool insureHaveAllBoxReceipts(const std::string &serverID, const std::string &nymID, const std::string &accountID, int32_t nBoxType)
EXPORT OT_UTILITY_OT std::string getLastReplyReceived() const
OT_UTILITY_OT bool VerifyMessage(const string &strMessage)
EXPORT OT_UTILITY_OT int32_t receiveReplySuccessLowLevel(const std::string &serverID18, const std::string &nymID, int32_t nRequestNumber7, const std::string &IN_FUNCTION)
OTLOG_IMPORT OTLogStream otOut
OTLOG_IMPORT OTLogStream otLog3
static EXPORT int32_t getAccountFiles(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCT_ID)
Definition: OTAPI.cpp:2110
static EXPORT std::string Nymbox_GetReplyNotice(const std::string &SERVER_ID, const std::string &USER_ID, const int64_t &REQUEST_NUMBER)
Definition: OTAPI.cpp:1499
EXPORT OT_UTILITY_OT void delay() const
OT_UTILITY_OT int32_t VerifyMsgBalanceAgrmntSuccess(const string &SERVER_ID, const string &USER_ID, const string &ACCOUNT_ID, const string &strMessage)
static EXPORT bool RemoveSentMessage(const int64_t &REQUEST_NUMBER, const std::string &SERVER_ID, const std::string &USER_ID)
Definition: OTAPI.cpp:2351
OT_UTILITY_OT int32_t VerifyMessageSuccess(const string &strMessage)
EXPORT OT_UTILITY_OT bool getIntermediaryFiles_old(const std::string &serverID, const std::string &nymID, const std::string &accountID, bool bForceDownload)
static EXPORT int32_t getBoxReceipt(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID, const int32_t &nBoxType, const int64_t &TRANSACTION_NUMBER)
Definition: OTAPI.cpp:576
OT_UTILITY_OT int32_t InterpretTransactionMsgReply(const string &SERVER_ID, const string &USER_ID, const string &ACCOUNT_ID, const string &strAttempt, const string &strResponse)
static EXPORT std::string LoadNymboxNoVerify(const std::string &SERVER_ID, const std::string &USER_ID)
Definition: OTAPI.cpp:1519
EXPORT OT_UTILITY_OT int32_t getNymboxLowLevel(const std::string &serverID, const std::string &nymID)
static EXPORT int32_t Ledger_GetCount(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID, const std::string &THE_LEDGER)
Find out how many pending transactions (and receipts) are in this inbox.
Definition: OTAPI.cpp:1615
OT_UTILITY_OT bool VerifyExists(const string &theObjectNameAsStr)
static EXPORT void Sleep(const int64_t &MILLISECONDS)
Definition: OTAPI.cpp:2367
static EXPORT int32_t Message_GetTransactionSuccess(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID, const std::string &THE_MESSAGE)
Definition: OTAPI.cpp:2441
EXPORT OT_UTILITY_OT int32_t getInboxAccount_old(const std::string &serverID, const std::string &nymID, const std::string &accountID, bool &bWasSentInbox, bool &bWasSentAccount, bool bForceDownload)
static EXPORT bool VerifySignature(const std::string &SIGNER_NYM_ID, const std::string &THE_CONTRACT)
Definition: OTAPI.cpp:1006
static EXPORT OTVariable * FindVariable2(const std::string &str_var_name)
Definition: OT_ME.cpp:1146
EXPORT OT_UTILITY_OT int32_t getRequestNumber(const std::string &serverID, const std::string &nymID)
static EXPORT std::string Ledger_GetTransactionByID(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID, const std::string &THE_LEDGER, const int64_t &TRANSACTION_NUMBER)
Definition: OTAPI.cpp:1640
static EXPORT int64_t Ledger_GetTransactionIDByIndex(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID, const std::string &THE_LEDGER, const int32_t &nIndex)
Definition: OTAPI.cpp:1659
static EXPORT std::string GetNym_NymboxHash(const std::string &SERVER_ID, const std::string &NYM_ID)
Definition: OTAPI.cpp:664
EXPORT OT_UTILITY_OT bool getTransactionNumbers(const std::string &serverID, const std::string &nymID)
OTLOG_IMPORT OTLogStream otInfo
static EXPORT int32_t getAccount(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCT_ID)
Definition: OTAPI.cpp:2103
EXPORT OT_UTILITY_OT void setNbrTransactionCount(int32_t new_trans_dl)
OT_UTILITY_OT bool VerifyStringVal(const std::string &nValue)
static EXPORT std::string GetAccountWallet_OutboxHash(const std::string &ACCOUNT_ID)
Definition: OTAPI.cpp:935
static EXPORT int32_t getNymbox(const std::string &SERVER_ID, const std::string &USER_ID)
Definition: OTAPI.cpp:2209
static EXPORT int32_t getTransactionNumber(const std::string &SERVER_ID, const std::string &USER_ID)
Definition: OTAPI.cpp:2169
EXPORT OT_UTILITY_OT std::string ReceiveReplyLowLevel(const std::string &serverID17, const std::string &nymID, int32_t nRequestNumber8, const std::string &IN_FUNCTION)
static EXPORT int32_t getRequest(const std::string &SERVER_ID, const std::string &USER_ID)
Definition: OTAPI.cpp:2069
EXPORT OT_UTILITY_OT int32_t getAndProcessNymbox_8(const std::string &serverID, const std::string &nymID, bool &bWasMsgSent, bool bForceDownload, int32_t nRequestNumber, bool &bFoundNymboxItem, bool bHarvestingForRetry, const OTfourbool &bMsgFoursome)
EXPORT OT_UTILITY_OT int32_t processNymbox(const std::string &serverID, const std::string &nymID, bool &bWasMsgSent, int32_t &nMsgSentRequestNumOut, int32_t &nReplySuccessOut, int32_t &nBalanceSuccessOut, int32_t &nTransSuccessOut)
OTLOG_IMPORT OTLogStream otWarn
OT_UTILITY_OT int32_t VerifyMsgTrnxSuccess(const string &SERVER_ID, const string &USER_ID, const string &ACCOUNT_ID, const string &strMessage)
static EXPORT void FlushSentMessages(const bool &bHarvestingForRetry, const std::string &SERVER_ID, const std::string &USER_ID, const std::string &THE_NYMBOX)
Definition: OTAPI.cpp:2358
EXPORT OT_UTILITY_OT int32_t sendProcessNymboxLowLevel(const std::string &serverID, const std::string &nymID) const
std::array< bool, 4 > OTfourbool
EXPORT OT_UTILITY_OT void setLastReplyReceived(const std::string &strReply)
EXPORT OT_UTILITY_OT int32_t getInboxAccount(const std::string &serverID, const std::string &nymID, const std::string &accountID, bool &bWasSentInbox, bool &bWasSentAccount)
static EXPORT std::string Message_GetNymboxHash(const std::string &THE_MESSAGE)
Definition: OTAPI.cpp:2418
EXPORT OT_UTILITY_OT int32_t getInboxLowLevel(const std::string &serverID, const std::string &nymID, const std::string &accountID, bool &bWasSent)
static EXPORT int32_t getOutbox(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCT_ID)
Definition: OTAPI.cpp:2215
static EXPORT std::string PopMessageBuffer(const int64_t &REQUEST_NUMBER, const std::string &SERVER_ID, const std::string &USER_ID)
Definition: OTAPI.cpp:2332
EXPORT OT_UTILITY_OT bool getIntermediaryFiles(const std::string &serverID, const std::string &nymID, const std::string &accountID)
#define OT_UTILITY_OT
EXPORT OT_UTILITY_OT Utility()
static EXPORT std::string GetAccountWallet_InboxHash(const std::string &ACCOUNT_ID)
Definition: OTAPI.cpp:929
EXPORT OT_UTILITY_OT void longDelay() const
static EXPORT int32_t getInbox(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCT_ID)
Definition: OTAPI.cpp:2202
EXPORT OT_UTILITY_OT int32_t getTransactionNumLowLevel(const std::string &serverID, const std::string &nymID, bool &bWasSent)
EXPORT OT_UTILITY_OT bool getInboxOutboxAccount(const std::string &accountID)
static EXPORT std::string LoadInboxNoVerify(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID)
These versions don&#39;t verify the ledger, they just load it up.
Definition: OTAPI.cpp:1532
EXPORT OT_UTILITY_OT ~Utility()
static EXPORT bool HaveAlreadySeenReply(const std::string &SERVER_ID, const std::string &USER_ID, const int64_t &REQUEST_NUMBER)
Definition: OTAPI.cpp:1506
static EXPORT std::string GetAccountWallet_ServerID(const std::string &ACCOUNT_ID)
Definition: OTAPI.cpp:1047
static EXPORT std::string Transaction_GetType(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID, const std::string &THE_TRANSACTION)
Get Transaction Type (internally uses GetTransactionTypeString().)
Definition: OTAPI.cpp:1762
static EXPORT int32_t Message_GetBalanceAgreementSuccess(const std::string &SERVER_ID, const std::string &USER_ID, const std::string &ACCOUNT_ID, const std::string &THE_MESSAGE)
Definition: OTAPI.cpp:1813