23 #include <boost/assign/list_of.hpp>
24 #include <boost/algorithm/string.hpp>
25 #include <boost/algorithm/string/find.hpp>
26 #include <boost/algorithm/string/join.hpp>
27 #include <boost/lexical_cast.hpp>
28 #include <boost/format.hpp>
29 #include <boost/filesystem.hpp>
30 #include "json/json_spirit_utils.h"
31 #include "json/json_spirit_value.h"
33 #include "leveldb/db.h"
34 #include "leveldb/write_batch.h"
36 #include <openssl/sha.h>
38 #include <boost/math/constants/constants.hpp>
39 #include <boost/multiprecision/cpp_int.hpp>
40 #include <boost/multiprecision/cpp_dec_float.hpp>
42 using boost::multiprecision::int128_t;
43 using boost::multiprecision::cpp_int;
44 using boost::multiprecision::cpp_dec_float;
45 using boost::multiprecision::cpp_dec_float_100;
48 using namespace boost;
67 md_PropertiesMap::iterator it =
metadex.find(prop);
69 if (it !=
metadex.end())
return &(it->second);
76 md_PricesMap::iterator it = p->find(price);
78 if (it != p->end())
return &(it->second);
97 case NOTHING:
return string(
"NOTHING");
98 case TRADED:
return string(
"TRADED");
101 case ADDED:
return string(
"ADDED");
102 case CANCELLED:
return string(
"CANCELLED");
103 default:
return string(
"* unknown *");
114 return !(first == second);
129 const bool bOK = (left == right);
131 file_log(
"PRICE CHECK %s: buyer = %s , inserted = %s : %s\n", label,
147 bool bBuyerSatisfied =
false;
149 const XDOUBLE desprice = (1/buyersprice);
151 if (msc_debug_metadex1)
153 file_log(
"%s(%s: prop=%u, desprop=%u, desprice= %s);newo: %s\n",
162 file_log(
"%s()=%u:%s NOT FOUND ON THE MARKET\n", __FUNCTION__, NewReturn,
getTradeReturnType(NewReturn));
167 for (md_PricesMap::iterator my_it = prices->begin(); my_it != prices->end(); ++my_it)
169 XDOUBLE sellers_price = (my_it->first);
171 if (msc_debug_metadex2) file_log(
"comparing prices: desprice %s needs to be GREATER THAN OR EQUAL TO %s\n",
175 if (desprice < sellers_price)
continue;
177 md_Set *indexes = &(my_it->second);
180 md_Set::iterator iitt;
181 for (iitt = indexes->begin(); iitt != indexes->end();)
185 if (msc_debug_metadex1) file_log(
"Looking at existing: %s (its prop= %u, its des prop= %u) = %s\n",
195 if (msc_debug_metadex1) file_log(
"MATCH FOUND, Trade: %s = %s\n", sellers_price.str(
DISPLAY_PRECISION_LEN, std::ios_base::fixed), p_older->
ToString());
205 if (msc_debug_metadex1) file_log(
"$$ trading using price: %s; seller: forsale= %ld, wanted= %ld, buyer amount offered= %ld\n",
206 sellers_price.str(
DISPLAY_PRECISION_LEN, std::ios_base::fixed), seller_amountForSale, seller_amountWanted, buyer_amountOffered);
208 if (msc_debug_metadex1) file_log(
"$$ old: %s\n", p_older->
ToString());
209 if (msc_debug_metadex1) file_log(
"$$ new: %s\n", newo->
ToString());
211 int64_t seller_amountGot = seller_amountWanted;
213 if (buyer_amountOffered < seller_amountWanted)
215 seller_amountGot = buyer_amountOffered;
218 const int64_t buyer_amountStillForSale = buyer_amountOffered - seller_amountGot;
226 std::string str_buyer_got_int_part = str_buyer_got.substr(0, str_buyer_got.find_first_of(
"."));
227 const int64_t buyer_amountGot = boost::lexical_cast<int64_t>( str_buyer_got_int_part );
229 const int64_t seller_amountLeft = p_older->
getAmountForSale() - buyer_amountGot;
231 if (msc_debug_metadex1) file_log(
"$$ buyer_got= %ld, seller_got= %ld, seller_left_for_sale= %ld, buyer_still_for_sale= %ld\n",
232 buyer_amountGot, seller_amountGot, seller_amountLeft, buyer_amountStillForSale);
234 XDOUBLE seller_amount_stilldesired = (
XDOUBLE) seller_amountLeft * sellers_price;
236 seller_amount_stilldesired += (
XDOUBLE) 0.5;
238 std::string str_amount_stilldesired = seller_amount_stilldesired.str(
INTERNAL_PRECISION_LEN, std::ios_base::fixed);
239 std::string str_stilldesired_int_part = str_amount_stilldesired.substr(0, str_amount_stilldesired.find_first_of(
"."));
244 seller_replacement.
setAmountForSale(seller_amountLeft,
"seller_replacement");
245 seller_replacement.
setAmountDesired(boost::lexical_cast<int64_t>( str_stilldesired_int_part ),
"seller_replacement");
274 std::string str_will_pay_int_part = str_will_pay.substr(0, str_will_pay.find_first_of(
"."));
277 newo->
setAmountDesired(boost::lexical_cast<int64_t>( str_will_pay_int_part ),
"buyer");
279 if (0 < buyer_amountStillForSale)
287 bBuyerSatisfied =
true;
290 if (0 < seller_amountLeft)
293 bBuyerSatisfied =
true;
298 if (msc_debug_metadex1) file_log(
"==== TRADED !!! %u=%s\n", NewReturn,
getTradeReturnType(NewReturn));
303 if (msc_debug_metadex1) file_log(
"++ erased old: %s\n", iitt->ToString());
305 indexes->erase(iitt++);
312 file_log(
"++ inserting seller_replacement: %s\n", seller_replacement.
ToString());
313 indexes->insert(seller_replacement);
319 if (bBuyerSatisfied)
break;
330 for (md_PropertiesMap::iterator my_it =
metadex.begin(); my_it !=
metadex.end(); ++my_it)
332 unsigned int prop = my_it->first;
334 file_log(
" ## property: %u\n", prop);
337 for (md_PricesMap::iterator it = prices.begin(); it != prices.end(); ++it)
340 md_Set & indexes = (it->second);
342 if (bShowPriceLevel) file_log(
" # Price Level: %s\n", price.str(
DISPLAY_PRECISION_LEN, std::ios_base::fixed));
344 for (md_Set::iterator it = indexes.begin(); it != indexes.end(); ++it)
361 void CMPMetaDEx::Set(
const string &sa,
int b,
unsigned int c, uint64_t nValue,
unsigned int cd, uint64_t ad,
const uint256 &tx,
unsigned int i,
unsigned char suba)
367 amount_forsale = nValue;
368 desired_property = cd;
374 CMPMetaDEx::CMPMetaDEx(
const string &addr,
int b,
unsigned int c, uint64_t nValue,
unsigned int cd, uint64_t ad,
const uint256 &tx,
unsigned int i,
unsigned char suba, uint64_t lfors)
376 still_left_forsale = lfors;
377 Set(addr, b,c,nValue,cd,ad,tx,i,suba);
382 return strprintf(
"%s:%34s in %d/%03u, txid: %s , trade #%u %s for #%u %s",
384 addr.c_str(), block, idx, txid.ToString().substr(0,10).c_str(),
385 property,
FormatMP(property, amount_forsale), desired_property,
FormatMP(desired_property, amount_desired));
393 OfferMap::iterator my_it =
my_offers.find(combo);
402 if (
msc_debug_dex) file_log(
"%s(%s, %u)\n", __FUNCTION__, seller_addr, prop);
404 OfferMap::iterator my_it =
my_offers.find(combo);
406 if (my_it !=
my_offers.end())
return &(my_it->second);
414 if (
msc_debug_dex) file_log(
"%s(%s, %u, %s)\n", __FUNCTION__, seller_addr, prop, buyer_addr);
416 AcceptMap::iterator my_it =
my_accepts.find(combo);
418 if (my_it !=
my_accepts.end())
return &(my_it->second);
424 int mastercore::DEx_offerCreate(
string seller_addr,
unsigned int prop, uint64_t nValue,
int block, uint64_t amount_des, uint64_t fee,
unsigned char btl,
const uint256 &txid, uint64_t *nAmended)
436 file_log(
"%s(%s|%s), nValue=%lu)\n", __FUNCTION__, seller_addr, combo, nValue);
441 if (nValue > balanceReallyAvailable)
446 BTC = amount_des * balanceReallyAvailable;
447 BTC /= (double)nValue;
450 nValue = balanceReallyAvailable;
452 if (nAmended) *nAmended = nValue;
459 my_offers.insert(std::make_pair(combo,
CMPOffer(block, nValue, prop, amount_des, fee, btl, txid)));
476 OfferMap::iterator my_it;
490 file_log(
"%s(%s|%s)\n", __FUNCTION__, seller_addr, combo);
496 int mastercore::DEx_offerUpdate(
const string &seller_addr,
unsigned int prop, uint64_t nValue,
int block, uint64_t desired, uint64_t fee,
unsigned char btl,
const uint256 &txid, uint64_t *nAmended)
500 file_log(
"%s(%s, %d)\n", __FUNCTION__, seller_addr, prop);
508 rc =
DEx_offerCreate(seller_addr, prop, nValue, block, desired, fee, btl, txid, nAmended);
515 int mastercore::DEx_acceptCreate(
const string &buyer,
const string &seller,
int prop, uint64_t nValue,
int block, uint64_t fee_paid, uint64_t *nAmended)
518 OfferMap::iterator my_it;
534 file_log(
"ERROR: fee too small -- the ACCEPT is rejected! (%lu is smaller than %lu)\n", fee_paid, offer.
getMinFee());
538 file_log(
"%s(%s) OFFER FOUND\n", __FUNCTION__, selloffer_combo);
543 file_log(
"%s() ERROR: an accept from this same seller for this same offer is already open !!!!!\n", __FUNCTION__);
547 if (nActualAmount > nValue)
549 nActualAmount = nValue;
551 if (nAmended) *nAmended = nActualAmount;
582 if (!p_accept)
return rc;
589 bReturnToMoney =
true;
599 bReturnToMoney =
false;
604 bReturnToMoney =
true;
629 const AcceptMap::iterator my_it =
my_accepts.find(accept_combo);
655 if (
msc_debug_dex) file_log(
"%s(%s, %s)\n", __FUNCTION__, seller, buyer);
664 double perc_X = (double)BTC_paid/BTC_desired_original;
665 double Purchased = offer_amount_original * perc_X;
672 file_log(
"BTC_desired= %30.20lf , offer_amount=%30.20lf , perc_X= %30.20lf , Purchased= %30.20lf , units_purchased= %lu\n",
673 BTC_desired_original, offer_amount_original, perc_X, Purchased, units_purchased);
676 if (nActualAmount < units_purchased)
678 units_purchased = nActualAmount;
680 if (nAmended) *nAmended = units_purchased;
690 file_log(
"#######################################################\n");
702 if ((0 == selloffer_reserve) && (0 == accept_reserve))
713 unsigned int how_many_erased = 0;
714 AcceptMap::iterator my_it =
my_accepts.begin();
725 file_log(
"%s() FOUND EXPIRED ACCEPT, erasing: blockNow=%d, offer block=%d, blocktimelimit= %d\n",
729 std::vector<std::string> vstr;
730 boost::split(vstr, my_it->first, boost::is_any_of(
"-+"), token_compress_on);
731 string seller = vstr[0];
732 int property =
atoi(vstr[1]);
733 string buyer = vstr[2];
745 return how_many_erased;
749 int mastercore::MetaDEx_ADD(
const string &sender_addr,
unsigned int prop, uint64_t amount,
int block,
unsigned int property_desired, uint64_t amount_desired,
const uint256 &txid,
unsigned int idx)
764 if (msc_debug_metadex1) file_log(
"%s(); buyer obj: %s\n", __FUNCTION__, new_mdex.
ToString());
770 if (0 >= neworder_buyersprice)
787 x_AddOrCancel(&new_mdex);
797 md_Set temp_indexes, *p_indexes = NULL;
798 std::pair<md_Set::iterator,bool> ret;
802 p_indexes =
get_Indexes(p_prices, neworder_buyersprice);
805 if (!p_indexes) p_indexes = &temp_indexes;
807 ret = p_indexes->insert(new_mdex);
809 if (
false == ret.second)
811 file_log(
"%s() ERROR: ALREADY EXISTS, line %d, file: %s\n", __FUNCTION__, __LINE__, __FILE__);
827 if (msc_debug_metadex1) file_log(
"==== INSERTED: %s= %s\n", neworder_buyersprice.str(
DISPLAY_PRECISION_LEN, std::ios_base::fixed), new_mdex.
ToString());
830 if (!p_prices) p_prices = &temp_prices;
832 (*p_prices)[neworder_buyersprice] = *p_indexes;
851 if (msc_debug_metadex1) file_log(
"%s():%s\n", __FUNCTION__, mdex.
ToString());
857 file_log(
"%s() NOTHING FOUND for %s\n", __FUNCTION__, mdex.
ToString());
862 for (md_PricesMap::iterator my_it = prices->begin(); my_it != prices->end(); ++my_it)
864 XDOUBLE sellers_price = (my_it->first);
868 md_Set *indexes = &(my_it->second);
870 for (md_Set::iterator iitt = indexes->begin(); iitt != indexes->end();)
874 if (msc_debug_metadex3) file_log(
"%s(): %s\n", __FUNCTION__, p_mdex->
ToString());
883 file_log(
"%s(): REMOVING %s\n", __FUNCTION__, p_mdex->
ToString());
893 indexes->erase(iitt++);
908 file_log(
"%s(%d,%d)\n", __FUNCTION__, prop, property_desired);
914 file_log(
"%s() NOTHING FOUND\n", __FUNCTION__);
919 for (md_PricesMap::iterator my_it = prices->begin(); my_it != prices->end(); ++my_it)
921 md_Set *indexes = &(my_it->second);
923 for (md_Set::iterator iitt = indexes->begin(); iitt != indexes->end();)
927 if (msc_debug_metadex3) file_log(
"%s(): %s\n", __FUNCTION__, p_mdex->
ToString());
936 file_log(
"%s(): REMOVING %s\n", __FUNCTION__, p_mdex->
ToString());
946 indexes->erase(iitt++);
960 file_log(
"%s()\n", __FUNCTION__);
964 file_log(
"<<<<<<\n");
966 for (md_PropertiesMap::iterator my_it =
metadex.begin(); my_it !=
metadex.end(); ++my_it)
968 unsigned int prop = my_it->first;
970 file_log(
" ## property: %u\n", prop);
973 for (md_PricesMap::iterator it = prices.begin(); it != prices.end(); ++it)
976 md_Set & indexes = (it->second);
980 for (md_Set::iterator it = indexes.begin(); it != indexes.end();)
984 if ((it->getAddr() != sender_addr))
991 file_log(
"%s(): REMOVING %s\n", __FUNCTION__, it->ToString());
1001 indexes.erase(it++);
1005 file_log(
">>>>>>\n");
1020 string lineOut = (
boost::format(
"%s,%d,%d,%d,%d,%d,%d,%d,%s,%d")
1027 % (
unsigned int) subaction
1030 % still_left_forsale
1034 SHA256_Update(shaCtx, lineOut.c_str(), lineOut.length());
1037 file << lineOut << endl;
static MatchReturnType x_Trade(CMPMetaDEx *newo)
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)
bool DEx_offerExists(const string &seller_addr, unsigned int)
md_PricesMap * get_Prices(unsigned int prop)
CMPOffer * DEx_getOffer(const string &seller_addr, unsigned int)
int MetaDEx_CANCEL_AT_PRICE(const uint256, unsigned int, const string &, unsigned int, uint64_t, unsigned int, uint64_t)
bool operator>=(XDOUBLE first, XDOUBLE second)
bool update_tally_map(string who, unsigned int which_currency, int64_t amount, TallyType ttype)
#define INTERNAL_PRECISION_LEN
cpp_dec_float_100 XDOUBLE
bool operator==(XDOUBLE first, XDOUBLE second)
void recordMetaDExCancelTX(const uint256 &txidMaster, const uint256 &txidSub, bool fValid, int nBlock, unsigned int propertyId, uint64_t nValue)
bool operator!=(XDOUBLE first, XDOUBLE second)
uint64_t getOfferAmountOriginal() const
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)
#define STR_ACCEPT_ADDR_PROP_ADDR_COMBO(_seller, _buyer)
uint64_t getBTCDesiredOriginal()
#define DISPLAY_PRECISION_LEN
#define OMNI_PROPERTY_MSC
CMPAccept * DEx_getAccept(const string &seller_addr, unsigned int, const string &buyer_addr)
#define DEX_ERROR_SELLOFFER
void recordPaymentTX(const uint256 &txid, bool fValid, int nBlock, unsigned int vout, unsigned int propertyId, uint64_t nValue, string buyer, string seller)
unsigned char getBlockTimeLimit()
unsigned int eraseExpiredAccepts(int blockNow)
int MetaDEx_CANCEL_ALL_FOR_PAIR(const uint256, unsigned int, const string &, unsigned int, unsigned int)
uint64_t getOfferAmountOriginal()
#define OMNI_PROPERTY_TMSC
uint64_t getAcceptAmountRemaining() const
int DEx_payment(uint256 txid, unsigned int vout, string seller, string buyer, uint64_t BTC_paid, int blockNow, uint64_t *nAmended=NULL)
CMPTradeList * t_tradelistdb
uint64_t rounduint64(long double ld)
Converts numbers to 64 bit wide unsigned integer whereby any signedness is ignored.
uint64_t getBTCDesiredOriginal() const
uint64_t getMinFee() const
bool reduceAcceptAmountRemaining_andIsZero(const uint64_t really_purchased)
void MetaDEx_debug_print(bool bShowPriceLevel=false, bool bDisplay=false)
int MetaDEx_CANCEL_EVERYTHING(const uint256, unsigned int, const string &)
std::map< XDOUBLE, md_Set > md_PricesMap
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)
unsigned int getProperty() const
std::string GetHex() const
int DEx_offerDestroy(const string &seller_addr, unsigned int)
const string getTradeReturnType(MatchReturnType ret)
std::set< CMPMetaDEx, MetaDEx_compare > md_Set
unsigned char getBlockTimeLimit() const
int DEx_acceptDestroy(const string &buyer, const string &seller, int, bool bForceErase=false)
md_Set * get_Indexes(md_PricesMap *p, XDOUBLE price)
bool operator<=(XDOUBLE first, XDOUBLE second)
#define DEX_ERROR_PAYMENT
std::string FormatMP(unsigned int property, int64_t n, bool fSign)
static void PriceCheck(const string &label, XDOUBLE left, XDOUBLE right)
#define STR_SELLOFFER_ADDR_PROP_COMBO(x)
int64_t getMPbalance(const string &Address, unsigned int property, TallyType ttype)
std::map< unsigned int, md_PricesMap > md_PropertiesMap
int atoi(const std::string &str)
void recordTrade(const uint256 txid1, const uint256 txid2, string address1, string address2, unsigned int prop1, unsigned int prop2, uint64_t amount1, uint64_t amount2, int blockNum)