diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 3c5cfe4d6..0afb47894 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -90,7 +90,7 @@ void WaitForShutdown(boost::thread_group* threadGroup) //komodo_longestchain(); if ( ASSETCHAINS_CBOPRET != 0 ) komodo_cbopretupdate(); - for (i=0; istored.ori = ori; while (!tg_fits(obj, obj->falling)) { obj->falling.loc.row--; + if (tg_fits(obj, obj->falling)) { + break; + } + obj->falling.loc.col--; + if (tg_fits(obj, obj->falling)) { + break; + } + obj->falling.loc.col += 2; } } tg_put(obj, obj->falling); diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index e76da09ec..38f9041c1 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -201,6 +201,9 @@ try_again: curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS, 1L); // no progress callback + //curl_easy_setopt(curl_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + //curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, 2); + if ( strncmp(url,"https",5) == 0 ) { curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0); @@ -247,13 +250,13 @@ try_again: numretries++; if ( specialcase != 0 ) { - printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res); + fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res); free(s.ptr); return(0); } else if ( numretries >= 1 ) { - //printf("Maximum number of retries exceeded!\n"); + fprintf(stderr,"Maximum number of retries exceeded!\n"); free(s.ptr); return(0); } diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 6a9afd473..c1e5dcdcb 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -1565,7 +1565,7 @@ int32_t komodo_heightpricebits(uint32_t prevbits[4],int32_t nHeight) GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret); if ( vopret.size() >= PRICES_SIZEBIT0 ) { - memcpy(prevbits,&vopret[0],PRICES_SIZEBIT0); + memcpy(prevbits,vopret.data(),vopret.size()); return(0); } } @@ -1579,44 +1579,64 @@ int32_t komodo_heightpricebits(uint32_t prevbits[4],int32_t nHeight) */ uint32_t komodo_pricenew(int32_t *maxflagp,uint32_t price,uint32_t refprice,int64_t tolerance) { - uint32_t highprice,lowprice; + uint64_t highprice,lowprice; + if ( refprice < 2 ) + return(0); highprice = ((uint64_t)refprice * (COIN + tolerance)) / COIN; // calc highest acceptable price lowprice = ((uint64_t)refprice * (COIN - tolerance)) / COIN; // and lowest + if ( highprice == refprice ) + highprice++; + if ( lowprice == refprice ) + lowprice--; if ( price >= highprice ) { - *maxflagp = 1; + //fprintf(stderr,"high %u vs h%llu l%llu tolerance.%llu\n",price,(long long)highprice,(long long)lowprice,(long long)tolerance); if ( price > highprice ) // return non-zero only if we violate the tolerance + { + *maxflagp = 2; return(highprice); + } + *maxflagp = 1; } else if ( price <= lowprice ) { - *maxflagp = -1; + //fprintf(stderr,"low %u vs h%llu l%llu tolerance.%llu\n",price,(long long)highprice,(long long)lowprice,(long long)tolerance); if ( price < lowprice ) + { + *maxflagp = -2; return(lowprice); + } + *maxflagp = -1; } - else return(0); + return(0); } // komodo_pricecmp() returns -1 if any of the prices are beyond the tolerance -int32_t komodo_pricecmp(int32_t *maxflagp,uint32_t pricebitsA[4],uint32_t pricebitsB[4],int64_t tolerance) +int32_t komodo_pricecmp(int32_t nHeight,int32_t n,int32_t *maxflagp,uint32_t *pricebitsA,uint32_t *pricebitsB,int64_t tolerance) { - int32_t i; + int32_t i; uint32_t newprice; *maxflagp = 0; - for (i=1; i<4; i++) - if ( komodo_pricenew(maxflagp,pricebitsA[i],pricebitsB[i],tolerance) != 0 ) + for (i=1; i newprice.%u out of tolerance maxflag.%d\n",nHeight,i,n,pricebitsB[i],pricebitsA[i],newprice,*maxflagp); return(-1); + } + } return(0); } // komodo_priceclamp() clamps any price that is beyond tolerance -int32_t komodo_priceclamp(uint32_t pricebits[4],uint32_t refprices[4],int64_t tolerance) +int32_t komodo_priceclamp(int32_t n,uint32_t *pricebits,uint32_t *refprices,int64_t tolerance) { - int32_t i,maxflag = 0; uint32_t newprice; - for (i=1; i<4; i++) + int32_t i,maxflag; uint32_t newprice; + for (i=1; i %u\n",i,pricebits[i],newprice); + fprintf(stderr,"priceclamped[%d of %d] %u vs %u -> %u\n",i,n,refprices[i],pricebits[i],newprice); pricebits[i] = newprice; } } @@ -1626,20 +1646,35 @@ int32_t komodo_priceclamp(uint32_t pricebits[4],uint32_t refprices[4],int64_t to // komodo_mineropret() returns a valid pricedata to add to the coinbase opreturn for nHeight CScript komodo_mineropret(int32_t nHeight) { - CScript opret; uint32_t pricebits[4],prevbits[4]; int32_t maxflag; + CScript opret; uint32_t pricebits[8192],prevbits[8192]; int32_t maxflag,i,n,numzero=0; if ( Mineropret.size() >= PRICES_SIZEBIT0 ) { + n = (int32_t)(Mineropret.size() / sizeof(uint32_t)); + numzero = 1; + while ( numzero > 0 ) + { + memcpy(pricebits,Mineropret.data(),Mineropret.size()); + for (i=numzero=0; i vopret; uint32_t localbits[4],pricebits[4],prevbits[4],newprice; int32_t i,lag,lag2,maxflag=0; + std::vector vopret; double btcusd,btcgbp,btceur; uint32_t localbits[8192],pricebits[8192],prevbits[8192],newprice; int32_t i,lag,lag2,n,maxflag=0; uint32_t now = (uint32_t)time(NULL); if ( ASSETCHAINS_CBOPRET != 0 ) { GetOpReturnData(scriptPubKey,vopret); if ( vopret.size() >= PRICES_SIZEBIT0 ) { - memcpy(pricebits,&vopret[0],PRICES_SIZEBIT0); - lag = (int32_t)(time(NULL) - pricebits[0]); - if ( lag < 0 ) - lag = -lag; - lag2 = (int32_t)(pricebits[0] - komodo_heightstamp(nHeight-1)); - fprintf(stderr,"ht.%d: t%u lag.%d %.4f USD, %.4f GBP, %.4f EUR htstamp.%d [%d]\n",nHeight,pricebits[0],lag,(double)pricebits[1]/10000,(double)pricebits[2]/10000,(double)pricebits[3]/10000,komodo_heightstamp(nHeight-1),lag2); + n = (int32_t)(vopret.size() / sizeof(uint32_t)); + memcpy(pricebits,vopret.data(),Mineropret.size()); if ( nHeight > 1 ) { + lag = (int32_t)(now - pricebits[0]); + lag2 = (int32_t)(komodo_heightstamp(nHeight-1) - pricebits[0]); + if ( lag < -60 ) // avoid data from future + { + fprintf(stderr,"now.%u htstamp.%u - pricebits[0] %u -> lag.%d\n",now,komodo_heightstamp(nHeight-1),pricebits[0],lag2); + return(-1); + } + // else need to check against current blocktime to prevent pricebits[0] games + btcusd = (double)pricebits[1]/10000; + btcgbp = (double)pricebits[2]/10000; + btceur = (double)pricebits[3]/10000; + fprintf(stderr,"ht.%d: lag.%d %.4f USD, %.4f GBP, %.4f EUR, GBPUSD %.6f, EURUSD %.6f, EURGBP %.6f [%d]\n",nHeight,lag,btcusd,btcgbp,btceur,btcusd/btcgbp,btcusd/btceur,btcgbp/btceur,lag2); if ( komodo_heightpricebits(prevbits,nHeight-1) == 0 ) { - if ( komodo_pricecmp(&maxflag,pricebits,prevbits,PRICES_MAXCHANGE) < 0 ) - return(-1); - } else return(-1); - } - if ( lag < ASSETCHAINS_BLOCKTIME && Mineropret.size() >= PRICES_SIZEBIT0 ) - { - memcpy(localbits,&Mineropret[0],PRICES_SIZEBIT0); - if ( maxflag == 0 ) - { - if ( komodo_pricecmp(&maxflag,localbits,prevbits,PRICES_MAXCHANGE) < 0 ) - return(-1); - } - else - { - for (i=1; i<4; i++) + if ( komodo_pricecmp(nHeight,n,&maxflag,pricebits,prevbits,PRICES_MAXCHANGE) < 0 ) { - maxflag = 0; - if ( (newprice= komodo_pricenew(&maxflag,pricebits[i],prevbits[i],PRICES_MAXCHANGE)) != 0 ) // proposed price is clamped + for (i=1; i 0 && localbits[i] < pricebits[i] ) - return(-1); - else if ( maxflag < 0 && localbits[i] > pricebits[i] ) + if ( komodo_pricecmp(nHeight,n,&maxflag,pricebits,prevbits,PRICES_MAXCHANGE) < 0 ) + { + fprintf(stderr,"vs prev maxflag.%d cmp error\n",maxflag); return(-1); + } + } + } + } else return(-1); + if ( lag < ASSETCHAINS_BLOCKTIME && Mineropret.size() >= PRICES_SIZEBIT0 ) + { + memcpy(localbits,Mineropret.data(),Mineropret.size()); + for (i=0; i 0 && localbits[i] < prevbits[i] ) + return(-1); + else if ( maxflag < 0 && localbits[i] > prevbits[i] ) + return(-1); + } } } } } return(0); - } else fprintf(stderr,"wrong size %d vs %d, scriptPubKey size %d [%02x]\n",(int32_t)vopret.size(),(int32_t)PRICES_SIZEBIT0,(int32_t)scriptPubKey.size(),scriptPubKey[0]); + } else fprintf(stderr,"wrong size %d vs %d, scriptPubKey size %d [%02x]\n",(int32_t)vopret.size(),(int32_t)Mineropret.size(),(int32_t)scriptPubKey.size(),scriptPubKey[0]); return(-1); } return(0); } +char *nonportable_path(char *str) +{ + int32_t i; + for (i=0; str[i]!=0; i++) + if ( str[i] == '/' ) + str[i] = '\\'; + return(str); +} + +char *portable_path(char *str) +{ +#ifdef _WIN32 + return(nonportable_path(str)); +#else +#ifdef __PNACL + /*int32_t i,n; + if ( str[0] == '/' ) + return(str); + else + { + n = (int32_t)strlen(str); + for (i=n; i>0; i--) + str[i] = str[i-1]; + str[0] = '/'; + str[n+1] = 0; + }*/ +#endif + return(str); +#endif +} + +void *loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep) +{ + FILE *fp; + long filesize,buflen = *allocsizep; + uint8_t *buf = *bufp; + *lenp = 0; + if ( (fp= fopen(portable_path(fname),"rb")) != 0 ) + { + fseek(fp,0,SEEK_END); + filesize = ftell(fp); + if ( filesize == 0 ) + { + fclose(fp); + *lenp = 0; + //printf("loadfile null size.(%s)\n",fname); + return(0); + } + if ( filesize > buflen ) + { + *allocsizep = filesize; + *bufp = buf = (uint8_t *)realloc(buf,(long)*allocsizep+64); + } + rewind(fp); + if ( buf == 0 ) + printf("Null buf ???\n"); + else + { + if ( fread(buf,1,(long)filesize,fp) != (unsigned long)filesize ) + printf("error reading filesize.%ld\n",(long)filesize); + buf[filesize] = 0; + } + fclose(fp); + *lenp = filesize; + //printf("loaded.(%s)\n",buf); + } //else printf("OS_loadfile couldnt load.(%s)\n",fname); + return(buf); +} + +void *filestr(long *allocsizep,char *_fname) +{ + long filesize = 0; char *fname,*buf = 0; void *retptr; + *allocsizep = 0; + fname = (char *)malloc(strlen(_fname)+1); + strcpy(fname,_fname); + retptr = loadfile(fname,(uint8_t **)&buf,&filesize,allocsizep); + free(fname); + return(retptr); +} + +cJSON *send_curl(char *url,char *fname) +{ + long fsize; char curlstr[1024],*jsonstr; cJSON *json=0; + sprintf(curlstr,"wget -q \"%s\" -O %s",url,fname); + if ( system(curlstr) == 0 ) + { + if ( (jsonstr= (char *)filestr((long *)&fsize,fname)) != 0 ) + { + json = cJSON_Parse(jsonstr); + free(jsonstr); + } + } + return(json); +} + // get_urljson just returns the JSON returned by the URL using issue_curl #define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"CBCOINBASE",cmdstr,0,0,0) +const char *Cryptos[] = { "KMD", "ETH", "LTC", "BCHABC", "XMR", "IOTA", "DASH", "XEM", "ZEC", "WAVES", "RVN", "LSK", "DCR", "BTS", "ICX", "HOT", "STEEM", "ENJ", "STRAT" }; + +const char *Forex[] = +{ "BGN","NZD","ILS","RUB","CAD","PHP","CHF","AUD","JPY","TRY","HKD","MYR","HRK","CZK","IDR","DKK","NOK","HUF","GBP","MXN","THB","ISK","ZAR","BRL","SGD","PLN","INR","KRW","RON","CNY","SEK","EUR" +}; + +/* +const char *Techstocks[] = +{ "AAPL","ADBE","ADSK","AKAM","AMD","AMZN","ATVI","BB","CDW","CRM","CSCO","CYBR","DBX","EA","FB","GDDY","GOOG","GRMN","GSAT","HPQ","IBM","INFY","INTC","INTU","JNPR","MSFT","MSI","MU","MXL","NATI","NCR","NFLX","NTAP","NVDA","ORCL","PANW","PYPL","QCOM","RHT","S","SHOP","SNAP","SPOT","SYMC","SYNA","T","TRIP","TWTR","TXN","VMW","VOD","VRSN","VZ","WDC","XRX","YELP","YNDX","ZEN" +}; +const char *Metals[] = { "XAU", "XAG", "XPT", "XPD", }; + +const char *Markets[] = { "DJIA", "SPX", "NDX", "VIX" }; +*/ + cJSON *get_urljson(char *url) { char *jsonstr; cJSON *json = 0; @@ -1722,11 +1899,105 @@ cJSON *get_urljson(char *url) return(json); } +uint32_t get_stockprice(const char *symbol) +{ + char url[512]; cJSON *json,*obj; uint32_t high,low,price = 0; + sprintf(url,"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=%s&interval=15min&apikey=%s",symbol,NOTARY_PUBKEY.data()+50); + if ( (json= get_urljson(url)) != 0 ) + { + if ( (obj= jobj(json,(char *)"Time Series (15min)")) != 0 ) + { + high = jdouble(jitem(obj,0),(char *)"2. high")*10000 + 0.000049; + low = jdouble(jitem(obj,0),(char *)"3. low")*10000 + 0.000049; + price = (high + low) / 2; + } + free_json(json); + } + return(price); +} + +uint32_t get_dailyfx(uint32_t *prices) +{ + //{"base":"USD","rates":{"BGN":1.74344803,"NZD":1.471652701,"ILS":3.6329113924,"RUB":65.1997682296,"CAD":1.3430201462,"USD":1.0,"PHP":52.8641469068,"CHF":0.9970582992,"AUD":1.4129078267,"JPY":110.6792654662,"TRY":5.6523444464,"HKD":7.8499732573,"MYR":4.0824567659,"HRK":6.6232840078,"CZK":22.9862720628,"IDR":14267.4986628633,"DKK":6.6551078624,"NOK":8.6806917454,"HUF":285.131039401,"GBP":0.7626582278,"MXN":19.4183455161,"THB":31.8702085933,"ISK":122.5708682475,"ZAR":14.7033339276,"BRL":3.9750401141,"SGD":1.3573720806,"PLN":3.8286682118,"INR":69.33187734,"KRW":1139.1602781244,"RON":4.2423783206,"CNY":6.7387234801,"SEK":9.3385630237,"EUR":0.8914244963},"date":"2019-03-28"} + char url[512],*datestr; cJSON *json,*rates; int32_t i; uint32_t datenum=0,price = 0; + sprintf(url,"https://api.openrates.io/latest?base=USD"); + if ( (json= send_curl(url,(char *)"dailyfx")) != 0 ) + { + if ( (rates= jobj(json,(char *)"rates")) != 0 ) + { + for (i=0; i 333 ) + ASSETCHAINS_CBOPRET = 7; + size = PRICES_SIZEBIT0; + if ( (ASSETCHAINS_CBOPRET & 2) != 0 ) + size += sizeof(forexprices); + if ( (ASSETCHAINS_CBOPRET & 4) != 0 ) + size += sizeof(cryptoprices); + if ( Mineropret.size() < size ) + Mineropret.resize(size); + size = PRICES_SIZEBIT0; + if ( now > lastbtc+120 && get_btcusd(pricebits) == 0 ) { - if ( Mineropret.size() < PRICES_SIZEBIT0 ) - Mineropret.resize(PRICES_SIZEBIT0); - memcpy(&Mineropret[0],pricebits,PRICES_SIZEBIT0); - //int32_t i; for (i=0; i lasttime+3600*5 || forexprices[0] == 0 ) + { + get_dailyfx(forexprices); + memcpy(&Mineropret.data()[size],forexprices,sizeof(forexprices)); + lasttime = (uint32_t)time(NULL); + } + size += sizeof(forexprices); + } + if ( (ASSETCHAINS_CBOPRET & 4) != 0 ) + { + if ( now > lastcrypto+100 ) + { + get_cryptoprices(cryptoprices,Cryptos,(int32_t)(sizeof(Cryptos)/sizeof(*Cryptos))); + memcpy(&Mineropret.data()[size],cryptoprices,sizeof(cryptoprices)); + lastcrypto = (uint32_t)time(NULL); + } + size += sizeof(cryptoprices); + } + //int32_t i; for (i=0; i 0: - print_players_list(rpc_connection) + if is_game_a_rogue: + new_game_txid = rpc_connection.cclib("newgame", "17", "[1]")["txid"] + print("New singleplayer training game succesfully created. txid: " + new_game_txid) while True: - is_choice_needed = input("Do you want to choose a player for this game? [y/n] ") - if is_choice_needed == "y": - player_txid = input("Please input player txid: ") - newgame_regisration_txid = rogue_game_register(rpc_connection, new_game_txid, player_txid)["txid"] - break - elif is_choice_needed == "n": - set_warriors_name(rpc_connection) - newgame_regisration_txid = rogue_game_register(rpc_connection, new_game_txid)["txid"] - break + mempool = rpc_connection.getrawmempool() + if new_game_txid in mempool: + print(colorize("Waiting for game transaction to be mined", "blue")) + time.sleep(5) else: - print("Please choose y or n !") + print(colorize("Game transaction is mined", "green")) + break + else: + pending_games = rpc_connection.cclib("pending", "17")["pending"] + new_game_txid = random.choice(pending_games) + if is_game_a_rogue: + players_list = rogue_players_list(rpc_connection) + if len(players_list["playerdata"]) > 0: + print_players_list(rpc_connection) + while True: + is_choice_needed = input("Do you want to choose a player for this game? [y/n] ") + if is_choice_needed == "y": + player_txid = input("Please input player txid: ") + newgame_regisration_txid = rogue_game_register(rpc_connection, new_game_txid, player_txid)["txid"] + break + elif is_choice_needed == "n": + set_warriors_name(rpc_connection) + newgame_regisration_txid = rogue_game_register(rpc_connection, new_game_txid)["txid"] + break + else: + print("Please choose y or n !") + else: + print("No players available to select") + input("Press [Enter] to continue...") + newgame_regisration_txid = rogue_game_register(rpc_connection, new_game_txid)["txid"] else: - print("No players available to select") - input("Press [Enter] to continue...") newgame_regisration_txid = rogue_game_register(rpc_connection, new_game_txid)["txid"] while True: mempool = rpc_connection.getrawmempool() @@ -1143,7 +1151,7 @@ def rogue_newgame_singleplayer(rpc_connection, is_game_a_rogue=True): print("Let's wait a little bit more") time.sleep(5) pass - if confirmations_amount < 2: + if confirmations_amount < 1: print("Last keystroke not confirmed yet! Let's wait a little") time.sleep(10) else: @@ -1163,15 +1171,16 @@ def rogue_newgame_singleplayer(rpc_connection, is_game_a_rogue=True): is_bailout_needed = input("Do you want to make bailout now [y] or wait for one more block [n]? [y/n]: ") if is_bailout_needed == "y": bailout_info = rogue_bailout(rpc_connection, new_game_txid) - while True: - try: - confirmations_amount = rpc_connection.getrawtransaction(bailout_info["txid"], 1)["confirmations"] - break - except Exception as e: - print(e) - print("Bailout not on blockchain yet. Let's wait a little bit more") - time.sleep(20) - pass + if is_game_a_rogue: + while True: + try: + confirmations_amount = rpc_connection.getrawtransaction(bailout_info["txid"], 1)["confirmations"] + break + except Exception as e: + print(e) + print("Bailout not on blockchain yet. Let's wait a little bit more") + time.sleep(20) + pass break elif is_bailout_needed == "n": game_end_height = int(rpc_connection.getinfo()["blocks"])