Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PayDividendVisitor.cpp
Go to the documentation of this file.
1 /************************************************************
2  *
3  * PayDividendVisitor.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 "PayDividendVisitor.hpp"
134 #include "OTServer.hpp"
135 
137 #include <opentxs/core/OTCheque.hpp>
138 #include <opentxs/core/OTLog.hpp>
139 #include <opentxs/core/OTString.hpp>
140 #include <opentxs/ext/OTPayment.hpp>
141 
142 namespace opentxs
143 {
144 
146  const OTIdentifier& theServerID, const OTIdentifier& theUserID,
147  const OTIdentifier& thePayoutAssetID, const OTIdentifier& theVoucherAcctID,
148  const OTString& strMemo, OTServer& theServer, int64_t lPayoutPerShare,
149  mapOfAccounts* pLoadedAccounts)
150  : AccountVisitor(theServerID, pLoadedAccounts)
151  , m_pUserID(new OTIdentifier(theUserID))
152  , m_pPayoutAssetID(new OTIdentifier(thePayoutAssetID))
153  , m_pVoucherAcctID(new OTIdentifier(theVoucherAcctID))
154  , m_pstrMemo(new OTString(strMemo))
155  , m_pServer(&theServer)
156  , m_lPayoutPerShare(lPayoutPerShare)
157  , m_lAmountPaidOut(0)
158  , m_lAmountReturned(0)
159 {
160 }
161 
163 {
164  if (nullptr != m_pUserID) delete m_pUserID;
165  m_pUserID = nullptr;
166  if (nullptr != m_pPayoutAssetID) delete m_pPayoutAssetID;
167  m_pPayoutAssetID = nullptr;
168  if (nullptr != m_pVoucherAcctID) delete m_pVoucherAcctID;
169  m_pVoucherAcctID = nullptr;
170  if (nullptr != m_pstrMemo) delete m_pstrMemo;
171  m_pstrMemo = nullptr;
172  m_pServer = nullptr; // don't delete this one (I don't own it.)
173  m_lPayoutPerShare = 0;
174  m_lAmountPaidOut = 0;
175  m_lAmountReturned = 0;
176 }
177 
178 // For each "simple" account of a specific asset type, this function
179 // is called in order to pay a dividend to the Nym who owns that account.
180 
181 // PayDividendVisitor::Trigger() is used in
182 // OTAssetContract::VisitAccountRecords()
183 // cppcheck-suppress unusedFunction
185  OTAccount& theSharesAccount) // theSharesAccount is, say, a Pepsi shares
186  // account. Here, we'll send a dollars voucher
187  // to its owner.
188 {
189  const int64_t lPayoutAmount =
190  (theSharesAccount.GetBalance() * GetPayoutPerShare());
191 
192  if (lPayoutAmount <= 0) {
193  OTLog::Output(0, "PayDividendVisitor::Trigger: nothing to pay, "
194  "since this account owns no shares. (Returning "
195  "true.)");
196  return true; // nothing to pay, since this account owns no shares.
197  // Success!
198  }
199  OT_ASSERT(nullptr != GetServerID());
200  const OTIdentifier& theServerID = *(GetServerID());
201  OT_ASSERT(nullptr != GetPayoutAssetID());
202  const OTIdentifier& thePayoutAssetID = *(GetPayoutAssetID());
203  OT_ASSERT(nullptr != GetVoucherAcctID());
204  const OTIdentifier& theVoucherAcctID = *(GetVoucherAcctID());
205  OT_ASSERT(nullptr != GetServer());
206  OTServer& theServer = *(GetServer());
207  OTPseudonym& theServerNym =
208  const_cast<OTPseudonym&>(theServer.GetServerNym());
209  const OTIdentifier theServerNymID(theServerNym);
210  const OTIdentifier& RECIPIENT_ID = theSharesAccount.GetUserID();
211  OT_ASSERT(nullptr != GetUserID());
212  const OTIdentifier& theSenderUserID = *(GetUserID());
213  OT_ASSERT(nullptr != GetMemo());
214  const OTString& strMemo = *(GetMemo());
215  // Note: theSenderUserID is the originator of the Dividend Payout.
216  // However, all the actual vouchers will be from "the server Nym" and
217  // not from theSenderUserID. So then why is it even here? Because anytime
218  // there's an error, the server will send to theSenderUserID instead of
219  // RECIPIENT_ID (so the original sender can have his money back, instead of
220  // just having it get lost in the ether.)
221  bool bReturnValue = false;
222 
223  OTCheque theVoucher(theServerID, thePayoutAssetID);
224 
225  // 10 minutes == 600 Seconds
226  // 1 hour == 3600 Seconds
227  // 1 day == 86400 Seconds
228  // 30 days == 2592000 Seconds
229  // 3 months == 7776000 Seconds
230  // 6 months == 15552000 Seconds
231 
232  const time64_t VALID_FROM =
233  OTTimeGetCurrentTime(); // This time is set to TODAY NOW
234  const time64_t VALID_TO = OTTimeAddTimeInterval(
235  VALID_FROM, OTTimeGetSecondsFromTime(
236  OT_TIME_SIX_MONTHS_IN_SECONDS)); // This time occurs in
237  // 180 days (6 months).
238  // Todo hardcoding.
239 
240  int64_t lNewTransactionNumber = 0;
241 
242  bool bGotNextTransNum = theServer.transactor_.issueNextTransactionNumber(
243  theServerNym, lNewTransactionNumber); // bStoreTheNumber defaults to
244  // true. We save the transaction
245  // number on the server Nym (normally we'd discard it) because
246  // when the cheque is deposited, the server nym, as the owner of
247  // the voucher account, needs to verify the transaction # on the
248  // cheque (to prevent double-spending of cheques.)
249  if (bGotNextTransNum) {
250  const bool bIssueVoucher = theVoucher.IssueCheque(
251  lPayoutAmount, // The amount of the cheque.
252  lNewTransactionNumber, // Requiring a transaction number prevents
253  // double-spending of cheques.
254  VALID_FROM, // The expiration date (valid from/to dates) of the
255  // cheque
256  VALID_TO, // Vouchers are automatically starting today and lasting 6
257  // months.
258  theVoucherAcctID, // The asset account the cheque is drawn on.
259  theServerNymID, // User ID of the sender (in this case the server
260  // nym.)
261  strMemo, // Optional memo field. Includes item note and request
262  // memo.
263  &RECIPIENT_ID);
264 
265  // All account crediting / debiting happens in the caller, in OTServer.
266  // (AND it happens only ONCE, to cover ALL vouchers.)
267  // Then in here, the voucher either gets send to the recipient, or if
268  // error, sent back home to
269  // the issuer Nym. (ALL the funds are removed, then the vouchers are
270  // sent one way or the other.)
271  // Any returned vouchers, obviously serve to notify the dividend payer
272  // of where the errors were
273  // (as well as give him the opportunity to get his money back.)
274  //
275  bool bSent = false;
276  if (bIssueVoucher) {
277  // All this does is set the voucher's internal contract string to
278  // "VOUCHER" instead of "CHEQUE". We also set the server itself as
279  // the remitter, which is unusual for vouchers, but necessary in the
280  // case of dividends.
281  //
282  theVoucher.SetAsVoucher(theServerNymID, theVoucherAcctID);
283  theVoucher.SignContract(theServerNym);
284  theVoucher.SaveContract();
285 
286  // Send the voucher to the payments inbox of the recipient.
287  //
288  const OTString strVoucher(theVoucher);
289  OTPayment thePayment(strVoucher);
290 
291  // calls DropMessageToNymbox
292  bSent = theServer.SendInstrumentToNym(
293  theServerID, theServerNymID, // sender nym
294  RECIPIENT_ID, // recipient nym
295  nullptr, &thePayment, "payDividend"); // todo: hardcoding.
296  bReturnValue = bSent; // <======= RETURN VALUE.
297  if (bSent)
298  m_lAmountPaidOut +=
299  lPayoutAmount; // At the end of iterating all accounts, if
300  // m_lAmountPaidOut is less than
301  // lTotalPayoutAmount, then we return to rest
302  // to the sender.
303  }
304  else {
305  const OTString strPayoutAssetID(thePayoutAssetID),
306  strRecipientUserID(RECIPIENT_ID);
307  OTLog::vError("PayDividendVisitor::Trigger: ERROR failed "
308  "issuing voucher (to send to dividend payout "
309  "recipient.) "
310  "WAS TRYING TO PAY %ld of asset type %s to Nym %s.\n",
311  lPayoutAmount, strPayoutAssetID.Get(),
312  strRecipientUserID.Get());
313  }
314  // If we didn't send it, then we need to return the funds to where they
315  // came from.
316  //
317  if (!bSent) {
318  OTCheque theReturnVoucher(theServerID, thePayoutAssetID);
319 
320  const bool bIssueReturnVoucher = theReturnVoucher.IssueCheque(
321  lPayoutAmount, // The amount of the cheque.
322  lNewTransactionNumber, // Requiring a transaction number
323  // prevents double-spending of cheques.
324  VALID_FROM, // The expiration date (valid from/to dates) of the
325  // cheque
326  VALID_TO, // Vouchers are automatically starting today and
327  // lasting 6 months.
328  theVoucherAcctID, // The asset account the cheque is drawn on.
329  theServerNymID, // User ID of the sender (in this case the
330  // server nym.)
331  strMemo, // Optional memo field. Includes item note and request
332  // memo.
333  &theSenderUserID); // We're returning the money to its original
334  // sender.
335  if (bIssueReturnVoucher) {
336  // All this does is set the voucher's internal contract string
337  // to
338  // "VOUCHER" instead of "CHEQUE".
339  //
340  theReturnVoucher.SetAsVoucher(theServerNymID, theVoucherAcctID);
341  theReturnVoucher.SignContract(theServerNym);
342  theReturnVoucher.SaveContract();
343 
344  // Return the voucher back to the payments inbox of the original
345  // sender.
346  //
347  const OTString strReturnVoucher(theReturnVoucher);
348  OTPayment theReturnPayment(strReturnVoucher);
349 
350  // calls DropMessageToNymbox
351  bSent = theServer.SendInstrumentToNym(
352  theServerID, theServerNymID, // sender nym
353  theSenderUserID, // recipient nym (original sender.)
354  nullptr, &theReturnPayment,
355  "payDividend"); // todo: hardcoding.
356  if (bSent)
357  m_lAmountReturned +=
358  lPayoutAmount; // At the end of iterating all accounts,
359  // if m_lAmountPaidOut+m_lAmountReturned
360  // is less than lTotalPayoutAmount, then
361  // we return the rest to the sender.
362  }
363  else {
364  const OTString strPayoutAssetID(thePayoutAssetID),
365  strSenderUserID(theSenderUserID);
366  OTLog::vError("PayDividendVisitor::Trigger: ERROR "
367  "failed issuing voucher (to return back to "
368  "the dividend payout initiator, after a failed "
369  "payment attempt to the originally intended "
370  "recipient.) WAS TRYING TO PAY %ld of asset type "
371  "%s to Nym %s.\n",
372  lPayoutAmount, strPayoutAssetID.Get(),
373  strSenderUserID.Get());
374  }
375  } // if !bSent
376  }
377  else // !bGotNextTransNum
378  {
379  const OTString strPayoutAssetID(thePayoutAssetID),
380  strRecipientUserID(RECIPIENT_ID);
382  "PayDividendVisitor::Trigger: ERROR!! Failed issuing next "
383  "transaction "
384  "number while trying to send a voucher (while paying dividends.) "
385  "WAS TRYING TO PAY %ld of asset type %s to Nym %s.\n",
386  lPayoutAmount, strPayoutAssetID.Get(), strRecipientUserID.Get());
387  }
388 
389  return bReturnValue;
390 }
391 
392 } // namespace opentxs
static EXPORT void vError(const char *szError,...)
Definition: OTLog.cpp:800
static EXPORT void Output(int32_t nVerbosity, const char *szOutput)
Definition: OTLog.cpp:710
bool issueNextTransactionNumber(OTPseudonym &nym, int64_t &txNumber, bool storeNumber=true)
Definition: Transactor.cpp:211
EXPORT int64_t GetBalance() const
Definition: OTAccount.cpp:664
EXPORT bool SaveContract()
time64_t OTTimeAddTimeInterval(time64_t lhs, int64_t rhs)
Definition: Common.hpp:238
virtual bool Trigger(OTAccount &theAccount)
int64_t time64_t
Definition: Common.hpp:209
#define OT_TIME_SIX_MONTHS_IN_SECONDS
Definition: Common.hpp:170
PayDividendVisitor(const OTIdentifier &theServerID, const OTIdentifier &theUserID, const OTIdentifier &thePayoutAssetID, const OTIdentifier &theVoucherAcctID, const OTString &strMemo, OTServer &theServer, int64_t lPayoutPerShare, mapOfAccounts *pLoadedAccounts=nullptr)
time64_t OTTimeGetCurrentTime()
Definition: Common.hpp:211
const OTPseudonym & GetServerNym() const
Definition: OTServer.cpp:345
#define OT_ASSERT(x)
Definition: Assert.hpp:150
std::map< std::string, OTAccount * > mapOfAccounts
Definition: OTWallet.hpp:157
void SetAsVoucher(const OTIdentifier &remitterUserID, const OTIdentifier &remitterAcctID)
Definition: OTCheque.hpp:160
EXPORT bool IssueCheque(const int64_t &lAmount, const int64_t &lTransactionNum, const time64_t &VALID_FROM, const time64_t &VALID_TO, const OTIdentifier &SENDER_ACCT_ID, const OTIdentifier &SENDER_USER_ID, const OTString &strMemo, const OTIdentifier *pRECIPIENT_USER_ID=nullptr)
Definition: OTCheque.cpp:322
EXPORT const char * Get() const
Definition: OTString.cpp:1045
virtual EXPORT bool SignContract(const OTPseudonym &theNym, const OTPasswordData *pPWData=nullptr)
Definition: OTContract.cpp:484
const OTIdentifier & GetUserID() const
int64_t OTTimeGetSecondsFromTime(time64_t time)
Definition: Common.hpp:230
EXPORT OTIdentifier * GetServerID()