141 #include <irrxml/irrXML.hpp>
151 int32_t OTCron::__trans_refill_amount =
154 int32_t OTCron::__cron_ms_between_process = 10000;
158 int32_t OTCron::__cron_max_items_per_nym = 10;
168 const char* szFilename =
"OT-CRON.crn";
182 const char* szFilename =
"OT-CRON.crn";
192 otErr <<
"Error saving main Cronfile:\n" << szFoldername
209 std::unique_ptr<OTDB::OfferListNym> pOfferList(
210 dynamic_cast<OTDB::OfferListNym*>(
213 for (
auto& it : m_mapMarkets) {
217 int32_t nNymOfferCount = 0;
230 nOfferCount += nNymOfferCount;
234 if (nOfferCount == 0)
237 else if (nOfferCount > 0) {
246 std::unique_ptr<OTDB::PackedBuffer> pBuffer(
247 pPacker->
Pack(*pOfferList));
249 if (
nullptr == pBuffer) {
251 <<
"Failed packing pOfferList in OTCron::GetNym_OfferList. \n";
257 const uint8_t* pUint =
static_cast<const uint8_t*
>(pBuffer->GetData());
258 const size_t theSize = pBuffer->GetSize();
260 if ((
nullptr != pUint) || (theSize < 2)) {
261 OTData theData(pUint, static_cast<uint32_t>(theSize));
270 otErr <<
"Null returned, or bad size, while getting buffer data in "
271 "OTCron::GetNym_OfferList.\n";
275 <<
"Error: Less-than-zero nOfferCount in OTCron::GetNym_OfferList: "
276 << nOfferCount <<
".\n";
288 std::unique_ptr<OTDB::MarketList> pMarketList(
289 dynamic_cast<OTDB::MarketList*>(
292 for (
auto& it : m_mapMarkets) {
296 std::unique_ptr<OTDB::MarketData> pMarketData(
297 dynamic_cast<OTDB::MarketData*>(
301 const OTString str_MARKET_ID(MARKET_ID);
306 pMarketData->server_id = str_ServerID.Get();
307 pMarketData->market_id = str_MARKET_ID.
Get();
308 pMarketData->asset_type_id = str_ASSET_ID.Get();
309 pMarketData->currency_type_id = str_CURRENCY_ID.Get();
311 const int64_t& lScale = pMarket->
GetScale();
313 pMarketData->scale = to_string<int64_t>(lScale);
318 pMarketData->current_bid = to_string<uint64_t>(theCurrentBid);
319 pMarketData->current_ask = to_string<uint64_t>(theCurrentAsk);
322 const int64_t& lTotalAvailableAssets =
325 pMarketData->total_assets = to_string<int64_t>(lTotalAvailableAssets);
326 pMarketData->last_sale_price = to_string<int64_t>(lLastSalePrice);
330 const mapOfOffers::size_type theBidCount = pMarket->
GetBidCount();
331 const mapOfOffers::size_type theAskCount = pMarket->
GetAskCount();
333 pMarketData->number_bids =
334 to_string<mapOfOffers::size_type>(theBidCount);
335 pMarketData->number_asks =
336 to_string<mapOfOffers::size_type>(theAskCount);
354 pMarketList->AddMarketData(*pMarketData);
359 if (0 == nMarketCount) {
362 else if (nMarketCount > 0) {
371 std::unique_ptr<OTDB::PackedBuffer> pBuffer(
372 pPacker->
Pack(*pMarketList));
374 if (
nullptr == pBuffer) {
375 otErr <<
"Failed packing pMarketList in OTCron::GetMarketList. \n";
383 const uint8_t* pUint =
static_cast<const uint8_t*
>(pBuffer->GetData());
384 const size_t theSize = pBuffer->GetSize();
386 if ((theSize > 0) && (
nullptr != pUint)) {
387 OTData theData(pUint, static_cast<uint32_t>(theSize));
398 otErr <<
"OTCron::GetMarketList: 0 size, or null return value, "
399 "while getting raw data from packed buffer.\n";
402 otErr <<
"OTCron::GetMarketList: nMarketCount is less than zero: "
403 << nMarketCount <<
".\n";
410 if (m_listTransactionNumbers.empty())
return 0;
412 return static_cast<int32_t
>(m_listTransactionNumbers.size());
417 m_listTransactionNumbers.push_back(lTransactionNum);
424 if (m_listTransactionNumbers.empty())
return 0;
426 int64_t lTransactionNum = m_listTransactionNumbers.front();
428 m_listTransactionNumbers.pop_front();
430 return lTransactionNum;
438 int32_t nReturnVal = 0;
451 if (!strcmp(
"cron", xml->getNodeName())) {
454 const OTString strServerID(xml->getAttributeValue(
"serverID"));
458 otOut <<
"\n\nLoading OTCron for ServerID: " << strServerID <<
"\n";
462 else if (!strcmp(
"transactionNum", xml->getNodeName())) {
463 const int64_t lTransactionNum = atol(xml->getAttributeValue(
"value"));
465 otWarn <<
"Transaction Number " << lTransactionNum
466 <<
" available for Cron.\n";
474 else if (!strcmp(
"cronItem", xml->getNodeName())) {
475 const OTString str_date_added = xml->getAttributeValue(
"dateAdded");
476 const int64_t lDateAdded =
477 (!str_date_added.
Exists() ? 0 : str_date_added.
ToLong());
484 otErr <<
"Error in OTCron::ProcessXMLNode: cronItem field without "
491 if (
nullptr == pItem) {
492 otErr <<
"Unable to create cron item from data in cron file.\n";
502 otErr <<
"OTCron::ProcessXMLNode: ERROR SECURITY: Server "
503 "signature failed to "
504 "verify on a cron item while loading: "
526 otInfo <<
"Successfully loaded cron item and added to list.\n";
529 otErr <<
"OTCron::ProcessXMLNode: Though loaded / verified "
531 "unable to add cron item (from cron file) to cron "
541 else if (!strcmp(
"market", xml->getNodeName())) {
542 const OTString strMarketID(xml->getAttributeValue(
"marketID"));
543 const OTString strAssetID(xml->getAttributeValue(
"assetID"));
544 const OTString strCurrencyID(xml->getAttributeValue(
"currencyID"));
546 const int64_t lScale = atol(xml->getAttributeValue(
"marketScale"));
548 const OTIdentifier ASSET_ID(strAssetID), CURRENCY_ID(strCurrencyID);
550 otWarn <<
"Loaded cron entry for Market:\n" << strMarketID <<
".\n";
554 new OTMarket(m_SERVER_ID, ASSET_ID, CURRENCY_ID, lScale);
568 otErr <<
"Somehow error while loading, verifying, or adding market "
569 "while loading Cron file.\n";
575 otWarn <<
"Loaded market entry from cronfile, and also loaded the "
576 "market file itself.\n";
591 const OTString SERVER_ID(m_SERVER_ID);
600 for (
auto& it : m_mapMarkets) {
612 " currencyID=\"%s\"\n"
613 " marketScale=\"%lld\""
615 str_MARKET_ID.
Get(), str_ASSET_ID.Get(),
616 str_CURRENCY_ID.Get(), pMarket->
GetScale());
620 for (
auto& it : m_multimapCronItems) {
632 "\" >\n%s</cronItem>\n\n",
633 lDateAdded, ascItem.
Get());
638 for (
auto& lTransactionNumber : m_listTransactionNumbers) {
651 if (!m_bIsActivated) {
652 otErr <<
"OTCron::ProcessCronItems: Not activated yet. (Skipping.)\n";
657 static Timer tCron(
true);
660 const int64_t cron_elapsed =
static_cast<int64_t
>(cron_tick2 - cron_tick1);
669 otErr <<
"WARNING: Cron has fewer than 20 percent of its normal "
670 "transaction number count available since the previous round! "
673 <<
" are currently available, with a max of "
676 <<
" were used in the last round alone!!! \n"
677 "SKIPPING THE CRON ITEMS THAT WERE SCHEDULED FOR THIS "
681 bool bNeedToSave =
false;
686 for (
auto it = m_multimapCronItems.begin();
687 it != m_multimapCronItems.end();) {
689 otErr <<
"WARNING: Cron has fewer than 20 percent of its normal "
691 "number count available since the previous cron item "
694 <<
" are currently available, with a max of "
697 <<
" were used in the current round alone!!! \n"
698 "SKIPPING THE REMAINDER OF THE CRON ITEMS THAT WERE "
699 "SCHEDULED FOR THIS ROUND!!!\n\n";
704 otInfo <<
"OTCron::" << __FUNCTION__
713 otOut <<
"OTCron::" << __FUNCTION__
715 it = m_multimapCronItems.erase(it);
717 OT_ASSERT(m_mapCronItems.end() != it_map);
718 m_mapCronItems.erase(it_map);
732 bool bSaveReceipt,
time64_t tDateAdded)
741 if (
nullptr == pCronItem) {
762 otErr << __FUNCTION__ <<
": Error saving receipt while adding new "
763 "CronItem to Cron.\n";
769 m_mapCronItems.insert(std::pair<int64_t, OTCronItem*>(
774 m_multimapCronItems.insert(
775 m_multimapCronItems.upper_bound(tDateAdded),
776 std::pair<time64_t, OTCronItem*>(tDateAdded, &theItem));
782 bool bSuccess =
true;
818 otOut << __FUNCTION__
819 <<
": New CronItem has been added to Cron: "
822 otErr << __FUNCTION__
823 <<
": Error saving while adding new CronItem to Cron: "
831 otErr << __FUNCTION__
832 <<
": Failed attempt to add CronItem with pre-existing "
847 if (m_mapCronItems.end() == it_map) {
848 otErr << __FUNCTION__
849 <<
": Attempt to remove non-existent CronItem from OTCron. "
850 "Transaction #: " << lTransactionNum <<
"\n";
865 m_mapCronItems.erase(it_map);
866 m_multimapCronItems.erase(it_multimap);
890 auto itt = m_mapCronItems.find(lTransactionNum);
892 if (itt != m_mapCronItems.end())
914 int64_t lTransactionNum)
916 auto itt = m_multimapCronItems.begin();
918 while (m_multimapCronItems.end() != itt) {
943 auto itt = m_mapCronItems.find(lTransactionNum);
945 if (itt != m_mapCronItems.end())
971 auto itt = m_mapCronItems.find(lOpeningNum);
973 if (itt == m_mapCronItems.end()) {
980 for (
auto& it : m_mapCronItems) {
1015 std::string std_MARKET_ID = str_MARKET_ID.
Get();
1018 auto it = m_mapMarkets.find(std_MARKET_ID);
1021 if (it == m_mapMarkets.end()) {
1026 if (bSaveMarketFile && !theMarket.
SaveMarket()) {
1028 <<
"Error saving market file while adding new Market to Cron:\n"
1029 << std_MARKET_ID <<
"\n";
1033 m_mapMarkets[std_MARKET_ID] = &theMarket;
1035 bool bSuccess =
true;
1042 if (bSaveMarketFile)
1053 otLog3 <<
"New Market has been added to Cron.\n";
1055 otErr <<
"Error saving while adding new Market to Cron.\n";
1062 otErr <<
"Attempt to add Market that was already there: "
1063 << std_MARKET_ID <<
"\n";
1072 const int64_t& lScale)
1084 if (
nullptr != pExistingMarket) {
1087 return pExistingMarket;
1097 otOut <<
"New market created and added to Cron.\n";
1100 otErr <<
"Error trying to add new market to Cron.\n";
1113 std::string std_MARKET_ID = str_MARKET_ID.
Get();
1116 auto it = m_mapMarkets.find(std_MARKET_ID);
1118 if (it == m_mapMarkets.end()) {
1129 const OTString str_LOOP_MARKET_ID(LOOP_MARKET_ID);
1131 if (MARKET_ID == LOOP_MARKET_ID)
1134 otErr <<
"Expected Market with ID:\n" << std_MARKET_ID
1135 <<
"\n but found " << str_LOOP_MARKET_ID <<
"\n";
1143 , m_bIsActivated(false)
1144 , m_pServerNym(nullptr)
1148 otLog3 <<
"OTCron::OTCron: Finished calling InitCron 0.\n";
1153 , m_bIsActivated(false)
1154 , m_pServerNym(nullptr)
1159 otLog3 <<
"OTCron::OTCron: Finished calling InitCron 1.\n";
1164 , m_bIsActivated(false)
1165 , m_pServerNym(nullptr)
1173 otLog3 <<
"OTCron::OTCron: Finished calling InitCron 2.\n";
1180 m_pServerNym =
nullptr;
1199 while (!m_multimapCronItems.empty()) {
1200 auto it = m_multimapCronItems.begin();
1201 m_multimapCronItems.erase(it);
1207 while (!m_mapCronItems.empty()) {
1208 OTCronItem* pItem = m_mapCronItems.begin()->second;
1209 auto it = m_mapCronItems.begin();
1210 m_mapCronItems.erase(it);
1215 while (!m_mapMarkets.empty()) {
1216 OTMarket* pMarket = m_mapMarkets.begin()->second;
1217 auto it = m_mapMarkets.begin();
1218 m_mapMarkets.erase(it);
OTMarket * GetOrCreateMarket(const OTIdentifier &ASSET_ID, const OTIdentifier &CURRENCY_ID, const int64_t &lScale)
EXPORT Storage * GetDefaultStorage()
EXPORT void AddTransactionNumber(const int64_t &lTransactionNum)
int64_t GetNextTransactionNumber()
EXPORT Storable * CreateObject(StoredObjectType eType)
virtual void UpdateContents()
EXPORT double getElapsedTimeInMilliSec()
void SetServerID(const OTIdentifier &SERVER_ID)
EXPORT bool SaveCronReceipt()
PackedBuffer * Pack(Storable &inObj)
int64_t GetTransactionNum() const
virtual bool IsValidOpeningNumber(const int64_t &lOpeningNum) const
bool GetNym_OfferList(const OTIdentifier &NYM_ID, OTDB::OfferListNym &theOutputList, int32_t &nNymOfferCount)
EXPORT bool SaveContract()
EXPORT int64_t ToLong() const
void HookRemovalFromCron(OTPseudonym *pRemover, int64_t newTransactionNo)
static EXPORT const char * PathSeparator()
EXPORT bool AddCronItem(OTCronItem &theItem, OTPseudonym *pActivator, bool bSaveReceipt, time64_t tDateAdded)
virtual bool SaveContractWallet(std::ofstream &ofs) const
mapOfOffers::size_type GetBidCount()
EXPORT OTCronItem * GetItemByOfficialNum(int64_t lTransactionNum)
OTLOG_IMPORT OTLogStream otOut
const OTIdentifier & GetCurrencyID() const
const OTIdentifier & GetServerID() const
OTLOG_IMPORT OTLogStream otLog3
int64_t GetLowestAskPrice()
time64_t OTTimeGetTimeFromSeconds(int64_t seconds)
const OTIdentifier & GetServerID() const
EXPORT OTCronItem * GetItemByValidOpeningNum(int64_t lOpeningNum)
EXPORT mapOfCronItems::iterator FindItemOnMap(int64_t lTransactionNum)
EXPORT void Concatenate(const char *arg,...)
const OTIdentifier & GetAssetID() const
EXPORT void ReleaseSignatures()
EXPORT bool Exists() const
EXPORT void SetString(const char *szString)
void SetCronPointer(OTCron &theCron)
EXPORT multimapOfCronItems::iterator FindItemOnMultimap(int64_t lTransactionNum)
EXPORT void Set(const char *data, uint32_t enforcedMaxLength=0)
virtual bool ProcessCron()
EXPORT void ProcessCronItems()
bool AddMarket(OTMarket &theMarket, bool bSaveMarketFile=true)
static EXPORT bool LoadEncodedTextField(irr::io::IrrXMLReader *&xml, OTASCIIArmor &ascOutput)
OTString m_strContractType
virtual int32_t ProcessXMLNode(irr::io::IrrXMLReader *&xml)
OTLOG_IMPORT OTLogStream otInfo
virtual EXPORT bool LoadContract()
OTStringXML m_xmlUnsigned
OTLOG_IMPORT OTLogStream otWarn
EXPORT const char * Get() const
virtual EXPORT bool SignContract(const OTPseudonym &theNym, const OTPasswordData *pPWData=nullptr)
const int64_t & GetScale() const
OTLOG_IMPORT OTLogStream otErr
void setServerNym(OTPseudonym *serverNym)
mapOfOffers::size_type GetAskCount()
EXPORT OTPacker * GetPacker(PackType ePackType=OTDB_DEFAULT_PACKER)
void setServerId(OTIdentifier *serverId)
virtual EXPORT void Release()
EXPORT int32_t GetTransactionCount() const
OTPseudonym * GetServerNym() const
int64_t GetHighestBidPrice()
virtual EXPORT bool VerifySignature(const OTPseudonym &theNym, const OTPasswordData *pPWData=nullptr) const
static int32_t GetCronRefillAmount()
static EXPORT const OTString & Cron()
EXPORT bool SetData(const OTData &theData, bool bLineBreaks=true)
EXPORT bool GetMarketList(OTASCIIArmor &ascOutput, int32_t &nMarketCount)
EXPORT bool GetNym_OfferList(OTASCIIArmor &ascOutput, const OTIdentifier &NYM_ID, int32_t &nOfferCount)
int64_t OTTimeGetSecondsFromTime(time64_t time)
int64_t GetTotalAvailableAssets()
const int64_t & GetLastSalePrice()
EXPORT OTMarket * GetMarket(const OTIdentifier &MARKET_ID)
const std::string & GetLastSaleDate()
static int32_t GetCronMsBetweenProcess()
void HookActivationOnCron(OTPseudonym *pActivator, bool bForTheFirstTime=false)
virtual EXPORT void Release()
void SetCronPointer(OTCron &theCron)
static EXPORT OTCronItem * NewCronItem(const OTString &strCronItem)
EXPORT bool RemoveCronItem(int64_t lTransactionNum, OTPseudonym &theRemover)