Master Core  v0.0.9 - 2abfd2849db8ba7a83957c64eb976b406713c123
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
mastercore_tx.cpp
Go to the documentation of this file.
1 // Master Protocol transaction code
2 
3 #include "base58.h"
4 #include "rpcserver.h"
5 #include "init.h"
6 #include "util.h"
7 #include "wallet.h"
8 
9 #include <stdint.h>
10 #include <string.h>
11 #include <map>
12 
13 #include <fstream>
14 #include <algorithm>
15 
16 #include <vector>
17 
18 #include <utility>
19 #include <string>
20 
21 #include <boost/assign/list_of.hpp>
22 #include <boost/algorithm/string.hpp>
23 #include <boost/algorithm/string/find.hpp>
24 #include <boost/algorithm/string/join.hpp>
25 #include <boost/lexical_cast.hpp>
26 #include <boost/format.hpp>
27 #include <boost/filesystem.hpp>
28 #include "json/json_spirit_utils.h"
29 #include "json/json_spirit_value.h"
30 
31 #include "leveldb/db.h"
32 #include "leveldb/write_batch.h"
33 
34 #include <openssl/sha.h>
35 
36 #include <boost/multiprecision/cpp_int.hpp>
37 
38 using boost::multiprecision::int128_t;
39 using boost::multiprecision::cpp_int;
40 using namespace std;
41 using namespace boost;
42 using namespace boost::assign;
43 using namespace json_spirit;
44 using namespace leveldb;
45 
46 #include "mastercore.h"
47 
48 using namespace mastercore;
49 
50 #include "mastercore_convert.h"
51 #include "mastercore_dex.h"
52 #include "mastercore_tx.h"
53 #include "mastercore_sp.h"
54 
55 // initial packet interpret step
57 {
58  if (PACKET_SIZE_CLASS_A > pkt_size) // class A could be 19 bytes
59  {
60  file_log("%s() ERROR PACKET TOO SMALL; size = %d, line %d, file: %s\n", __FUNCTION__, pkt_size, __LINE__, __FILE__);
61  return -(PKT_ERROR -1);
62  }
63 
64  // collect version
65  memcpy(&version, &pkt[0], 2);
66  swapByteOrder16(version);
67 
68  // blank out version bytes in the packet
69  pkt[0]=0; pkt[1]=0;
70 
71  memcpy(&type, &pkt[0], 4);
72 
73  swapByteOrder32(type);
74 
75  file_log("version: %d, Class %s\n", version, !multi ? "A":"B");
76  file_log("\t type: %u (%s)\n", type, c_strMasterProtocolTXType(type));
77 
78  return (type);
79 }
80 
81 // extract alert info for alert packets
82 int CMPTransaction::step2_Alert(std::string *new_global_alert_message)
83 {
84  const char *p = 4 + (char *)&pkt;
85  std::vector<std::string>spstr;
86  char alertString[SP_STRING_FIELD_LEN];
87 
88  // is sender authorized?
89  bool authorized = false;
90  if (
91  (sender=="mMichaelsAddress") || // Michael
92  (sender=="mfaiZGBkY4mBqt3PHPD2qWgbaafGa7vR64") || //Faiz
93  (sender=="mCraigAddress") || // Craig
94  (sender=="mpZATHupfCLqet5N1YL48ByCM1ZBfddbGJ") //Zathras
95  ) authorized = true;
96 
97  if(!authorized)
98  {
99  // not authorized, ignore alert
100  file_log("\t alert auth: false\n");
101  return (PKT_ERROR -912);
102  }
103  else
104  {
105  // authorized, decode and make sure there are 4 tokens, then replace global_alert_message
106  spstr.push_back(std::string(p));
107  memcpy(alertString, spstr[0].c_str(), std::min(spstr[0].length(),sizeof(alertString)-1));
108 
109  std::vector<std::string> vstr;
110  boost::split(vstr, alertString, boost::is_any_of(":"), token_compress_on);
111  file_log("\t alert auth: true\n");
112  file_log("\t alert sender: %s\n", sender);
113 
114  if (5 != vstr.size())
115  {
116  // there are not 5 tokens in the alert, badly formed alert and must discard
117  file_log("\t packet error: badly formed alert != 5 tokens\n");
118  return (PKT_ERROR -911);
119  }
120  else
121  {
122  int32_t alertType;
123  uint64_t expiryValue;
124  uint32_t typeCheck;
125  uint32_t verCheck;
126  string alertMessage;
127  try
128  {
129  alertType = boost::lexical_cast<int32_t>(vstr[0]);
130  expiryValue = boost::lexical_cast<uint64_t>(vstr[1]);
131  typeCheck = boost::lexical_cast<uint32_t>(vstr[2]);
132  verCheck = boost::lexical_cast<uint32_t>(vstr[3]);
133  } catch (const boost::bad_lexical_cast &e)
134  {
135  file_log("DEBUG ALERT - error in converting values from global alert string\n");
136  return (PKT_ERROR -910); //(something went wrong)
137  }
138  alertMessage = vstr[4];
139  file_log("\t message type: %llu\n",alertType);
140  file_log("\t expiry value: %llu\n",expiryValue);
141  file_log("\t type check: %llu\n",typeCheck);
142  file_log("\t ver check: %llu\n",verCheck);
143  file_log("\t alert message: %s\n", alertMessage);
144  // copy the alert string into the global_alert_message and return a 0 rc
145  string message(alertString);
146  *new_global_alert_message=message;
147  return 0;
148  }
149  }
150 }
151 
152 // extract Value for certain types of packets
154 {
155  memcpy(&nValue, &pkt[8], 8);
156  swapByteOrder64(nValue);
157 
158  // here we are copying nValue into nNewValue to be stored into our leveldb later: MP_txlist
159  nNewValue = nValue;
160 
161  memcpy(&property, &pkt[4], 4);
162  swapByteOrder32(property);
163 
164  file_log("\t property: %u (%s)\n", property, strMPProperty(property));
165  file_log("\t value: %s\n", FormatMP(property, nValue));
166 
167  if (MAX_INT_8_BYTES < nValue)
168  {
169  return (PKT_ERROR -801); // out of range
170  }
171 
172  return 0;
173 }
174 
175 // overrun check, are we beyond the end of packet?
176 bool CMPTransaction::isOverrun(const char *p, unsigned int line)
177 {
178 int now = (char *)p - (char *)&pkt;
179 bool bRet = (now > pkt_size);
180 
181  if (bRet) file_log("%s(%sline=%u):now= %u, pkt_size= %u\n", __FUNCTION__, bRet ? "OVERRUN !!! ":"", line, now, pkt_size);
182 
183  return bRet;
184 }
185 
186 // extract Smart Property data
187 // RETURNS: the pointer to the next piece to be parsed
188 // ERROR is returns NULL and/or sets the error_code
189 const char *CMPTransaction::step2_SmartProperty(int &error_code)
190 {
191 const char *p = 11 + (char *)&pkt;
192 std::vector<std::string>spstr;
193 unsigned int i;
194 unsigned int prop_id;
195 
196  error_code = 0;
197 
198  memcpy(&ecosystem, &pkt[4], 1);
199  file_log("\t Ecosystem: %u\n", ecosystem);
200 
201  // valid values are 1 & 2
202  if ((OMNI_PROPERTY_MSC != ecosystem) && (OMNI_PROPERTY_TMSC != ecosystem))
203  {
204  error_code = (PKT_ERROR_SP -501);
205  return NULL;
206  }
207 
208  prop_id = _my_sps->peekNextSPID(ecosystem);
209 
210  memcpy(&prop_type, &pkt[5], 2);
211  swapByteOrder16(prop_type);
212 
213  memcpy(&prev_prop_id, &pkt[7], 4);
214  swapByteOrder32(prev_prop_id);
215 
216  file_log("\t Property ID: %u (%s)\n", prop_id, strMPProperty(prop_id));
217  file_log("\t Property type: %u (%s)\n", prop_type, c_strPropertyType(prop_type));
218  file_log("\tPrev Property ID: %u\n", prev_prop_id);
219 
220  // only 1 & 2 are valid right now
221  if ((MSC_PROPERTY_TYPE_INDIVISIBLE != prop_type) && (MSC_PROPERTY_TYPE_DIVISIBLE != prop_type))
222  {
223  error_code = (PKT_ERROR_SP -502);
224  return NULL;
225  }
226 
227  for (i = 0; i<5; i++)
228  {
229  spstr.push_back(std::string(p));
230  p += spstr.back().size() + 1;
231  }
232 
233  i = 0;
234 
235  memcpy(category, spstr[i].c_str(), std::min(spstr[i].length(),sizeof(category)-1)); i++;
236  memcpy(subcategory, spstr[i].c_str(), std::min(spstr[i].length(),sizeof(subcategory)-1)); i++;
237  memcpy(name, spstr[i].c_str(), std::min(spstr[i].length(),sizeof(name)-1)); i++;
238  memcpy(url, spstr[i].c_str(), std::min(spstr[i].length(),sizeof(url)-1)); i++;
239  memcpy(data, spstr[i].c_str(), std::min(spstr[i].length(),sizeof(data)-1)); i++;
240 
241  file_log("\t Category: %s\n", category);
242  file_log("\t Subcategory: %s\n", subcategory);
243  file_log("\t Name: %s\n", name);
244  file_log("\t URL: %s\n", url);
245  file_log("\t Data: %s\n", data);
246 
247  if (!isTransactionTypeAllowed(block, prop_id, type, version))
248  {
249  error_code = (PKT_ERROR_SP -503);
250  return NULL;
251  }
252 
253  // name can not be NULL
254  if ('\0' == name[0])
255  {
256  error_code = (PKT_ERROR_SP -505);
257  return NULL;
258  }
259 
260  if (!p) error_code = (PKT_ERROR_SP -510);
261 
262  if (isOverrun(p, __LINE__))
263  {
264  error_code = (PKT_ERROR_SP -800);
265  return NULL;
266  }
267 
268  return p;
269 }
270 
272 {
273  if (!p) return (PKT_ERROR_SP -1);
274 
275  memcpy(&nValue, p, 8);
276  swapByteOrder64(nValue);
277  p += 8;
278 
279  // here we are copying nValue into nNewValue to be stored into our leveldb later: MP_txlist
280  nNewValue = nValue;
281 
282  if (MSC_PROPERTY_TYPE_INDIVISIBLE == prop_type)
283  {
284  file_log("\t value: %lu\n", nValue);
285  if (0 == nValue) return (PKT_ERROR_SP -101);
286  }
287  else
288  if (MSC_PROPERTY_TYPE_DIVISIBLE == prop_type)
289  {
290  file_log("\t value: %lu.%08lu\n", nValue/COIN, nValue%COIN);
291  if (0 == nValue) return (PKT_ERROR_SP -102);
292  }
293 
294  if (MAX_INT_8_BYTES < nValue)
295  {
296  return (PKT_ERROR -802); // out of range
297  }
298 
299  if (isOverrun(p, __LINE__)) return (PKT_ERROR_SP -900);
300 
301  return 0;
302 }
303 
305 {
306  if (!p) return (PKT_ERROR_SP -1);
307 
308  memcpy(&property, p, 4); // property desired
309  swapByteOrder32(property);
310  p += 4;
311 
312  file_log("\t property: %u (%s)\n", property, strMPProperty(property));
313 
314  memcpy(&nValue, p, 8);
315  swapByteOrder64(nValue);
316  p += 8;
317 
318  // here we are copying nValue into nNewValue to be stored into our leveldb later: MP_txlist
319  nNewValue = nValue;
320 
321  if (MSC_PROPERTY_TYPE_INDIVISIBLE == prop_type)
322  {
323  file_log("\t value: %lu\n", nValue);
324  if (0 == nValue) return (PKT_ERROR_SP -201);
325  }
326  else
327  if (MSC_PROPERTY_TYPE_DIVISIBLE == prop_type)
328  {
329  file_log("\t value: %lu.%08lu\n", nValue/COIN, nValue%COIN);
330  if (0 == nValue) return (PKT_ERROR_SP -202);
331  }
332 
333  if (MAX_INT_8_BYTES < nValue)
334  {
335  return (PKT_ERROR -803); // out of range
336  }
337 
338  memcpy(&deadline, p, 8);
339  swapByteOrder64(deadline);
340  p += 8;
341  file_log("\t Deadline: %s (%lX)\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", deadline), deadline);
342 
343  if (!deadline) return (PKT_ERROR_SP -203); // deadline cannot be 0
344 
345  // deadline can not be smaller than the timestamp of the current block
346  if (deadline < (uint64_t)blockTime) return (PKT_ERROR_SP -204);
347 
348  memcpy(&early_bird, p++, 1);
349  file_log("\tEarly Bird Bonus: %u\n", early_bird);
350 
351  memcpy(&percentage, p++, 1);
352  file_log("\t Percentage: %u\n", percentage);
353 
354  if (isOverrun(p, __LINE__)) return (PKT_ERROR_SP -765);
355 
356  return 0;
357 }
358 
360 {
361  fprintf(fp, "BLOCK: %d txid: %s, Block Time: %s\n", block, txid.GetHex().c_str(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", blockTime).c_str());
362  fprintf(fp, "sender: %s\n", sender.c_str());
363 }
364 
366 {
367 int rc = PKT_ERROR_TRADEOFFER;
368 uint64_t amount_desired, min_fee;
369 unsigned char blocktimelimit, subaction = 0;
370 static const char * const subaction_name[] = { "empty", "new", "update", "cancel" };
371 
372  if ((OMNI_PROPERTY_TMSC != property) && (OMNI_PROPERTY_MSC != property))
373  {
374  file_log("No smart properties allowed on the DeX...\n");
375  return PKT_ERROR_TRADEOFFER -72;
376  }
377 
378  // block height checks, for instance DEX is only available on MSC starting with block 290630
379  if (!isTransactionTypeAllowed(block, property, type, version)) return -88888;
380 
381  memcpy(&amount_desired, &pkt[16], 8);
382  memcpy(&blocktimelimit, &pkt[24], 1);
383  memcpy(&min_fee, &pkt[25], 8);
384  memcpy(&subaction, &pkt[33], 1);
385 
386  swapByteOrder64(amount_desired);
387  swapByteOrder64(min_fee);
388 
389  file_log("\t amount desired: %lu.%08lu\n", amount_desired / COIN, amount_desired % COIN);
390  file_log("\tblock time limit: %u\n", blocktimelimit);
391  file_log("\t min fee: %lu.%08lu\n", min_fee / COIN, min_fee % COIN);
392  file_log("\t sub-action: %u (%s)\n", subaction, subaction < sizeof(subaction_name)/sizeof(subaction_name[0]) ? subaction_name[subaction] : "");
393 
394  if (obj_o)
395  {
396  obj_o->Set(amount_desired, min_fee, blocktimelimit, subaction);
397  return PKT_RETURNED_OBJECT;
398  }
399 
400  // figure out which Action this is based on amount for sale, version & etc.
401  switch (version)
402  {
403  case MP_TX_PKT_V0:
404  if (0 != nValue)
405  {
406  if (!DEx_offerExists(sender, property))
407  {
408  rc = DEx_offerCreate(sender, property, nValue, block, amount_desired, min_fee, blocktimelimit, txid, &nNewValue);
409  }
410  else
411  {
412  rc = DEx_offerUpdate(sender, property, nValue, block, amount_desired, min_fee, blocktimelimit, txid, &nNewValue);
413  }
414  }
415  else
416  // what happens if nValue is 0 for V0 ? ANSWER: check if exists and it does -- cancel, otherwise invalid
417  {
418  if (DEx_offerExists(sender, property))
419  {
420  rc = DEx_offerDestroy(sender, property);
421  }
422  }
423 
424  break;
425 
426  case MP_TX_PKT_V1:
427  {
428  if (DEx_offerExists(sender, property))
429  {
430  if ((CANCEL != subaction) && (UPDATE != subaction))
431  {
432  file_log("%s() INVALID SELL OFFER -- ONE ALREADY EXISTS\n", __FUNCTION__);
433  rc = PKT_ERROR_TRADEOFFER -11;
434  break;
435  }
436  }
437  else
438  {
439  // Offer does not exist
440  if ((NEW != subaction))
441  {
442  file_log("%s() INVALID SELL OFFER -- UPDATE OR CANCEL ACTION WHEN NONE IS POSSIBLE\n", __FUNCTION__);
443  rc = PKT_ERROR_TRADEOFFER -12;
444  break;
445  }
446  }
447 
448  switch (subaction)
449  {
450  case NEW:
451  rc = DEx_offerCreate(sender, property, nValue, block, amount_desired, min_fee, blocktimelimit, txid, &nNewValue);
452  break;
453 
454  case UPDATE:
455  rc = DEx_offerUpdate(sender, property, nValue, block, amount_desired, min_fee, blocktimelimit, txid, &nNewValue);
456  break;
457 
458  case CANCEL:
459  rc = DEx_offerDestroy(sender, property);
460  break;
461 
462  default:
463  rc = (PKT_ERROR -999);
464  break;
465  }
466  break;
467  }
468 
469  default:
470  rc = (PKT_ERROR -500); // neither V0 nor V1
471  break;
472  };
473 
474  return rc;
475 }
476 
478 {
479 int rc = DEX_ERROR_ACCEPT;
480 
481  // the min fee spec requirement is checked in the following function
482  rc = DEx_acceptCreate(sender, receiver, property, nValue, block, tx_fee_paid, &nNewValue);
483 
484  return rc;
485 }
486 
488 {
489 int rc = PKT_ERROR_METADEX -100;
490 unsigned char action = 0;
491 
492  if (!isTransactionTypeAllowed(block, property, type, version)) return (PKT_ERROR_METADEX -888);
493 
494  memcpy(&desired_property, &pkt[16], 4);
495  swapByteOrder32(desired_property);
496 
497  memcpy(&desired_value, &pkt[20], 8);
498  swapByteOrder64(desired_value);
499 
500  file_log("\tdesired property: %u (%s)\n", desired_property, strMPProperty(desired_property));
501  file_log("\t desired value: %s\n", FormatMP(desired_property, desired_value));
502 
503  memcpy(&action, &pkt[28], 1);
504 
505  file_log("\t action: %u\n", action);
506 
507  if (mdex_o)
508  {
509  mdex_o->Set(sender, block, property, nValue, desired_property, desired_value, txid, tx_idx, action);
510  return PKT_RETURNED_OBJECT;
511  }
512 
513  switch (action)
514  {
515  case ADD:
516  if (!isTransactionTypeAllowed(block, desired_property, type, version)) return (PKT_ERROR_METADEX -889);
517 
518  // ensure we are not trading same property for itself
519  if (property == desired_property) return (PKT_ERROR_METADEX -5);
520 
521  // ensure no cross-over of currencies from Test Eco to normal
522  if (isTestEcosystemProperty(property) != isTestEcosystemProperty(desired_property)) return (PKT_ERROR_METADEX -4);
523 
524  // ensure the desired property exists in our universe
525  if (!_my_sps->hasSP(desired_property)) return (PKT_ERROR_METADEX -30);
526 
527  if (!nValue) return (PKT_ERROR_METADEX -11);
528  if (!desired_value) return (PKT_ERROR_METADEX -12);
529 
530  // ensure sufficient balance is available to offer
531  if (getMPbalance(sender, property, BALANCE) < (int64_t)nValue) return (PKT_ERROR_METADEX -567);
532 
533  // Does the sender have any tokens?
534  if (0 >= nNewValue) return (PKT_ERROR_METADEX -3);
535 
536  rc = MetaDEx_ADD(sender, property, nNewValue, block, desired_property, desired_value, txid, tx_idx);
537  break;
538 
539  case CANCEL_AT_PRICE:
540  // ensure the 4 necessary parameters for this command are provided
541  // TODO
542  // ...
543  rc = MetaDEx_CANCEL_AT_PRICE(txid, block, sender, property, nNewValue, desired_property, desired_value);
544  break;
545 
546  case CANCEL_ALL_FOR_PAIR:
547  // ensure the 2 necessary parameters for this command are provided
548  // TODO
549  // ...
550  rc = MetaDEx_CANCEL_ALL_FOR_PAIR(txid, block, sender, property, desired_property);
551  break;
552 
553  case CANCEL_EVERYTHING:
554  rc = MetaDEx_CANCEL_EVERYTHING(txid, block, sender);
555  break;
556 
557  default:
558  return (PKT_ERROR_METADEX -999);
559  }
560 
561  return rc;
562 }
563 
565 {
566  int rc = PKT_ERROR_TOKENS - 1000;
567 
568  if (!isTransactionTypeAllowed(block, property, type, version)) {
569  file_log("\tRejecting Grant: Transaction type not yet allowed\n");
570  return (PKT_ERROR_TOKENS - 22);
571  }
572 
573  if (sender.empty()) {
574  file_log("\tRejecting Grant: Sender is empty\n");
575  return (PKT_ERROR_TOKENS - 23);
576  }
577 
578  // manual issuance check
579  if (false == _my_sps->hasSP(property)) {
580  file_log("\tRejecting Grant: SP id:%u does not exist\n", property);
581  return (PKT_ERROR_TOKENS - 24);
582  }
583 
584  CMPSPInfo::Entry sp;
585  _my_sps->getSP(property, sp);
586 
587  if (false == sp.manual) {
588  file_log("\tRejecting Grant: SP id:%u was not issued with a TX 54\n", property);
589  return (PKT_ERROR_TOKENS - 25);
590  }
591 
592 
593  // issuer check
594  if (false == boost::iequals(sender, sp.issuer)) {
595  file_log("\tRejecting Grant: %s is not the issuer of SP id: %u\n", sender, property);
596  return (PKT_ERROR_TOKENS - 26);
597  }
598 
599  // overflow tokens check
600  if (MAX_INT_8_BYTES - sp.num_tokens < nValue) {
601  char prettyTokens[256];
602  if (sp.isDivisible()) {
603  snprintf(prettyTokens, 256, "%lu.%08lu", nValue / COIN, nValue % COIN);
604  } else {
605  snprintf(prettyTokens, 256, "%lu", nValue);
606  }
607  file_log("\tRejecting Grant: granting %s tokens on SP id:%u would overflow the maximum limit for tokens in a smart property\n", prettyTokens, property);
608  return (PKT_ERROR_TOKENS - 27);
609  }
610 
611  // grant the tokens
612  update_tally_map(sender, property, nValue, BALANCE);
613 
614  // call the send logic
615  rc = logicMath_SimpleSend();
616 
617  // record this grant
618  std::vector<uint64_t> dataPt;
619  dataPt.push_back(nValue);
620  dataPt.push_back(0);
621  string txidStr = txid.ToString();
622  sp.historicalData.insert(std::make_pair(txidStr, dataPt));
623  sp.update_block = chainActive[block]->GetBlockHash();
624  _my_sps->updateSP(property, sp);
625 
626  return rc;
627 }
628 
630 {
631  int rc = PKT_ERROR_TOKENS - 1000;
632 
633  if (!isTransactionTypeAllowed(block, property, type, version)) {
634  file_log("\tRejecting Revoke: Transaction type not yet allowed\n");
635  return (PKT_ERROR_TOKENS - 22);
636  }
637 
638  if (sender.empty()) {
639  file_log("\tRejecting Revoke: Sender is empty\n");
640  return (PKT_ERROR_TOKENS - 23);
641  }
642 
643  // manual issuance check
644  if (false == _my_sps->hasSP(property)) {
645  file_log("\tRejecting Revoke: SP id:%d does not exist\n", property);
646  return (PKT_ERROR_TOKENS - 24);
647  }
648 
649  CMPSPInfo::Entry sp;
650  _my_sps->getSP(property, sp);
651 
652  if (false == sp.manual) {
653  file_log("\tRejecting Revoke: SP id:%d was not issued with a TX 54\n", property);
654  return (PKT_ERROR_TOKENS - 25);
655  }
656 
657  // insufficient funds check and revoke
658  if (false == update_tally_map(sender, property, -nValue, BALANCE)) {
659  file_log("\tRejecting Revoke: insufficient funds\n");
660  return (PKT_ERROR_TOKENS - 111);
661  }
662 
663  // record this revoke
664  std::vector<uint64_t> dataPt;
665  dataPt.push_back(0);
666  dataPt.push_back(nValue);
667  string txidStr = txid.ToString();
668  sp.historicalData.insert(std::make_pair(txidStr, dataPt));
669  sp.update_block = chainActive[block]->GetBlockHash();
670  _my_sps->updateSP(property, sp);
671 
672  rc = 0;
673  return rc;
674 }
675 
677 {
678  int rc = PKT_ERROR_TOKENS - 1000;
679 
680  if (!isTransactionTypeAllowed(block, property, type, version)) {
681  file_log("\tRejecting Change of Issuer: Transaction type not yet allowed\n");
682  return (PKT_ERROR_TOKENS - 22);
683  }
684 
685  if (sender.empty()) {
686  file_log("\tRejecting Change of Issuer: Sender is empty\n");
687  return (PKT_ERROR_TOKENS - 23);
688  }
689 
690  if (receiver.empty()) {
691  file_log("\tRejecting Change of Issuer: Receiver is empty\n");
692  return (PKT_ERROR_TOKENS - 23);
693  }
694 
695  if (false == _my_sps->hasSP(property)) {
696  file_log("\tRejecting Change of Issuer: SP id:%d does not exist\n", property);
697  return (PKT_ERROR_TOKENS - 24);
698  }
699 
700  CMPSPInfo::Entry sp;
701  _my_sps->getSP(property, sp);
702 
703  // issuer check
704  if (false == boost::iequals(sender, sp.issuer)) {
705  file_log("\tRejecting Change of Issuer: %s is not the issuer of SP id:%d\n", sender, property);
706  return (PKT_ERROR_TOKENS - 26);
707  }
708 
709  // record this change of issuer
710  sp.issuer = receiver;
711  sp.update_block = chainActive[block]->GetBlockHash();
712  _my_sps->updateSP(property, sp);
713 
714  rc = 0;
715  return rc;
716 }
717 
719 {
720 int rc = -12345;
721 
722  return rc;
723 }
724 
726 {
727 int rc = -23456;
728 
729  return rc;
730 }
731 
733 {
734  switch (i)
735  {
736  case MSC_TYPE_SIMPLE_SEND: return ((char *)"Simple Send");
737  case MSC_TYPE_RESTRICTED_SEND: return ((char *)"Restricted Send");
738  case MSC_TYPE_SEND_TO_OWNERS: return ((char *)"Send To Owners");
739  case MSC_TYPE_SAVINGS_MARK: return ((char *)"Savings");
740  case MSC_TYPE_SAVINGS_COMPROMISED: return ((char *)"Savings COMPROMISED");
741  case MSC_TYPE_RATELIMITED_MARK: return ((char *)"Rate-Limiting");
742  case MSC_TYPE_AUTOMATIC_DISPENSARY: return ((char *)"Automatic Dispensary");
743  case MSC_TYPE_TRADE_OFFER: return ((char *)"DEx Sell Offer");
744  case MSC_TYPE_METADEX: return ((char *)"MetaDEx token trade");
745  case MSC_TYPE_ACCEPT_OFFER_BTC: return ((char *)"DEx Accept Offer");
746  case MSC_TYPE_CREATE_PROPERTY_FIXED: return ((char *)"Create Property - Fixed");
747  case MSC_TYPE_CREATE_PROPERTY_VARIABLE: return ((char *)"Create Property - Variable");
748  case MSC_TYPE_PROMOTE_PROPERTY: return ((char *)"Promote Property");
749  case MSC_TYPE_CLOSE_CROWDSALE: return ((char *)"Close Crowdsale");
750  case MSC_TYPE_CREATE_PROPERTY_MANUAL: return ((char *)"Create Property - Manual");
751  case MSC_TYPE_GRANT_PROPERTY_TOKENS: return ((char *)"Grant Property Tokens");
752  case MSC_TYPE_REVOKE_PROPERTY_TOKENS: return ((char *)"Revoke Property Tokens");
753  case MSC_TYPE_CHANGE_ISSUER_ADDRESS: return ((char *)"Change Issuer Address");
754  case MSC_TYPE_NOTIFICATION: return ((char *)"Notification");
755  case OMNICORE_MESSAGE_TYPE_ALERT: return ((char *)"ALERT");
756 
757  default: return ((char *)"* unknown type *");
758  }
759 }
760 
#define PKT_ERROR_TOKENS
Definition: mastercore.h:127
int logicMath_RevokeTokens(void)
int DEx_offerCreate(string seller_addr, unsigned int, uint64_t nValue, int block, uint64_t amount_desired, uint64_t fee, unsigned char btl, const uint256 &txid, uint64_t *nAmended=NULL)
void swapByteOrder16(uint16_t &us)
Swaps byte order on little-endian systems and does nothing otherwise.
bool DEx_offerExists(const string &seller_addr, unsigned int)
bool isTestEcosystemProperty(unsigned int property)
Definition: mastercore.cpp:495
uint256 update_block
Definition: mastercore_sp.h:37
CMPSPInfo * _my_sps
Definition: mastercore.cpp:362
Definition: init.h:13
int MetaDEx_CANCEL_AT_PRICE(const uint256, unsigned int, const string &, unsigned int, uint64_t, unsigned int, uint64_t)
bool update_tally_map(string who, unsigned int which_currency, int64_t amount, TallyType ttype)
Definition: mastercore.cpp:687
#define MSC_PROPERTY_TYPE_INDIVISIBLE
Definition: mastercore.h:78
string issuer
Definition: mastercore_sp.h:11
void swapByteOrder32(uint32_t &ui)
int logicMath_GrantTokens(void)
#define PKT_ERROR_METADEX
Definition: mastercore.h:125
STL namespace.
void Set(uint64_t d, uint64_t fee, unsigned char btl, unsigned char suba)
int MetaDEx_ADD(const string &sender_addr, unsigned int, uint64_t, int block, unsigned int property_desired, uint64_t amount_desired, const uint256 &txid, unsigned int idx)
bool hasSP(unsigned int spid)
uint64_t num_tokens
Definition: mastercore_sp.h:19
bool isOverrun(const char *p, unsigned int line)
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
Definition: util.cpp:1429
#define OMNI_PROPERTY_MSC
Definition: mastercore.h:130
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:48
std::map< std::string, std::vector< uint64_t > > historicalData
Definition: mastercore_sp.h:43
Definition: mastercore_sp.h:9
char * c_strMasterProtocolTXType(int i)
const char * url
Definition: rpcconsole.cpp:35
int MetaDEx_CANCEL_ALL_FOR_PAIR(const uint256, unsigned int, const string &, unsigned int, unsigned int)
const char * step2_SmartProperty(int &error_code)
int step2_Alert(std::string *new_global_alert_message)
#define OMNI_PROPERTY_TMSC
Definition: mastercore.h:131
int logicMath_SavingsCompromised(void)
#define MP_TX_PKT_V0
Definition: mastercore.h:41
#define SP_STRING_FIELD_LEN
Definition: mastercore.h:31
bool getSP(unsigned int spid, Entry &info)
bool isDivisible() const
int step3_sp_fixed(const char *p)
int MetaDEx_CANCEL_EVERYTHING(const uint256, unsigned int, const string &)
#define MSC_PROPERTY_TYPE_DIVISIBLE
Definition: mastercore.h:79
int DEx_acceptCreate(const string &buyer, const string &seller, int, uint64_t nValue, int block, uint64_t fee_paid, uint64_t *nAmended=NULL)
int DEx_offerUpdate(const string &seller_addr, unsigned int, uint64_t nValue, int block, uint64_t desired, uint64_t fee, unsigned char btl, const uint256 &txid, uint64_t *nAmended=NULL)
int DEx_offerDestroy(const string &seller_addr, unsigned int)
int logicMath_ChangeIssuer(void)
#define MAX_INT_8_BYTES
Definition: mastercore.h:26
int logicMath_SavingsMark(void)
#define PACKET_SIZE_CLASS_A
Definition: mastercore.h:49
int logicMath_TradeOffer(CMPOffer *)
static const int64_t COIN
Definition: util.h:38
#define MP_TX_PKT_V1
Definition: mastercore.h:42
void printInfo(FILE *fp)
int step2_Value(void)
string strMPProperty(unsigned int i)
Definition: mastercore.cpp:298
int logicMath_AcceptOffer_BTC(void)
char * c_strPropertyType(int i)
void * memcpy(void *a, const void *b, size_t c)
Definition: glibc_compat.cpp:7
unsigned int peekNextSPID(unsigned char ecosystem)
#define DEX_ERROR_ACCEPT
Definition: mastercore.h:117
int step3_sp_variable(const char *p)
std::string FormatMP(unsigned int property, int64_t n, bool fSign)
Definition: mastercore.cpp:349
void Set(const string &, int, unsigned int, uint64_t, unsigned int, uint64_t, const uint256 &, unsigned int, unsigned char)
static const CCheckpointData data
Definition: checkpoints.cpp:56
#define PKT_ERROR_SP
Definition: mastercore.h:120
unsigned int updateSP(unsigned int propertyID, Entry const &info)
#define PKT_RETURNED_OBJECT
Definition: mastercore.h:113
int64_t getMPbalance(const string &Address, unsigned int property, TallyType ttype)
Definition: mastercore.cpp:437
void swapByteOrder64(uint64_t &ull)
#define PKT_ERROR
Definition: mastercore.h:115
bool isTransactionTypeAllowed(int txBlock, unsigned int txProperty, unsigned int txType, unsigned short version, bool bAllowNullProperty=false)
Definition: mastercore.cpp:859
bool manual
Definition: mastercore_sp.h:39
#define PKT_ERROR_TRADEOFFER
Definition: mastercore.h:124
int logicMath_MetaDEx(CMPMetaDEx *)