diff --git a/.gitignore b/.gitignore index cd5f8cd78..e28d825a6 100755 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,17 @@ deprecated/.DS_Store .DS_Store + +iguana/help/.tmpmarker + +iguana/genesis/.tmpmarker + +iguana/help.json + +iguana/autoAPI.md + +iguana/basilisk.o-2ad8cb38 +======= *.pbxproj iguana/tmp/.tmpmarker diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..20c9e805a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,22 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C++ Launch (Windows)", + "type": "cppvsdbg", + "request": "launch", + "program": "enter program name, for example ${workspaceRoot}/a.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceRoot}", + "environment": [], + "externalConsole": false + }, + { + "name": "C++ Attach (Windows)", + "type": "cppvsdbg", + "request": "attach", + "processId": "${command:pickProcess}" + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 2d49a0b55..d9dfd7341 100755 --- a/README.md +++ b/README.md @@ -223,3 +223,35 @@ sudo service ntp start Now things should be ready. To update and run notary node: pkill iguana; ./m_LP; tests/notaryinit + + + +##Build for OSX distribution## +Get OSX SDK 10.6 from https://github.com/ca333/MacOSX-SDKs/releases/tag/10.6 + +Unpack & move the .sdk folder to Xcodes SDK folder: + +```cd DownloadDirectory``` + +```mv MacOSX10.6.sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/.``` + +If you are using Xcode > 7.3 add the new SDK to XCode by changing MinimumSDKVersion in your Info.plist: + +```vi /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Info.plist``` + +Change the value to: + +``` +MinimumSDKVersion +10.6 +``` +Build crypto777 library and agents with OSX release makefile: + +```./m_onetime m_osx_release``` + +Execute the OSX deploy script: + +``` +./osx_deploy.sh +``` +The iguana binary and its linked libraries are in ```$HOME/tmp/iguana```. diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 5229414a6..84ba44794 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -198,6 +198,8 @@ int32_t OS_nonportable_init(); void OS_portable_init(); void OS_init(); +int32_t sortds(double *buf,uint32_t num,int32_t size); +int32_t revsortds(double *buf,uint32_t num,int32_t size); double OS_portable_milliseconds(); void OS_portable_randombytes(uint8_t *x,long xlen); diff --git a/crypto777/hmac_sha512.c b/crypto777/hmac_sha512.c index e1fe4e523..7df6d978f 100755 --- a/crypto777/hmac_sha512.c +++ b/crypto777/hmac_sha512.c @@ -621,4 +621,28 @@ char *hmac_whirlpool_str(char *dest,char *key,int32_t key_size,char *message) return(dest); } +void calc_md2str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) +{ + bits128 x; + calc_md2(hexstr,buf,msg,len); + decode_hex(buf,sizeof(x),hexstr); + //memcpy(buf,x.bytes,sizeof(x)); +} + +void calc_md4str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) +{ + bits128 x; + calc_md4(hexstr,buf,msg,len); + decode_hex(buf,sizeof(x),hexstr); + //memcpy(buf,x.bytes,sizeof(x)); +} + +void calc_md5str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) +{ + bits128 x; + calc_md5(hexstr,msg,len); + decode_hex(buf,sizeof(x),hexstr); + //memcpy(buf,x.bytes,sizeof(x)); +} + diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index 47ab6f5a4..5b0ce5743 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -522,11 +522,24 @@ static int _increasing_double(const void *a,const void *b) { #define double_a (*(double *)a) #define double_b (*(double *)b) - if ( double_b > double_a ) - return(-1); - else if ( double_b < double_a ) - return(1); - return(0); + if ( double_b > double_a ) + return(-1); + else if ( double_b < double_a ) + return(1); + return(0); +#undef double_a +#undef double_b +} + +static int _decreasing_double(const void *a,const void *b) +{ +#define double_a (*(double *)a) +#define double_b (*(double *)b) + if ( double_b > double_a ) + return(1); + else if ( double_b < double_a ) + return(-1); + return(0); #undef double_a #undef double_b } @@ -572,8 +585,14 @@ static int _decreasing_uint32(const void *a,const void *b) int32_t sortds(double *buf,uint32_t num,int32_t size) { - qsort(buf,num,size,_increasing_double); - return(0); + qsort(buf,num,size,_increasing_double); + return(0); +} + +int32_t revsortds(double *buf,uint32_t num,int32_t size) +{ + qsort(buf,num,size,_decreasing_double); + return(0); } int32_t sort64s(uint64_t *buf,uint32_t num,int32_t size) @@ -1086,30 +1105,6 @@ void rmd160ofsha256(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) calc_rmd160(hexstr,buf,sha256,sizeof(sha256)); } -void calc_md2str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) -{ - bits128 x; - calc_md2(hexstr,buf,msg,len); - decode_hex(buf,sizeof(x),hexstr); - //memcpy(buf,x.bytes,sizeof(x)); -} - -void calc_md4str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) -{ - bits128 x; - calc_md4(hexstr,buf,msg,len); - decode_hex(buf,sizeof(x),hexstr); - //memcpy(buf,x.bytes,sizeof(x)); -} - -void calc_md5str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) -{ - bits128 x; - calc_md5(hexstr,msg,len); - decode_hex(buf,sizeof(x),hexstr); - //memcpy(buf,x.bytes,sizeof(x)); -} - void calc_crc32str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) { uint32_t crc; uint8_t serialized[sizeof(crc)]; diff --git a/iguana/exchanges/DB/.tmpmarker b/iguana/exchanges/DB/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/ECB/.tmpmarker b/iguana/exchanges/DB/ECB/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/SWAPS/.tmpmarker b/iguana/exchanges/DB/SWAPS/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/TRANSACTIONS/.tmpmarker b/iguana/exchanges/DB/TRANSACTIONS/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/purgeable/.tmpmarker b/iguana/exchanges/DB/purgeable/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/purgeable/BTC/.tmpmarker b/iguana/exchanges/DB/purgeable/BTC/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/purgeable/BTCD/.tmpmarker b/iguana/exchanges/DB/purgeable/BTCD/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DEXstats.h b/iguana/exchanges/DEXstats.h index dec43b0cc..e31ff68e3 100644 --- a/iguana/exchanges/DEXstats.h +++ b/iguana/exchanges/DEXstats.h @@ -927,7 +927,7 @@ char *stats_prices(char *symbol,char *dest,struct DEXstats_disp *prices,int32_t } #ifndef FROM_MARKETMAKER -char *stats_JSON(char *myipaddr,int32_t mypubsock,double profitmargin,cJSON *argjson,char *remoteaddr,uint16_t port) +char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char *remoteaddr,uint16_t port) { char *method,*agent,*retstr,*source,*dest; struct tai T; uint32_t endtimestamp; struct DEXstats_disp prices[365]; int32_t leftdatenum,seconds,numdates; if ( (method= jstr(argjson,"method")) == 0 ) diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 3aba41ed2..035a90e28 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -2028,6 +2028,11 @@ char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *meth return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,2)); } +char *bitcoind_passthrut(char *coinstr,char *serverport,char *userpass,char *method,char *params,int32_t timeout) +{ + return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,timeout)); +} + int32_t bitcoin_addr2rmd160(uint8_t taddr,uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr) { bits256 hash; uint8_t *buf,_buf[26]; int32_t len,offset; @@ -2083,7 +2088,7 @@ char *bitcoin_address(char *coinaddr,uint8_t taddr,uint8_t addrtype,uint8_t *pub return(coinaddr); } -void iguana_priv2pub(void *ctx,uint8_t *pubkey33,char *coinaddr,bits256 privkey,uint8_t taddr,uint8_t addrtype) +void bitcoin_priv2pub(void *ctx,uint8_t *pubkey33,char *coinaddr,bits256 privkey,uint8_t taddr,uint8_t addrtype) { bits256 pub; //char privstr[65],url[512],postdata[1024],*retstr,*pubstr,*addr; cJSON *retjson; memset(pubkey33,0,33); @@ -2145,9 +2150,10 @@ int32_t base58encode_checkbuf(uint8_t taddr,uint8_t addrtype,uint8_t *data,int32 return(data_len + 4 + offset); } -int32_t bitcoin_wif2priv(uint8_t *addrtypep,bits256 *privkeyp,char *wifstr) +int32_t bitcoin_wif2priv(uint8_t wiftaddr,uint8_t *addrtypep,bits256 *privkeyp,char *wifstr) { - int32_t len = -1; bits256 hash; uint8_t buf[256]; + int32_t offset,len = -1; bits256 hash; uint8_t buf[256]; + offset = 1 + (wiftaddr != 0); memset(buf,0,sizeof(buf)); if ( (len= bitcoin_base58decode(buf,wifstr)) >= 4 ) { @@ -2155,8 +2161,8 @@ int32_t bitcoin_wif2priv(uint8_t *addrtypep,bits256 *privkeyp,char *wifstr) if ( len < 38 ) len = 38; hash = bits256_doublesha256(0,buf,len - 4); - *addrtypep = *buf; - memcpy(privkeyp,buf+1,32); + *addrtypep = (wiftaddr == 0) ? *buf : buf[1]; + memcpy(privkeyp,buf+offset,32); if ( (buf[len - 4]&0xff) == hash.bytes[31] && (buf[len - 3]&0xff) == hash.bytes[30] &&(buf[len - 2]&0xff) == hash.bytes[29] && (buf[len - 1]&0xff) == hash.bytes[28] ) { //int32_t i; for (i=0; i wif.(%s) addrtype.%02x -> %02x (%s)\n",bits256_str(str,privkey),wifstr,addrtype,checktype,bits256_str(str2,checkpriv)); @@ -2195,17 +2213,18 @@ int32_t bitcoin_priv2wif(char *wifstr,bits256 privkey,uint8_t addrtype) return((int32_t)strlen(wifstr)); } -int32_t bitcoin_priv2wiflong(char *wifstr,bits256 privkey,uint8_t addrtype) +int32_t bitcoin_priv2wiflong(uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype) { - uint8_t data[128]; int32_t len = 32; - memcpy(data+1,privkey.bytes,sizeof(privkey)); - len = base58encode_checkbuf(0,addrtype,data,len); + uint8_t data[128]; int32_t offset,len = 32; + offset = 1 + (wiftaddr != 0); + memcpy(data+offset,privkey.bytes,sizeof(privkey)); + len = base58encode_checkbuf(wiftaddr,addrtype,data,len); if ( bitcoin_base58encode(wifstr,data,len) == 0 ) return(-1); if ( 1 ) { uint8_t checktype; bits256 checkpriv; char str[65],str2[65]; - if ( bitcoin_wif2priv(&checktype,&checkpriv,wifstr) == sizeof(bits256) ) + if ( bitcoin_wif2priv(wiftaddr,&checktype,&checkpriv,wifstr) == sizeof(bits256) ) { if ( checktype != addrtype || bits256_cmp(checkpriv,privkey) != 0 ) printf("(%s) -> wif.(%s) addrtype.%02x -> %02x (%s)\n",bits256_str(str,privkey),wifstr,addrtype,checktype,bits256_str(str2,checkpriv)); @@ -2229,11 +2248,11 @@ bits256 LP_pubkey(bits256 privkey) return(pubkey); } -char *_setVsigner(uint8_t pubtype,struct vin_info *V,int32_t ind,char *pubstr,char *wifstr) +char *_setVsigner(uint8_t wiftaddr,uint8_t pubtype,struct vin_info *V,int32_t ind,char *pubstr,char *wifstr) { uint8_t addrtype; decode_hex(V->signers[ind].pubkey,(int32_t)strlen(pubstr)/2,pubstr); - bitcoin_wif2priv(&addrtype,&V->signers[ind].privkey,wifstr); + bitcoin_wif2priv(wiftaddr,&addrtype,&V->signers[ind].privkey,wifstr); if ( addrtype != pubtype ) return(clonestr("{\"error\":\"invalid wifA\"}")); else return(0); diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 697823cc6..a5fd82434 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -18,7 +18,7 @@ // marketmaker // -char *portstrs[][2] = { { "BTC", "8332" }, { "KMD", "7771" } }; +char *portstrs[][3] = { { "BTC", "8332" }, { "KMD", "7771" } }; uint16_t LP_rpcport(char *symbol) { @@ -29,6 +29,15 @@ uint16_t LP_rpcport(char *symbol) return(0); } +uint16_t LP_busport(uint16_t rpcport) +{ + if ( rpcport == 8332 ) + return(8334); // BTC + else if ( rpcport < (1 << 15) ) + return(65535 - rpcport); + else return(rpcport+1); +} + char *parse_conf_line(char *line,char *field) { line += strlen(field); @@ -72,8 +81,13 @@ void LP_userpassfp(char *symbol,char *username,char *password,FILE *fp) free(rpcpassword); } -void LP_statefname(char *fname,char *symbol,char *assetname,char *str,char *name) +void LP_statefname(char *fname,char *symbol,char *assetname,char *str,char *name,char *confpath) { + if ( confpath != 0 && confpath[0] != 0 ) + { + strcpy(fname,confpath); + return; + } sprintf(fname,"%s",LP_getdatadir()); #ifdef WIN32 strcat(fname,"\\"); @@ -129,11 +143,13 @@ void LP_statefname(char *fname,char *symbol,char *assetname,char *str,char *name strcat(fname,str); } -int32_t LP_userpass(char *userpass,char *symbol,char *assetname,char *confroot,char *name) +int32_t LP_userpass(char *userpass,char *symbol,char *assetname,char *confroot,char *name,char *confpath) { - FILE *fp; char fname[512],username[512],password[512],confname[16]; + FILE *fp; char fname[512],username[512],password[512],confname[512]; userpass[0] = 0; sprintf(confname,"%s.conf",confroot); + if ( 0 ) + printf("%s (%s) %s confname.(%s) confroot.(%s)\n",symbol,assetname,name,confname,confroot); #ifdef __APPLE__ int32_t len; confname[0] = toupper(confname[0]); @@ -141,23 +157,31 @@ int32_t LP_userpass(char *userpass,char *symbol,char *assetname,char *confroot,c if ( strcmp(&confname[len-4],"coin") == 0 ) confname[len - 4] = 'C'; #endif - LP_statefname(fname,symbol,assetname,confname,name); + LP_statefname(fname,symbol,assetname,confname,name,confpath); if ( (fp= fopen(fname,"rb")) != 0 ) { LP_userpassfp(symbol,username,password,fp); sprintf(userpass,"%s:%s",username,password); fclose(fp); - if ( 0 && strcmp(symbol,"HUSH") == 0 ) - printf("LP_statefname.(%s) <- %s %s %s (%s)\n",fname,name,symbol,assetname,userpass); + if ( 0 ) + printf("LP_statefname.(%s) <- %s %s %s (%s) (%s)\n",fname,name,symbol,assetname,userpass,confpath); return((int32_t)strlen(userpass)); } else printf("cant open.(%s)\n",fname); return(-1); } -cJSON *LP_coinjson(struct iguana_info *coin) +cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) { - cJSON *item = cJSON_CreateObject(); + char wifstr[128]; uint8_t tmptype; bits256 checkkey; cJSON *item = cJSON_CreateObject(); jaddstr(item,"coin",coin->symbol); + if ( showwif != 0 ) + { + bitcoin_priv2wif(coin->wiftaddr,wifstr,LP_mypriv25519,coin->wiftype); + bitcoin_wif2priv(coin->wiftaddr,&tmptype,&checkkey,wifstr); + if ( bits256_cmp(LP_mypriv25519,checkkey) == 0 ) + jaddstr(item,"wif",wifstr); + else jaddstr(item,"wif","error creating wif"); + } if ( coin->inactive != 0 ) jaddstr(item,"status","inactive"); else jaddstr(item,"status","active"); @@ -168,21 +192,42 @@ cJSON *LP_coinjson(struct iguana_info *coin) jaddnum(item,"pubtype",coin->pubtype); jaddnum(item,"p2shtype",coin->p2shtype); jaddnum(item,"wiftype",coin->wiftype); - jaddnum(item,"estimatedrate",coin->estimatedrate); jaddnum(item,"txfee",coin->txfee); return(item); } -cJSON *LP_coinsjson() +cJSON *LP_coinsjson(int32_t showwif) { struct iguana_info *coin,*tmp; cJSON *array = cJSON_CreateArray(); HASH_ITER(hh,LP_coins,coin,tmp) { - jaddi(array,LP_coinjson(coin)); + jaddi(array,LP_coinjson(coin,showwif)); } return(array); } +char *LP_getcoin(char *symbol) +{ + int32_t numenabled,numdisabled; struct iguana_info *coin,*tmp; cJSON *item=0,*retjson; + numenabled = numdisabled = 0; + retjson = cJSON_CreateObject(); + HASH_ITER(hh,LP_coins,coin,tmp) + { + if ( strcmp(symbol,coin->symbol) == 0 ) + item = LP_coinjson(coin,0); + if ( coin->inactive == 0 ) + numenabled++; + else numdisabled++; + } + jaddstr(retjson,"result","success"); + jaddnum(retjson,"enabled",numenabled); + jaddnum(retjson,"disabled",numdisabled); + if ( item == 0 ) + item = cJSON_CreateObject(); + jadd(retjson,"coin",item); + return(jprint(retjson,1)); +} + struct iguana_info *LP_coinsearch(char *symbol) { struct iguana_info *coin; @@ -204,7 +249,7 @@ struct iguana_info *LP_coinadd(struct iguana_info *cdata) return(coin); } -int32_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetname,int32_t isPoS,uint16_t port,uint8_t pubtype,uint8_t p2shtype,uint8_t wiftype,uint64_t txfee,double estimatedrate,int32_t longestchain,uint8_t taddr) +int32_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetname,int32_t isPoS,uint16_t port,uint8_t pubtype,uint8_t p2shtype,uint8_t wiftype,uint64_t txfee,double estimatedrate,int32_t longestchain,uint8_t wiftaddr,uint8_t taddr,uint16_t busport,char *confpath) { char *name2; memset(coin,0,sizeof(*coin)); @@ -212,17 +257,23 @@ int32_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asset sprintf(coin->serverport,"127.0.0.1:%u",port); coin->isPoS = isPoS; coin->taddr = taddr; + coin->wiftaddr = wiftaddr; coin->longestchain = longestchain; coin->txfee = txfee; - coin->estimatedrate = estimatedrate; coin->pubtype = pubtype; coin->p2shtype = p2shtype; coin->wiftype = wiftype; coin->inactive = (uint32_t)time(NULL); + coin->bussock = LP_coinbus(busport); if ( strcmp(symbol,"KMD") == 0 || (assetname != 0 && assetname[0] != 0) ) name2 = 0; else name2 = name; - return(LP_userpass(coin->userpass,symbol,assetname,name,name2)); + if ( strcmp(symbol,"XVG") == 0 || strcmp(symbol,"CLOAK") == 0 || strcmp(symbol,"PPC") == 0 || strcmp(symbol,"BCC") == 0 || strcmp(symbol,"ORB") == 0 ) + { + coin->noimportprivkey_flag = 1; + printf("truncate importprivkey for %s\n",symbol); + } + return(LP_userpass(coin->userpass,symbol,assetname,name,name2,confpath)); } int32_t LP_isdisabled(char *base,char *rel) @@ -237,13 +288,15 @@ int32_t LP_isdisabled(char *base,char *rel) struct iguana_info *LP_coinfind(char *symbol) { - struct iguana_info *coin,cdata; int32_t isPoS,longestchain = 1; uint16_t port; uint64_t txfee; double estimatedrate; uint8_t pubtype,p2shtype,wiftype; char *name,*assetname; + struct iguana_info *coin,cdata; int32_t isinactive,isPoS,longestchain = 1; uint16_t port,busport; uint64_t txfee; double estimatedrate; uint8_t pubtype,p2shtype,wiftype; char *name,*assetname; if ( (coin= LP_coinsearch(symbol)) != 0 ) return(coin); if ( (port= LP_rpcport(symbol)) == 0 ) return(0); + if ( (busport= LP_busport(port)) == 0 ) + return(0); isPoS = 0; - txfee = 10000; + txfee = LP_MIN_TXFEE; estimatedrate = 20; pubtype = 60; p2shtype = 85; @@ -251,7 +304,7 @@ struct iguana_info *LP_coinfind(char *symbol) assetname = ""; if ( strcmp(symbol,"BTC") == 0 ) { - txfee = 50000; + txfee = 0; estimatedrate = 300; pubtype = 0; p2shtype = 5; @@ -261,17 +314,16 @@ struct iguana_info *LP_coinfind(char *symbol) else if ( strcmp(symbol,"KMD") == 0 ) name = "komodo"; else return(0); - if ( LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0) > 0 ) + isinactive = LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0,0,busport,0) < 0; + if ( (coin= LP_coinadd(&cdata)) != 0 ) { - if ( (coin= LP_coinadd(&cdata)) != 0 ) + coin->inactive = isinactive * (uint32_t)time(NULL); + if ( strcmp(symbol,"KMD") == 0 ) + coin->inactive = 0; + else if ( strcmp(symbol,"BTC") == 0 ) { - if ( strcmp(symbol,"KMD") == 0 ) - coin->inactive = 0; - else if ( strcmp(symbol,"BTC") == 0 ) - { - coin->inactive = (uint32_t)time(NULL); // * !IAMLP - printf("BTC inactive.%u\n",coin->inactive); - } + coin->inactive = (uint32_t)time(NULL) * !IAMLP; + printf("BTC inactive.%u\n",coin->inactive); } } return(coin); @@ -286,26 +338,28 @@ struct iguana_info *LP_coincreate(cJSON *item) if ( (symbol= jstr(item,"coin")) != 0 && symbol[0] != 0 && strlen(symbol) < 16 && LP_coinfind(symbol) == 0 && (port= juint(item,"rpcport")) != 0 ) { isPoS = jint(item,"isPoS"); - if ( (txfee= j64bits(item,"txfee")) == 0 ) - txfee = 10000; + txfee = j64bits(item,"txfee"); if ( (estimatedrate= jdouble(item,"estimatedrate")) == 0. ) estimatedrate = 20; - if ( (pubtype= juint(item,"pubtype")) == 0 ) - pubtype = 60; + pubtype = juint(item,"pubtype"); if ( (p2shtype= juint(item,"p2shtype")) == 0 ) p2shtype = 85; if ( (wiftype= juint(item,"wiftype")) == 0 ) wiftype = 188; if ( (assetname= jstr(item,"asset")) != 0 ) + { name = assetname; + pubtype = 60; + } else if ( (name= jstr(item,"name")) == 0 ) name = symbol; - if ( LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,jint(item,"taddr")) < 0 ) + if ( LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,juint(item,"wiftaddr"),juint(item,"taddr"),LP_busport(port),jstr(item,"confpath")) < 0 ) { coin = LP_coinadd(&cdata); coin->inactive = (uint32_t)time(NULL); } else coin = LP_coinadd(&cdata); - } + } else if ( symbol != 0 && jobj(item,"rpcport") == 0 ) + printf("SKIP %s, missing rpcport field in coins array\n",symbol); if ( coin != 0 && item != 0 ) { if ( strcmp("KMD",coin->symbol) != 0 ) diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index d759c4723..7af18862c 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -18,11 +18,24 @@ // marketmaker // +char *LP_numutxos() +{ + cJSON *retjson = cJSON_CreateObject(); + if ( LP_mypeer != 0 ) + { + jaddstr(retjson,"ipaddr",LP_mypeer->ipaddr); + jaddnum(retjson,"port",LP_mypeer->port); + jaddnum(retjson,"numutxos",LP_mypeer->numutxos); + jaddnum(retjson,"numpeers",LP_mypeer->numpeers); + jaddnum(retjson,"session",LP_sessionid); + } else jaddstr(retjson,"error","client node"); + return(jprint(retjson,1)); +} -char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,double profitmargin,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port +char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port { - char *method,*ipaddr,*userpass,*base,*rel,*coin,*retstr = 0; uint16_t argport=0,pushport,subport; int32_t otherpeers,othernumutxos,flag = 0; struct LP_peerinfo *peer; cJSON *retjson; struct iguana_info *ptr; - //printf("stats_JSON(%s)\n",jprint(argjson,0)); + char *method,*ipaddr,*userpass,*base,*rel,*coin,*retstr = 0; uint16_t argport=0,pushport,subport; int32_t changed,otherpeers,othernumutxos,flag = 0; struct LP_peerinfo *peer; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; +//printf("stats_JSON(%s)\n",jprint(argjson,0)); if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 ) { if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) @@ -41,8 +54,10 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,double profitmargin,cJ printf("change.(%s) numutxos.%d -> %d mynumutxos.%d\n",peer->ipaddr,peer->numutxos,othernumutxos,LP_mypeer != 0 ? LP_mypeer->numutxos:0); peer->numutxos = othernumutxos; } + if ( peer->sessionid == 0 ) + peer->sessionid = juint(argjson,"session"); //printf("peer.(%s) found (%d %d) (%d %d) (%s)\n",peer->ipaddr,peer->numpeers,peer->numutxos,otherpeers,othernumutxos,jprint(argjson,0)); - } else LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,argport,pushport,subport,jdouble(argjson,"profit"),jint(argjson,"numpeers"),jint(argjson,"numutxos")); + } else LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,argport,pushport,subport,jint(argjson,"numpeers"),jint(argjson,"numutxos"),juint(argjson,"session")); } } if ( (method= jstr(argjson,"method")) == 0 ) @@ -51,48 +66,63 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,double profitmargin,cJ printf("stats_JSON no method: (%s) (%s:%u)\n",jprint(argjson,0),ipaddr,argport); return(0); } - if ( strcmp(method,"hello") == 0 ) + /*if ( strcmp(method,"hello") == 0 ) { //printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport); return(0); } - else if ( strcmp(method,"message") == 0 ) + else*/ if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 0 ) { - printf("got message.(%s) from %s:%u\n",jprint(argjson,0),ipaddr!=0?ipaddr:"",argport); - return(0); + static char *laststr; + char *newstr; bits256 pubkey = jbits256(argjson,"pubkey"); + if ( bits256_nonz(pubkey) == 0 || bits256_cmp(pubkey,LP_mypub25519) == 0 ) + { + newstr = jprint(argjson,0); + if ( laststr == 0 || strcmp(laststr,newstr) != 0 ) + { + printf("got message.(%s) from %s:%u\n",newstr,ipaddr!=0?ipaddr:"",argport); + if ( laststr != 0 ) + free(laststr); + laststr = newstr; + LP_gotmessage(argjson); + retstr = clonestr(laststr); + } + } else retstr = clonestr("{\"error\":\"duplicate message\"}"); } - else if ( strcmp(method,"nn_tests") == 0 ) - return(clonestr("{\"result\":\"success\"}")); + //else if ( strcmp(method,"nn_tests") == 0 ) + // return(clonestr("{\"result\":\"success\"}")); else if ( strcmp(method,"help") == 0 ) return(clonestr("{\"result\":\" \ available localhost RPC commands:\n \ +pricearray(base, rel, firsttime=0, lasttime=-1, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\ setprice(base, rel, price)\n\ +autoprice(base, rel, price, margin, type)\n\ +goal(coin=*, val=)\n\ myprice(base, rel)\n\ enable(coin)\n\ disable(coin)\n\ inventory(coin)\n\ bestfit(rel, relvolume)\n\ -ordermatch(base, txfee=0, rel, desttxfee=0, price, txid, vout, feetxid, feevout, duration=3600)\n\ +ordermatch(base, txfee=0, rel, desttxfee=0, price, relvolume=0, txid, vout, feetxid, feevout, duration=3600)\n\ trade(price, timeout=10, duration=3600, )\n\ autotrade(base, rel, price, relvolume, timeout=10, duration=3600)\n\ swapstatus()\n\ swapstatus(requestid, quoteid)\n\ public API:\n \ getcoins()\n\ +getcoin(coin)\n\ +portfolio()\n\ getpeers()\n\ getutxos()\n\ getutxos(coin, lastn)\n\ orderbook(base, rel, duration=3600)\n\ getprices(base, rel)\n\ +sendmessage(base=coin, rel="", pubkey=zero, )\n\ +getmessages(firsti=0, num=100)\n\ +clearmessages(firsti=0, num=100)\n\ trust(pubkey, trust)\n\ -register(pubkey,pushaddr)\n\ -registerall(numnodes)\n\ -lookup(pubkey)\n\ -message(pubkey,)\n\ -forward(pubkey,method2,)\n\ -forward(pubkey,method2=publish,)\n\ -forwardhex(pubkey,hex)\n\ \"}")); + base = jstr(argjson,"base"); rel = jstr(argjson,"rel"); if ( USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 ) @@ -102,27 +132,64 @@ forwardhex(pubkey,hex)\n\ USERPASS_COUNTER = 1; retjson = cJSON_CreateObject(); jaddstr(retjson,"userpass",USERPASS); - jaddbits256(retjson,"mypubkey",LP_mypubkey); - jadd(retjson,"coins",LP_coinsjson()); + jaddbits256(retjson,"mypubkey",LP_mypub25519); + jadd(retjson,"coins",LP_coinsjson(LP_showwif)); return(jprint(retjson,1)); } if ( (userpass= jstr(argjson,"userpass")) == 0 || strcmp(userpass,USERPASS) != 0 ) return(clonestr("{\"error\":\"authentication error\"}")); + jdelete(argjson,"userpass"); + if ( strcmp(method,"sendmessage") == 0 ) + { + if ( jobj(argjson,"method2") == 0 ) + { + printf("broadcast message\n"); + LP_broadcast_message(LP_mypubsock,base!=0?base:jstr(argjson,"coin"),rel,jbits256(argjson,"pubkey"),jprint(argjson,0)); + } + return(clonestr("{\"result\":\"success\"}")); + } + else if ( strcmp(method,"getmessages") == 0 ) + { + if ( (retjson= LP_getmessages(jint(argjson,"firsti"),jint(argjson,"num"))) != 0 ) + return(jprint(retjson,1)); + else return(clonestr("{\"error\":\"null messages\"}")); + } + else if ( strcmp(method,"deletemessages") == 0 ) + { + LP_deletemessages(jint(argjson,"firsti"),jint(argjson,"num")); + return(clonestr("{\"result\":\"success\"}")); + } + else if ( strcmp(method,"portfolio") == 0 ) + { + return(LP_portfolio()); + } if ( base != 0 && rel != 0 ) { double price,bid,ask; - if ( LP_isdisabled(base,rel) != 0 ) + if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 ) return(clonestr("{\"error\":\"at least one of coins disabled\"}")); price = jdouble(argjson,"price"); if ( strcmp(method,"setprice") == 0 ) { if ( price > SMALLVAL ) { - if ( LP_mypriceset(base,rel,price) < 0 ) + if ( LP_mypriceset(&changed,base,rel,price) < 0 ) return(clonestr("{\"error\":\"couldnt set price\"}")); - else return(LP_pricepings(ctx,myipaddr,LP_mypubsock,profitmargin,base,rel,price * LP_profitratio)); + //else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 ) + // return(clonestr("{\"error\":\"couldnt set price\"}")); + else return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio)); } else return(clonestr("{\"error\":\"no price\"}")); } + else if ( strcmp(method,"autoprice") == 0 ) + { + if ( LP_autoprice(base,rel,price,jdouble(argjson,"margin"),jstr(argjson,"type")) < 0 ) + return(clonestr("{\"error\":\"couldnt set autoprice\"}")); + else return(clonestr("{\"result\":\"success\"}")); + } + else if ( strcmp(method,"pricearray") == 0 ) + { + return(jprint(LP_pricearray(base,rel,juint(argjson,"firsttime"),juint(argjson,"lasttime"),jint(argjson,"timescale")),1)); + } else if ( strcmp(method,"myprice") == 0 ) { if ( LP_myprice(&bid,&ask,base,rel) > SMALLVAL ) @@ -138,7 +205,7 @@ forwardhex(pubkey,hex)\n\ else if ( strcmp(method,"ordermatch") == 0 ) { if ( price > SMALLVAL ) - return(LP_ordermatch(base,j64bits(argjson,"txfee"),price,rel,jbits256(argjson,"txid"),jint(argjson,"vout"),jbits256(argjson,"feetxid"),jint(argjson,"feevout"),j64bits(argjson,"desttxfee"),jint(argjson,"duration"))); + return(LP_ordermatch(base,j64bits(argjson,"txfee"),price,jdouble(argjson,"relvolume"),rel,jbits256(argjson,"txid"),jint(argjson,"vout"),jbits256(argjson,"feetxid"),jint(argjson,"feevout"),j64bits(argjson,"desttxfee"),jint(argjson,"duration"))); else return(clonestr("{\"error\":\"no price set\"}")); } else if ( strcmp(method,"trade") == 0 ) @@ -147,16 +214,14 @@ forwardhex(pubkey,hex)\n\ if ( price > SMALLVAL || jobj(argjson,"quote") != 0 ) { LP_quoteparse(&Q,jobj(argjson,"quote")); - return(LP_trade(ctx,myipaddr,pubsock,profitmargin,&Q,price,jint(argjson,"timeout"),jint(argjson,"duration"))); + return(LP_trade(ctx,myipaddr,pubsock,&Q,price,jint(argjson,"timeout"),jint(argjson,"duration"))); } else return(clonestr("{\"error\":\"no price set or no quote object\"}")); } else if ( strcmp(method,"autotrade") == 0 ) { if ( price > SMALLVAL ) { - printf("price set (%s/%s) <- %.8f\n",rel,base,1./price); - LP_mypriceset(rel,base,1./price); - return(LP_autotrade(ctx,myipaddr,pubsock,profitmargin,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"))); + return(LP_autotrade(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"))); } else return(clonestr("{\"error\":\"no price set\"}")); } } @@ -173,24 +238,25 @@ forwardhex(pubkey,hex)\n\ { if ( (ptr= LP_coinsearch(coin)) != 0 ) ptr->inactive = 0; - return(jprint(LP_coinsjson(),1)); + return(jprint(LP_coinsjson(0),1)); } else if ( strcmp(method,"disable") == 0 ) { if ( (ptr= LP_coinsearch(coin)) != 0 ) ptr->inactive = (uint32_t)time(NULL); - return(jprint(LP_coinsjson(),1)); + return(jprint(LP_coinsjson(0),1)); } if ( LP_isdisabled(coin,0) != 0 ) return(clonestr("{\"error\":\"coin is disabled\"}")); if ( strcmp(method,"inventory") == 0 ) { - struct iguana_info *ptr; bits256 privkey,pubkey; uint8_t pubkey33[33]; + struct iguana_info *ptr; if ( (ptr= LP_coinfind(coin)) != 0 ) { - privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,ptr,"",USERPASS_WIFSTR); + //privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,ptr,"",USERPASS_WIFSTR); //LP_utxopurge(0); - LP_privkey_init(-1,ptr,privkey,pubkey,pubkey33); + if ( bits256_nonz(LP_mypriv25519) != 0 ) + LP_privkey_init(-1,ptr,LP_mypriv25519,LP_mypub25519); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jaddstr(retjson,"coin",coin); @@ -200,7 +266,13 @@ forwardhex(pubkey,hex)\n\ return(jprint(retjson,1)); } } + else if ( strcmp(method,"goal") == 0 ) + return(LP_portfolio_goal(coin,jdouble(argjson,"val"))); + else if ( strcmp(method,"getcoin") == 0 ) + return(LP_getcoin(coin)); } + else if ( strcmp(method,"goal") == 0 ) + return(LP_portfolio_goal("*",100.)); else if ( strcmp(method,"swapstatus") == 0 ) { uint32_t requestid,quoteid; @@ -213,9 +285,22 @@ forwardhex(pubkey,hex)\n\ else if ( strcmp(method,"trust") == 0 ) return(LP_pubkey_trustset(jbits256(argjson,"pubkey"),jint(argjson,"trust"))); } - if ( LP_isdisabled(base,rel) != 0 ) + if ( IAMLP == 0 ) + { + if ( (reqjson= LP_dereference(argjson,"broadcast")) != 0 ) + { + if ( jobj(reqjson,"method2") != 0 ) + { + jdelete(reqjson,"method"); + method = jstr(reqjson,"method2"); + jaddstr(reqjson,"method",method); + } + argjson = reqjson; + } + } + if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 ) return(clonestr("{\"result\":\"at least one of coins disabled\"}")); - else if ( LP_isdisabled(jstr(argjson,"coin"),0) != 0 ) + else if ( IAMLP == 0 && LP_isdisabled(jstr(argjson,"coin"),0) != 0 ) retstr = clonestr("{\"result\":\"coin is disabled\"}"); else if ( strcmp(method,"reserved") == 0 ) retstr = LP_quotereceived(argjson); @@ -224,59 +309,63 @@ forwardhex(pubkey,hex)\n\ else if ( strcmp(method,"checktxid") == 0 ) retstr = LP_spentcheck(argjson); else if ( strcmp(method,"getcoins") == 0 ) - return(jprint(LP_coinsjson(),1)); + return(jprint(LP_coinsjson(0),1)); + else if ( strcmp(method,"numutxos") == 0 ) + return(LP_numutxos()); else if ( strcmp(method,"postprice") == 0 ) retstr = LP_postedprice(argjson); - else if ( strcmp(method,"broadcast") == 0 ) - retstr = LP_broadcasted(argjson); + else if ( strcmp(method,"encrypted") == 0 ) + retstr = clonestr("{\"result\":\"success\"}"); else if ( strcmp(method,"getprices") == 0 ) return(LP_prices()); else if ( strcmp(method,"orderbook") == 0 ) return(LP_orderbook(base,rel,jint(argjson,"duration"))); else if ( strcmp(method,"registerall") == 0 ) - return(LP_registerall(jint(argjson,"numnodes"))); + return(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); else if ( strcmp(method,"forward") == 0 ) - { - cJSON *reqjson; - if ( (reqjson= LP_dereference(argjson,"forward")) != 0 ) - { - //printf("FORWARDED.(%s)\n",jprint(argjson,0)); - if ( LP_forward(ctx,myipaddr,pubsock,profitmargin,jbits256(argjson,"pubkey"),jprint(reqjson,1),1) > 0 ) - retstr = clonestr("{\"result\":\"success\"}"); - else retstr = clonestr("{\"result\":\"error forwarding\"}"); - } else retstr = clonestr("{\"result\":\"cant recurse forwards\"}"); - return(retstr); - } + return(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); else if ( strcmp(method,"keepalive") == 0 ) - { - printf("got keepalive lag.%d switch.%u\n",(int32_t)time(NULL) - LP_deadman_switch,LP_deadman_switch); - LP_deadman_switch = (uint32_t)time(NULL); - return(clonestr("{\"result\":\"success\"}")); - } + return(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); else if ( strcmp(method,"getpeers") == 0 ) return(LP_peers()); else if ( strcmp(method,"getutxos") == 0 ) return(LP_utxos(1,LP_mypeer,jstr(argjson,"coin"),jint(argjson,"lastn"))); - else if ( strcmp(method,"notified") == 0 ) + else if ( strcmp(method,"utxo") == 0 ) { if ( LP_utxoaddjson(1,LP_mypubsock,argjson) != 0 ) - return(clonestr("{\"result\":\"success\",\"notifyutxo\":\"received\"}")); - else return(clonestr("{\"result\":\"couldnt add utxo\"}")); + retstr = clonestr("{\"result\":\"success\",\"utxo\":\"received\"}"); + else retstr = clonestr("{\"result\":\"couldnt add utxo\"}"); } else { if ( IAMLP != 0 ) { if ( strcmp(method,"register") == 0 ) + return(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); + else if ( strcmp(method,"lookup") == 0 ) + return(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); + if ( strcmp(method,"broadcast") == 0 ) { - retstr = LP_register(jbits256(argjson,"client"),jstr(argjson,"pushaddr"),juint(argjson,"pushport")); - //printf("got (%s) from register\n",retstr!=0?retstr:""); - return(retstr); + bits256 zero; char *cipherstr; int32_t cipherlen; uint8_t cipher[LP_ENCRYPTED_MAXSIZE]; + if ( (reqjson= LP_dereference(argjson,"broadcast")) != 0 ) + { + if ( (cipherstr= jstr(reqjson,"cipher")) != 0 ) + { + cipherlen = (int32_t)strlen(cipherstr) >> 1; + if ( cipherlen <= sizeof(cipher) ) + { + decode_hex(cipher,cipherlen,cipherstr); + LP_queuesend(calc_crc32(0,&cipher[2],cipherlen-2),LP_mypubsock,base,rel,cipher,cipherlen); + } else retstr = clonestr("{\"error\":\"cipher too big\"}"); + } + else + { + memset(zero.bytes,0,sizeof(zero)); + LP_broadcast_message(LP_mypubsock,base!=0?base:jstr(argjson,"coin"),rel,zero,jprint(reqjson,0)); + } + retstr = clonestr("{\"result\":\"success\"}"); + } else retstr = clonestr("{\"error\":\"couldnt dereference sendmessage\"}"); } - else if ( strcmp(method,"lookup") == 0 ) - return(LP_lookup(jbits256(argjson,"client"))); - else if ( strcmp(method,"forwardhex") == 0 ) - retstr = LP_forwardhex(ctx,pubsock,jbits256(argjson,"pubkey"),jstr(argjson,"hex")); else if ( strcmp(method,"psock") == 0 ) { if ( myipaddr == 0 || myipaddr[0] == 0 || strcmp(myipaddr,"127.0.0.1") == 0 ) @@ -285,25 +374,30 @@ forwardhex(pubkey,hex)\n\ myipaddr = LP_mypeer->ipaddr; else printf("LP_psock dont have actual ipaddr?\n"); } - return(LP_psock(myipaddr,jint(argjson,"ispaired"))); + if ( jint(argjson,"ispaired") != 0 ) + return(LP_psock(myipaddr,jint(argjson,"ispaired"))); + else return(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); } else if ( strcmp(method,"notify") == 0 ) retstr = clonestr("{\"result\":\"success\",\"notify\":\"received\"}"); } else { - if ( strcmp(method,"register") == 0 ) + if ( strcmp(method,"psock") == 0 ) { - printf("nonLP got (%s)\n",jprint(argjson,0)); - retstr = clonestr("{\"result\":\"success\",\"register\":\"received\"}"); + //printf("nonLP got (%s)\n",jprint(argjson,0)); + retstr = clonestr("{\"result\":\"success\"}"); } } } + if ( retstr == 0 ) + printf("ERROR.(%s)\n",jprint(argjson,0)); + if ( reqjson != 0 ) + free_json(reqjson); if ( retstr != 0 ) { free(retstr); return(0); } - printf("ERROR.(%s)\n",jprint(argjson,0)); return(0); } diff --git a/iguana/exchanges/LP_forwarding.c b/iguana/exchanges/LP_forwarding.c index 25a1c9b4c..749cf2f2e 100644 --- a/iguana/exchanges/LP_forwarding.c +++ b/iguana/exchanges/LP_forwarding.c @@ -18,6 +18,19 @@ // marketmaker // +cJSON *LP_dereference(cJSON *argjson,char *excludemethod) +{ + cJSON *reqjson = 0; + if ( jstr(argjson,"method2") != 0 && strncmp(excludemethod,jstr(argjson,"method2"),strlen(excludemethod)) != 0 ) + { + reqjson = jduplicate(argjson); + jdelete(reqjson,"method"); + jaddstr(reqjson,"method",jstr(argjson,"method2")); + } + return(reqjson); +} + +/* struct LP_forwardinfo { UT_hash_handle hh; @@ -176,24 +189,13 @@ int32_t LP_forwarding_register(bits256 pubkey,char *publicaddr,uint16_t publicpo if ( peer->pushsock >= 0 ) { if ( LP_send(peer->pushsock,argstr,arglen,0) != arglen ) - printf("you can ignore error sending command to %s:%u\n",peer->ipaddr,peer->port); - //else printf("sent register to %s:%u\n",peer->ipaddr,peer->port); + { + if ( strncmp(peer->ipaddr,"5.9.253",strlen("5.9.253")) == 0 ) + printf("error registering with %s:%u\n",peer->ipaddr,peer->port); + } n++; } //printf("register.(%s) %s %u with (%s)\n",publicaddr,ipaddr,publicport,peer->ipaddr); - /*if ( (retstr= issue_LP_register(peer->ipaddr,peer->port,pubkey,ipaddr,publicport)) != 0 ) - { - //printf("[%s] LP_register.(%s) returned.(%s)\n",publicaddr,peer->ipaddr,retstr); - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( jint(retjson,"registered") != 0 && ++n >= max ) - retval = 0; - free_json(retjson); - } - free(retstr); - } else printf("timeout registering with %s errs.%d good.%d\n",peer->ipaddr,peer->errors,peer->good); - if ( retval == 0 ) - break;*/ } free(argstr); return(n); @@ -218,18 +220,6 @@ char *LP_registerall(int32_t numnodes) return(jprint(retjson,1)); } -cJSON *LP_dereference(cJSON *argjson,char *excludemethod) -{ - cJSON *reqjson = 0; - if ( jstr(argjson,"method2") != 0 && strncmp(excludemethod,jstr(argjson,"method2"),strlen(excludemethod)) != 0 ) - { - reqjson = jduplicate(argjson); - jdelete(reqjson,"method"); - jaddstr(reqjson,"method",jstr(argjson,"method2")); - } - return(reqjson); -} - char *LP_forwardhex(void *ctx,int32_t pubsock,bits256 pubkey,char *hexstr) { struct LP_forwardinfo *ptr=0; uint8_t *data; int32_t datalen=0,sentbytes=0; char *msg,*retstr=0; cJSON *retjson=0,*argjson=0,*reqjson=0; @@ -245,7 +235,7 @@ char *LP_forwardhex(void *ctx,int32_t pubsock,bits256 pubkey,char *hexstr) if ( reqjson != 0 ) { retstr = LP_command_process(ctx,LP_mypeer != 0 ? LP_mypeer->ipaddr : "127.0.0.1",LP_mypubsock,reqjson,0,0,LP_profitratio - 1.); - printf("LP_forwardhex.(%s) -> (%s)\n",jprint(reqjson,0),retstr!=0?retstr:""); + //printf("LP_forwardhex.(%s) -> (%s)\n",jprint(reqjson,0),retstr!=0?retstr:""); if ( pubsock >= 0 ) { msg = jprint(reqjson,0); @@ -255,16 +245,20 @@ char *LP_forwardhex(void *ctx,int32_t pubsock,bits256 pubkey,char *hexstr) } else if ( (ptr= LP_forwardfind(pubkey)) != 0 ) { - if ( ptr->pushsock >= 0 )//&& ptr->hello != 0 ) + if ( ptr->pushsock >= 0 ) { printf("%s forwardhex.(%s)\n",ptr->pushaddr,(char *)data); sentbytes = LP_send(ptr->pushsock,(char *)data,datalen,0); } retjson = cJSON_CreateObject(); - if ( sentbytes == datalen ) + if ( sentbytes >= 0 ) { jaddstr(retjson,"result","success"); - jaddnum(retjson,"forwarded",sentbytes); + if ( sentbytes == datalen ) + jaddnum(retjson,"forwarded",sentbytes); + else if ( sentbytes == 0 ) + jaddnum(retjson,"queued",sentbytes); + else jaddnum(retjson,"mismatch",sentbytes); retstr = jprint(retjson,1); } else @@ -294,9 +288,9 @@ char *LP_forwardhex(void *ctx,int32_t pubsock,bits256 pubkey,char *hexstr) return(retstr); } -int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,double profitmargin,bits256 pubkey,char *jsonstr,int32_t freeflag) +int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,bits256 pubkey,char *jsonstr,int32_t freeflag) { - struct LP_forwardinfo *ptr; struct LP_peerinfo *peer,*tmp; char *msg,*hexstr,*retstr; int32_t len,n=0,mlen; cJSON *retjson,*reqjson,*argjson; + struct LP_forwardinfo *ptr; struct LP_peerinfo *peer,*tmp; char *msg,*hexstr,*retstr; int32_t len,n=0,mlen; cJSON *reqjson,*argjson; if ( jsonstr == 0 || jsonstr[0] == 0 ) return(-1); len = (int32_t)strlen(jsonstr) + 1; @@ -307,7 +301,7 @@ int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,double profitmargin, printf("GOT FORWARDED.(%s)\n",myipaddr); if ( (argjson= cJSON_Parse(jsonstr)) != 0 ) { - if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,0,0,profitmargin)) != 0 ) + if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,0,0)) != 0 ) free(retstr); free_json(argjson); } @@ -315,15 +309,11 @@ int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,double profitmargin, free(jsonstr); return(1); } - else if ( IAMLP != 0 && (ptr= LP_forwardfind(pubkey)) != 0 && ptr->pushsock >= 0 )//&& ptr->lasttime > time(NULL)-LP_KEEPALIVE ) + else if ( IAMLP != 0 && (ptr= LP_forwardfind(pubkey)) != 0 && ptr->pushsock >= 0 ) { printf("GOT FORWARDED.(%s) -> pushsock.%d\n",jsonstr,ptr->pushsock); - if ( LP_send(ptr->pushsock,jsonstr,len,0) == len ) - { - if ( freeflag != 0 ) - free(jsonstr); + if ( LP_send(ptr->pushsock,jsonstr,len,freeflag) == len ) return(1); - } } } hexstr = malloc(len*2 + 1); @@ -333,27 +323,15 @@ int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,double profitmargin, reqjson = cJSON_CreateObject(); jaddstr(reqjson,"method","forwardhex"); jaddstr(reqjson,"hex",hexstr); - jaddbits256(reqjson,"pubkey",pubkey); free(hexstr); msg = jprint(reqjson,1); mlen = (int32_t)strlen(msg) + 1; HASH_ITER(hh,LP_peerinfos,peer,tmp) { - if ( (retstr= issue_LP_lookup(peer->ipaddr,peer->port,pubkey)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( jint(retjson,"forwarding") != 0 && peer->pushsock >= 0 ) - { - printf("found LPnode.(%s) forward.(%s)\n",peer->ipaddr,msg); - if ( LP_send(peer->pushsock,msg,mlen,0) == mlen ) - n++; - } else printf("%s:%u doesnt forward pubkey (%s)\n",peer->ipaddr,peer->port,retstr); - free_json(retjson); - } - free(retstr); - } else printf("%s:%u doesnt have pubkey\n",peer->ipaddr,peer->port); - if ( n >= 3 )//sizeof(default_LPnodes)/sizeof(*default_LPnodes) ) + //printf("found LPnode.(%s) forward.(%s)\n",peer->ipaddr,msg); + if ( LP_send(peer->pushsock,msg,mlen,0) == mlen ) + n++; + if ( n >= 8 )//sizeof(default_LPnodes)/sizeof(*default_LPnodes) ) break; } if ( msg != 0 ) @@ -369,5 +347,5 @@ char *LP_broadcasted(cJSON *argjson) printf("RECV BROADCAST.(%s)\n",jprint(argjson,0)); return(clonestr("{\"result\":\"need to update broadcast messages\"}")); } - +*/ diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index a9f39580c..2f054f70a 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -21,12 +21,16 @@ #ifndef LP_INCLUDE_H #define LP_INCLUDE_H +#define LP_STRICTPEERS + #define LP_COMMAND_SENDSOCK NN_PUSH #define LP_COMMAND_RECVSOCK NN_PULL +#define LP_ENCRYPTED_MAXSIZE (4096 + 2 + crypto_box_NONCEBYTES + crypto_box_ZEROBYTES) + #define LP_MAXPUBKEY_ERRORS 3 #define PSOCK_KEEPALIVE 3600 -#define MAINLOOP_PERSEC 10 +#define MAINLOOP_PERSEC 100 #define MAX_PSOCK_PORT 60000 #define MIN_PSOCK_PORT 10000 #define LP_MEMPOOL_TIMEINCR 10 @@ -38,11 +42,13 @@ #define LP_MINPEER_GOOD 20 #define LP_PEERGOOD_ERRORDECAY 0.9 -#define LP_SWAPSTEP_TIMEOUT 3 +#define LP_SWAPSTEP_TIMEOUT 30 #define LP_AUTOTRADE_TIMEOUT 60 #define LP_MIN_TXFEE 10000 #define LP_MINVOL 10 #define LP_MINCLIENTVOL 20 +#define LP_MINSIZE_TXFEEMULT 10 +#define LP_REQUIRED_TXFEE 0.95 #define LP_DEXFEE(destsatoshis) ((destsatoshis) / INSTANTDEX_INSURANCEDIV) #define LP_DEPOSITSATOSHIS(satoshis) ((satoshis) + (satoshis >> 3)) @@ -62,7 +68,7 @@ #define LP_PROPAGATION_SLACK 100 // txid ordering is not enforced, so getting extra recent txid #define LP_RESERVETIME 60 -#define LP_AVETXSIZE 200 +#define LP_AVETXSIZE 256 #define LP_CACHEDURATION 60 #define BASILISK_DEFAULT_NUMCONFIRMS 1 #define DEX_SLEEP 3 @@ -145,7 +151,7 @@ struct basilisk_swapinfo bits256 myhash,otherhash,orderhash; uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration; int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad; - uint64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance; + uint64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee; bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn; uint32_t crcs_mypub[2],crcs_mychoosei[2],crcs_myprivs[2],crcs_mypriv[2]; @@ -173,21 +179,26 @@ struct iguana_info { UT_hash_handle hh; portable_mutex_t txmutex; struct LP_transaction *transactions; - uint64_t txfee; double estimatedrate,profitmargin; - int32_t longestchain,firstrefht,firstscanht,lastscanht; uint32_t counter,inactive,lastmempool,lastgetinfo; - uint8_t pubtype,p2shtype,isPoS,wiftype,taddr; + uint64_t txfee; + int32_t longestchain,firstrefht,firstscanht,lastscanht,bussock; uint16_t busport; + uint32_t counter,inactive,lastmempool,lastgetinfo; + uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag; char symbol[16],smartaddr[64],userpass[1024],serverport[128]; + // portfolio + double price_kmd,force,perc,goal,goalperc,relvolume; + uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB; + uint8_t pubkey33[33]; }; struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t vout; }; -struct LP_utxostats { uint32_t lasttime,errors,swappending,spentflag,lastspentcheck,bestflag; }; +struct LP_utxostats { uint32_t sessionid,lasttime,errors,swappending,spentflag,lastspentcheck,bestflag; }; struct LP_utxobob { struct _LP_utxoinfo utxo,deposit; }; struct LP_utxoalice { struct _LP_utxoinfo utxo,fee; }; -struct LP_utxoswap { bits256 otherpubkey; void *swap; uint64_t satoshis; double profitmargin; }; +struct LP_utxoswap { bits256 otherpubkey; void *swap; uint64_t satoshis; }; struct LP_utxoinfo { @@ -207,8 +218,7 @@ struct LP_peerinfo { UT_hash_handle hh; uint64_t ip_port; - double profitmargin; - uint32_t ipbits,errortime,errors,numpeers,numutxos,lasttime,connected,lastutxos,lastpeers,diduquery,good; + uint32_t ipbits,errortime,errors,numpeers,numutxos,lasttime,connected,lastutxos,lastpeers,diduquery,good,sessionid; int32_t pushsock,subsock; uint16_t port; char ipaddr[64]; @@ -252,15 +262,21 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3 //double LP_query(char *method,struct LP_quoteinfo *qp,char *base,char *rel,bits256 mypub); int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys); void LP_quotesinit(char *base,char *rel); -int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,double profitmargin,bits256 pubkey,char *jsonstr,int32_t freeflag); +int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,bits256 pubkey,char *jsonstr,int32_t freeflag); int32_t LP_ismine(struct LP_utxoinfo *utxo); int32_t LP_isavailable(struct LP_utxoinfo *utxo); struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port); -char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen,double profitmargin); +char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen); void LP_availableset(struct LP_utxoinfo *utxo); int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol,bits256 txid,int32_t vout,uint64_t satoshis,bits256 txid2,int32_t vout2); -int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock,double profitmargin); +int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock); uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired); +void LP_utxo_clientpublish(struct LP_utxoinfo *utxo); +int32_t LP_coinbus(uint16_t coin_busport); +struct iguana_info *LP_coinfind(char *symbol); +int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32); +char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price); +uint64_t LP_txfeecalc(char *symbol,uint64_t txfee); #endif diff --git a/iguana/exchanges/LP_messages.c b/iguana/exchanges/LP_messages.c new file mode 100644 index 000000000..80847ee5c --- /dev/null +++ b/iguana/exchanges/LP_messages.c @@ -0,0 +1,97 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_messages.c +// marketmaker +// + +struct LP_messageinfo { struct LP_messageinfo *next,*prev; cJSON *msgjson; int32_t ind; } *LP_MSGS; +int32_t Num_messages; + +void LP_gotmessage(cJSON *argjson) +{ + struct LP_messageinfo *msg = calloc(1,sizeof(*msg)); + msg->msgjson = jduplicate(argjson); + msg->ind = Num_messages++; + portable_mutex_lock(&LP_messagemutex); + DL_APPEND(LP_MSGS,msg); + portable_mutex_unlock(&LP_messagemutex); +} + +void LP_deletemessages(int32_t firsti,int32_t num) +{ + struct LP_messageinfo *msg,*tmp; int32_t lasti; + if ( num == 0 ) + num = 100; + if ( firsti < 0 ) + firsti = 0; + else if ( firsti >= Num_messages ) + return; + lasti = firsti + num - 1; + if ( lasti < Num_messages-1 ) + lasti = Num_messages - 1; + DL_FOREACH_SAFE(LP_MSGS,msg,tmp) + { + if ( msg->ind >= firsti && msg->ind <= lasti ) + { + portable_mutex_lock(&LP_messagemutex); + DL_DELETE(LP_MSGS,msg); + portable_mutex_unlock(&LP_messagemutex); + free_json(msg->msgjson); + free(msg); + } + } +} + +cJSON *LP_getmessages(int32_t firsti,int32_t num) +{ + struct LP_messageinfo *msg,*tmp; int32_t lasti,n=0,maxi=-1,mini=-1; cJSON *retjson,*item,*array = cJSON_CreateArray(); + retjson = cJSON_CreateObject(); + if ( num == 0 ) + num = 100; + if ( firsti < 0 ) + firsti = 0; + else if ( firsti >= Num_messages ) + { + jadd(retjson,"messages",array); + return(retjson); + } + lasti = firsti + num - 1; + if ( lasti < Num_messages-1 ) + lasti = Num_messages - 1; + DL_FOREACH_SAFE(LP_MSGS,msg,tmp) + { + if ( msg->ind >= firsti && msg->ind <= lasti ) + { + item = cJSON_CreateObject(); + jaddnum(item,"ind",msg->ind); + jadd(item,"msg",jduplicate(msg->msgjson)); + jaddi(array,item); + if ( mini == -1 || msg->ind < mini ) + mini = msg->ind; + if ( maxi == -1 || msg->ind > maxi ) + maxi = msg->ind; + n++; + } + } + jadd(retjson,"messages",array); + jaddnum(retjson,"firsti",firsti); + jaddnum(retjson,"lasti",lasti); + jaddnum(retjson,"minind",mini); + jaddnum(retjson,"maxind",maxi); + jaddnum(retjson,"num",n); + return(retjson); +} diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index a239a73cd..e3bf7308e 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -13,25 +13,32 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ + // // LP_nativeDEX.c // marketmaker // -// activate orderbook timeouts -// verify bid volumes +// new features: +// bittrex balancing +// detect port conflicts on enable // stats -// auto-utxo creation +// PoW, JS +// verify actual pricing +// autoutxo, if < 10*txfee and > 10 utxo: combine smallest utxo into dexfee; autosplit if imbalanced + +// unduplicated bugs: +// swap cancel should cleanly cancel #include #include "LP_include.h" -portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex; +portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex; int32_t LP_canbind; -#include "LP_network.c" struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2]; struct LP_peerinfo *LP_peerinfos,*LP_mypeer; struct LP_forwardinfo *LP_forwardinfos; struct iguana_info *LP_coins; +#include "LP_network.c" char *activecoins[] = { "BTC", "KMD" }; char GLOBAL_DBDIR[] = { "DB" }; @@ -40,12 +47,15 @@ char LP_gui[16] = { "cli" }; char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", };//"5.9.253.204" }; // -uint32_t LP_deadman_switch; +//uint32_t LP_deadman_switch; uint16_t LP_fixed_pairport,LP_publicport; +int32_t LP_mybussock = -1; int32_t LP_mypubsock = -1; -int32_t USERPASS_COUNTER,IAMLP = 0; +int32_t LP_mypullsock = -1; +int32_t LP_pendingswaps,LP_showwif,USERPASS_COUNTER,IAMLP = 0; +uint32_t LP_sessionid; double LP_profitratio = 1.; -bits256 LP_mypubkey; +bits256 LP_mypub25519,LP_mypriv25519; // stubs @@ -82,122 +92,134 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_ #include "LP_utxos.c" #include "LP_forwarding.c" #include "LP_ordermatch.c" +#include "LP_portfolio.c" +#include "LP_messages.c" #include "LP_commands.c" -char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen,double profitmargin) +char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { char *retstr=0; if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 ) return(0); - if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen,profitmargin) <= 0 ) + if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) { - if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,profitmargin,argjson,"127.0.0.1",0)) != 0 ) + if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,"127.0.0.1",0)) != 0 ) { //printf("%s PULL.[%d]-> (%s)\n",myipaddr != 0 ? myipaddr : "127.0.0.1",datalen,retstr); - if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 && - LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0); + //if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 && + //LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0); } } return(retstr); } -char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,double profitmargin,void *ptr,int32_t recvlen,int32_t recvsock) +char *LP_decrypt(uint8_t *ptr,int32_t *recvlenp) { - int32_t len,datalen=0; char *msg,*retstr=0,*jsonstr=0; cJSON *argjson,*reqjson; - if ( (datalen= is_hexstr((char *)ptr,0)) > 0 ) - { - datalen >>= 1; - jsonstr = malloc(datalen + 1); - decode_hex((void *)jsonstr,datalen,(char *)ptr); - jsonstr[datalen] = 0; - } else jsonstr = (char *)ptr; - if ( 0 && IAMLP == 0 ) - printf("%s %d, datalen.%d (%s)\n",typestr,recvlen,datalen,jsonstr); - if ( (argjson= cJSON_Parse(jsonstr)) != 0 ) + uint8_t decoded[LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES],*nonce,*cipher; int32_t recvlen,cipherlen; char *jsonstr = 0; + recvlen = *recvlenp; + nonce = &ptr[2]; + cipher = &ptr[2 + crypto_box_NONCEBYTES]; + cipherlen = recvlen - (2 + crypto_box_NONCEBYTES); + if ( cipherlen > 0 && cipherlen <= sizeof(decoded) ) { - len = (int32_t)strlen(jsonstr) + 1; - portable_mutex_lock(&LP_commandmutex); - if ( jstr(argjson,"method") != 0 && strcmp(jstr(argjson,"method"),"forwardhex") == 0 ) - { - //printf("got forwardhex\n"); - if ( (retstr= LP_forwardhex(ctx,pubsock,jbits256(argjson,"pubkey"),jstr(argjson,"hex"))) != 0 ) - { - } - } - else if ( jstr(argjson,"method") != 0 && strcmp(jstr(argjson,"method"),"publish") == 0 ) + if ( (jsonstr= (char *)_SuperNET_decipher(nonce,cipher,decoded,cipherlen,GENESIS_PUBKEY,LP_mypriv25519)) != 0 ) { - printf("got publish\n"); - if ( jobj(argjson,"method2") != 0 ) - jdelete(argjson,"method2"); - jaddstr(argjson,"method2","broadcast"); - if ( pubsock >= 0 && (reqjson= LP_dereference(argjson,"publish")) != 0 ) + recvlen = (cipherlen - crypto_box_ZEROBYTES); + if ( strlen(jsonstr)+1 != recvlen ) { - msg = jprint(reqjson,1); - LP_send(pubsock,msg,(int32_t)strlen(msg)+1,1); - } + printf("unexpected len %d vs recvlen.%d\n",(int32_t)strlen(jsonstr)+1,recvlen); + jsonstr = 0; + } else printf("decrypted (%s)\n",jsonstr); } - else if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len,profitmargin)) != 0 ) + } else printf("cipher.%d too big for %d\n",cipherlen,(int32_t)sizeof(decoded)); + *recvlenp = recvlen; + return(jsonstr); +} + +char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,uint8_t *ptr,int32_t recvlen,int32_t recvsock) +{ + static uint32_t dup,uniq; + int32_t i,len,cipherlen,datalen=0,duplicate=0,encrypted=0; char *method,*method2,*tmp,*cipherstr,*retstr=0,*jsonstr=0; cJSON *argjson; uint32_t crc32; + crc32 = calc_crc32(0,&ptr[2],recvlen-2); + if ( (crc32 & 0xff) == ptr[0] && ((crc32>>8) & 0xff) == ptr[1] ) + encrypted = 1; + portable_mutex_lock(&LP_commandmutex); + i = LP_crc32find(&duplicate,-1,crc32); + if ( duplicate != 0 ) + dup++; + else uniq++; + if ( (rand() % 1000) == 0 ) + printf("%s dup.%d (%u / %u) %.1f%% encrypted.%d recv.%u [%02x %02x] vs %02x %02x U.%d\n",typestr,duplicate,dup,dup+uniq,(double)100*dup/(dup+uniq),encrypted,crc32,ptr[0],ptr[1],crc32&0xff,(crc32>>8)&0xff,LP_mypeer != 0 ? LP_mypeer->numutxos : -1); + if ( duplicate == 0 ) + { + if ( i >= 0 ) + LP_crc32find(&duplicate,i,crc32); + if ( encrypted != 0 ) + jsonstr = LP_decrypt(ptr,&recvlen); + else if ( (datalen= is_hexstr((char *)ptr,0)) > 0 ) { - } - portable_mutex_unlock(&LP_commandmutex); - if ( LP_COMMAND_RECVSOCK == NN_REP ) + datalen >>= 1; + jsonstr = malloc(datalen + 1); + decode_hex((void *)jsonstr,datalen,(char *)ptr); + jsonstr[datalen] = 0; + } else jsonstr = (char *)ptr; + if ( jsonstr != 0 && (argjson= cJSON_Parse(jsonstr)) != 0 ) { - if ( retstr != 0 ) + uint8_t decoded[LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES]; + //printf("[%s]\n",jsonstr); + cipherlen = 0; + if ( (cipherstr= jstr(argjson,"cipher")) != 0 && (cipherlen= is_hexstr(cipherstr,0)) > 32 && cipherlen <= sizeof(decoded)*2 ) { - if ( strcmp("PULL",typestr) == 0 ) + method2 = jstr(argjson,"method2"); + if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"encrypted") == 0 ||(method2 != 0 && strcmp(method2,"encrypted") == 0)) ) { - printf("%d got REQ.(%s) -> (%s)\n",recvsock,jprint(argjson,0),retstr); - LP_send(recvsock,retstr,(int32_t)strlen(retstr)+1,0); - } + cipherlen >>= 1; + decode_hex(decoded,cipherlen,cipherstr); + crc32 = calc_crc32(0,&decoded[2],cipherlen-2); + if ( (tmp= LP_decrypt(decoded,&cipherlen)) != 0 ) + { + jsonstr = tmp; + free_json(argjson); + argjson = cJSON_Parse(jsonstr); + recvlen = cipherlen; + encrypted = 1; + if ( (crc32 & 0xff) == decoded[0] && ((crc32>>8) & 0xff) == decoded[1] ) + { + i = LP_crc32find(&duplicate,-1,crc32); + if ( duplicate == 0 && i >= 0 ) + LP_crc32find(&duplicate,i,crc32); + } + printf("%02x %02x %08x duplicate.%d decrypted.(%s)\n",decoded[0],decoded[1],crc32,duplicate,jsonstr); + } + else + { + printf("packet not for this node %u\n",crc32); + } + } else printf("error (%s) method is %s\n",jsonstr,method); } - else if ( strcmp("PULL",typestr) == 0 ) + if ( jsonstr != 0 && argjson != 0 ) { - printf("%d got REQ.(%s) -> null\n",recvsock,jprint(argjson,0)); - LP_send(recvsock,"{\"result\":null}",(int32_t)strlen("{\"result\":null}")+1,0); + len = (int32_t)strlen(jsonstr) + 1; + if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 ) + { + } + free_json(argjson); } } - free_json(argjson); - } else printf("error parsing(%s)\n",jsonstr); - if ( (void *)jsonstr != ptr ) + } //else printf("DUPLICATE.(%s)\n",(char *)ptr); + portable_mutex_unlock(&LP_commandmutex); + if ( jsonstr != 0 && (void *)jsonstr != (void *)ptr && encrypted == 0 ) free(jsonstr); if ( ptr != 0 ) nn_freemsg(ptr), ptr = 0; return(retstr); } -int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock,double profitmargin) +void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo) { - void *ptr; int32_t recvlen=-1,nonz = 0; - *retstrp = 0; - if ( pullsock >= 0 ) - { - while ( (recvlen= nn_recv(pullsock,&ptr,NN_MSG,0)) > 0 ) - { - nonz++; - *retstrp = LP_process_message(ctx,"PULL",myipaddr,pubsock,profitmargin,ptr,recvlen,pullsock); - } - } - return(nonz); -} - -int32_t LP_subsock_check(void *ctx,char *myipaddr,int32_t pubsock,int32_t sock,double profitmargin) -{ - int32_t recvlen,nonz = 0; void *ptr; char *retstr; - if ( sock >= 0 ) - { - while ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 ) - { - nonz++; - if ( (retstr= LP_process_message(ctx,"SUB",myipaddr,pubsock,profitmargin,ptr,recvlen,sock)) != 0 ) - free(retstr); - } - } - return(nonz); -} - -void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo,double profitmargin) -{ - struct _LP_utxoinfo u; char str[65]; uint32_t now = (uint32_t)time(NULL); + struct _LP_utxoinfo u; struct iguana_info *coin; char str[65]; uint32_t now = (uint32_t)time(NULL); + if ( IAMLP != 0 && (coin= LP_coinfind(utxo->coin)) != 0 && coin->inactive != 0 ) + return; //printf("%s lag.%d\n",bits256_str(str,utxo->txid),now-utxo->lastspentcheck); if ( utxo->T.spentflag == 0 && now > utxo->T.lastspentcheck+60 ) { @@ -216,13 +238,13 @@ void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo,double profitma } } -void LP_myutxo_updates(void *ctx,int32_t pubsock,char *passphrase,double profitmargin) +void LP_myutxo_updates(void *ctx,int32_t pubsock,char *passphrase) { //LP_utxopurge(0); not good to disrupt existing pointers LP_privkey_updates(ctx,pubsock,passphrase,0); } -int32_t LP_peer_utxosquery(struct LP_peerinfo *mypeer,uint16_t myport,int32_t pubsock,struct LP_peerinfo *peer,uint32_t now,double profitmargin,int32_t interval) +int32_t LP_peer_utxosquery(struct LP_peerinfo *mypeer,uint16_t myport,int32_t pubsock,struct LP_peerinfo *peer,uint32_t now,int32_t interval,int32_t maxentries) { int32_t lastn,n = -1; if ( peer->lastutxos < now-interval ) @@ -234,16 +256,75 @@ int32_t LP_peer_utxosquery(struct LP_peerinfo *mypeer,uint16_t myport,int32_t pu { peer->lastutxos = now; //printf("query utxos from %s\n",peer->ipaddr); - n = LP_utxosquery(mypeer,pubsock,peer->ipaddr,peer->port,"",lastn,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1",myport,profitmargin); + n = LP_utxosquery(mypeer,pubsock,peer->ipaddr,peer->port,"",lastn,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1",myport,maxentries); } } //else printf("LP_peer_utxosquery skip.(%s) %u\n",peer->ipaddr,peer->lastutxos); return(n); } -int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t pushport,int32_t pullsock,uint16_t myport,char *passphrase,double profitmargin) +int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int32_t sock) +{ + int32_t recvlen=1,nonz = 0; void *ptr; char *retstr; struct nn_pollfd pfd; + if ( sock >= 0 ) + { + while ( nonz < 1000 && recvlen > 0 ) + { + memset(&pfd,0,sizeof(pfd)); + pfd.fd = sock; + pfd.events = NN_POLLIN; + if ( nn_poll(&pfd,1,1) != 1 ) + break; + if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 ) + { + nonz++; + if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,ptr,recvlen,sock)) != 0 ) + free(retstr); + } + } + } + return(nonz); +} + +void command_rpcloop(void *myipaddr) +{ + int32_t nonz = 0; char *origipaddr; struct LP_peerinfo *peer,*tmp; void *ctx; //struct iguana_info *coin,*ctmp; + ctx = bitcoin_ctx(); + if ( (origipaddr= myipaddr) == 0 ) + origipaddr = "127.0.0.1"; + while ( 1 ) + { + nonz = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( peer->errors >= LP_MAXPEER_ERRORS ) + { + if ( (rand() % 10000) == 0 ) + peer->errors--; + else continue; + } + //printf("check %s pubsock.%d\n",peer->ipaddr,peer->subsock); + nonz += LP_sock_check("PULL",ctx,origipaddr,LP_mypubsock,peer->subsock); + } + /*HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht + { + if ( coin->inactive != 0 ) + continue; + if ( coin->bussock >= 0 ) + nonz += LP_sock_check(coin->symbol,ctx,origipaddr,-1,coin->bussock,LP_profitratio - 1.); + }*/ + if ( LP_mypullsock >= 0 ) + nonz += LP_sock_check("SUB",ctx,origipaddr,-1,LP_mypullsock); + //if ( LP_mybussock >= 0 ) + // nonz += LP_sock_check("BUS",ctx,origipaddr,-1,LP_mybussock); + if ( nonz == 0 ) + usleep(10000); + } +} + +int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t myport,char *passphrase) { - static uint32_t counter,lastforward,numpeers; - struct LP_utxoinfo *utxo,*utmp; struct iguana_info *coin,*ctmp; char *retstr,*origipaddr; struct LP_peerinfo *peer,*tmp; uint32_t now; int32_t nonz = 0,n=0,lastn=-1; + static uint32_t counter,numpeers,lastresync; //lastforward + struct LP_utxoinfo *utxo,*utmp; cJSON *retjson; struct iguana_info *coin,*ctmp; char *retstr,*origipaddr; struct LP_peerinfo *peer,*tmp,*mostpeer; uint32_t id,now; int32_t mostutxos,nonz = 0,n=0,num,lastn=-1; now = (uint32_t)time(NULL); if ( (origipaddr= myipaddr) == 0 ) origipaddr = "127.0.0.1"; @@ -251,78 +332,88 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int myipaddr = "127.0.0.1"; //if ( LP_canbind == 0 ) printf("counter.%d canbind.%d peers\n",counter,LP_canbind); numpeers = LP_numpeers(); + mostutxos = 0; + mostpeer = 0; HASH_ITER(hh,LP_peerinfos,peer,tmp) { if ( peer->errors >= LP_MAXPEER_ERRORS ) { if ( (rand() % 10000) == 0 ) + { peer->errors--; - else continue; + peer->diduquery = 0; + } + if ( IAMLP == 0 ) + continue; } if ( now > peer->lastpeers+60 && peer->numpeers > 0 && (peer->numpeers != numpeers || (rand() % 10000) == 0) ) { - if ( IAMLP != 0 ) - printf("numpeers.%d updatepeer.%s lag.%d\n",numpeers,peer->ipaddr,now-peer->lastpeers); + //if ( IAMLP != 0 ) + // printf("numpeers.%d updatepeer.%s lag.%d\n",numpeers,peer->ipaddr,now-peer->lastpeers); peer->lastpeers = now; - if ( IAMLP != 0 && peer->numpeers != numpeers ) - printf("%s num.%d vs %d\n",peer->ipaddr,peer->numpeers,numpeers); + //if ( IAMLP != 0 && peer->numpeers != numpeers ) + // printf("%s num.%d vs %d\n",peer->ipaddr,peer->numpeers,numpeers); if ( strcmp(peer->ipaddr,myipaddr) != 0 ) - LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport,profitmargin); + LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); + if ( IAMLP != 0 && LP_mypeer != 0 && strcmp(peer->ipaddr,myipaddr) != 0 ) + { + if ( (retstr= issue_LP_numutxos(peer->ipaddr,peer->port,LP_mypeer->ipaddr,LP_mypeer->port,LP_mypeer->numpeers,LP_mypeer->numutxos)) != 0 ) + { + //printf("%d <- (%s)\n",peer->numutxos,retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (num= jint(retjson,"numutxos")) > peer->numutxos ) + peer->numutxos = num; + if ( (num= jint(retjson,"numpeers")) > peer->numpeers ) + peer->numpeers = num; + if ( (id= juint(retjson,"session")) != 0 ) + peer->sessionid = id; + free_json(retjson); + } + free(retstr); + retstr = 0; + } + } } if ( peer->diduquery == 0 ) { if ( lastn != n || n < 20 ) { lastn = n; - n = LP_peer_utxosquery(mypeer,myport,pubsock,peer,now,profitmargin,60); + n = LP_peer_utxosquery(mypeer,myport,pubsock,peer,now,60,100); } LP_peer_pricesquery(peer->ipaddr,peer->port); peer->diduquery = now; } - nonz += LP_subsock_check(ctx,origipaddr,pubsock,peer->subsock,profitmargin); - } - //if ( LP_canbind == 0 ) printf("counter.%d canbind.%d forwarding\n",counter,LP_canbind); - if ( (counter % 600) == 10 ) - { - LP_myutxo_updates(ctx,pubsock,passphrase,profitmargin); - if ( lastforward < now-3600 ) + if ( peer->numutxos > mostutxos ) { - if ( (retstr= LP_registerall(0)) != 0 ) - free(retstr); - //LP_forwarding_register(LP_mypubkey,pushaddr,pushport,10); - lastforward = now; + mostutxos = peer->numutxos; + mostpeer = peer; } } - //if ( LP_canbind == 0 ) printf("counter.%d canbind.%d utxos\n",counter,LP_canbind); - if ( (counter % 600) == 60 ) + //printf("numutxos vs mine.%d\n",LP_mypeer != 0 ? LP_mypeer->numutxos : -1); + if ( LP_mypeer != 0 && LP_mypeer->numutxos < mostutxos && mostpeer != 0 && time(NULL) > lastresync+180 ) + { + printf("myutxos.%d most.%d %s\n",LP_mypeer->numutxos,mostutxos,mostpeer->ipaddr); + LP_peer_utxosquery(LP_mypeer,myport,pubsock,mostpeer,now,60,(mostutxos-LP_mypeer->numutxos) * 2); + lastresync = (uint32_t)time(NULL); + //LP_peer_pricesquery(mostpeer->ipaddr,mostpeer->port); + } + if ( (counter % 6000) == 10 ) { + LP_myutxo_updates(ctx,pubsock,passphrase); HASH_ITER(hh,LP_utxoinfos[0],utxo,utmp) { - LP_utxo_spentcheck(pubsock,utxo,profitmargin); + LP_utxo_spentcheck(pubsock,utxo); } HASH_ITER(hh,LP_utxoinfos[1],utxo,utmp) { - //char str[65]; - LP_utxo_spentcheck(pubsock,utxo,profitmargin); - if ( utxo->T.lasttime == 0 ) + LP_utxo_spentcheck(pubsock,utxo); + if ( LP_isunspent(utxo) > 0 && utxo->T.lasttime == 0 && LP_ismine(utxo) > 0 ) + { + char str[65]; printf("publish mybob %s\n",bits256_str(str,utxo->payment.txid)); LP_utxo_clientpublish(utxo); - //else if ( strcmp(utxo->coin,"HUSH") == 0 ) - // printf("lasttime set %s\n",bits256_str(str,utxo->payment.txid)); - } - } - nonz += LP_pullsock_check(ctx,&retstr,myipaddr,pubsock,pullsock,profitmargin); - if ( retstr != 0 ) - free(retstr); - if ( IAMLP != 0 && (counter % 600) == 42 ) - LP_hellos(); - if ( LP_canbind == 0 && (counter % (PSOCK_KEEPALIVE*MAINLOOP_PERSEC/2)) == 13 ) - { - char keepalive[128]; - sprintf(keepalive,"{\"method\":\"keepalive\"}"); - //printf("send keepalive to %s pullsock.%d\n",pushaddr,pullsock); - if ( LP_send(pullsock,keepalive,(int32_t)strlen(keepalive)+1,0) < 0 ) - { - //LP_deadman_switch = 0; + } } } HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht @@ -367,7 +458,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int coin->lastscanht = coin->firstscanht; continue; } - printf("%s ref.%d scan.%d to %d, longest.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); + //printf("%s ref.%d scan.%d to %d, longest.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); if ( LP_blockinit(coin,coin->lastscanht) < 0 ) { printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht); @@ -411,12 +502,12 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins,char *passphrase) LP_privkey_updates(ctx,pubsock,passphrase,1); } -void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint16_t myport,char *seednode,double profitmargin) +void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint16_t myport,char *seednode) { int32_t i,j; uint32_t r; if ( IAMLP != 0 ) { - LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,profitmargin,0,0); + LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,0,0,LP_sessionid); if ( myipaddr == 0 || mypeer == 0 ) { printf("couldnt get myipaddr or null mypeer.%p\n",mypeer); @@ -426,11 +517,11 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint { for (i=0; i 25 ) - continue; - LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,mypeer->ipaddr,myport,profitmargin); + //if ( (rand() % 100) > 25 ) + // continue; + LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,mypeer->ipaddr,myport); } - } else LP_peersquery(mypeer,pubsock,seednode,myport,mypeer->ipaddr,myport,profitmargin); + } else LP_peersquery(mypeer,pubsock,seednode,myport,mypeer->ipaddr,myport); } else { @@ -445,15 +536,16 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint for (j=0; j /tmp/myipaddr") == 0 ) { if ( (myipaddr= OS_filestr(&filesize,"/tmp/myipaddr")) != 0 && myipaddr[0] != 0 ) @@ -544,12 +634,16 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profit printf(">>>>>>>>> myipaddr.%s (%s) pullsock.%d\n",myipaddr,subaddr,pubsock); LP_mypubsock = pubsock; } - LP_initpeers(pubsock,mypeer,myipaddr,myport,jstr(argjson,"seednode"),profitmargin); - pullsock = LP_initpublicaddr(ctx,&mypullport,pushaddr,myipaddr,mypullport,0); + printf("got %s, initpeers\n",myipaddr); + LP_initpeers(pubsock,mypeer,myipaddr,myport,jstr(argjson,"seednode")); + printf("get public socket\n"); + LP_mypullsock = LP_initpublicaddr(ctx,&mypullport,pushaddr,myipaddr,mypullport,0); strcpy(LP_publicaddr,pushaddr); LP_publicport = mypullport; - LP_deadman_switch = (uint32_t)time(NULL); - printf("canbind.%d my command address is (%s) pullsock.%d pullport.%u\n",LP_canbind,pushaddr,pullsock,mypullport); + LP_mybussock = LP_coinbus(mybusport); + //LP_deadman_switch = (uint32_t)time(NULL); + printf("canbind.%d my command address is (%s) pullsock.%d pullport.%u\n",LP_canbind,pushaddr,LP_mypullsock,mypullport); + printf("initcoins\n"); LP_initcoins(ctx,pubsock,jobj(argjson,"coins"),passphrase); if ( IAMLP != 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_psockloop,(void *)&myipaddr) != 0 ) { @@ -561,28 +655,28 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profit printf("error launching stats rpcloop for port.%u\n",myport); exit(-1); } - if ( (retstr= basilisk_swapentry(0,0)) != 0 ) - free(retstr); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)&myipaddr) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",myport); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)&myipaddr) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",myport); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,(void *)&myipaddr) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",myport); + exit(-1); + } + //if ( (retstr= basilisk_swapentry(0,0)) != 0 ) + // free(retstr); while ( 1 ) { //fprintf(stderr,"."); - if ( LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,mypullport,pullsock,myport,passphrase,profitmargin) == 0 ) + if ( LP_mainloop_iter(ctx,myipaddr,mypeer,pubsock,pushaddr,myport,passphrase) == 0 ) usleep(1000000 / MAINLOOP_PERSEC); - if ( LP_canbind == 0 ) - { - //printf("check deadman %u vs %u\n",LP_deadman_switch,(uint32_t)time(NULL)); - if ( LP_deadman_switch < time(NULL)-PSOCK_KEEPALIVE ) - { - printf("DEAD man's switch %u activated at %u lag.%d, register forwarding again\n",LP_deadman_switch,(uint32_t)time(NULL),(uint32_t)(time(NULL) - LP_deadman_switch)); - if ( pullsock >= 0 ) - nn_close(pullsock); - pullsock = LP_initpublicaddr(ctx,&mypullport,pushaddr,myipaddr,mypullport,0); - LP_deadman_switch = (uint32_t)time(NULL); - strcpy(LP_publicaddr,pushaddr); - LP_publicport = mypullport; - LP_forwarding_register(LP_mypubkey,pushaddr,mypullport,MAX_PSOCK_PORT); - } - } } } diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index a97f4b413..aadc2f485 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -30,13 +30,13 @@ uint16_t Numpsocks,Psockport = MIN_PSOCK_PORT; char *nanomsg_transportname(int32_t bindflag,char *str,char *ipaddr,uint16_t port) { - sprintf(str,"tcp://%s:%u",bindflag == 0 ? ipaddr : "*",port); + sprintf(str,"tcp://%s:%u",bindflag == 0 ? ipaddr : "*",port); // ws is worse return(str); } -int32_t LP_send(int32_t sock,void *msg,int32_t sendlen,int32_t freeflag) +int32_t _LP_send(int32_t sock,void *msg,int32_t sendlen,int32_t freeflag) { - int32_t sentbytes,i; struct nn_pollfd pfd; + int32_t sentbytes; if ( sock < 0 ) { printf("LP_send.(%s) to illegal socket\n",(char *)msg); @@ -44,31 +44,293 @@ int32_t LP_send(int32_t sock,void *msg,int32_t sendlen,int32_t freeflag) free(msg); return(-1); } - //len = (int32_t)strlen(msg) + 1; - for (i=0; i<1000; i++) // 1000 * (1 ms + 1000 us) = 2 seconds + if ( (sentbytes= nn_send(sock,msg,sendlen,0)) != sendlen ) + printf("LP_send sent %d instead of %d\n",sentbytes,sendlen); + //else printf("SENT.(%s)\n",msg); + if ( freeflag != 0 ) + free(msg); + return(sentbytes); +} + +int32_t LP_sockcheck(int32_t sock) +{ + struct nn_pollfd pfd; + pfd.fd = sock; + pfd.events = NN_POLLOUT; + if ( nn_poll(&pfd,1,1) > 0 ) + return(1); + else return(-1); +} + +struct LP_queue +{ + struct LP_queue *next,*prev; + int32_t sock,peerind,msglen; + uint32_t starttime,crc32; + uint8_t msg[]; +} *LP_Q; +int32_t LP_Qenqueued,LP_Qerrors,LP_Qfound; + +void _LP_sendqueueadd(uint32_t crc32,int32_t sock,uint8_t *msg,int32_t msglen,int32_t peerind) +{ + struct LP_queue *ptr; + ptr = calloc(1,sizeof(*ptr) + msglen); + ptr->crc32 = crc32; + ptr->sock = sock; + ptr->peerind = peerind; + ptr->msglen = msglen; + memcpy(ptr->msg,msg,msglen); + DL_APPEND(LP_Q,ptr); + LP_Qenqueued++; + //printf("Q.%p: peerind.%d msglen.%d\n",ptr,peerind,msglen); +} + +int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32) +{ + static uint32_t crcs[8192]; static unsigned long dup,total; + int32_t i; + *duplicatep = 0; + if ( ind < 0 ) { - pfd.fd = sock; - pfd.events = NN_POLLOUT; - //portable_mutex_lock(&LP_networkmutex); - if ( nn_poll(&pfd,1,1) > 0 ) + total++; + for (i=0; i 0 ) + { + crcs[i] = crcs[i >> 1]; + crcs[i >> 1] = crc32; + dup++; + //printf("duplicate %u in slot %d -> slot %d (%lu / %lu)\n",crc32,i,i>>1,dup,total); + } + *duplicatep = 1; + break; + } + else if ( crcs[i] == 0 ) + break; + } + if ( i >= sizeof(crcs)/sizeof(*crcs) ) + i = (rand() % (sizeof(crcs)/sizeof(*crcs))); + return(i); + } + else + { + crcs[ind] = crc32; + return(ind); + } +} + +int32_t LP_peerindsock(int32_t *peerindp) +{ + struct LP_peerinfo *peer,*tmp; int32_t peerind = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + peerind++; + if ( peer->errors < LP_MAXPEER_ERRORS && peer->pushsock >= 0 ) + { + if ( peerind < *peerindp ) + continue; + *peerindp = peerind; + //printf("peerind.%d -> sock %d\n",peerind,peer->pushsock); + return(peer->pushsock); } - //portable_mutex_unlock(&LP_networkmutex); - usleep(1000); } - printf("you can ignore: error LP_send sock.%d, i.%d timeout.(%s) %s\n",sock,i,(char *)msg,nn_strerror(nn_errno())); - if ( freeflag != 0 ) - free(msg); return(-1); } +void queue_loop(void *ignore) +{ + struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0; + while ( 1 ) + { + nonz = 0; + //printf("LP_Q.%p next.%p prev.%p\n",LP_Q,LP_Q!=0?LP_Q->next:0,LP_Q!=0?LP_Q->prev:0); + n = 0; + DL_FOREACH_SAFE(LP_Q,ptr,tmp) + { + n++; + flag = 0; + if ( ptr->sock >= 0 ) + { + if ( LP_sockcheck(ptr->sock) > 0 ) + { + if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen ) + printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen); + // else printf("%d %p qsent %u msglen.%d peerind.%d\n",n,ptr,ptr->crc32,ptr->msglen,ptr->peerind); + ptr->sock = -1; + if ( ptr->peerind > 0 ) + ptr->starttime = (uint32_t)time(NULL); + else flag = 1; + } + } + else if ( time(NULL) > ptr->starttime+13 ) + { + LP_crc32find(&duplicate,-1,ptr->crc32); + if ( duplicate > 0 ) + { + LP_Qfound++; + if ( (LP_Qfound % 10) == 0 ) + printf("found.%u Q.%d err.%d match.%d\n",ptr->crc32,LP_Qenqueued,LP_Qerrors,LP_Qfound); + flag = 1; + } + else + { + printf("couldnt find.%u peerind.%d Q.%d err.%d match.%d\n",ptr->crc32,ptr->peerind,LP_Qenqueued,LP_Qerrors,LP_Qfound); + ptr->peerind++; + if ( (ptr->sock= LP_peerindsock(&ptr->peerind)) < 0 ) + { + printf("%d no more peers to try at peerind.%d %p Q_LP.%p\n",n,ptr->peerind,ptr,LP_Q); + flag = 1; + LP_Qerrors++; + } + } + } + if ( flag != 0 ) + { + nonz++; + portable_mutex_lock(&LP_networkmutex); + DL_DELETE(LP_Q,ptr); + portable_mutex_unlock(&LP_networkmutex); + free(ptr); + ptr = 0; + } + } + //if ( n != 0 ) + // printf("LP_Q.[%d]\n",n); + if ( nonz == 0 ) + usleep(500000); + } +} + +void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32_t msglen,int32_t needack) +{ + int32_t sentbytes,peerind = 0; + if ( sock0 >= 0 || sock1 >= 0 ) + { + if ( sock0 >= 0 && LP_sockcheck(sock0) > 0 ) + { + if ( (sentbytes= nn_send(sock0,msg,msglen,0)) != msglen ) + printf("_LP_queuesend0 sent %d instead of %d\n",sentbytes,msglen); + else + { + //printf("Q sent %u\n",crc32); + sock0 = -1; + } + } + if ( sock1 >= 0 && LP_sockcheck(sock1) > 0 ) + { + if ( (sentbytes= nn_send(sock1,msg,msglen,0)) != msglen ) + printf("_LP_queuesend1 sent %d instead of %d\n",sentbytes,msglen); + else sock1 = -1; + } + if ( sock0 < 0 && sock1 < 0 ) + return; + } + else + { + peerind = 1; + sock0 = LP_peerindsock(&peerind); + } + portable_mutex_lock(&LP_networkmutex); + if ( sock0 >= 0 ) + _LP_sendqueueadd(crc32,sock0,msg,msglen,needack * peerind); + if ( sock1 >= 0 ) + _LP_sendqueueadd(crc32,sock1,msg,msglen,needack); + portable_mutex_unlock(&LP_networkmutex); +} + +void LP_queuesend(uint32_t crc32,int32_t pubsock,char *base,char *rel,uint8_t *msg,int32_t msglen) +{ + //struct iguana_info *coin; int32_t flag=0,socks[2]; + if ( pubsock >= 0 ) + { + //socks[0] = socks[1] = -1; + //if ( rel != 0 && rel[0] != 0 && (coin= LP_coinfind(rel)) != 0 && coin->bussock >= 0 ) + // socks[flag++] = coin->bussock; + //if ( base != 0 && base[0] != 0 && (coin= LP_coinfind(base)) != 0 && coin->bussock >= 0 ) + // socks[flag++] = coin->bussock; + //if ( flag == 0 && pubsock >= 0 ) + _LP_queuesend(crc32,pubsock,-1,msg,msglen,0); + //else _LP_queuesend(socks[0],socks[1],msg,msglen,0); + } else _LP_queuesend(crc32,-1,-1,msg,msglen,1); +} + +// first 2 bytes == (crc32 & 0xffff) if encrypted, then nonce is next crypto_box_NONCEBYTES +// GENESIS_PRIVKEY is always the sender + +void LP_broadcast_finish(int32_t pubsock,char *base,char *rel,uint8_t *msg,cJSON *argjson,uint32_t crc32) +{ + int32_t msglen; + msg = (void *)jprint(argjson,0); + msglen = (int32_t)strlen((char *)msg) + 1; + if ( crc32 == 0 ) + crc32 = calc_crc32(0,&msg[2],msglen - 2); + if ( IAMLP == 0 ) + { + free(msg); + jdelete(argjson,"method"); + jaddstr(argjson,"method","broadcast"); + msg = (void *)jprint(argjson,0); + msglen = (int32_t)strlen((char *)msg) + 1; + LP_queuesend(crc32,-1,base,rel,msg,msglen); + } else LP_queuesend(crc32,pubsock,base,rel,msg,msglen); + free(msg); +} + +void LP_broadcast_message(int32_t pubsock,char *base,char *rel,bits256 destpub25519,char *msgstr) +{ + uint8_t encoded[LP_ENCRYPTED_MAXSIZE],space[sizeof(encoded)],*msg,*nonce,*cipher; int32_t encrypted=0,msglen; uint32_t crc32=0; cJSON *argjson; char *methodstr,method[64],cipherstr[LP_ENCRYPTED_MAXSIZE*2+1]; + msglen = (int32_t)strlen(msgstr) + 1; + msg = (void *)msgstr; + if ( bits256_nonz(destpub25519) != 0 ) + { + nonce = &encoded[2]; + OS_randombytes(nonce,crypto_box_NONCEBYTES); + cipher = &encoded[2 + crypto_box_NONCEBYTES]; + msglen = _SuperNET_cipher(nonce,&encoded[2 + crypto_box_NONCEBYTES],msg,msglen,destpub25519,GENESIS_PRIVKEY,space); + msglen += crypto_box_NONCEBYTES; + crc32 = calc_crc32(0,&encoded[2],msglen); + encoded[0] = crc32 & 0xff; + encoded[1] = (crc32 >> 8) & 0xff; + msg = encoded; + msglen += 2; + encrypted = 1; + //printf("msgstr.(%s)\n",msgstr); + free(msgstr), msgstr = 0; + } + if ( encrypted == 0 ) + { + if ( (argjson= cJSON_Parse(msgstr)) != 0 ) + { + if ( (methodstr= jstr(argjson,"method")) != 0 && strlen(methodstr) <= sizeof(method) ) + { + strcpy(method,methodstr); + jdelete(argjson,"method"); + if ( jobj(argjson,"method2") != 0 ) + jdelete(argjson,"method2"); + jaddstr(argjson,"method2",method); + jaddstr(argjson,"method",method); + //printf("CRC32.%u (%s)\n",crc32,(char *)msg); + LP_broadcast_finish(pubsock,base,rel,msg,argjson,0); + } // else printf("no valid method in (%s)\n",msgstr); + free_json(argjson); + } else printf("couldnt parse (%s)\n",msgstr); + } + else + { + argjson = cJSON_CreateObject(); + init_hexbytes_noT(cipherstr,msg,msglen); + jaddstr(argjson,"cipher",cipherstr); + jaddstr(argjson,"method2","encrypted"); + jaddstr(argjson,"method","encrypted"); + LP_broadcast_finish(pubsock,base,rel,msg,argjson,crc32); + free_json(argjson); + } + if ( msgstr != 0 ) + free(msgstr); +} + uint32_t LP_swapsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t nextbits,uint32_t crcs[2]) { uint8_t *buf; int32_t sentbytes,offset=0,i; @@ -97,7 +359,7 @@ uint32_t LP_swapsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbit void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to work { static struct nn_pollfd *pfds; - int32_t i,n,nonz,iter,retval,size=0,sentbytes,sendsock = -1; uint32_t now; struct psock *ptr=0; void *buf=0; char keepalive[512];//,*myipaddr = _ptr; + int32_t i,n,nonz,iter,retval,sentbytes,size=0,sendsock = -1; uint32_t now; struct psock *ptr=0; void *buf=0; char keepalive[512]; while ( 1 ) { now = (uint32_t)time(NULL); @@ -105,15 +367,8 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w { if ( size > 0 ) { - if ( (sentbytes= LP_send(sendsock,buf,size,0)) > 0 ) - { - printf("PSOCKS (%d %d %d) (%s) -> %d/%d bytes %s\n",ptr->publicsock,ptr->sendsock,sendsock,(char *)buf,size,sentbytes,ptr->sendaddr); - } - else - { - ptr->errors++; - printf("send error.%d to %s\n",ptr->errors,ptr->sendaddr); - } + if ( (sentbytes= nn_send(sendsock,buf,size,0)) != size ) // need tight loop + printf("LP_psockloop sent %d instead of %d\n",sentbytes,size); if ( buf != 0 ) { if ( buf != keepalive ) @@ -176,7 +431,7 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w { if ( (size= nn_recv(ptr->sendsock,&buf,NN_MSG,0)) > 0 ) { - printf("%s paired has pollin (%s)\n",ptr->sendaddr,(char *)buf); + //printf("%s paired has pollin (%s)\n",ptr->sendaddr,(char *)buf); ptr->lasttime = now; if ( ptr->ispaired != 0 ) { @@ -232,11 +487,14 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w else if ( now > ptr->lastping+PSOCK_KEEPALIVE/2 && ptr->errors < 3 ) { ptr->lastping = now; - sendsock = ptr->sendsock; - sprintf(keepalive,"{\"method\":\"keepalive\",\"endpoint\":\"%s\"}",ptr->sendaddr); - size = (int32_t)strlen(keepalive) + 1; - buf = keepalive; - printf("send keepalive.(%s)\n",keepalive); + if ( 0 ) + { + sendsock = ptr->sendsock; + sprintf(keepalive,"{\"method\":\"keepalive\",\"endpoint\":\"%s\"}",ptr->sendaddr); + size = (int32_t)strlen(keepalive) + 1; + buf = keepalive; + printf("send keepalive.(%s)\n",keepalive); + } break; } } @@ -287,7 +545,7 @@ int32_t LP_psockmark(char *publicaddr) char *LP_psock(char *myipaddr,int32_t ispaired) { - char pushaddr[128],subaddr[128]; uint16_t i,publicport,subport,maxiters=100; int32_t timeout,maxsize,pullsock=-1,pubsock=-1; cJSON *retjson=0; + char pushaddr[128],subaddr[128]; uint16_t i,publicport,subport,maxiters=100; int32_t timeout,pullsock=-1,pubsock=-1; cJSON *retjson=0; retjson = cJSON_CreateObject(); publicport = Psockport++; subport = Psockport++; @@ -306,12 +564,11 @@ char *LP_psock(char *myipaddr,int32_t ispaired) { timeout = 1; nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); - timeout = 1; nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); if ( ispaired != 0 ) { - maxsize = 1024 * 1024; - nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize)); + //maxsize = 1024 * 1024; + //nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize)); } //if ( ispaired != 0 ) { @@ -354,36 +611,42 @@ char *LP_psock(char *myipaddr,int32_t ispaired) both are combined in LP_psock_get */ +char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired) +{ + char url[512],*retstr; + sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d",destip,destport,ispaired); + //return(LP_issue_curl("psock",destip,destport,url)); + retstr = issue_curlt(url,LP_HTTP_TIMEOUT*3); + printf("issue_LP_psock got (%s) from %s\n",retstr,destip); + return(retstr); +} -int32_t nn_tests(void *ctx,int32_t pullsock,char *pushaddr,int32_t nnother) +uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired) { - int32_t sock,n,m,timeout,retval = -1; char msg[512],*retstr; - printf("nn_tests.(%s)\n",pushaddr); - if ( (sock= nn_socket(AF_SP,nnother)) >= 0 ) + uint16_t publicport = 0; char *retstr,*addr; cJSON *retjson; struct LP_peerinfo *peer,*tmp; + HASH_ITER(hh,LP_peerinfos,peer,tmp) { - if ( nn_connect(sock,pushaddr) < 0 ) - printf("connect error %s\n",nn_strerror(nn_errno())); - else + connectaddr[0] = publicaddr[0] = 0; + if ( peer->errors < LP_MAXPEER_ERRORS && (retstr= issue_LP_psock(peer->ipaddr,peer->port,ispaired)) != 0 ) { - sleep(3); - timeout = 1; - nn_setsockopt(sock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); - sprintf(msg,"{\"method\":\"nn_tests\",\"ipaddr\":\"%s\"}",pushaddr); - n = LP_send(sock,msg,(int32_t)strlen(msg)+1,0); - sleep(3); - LP_pullsock_check(ctx,&retstr,"127.0.0.1",-1,pullsock,0.); - sprintf(msg,"{\"method\":\"nn_tests2\",\"ipaddr\":\"%s\"}",pushaddr); - m = LP_send(pullsock,msg,(int32_t)strlen(msg)+1,0); - printf(">>>>>>>>>>>>>>>>>>>>>> sent %d+%d bytes -> pullsock.%d retstr.(%s)\n",n,m,pullsock,retstr!=0?retstr:""); - if ( retstr != 0 ) + if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - free(retstr); - retval = 0; + printf("from %s:%u (%s)\n",peer->ipaddr,peer->port,retstr); + if ( (addr= jstr(retjson,"publicaddr")) != 0 ) + safecopy(publicaddr,addr,128); + if ( (addr= jstr(retjson,"connectaddr")) != 0 ) + safecopy(connectaddr,addr,128); + if ( publicaddr[0] != 0 && connectaddr[0] != 0 ) + publicport = juint(retjson,"publicport"); + free_json(retjson); } - } - nn_close(sock); + printf("got.(%s) connect.%s public.%s\n",retstr,connectaddr,publicaddr); + free(retstr); + } else printf("error psock from %s:%u\n",peer->ipaddr,peer->port); + if ( publicport != 0 ) + break; } - return(retval); + return(publicport); } int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char *myipaddr,uint16_t mypullport,int32_t ispaired) @@ -404,6 +667,11 @@ int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char else { *mypullportp = 0; + if ( ispaired == 0 ) + { + strcpy(publicaddr,"127.0.0.1"); + return(-1); + } while ( *mypullportp == 0 ) { if ( (*mypullportp= LP_psock_get(connectaddr,publicaddr,ispaired)) != 0 ) @@ -434,17 +702,17 @@ int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char } timeout = 1; nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - timeout = 1; nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); //maxsize = 2 * 1024 * 1024; //nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize)); if ( nntype == NN_SUB ) nn_setsockopt(pullsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); } - if ( LP_canbind != 0 || ispaired != 0 || nn_tests(ctx,pullsock,publicaddr,NN_PUSH) >= 0 ) - break; - printf("nn_tests failed, try again\n"); - sleep(3); + //if ( LP_canbind != 0 || ispaired != 0 || nn_tests(ctx,pullsock,publicaddr,NN_PUSH) >= 0 ) + // break; + //printf("nn_tests failed, try again\n"); + //sleep(3); + break; if ( pullsock >= 0 ) nn_close(pullsock); } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b54557ea4..e32930cda 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -19,6 +19,43 @@ // marketmaker // +uint64_t LP_txfeecalc(char *symbol,uint64_t txfee) +{ + struct iguana_info *coin; + if ( strcmp(symbol,"BTC") == 0 ) + { + if ( txfee == 0 && (txfee= LP_getestimatedrate(symbol) * LP_AVETXSIZE) < LP_MIN_TXFEE ) + txfee = LP_MIN_TXFEE; + } + else if ( (coin= LP_coinfind(symbol)) != 0 ) + txfee = coin->txfee; + if ( txfee < LP_MIN_TXFEE ) + txfee = LP_MIN_TXFEE; + return(txfee); +} + +void LP_txfees(uint64_t *txfeep,uint64_t *desttxfeep,char *base,char *rel) +{ + *txfeep = LP_txfeecalc(base,0); + *desttxfeep = LP_txfeecalc(rel,0); +} + +double LP_qprice_calc(int64_t *destsatoshisp,int64_t *satoshisp,double price,uint64_t b_satoshis,uint64_t txfee,uint64_t a_value,uint64_t maxdestsatoshis,uint64_t desttxfee) +{ + uint64_t destsatoshis,satoshis; + a_value -= (desttxfee + 1); + destsatoshis = ((b_satoshis - txfee) * price); + if ( destsatoshis > a_value ) + destsatoshis = a_value; + if ( maxdestsatoshis != 0 && destsatoshis > maxdestsatoshis-desttxfee-1 ) + destsatoshis = maxdestsatoshis-desttxfee-1; + satoshis = (destsatoshis / price + 0.49) - txfee; + *destsatoshisp = destsatoshis; + *satoshisp = satoshis; + if ( satoshis > 0 ) + return((double)destsatoshis / satoshis); + else return(0.); +} struct basilisk_request *LP_requestinit(struct basilisk_request *rp,bits256 srchash,bits256 desthash,char *src,uint64_t srcsatoshis,char *dest,uint64_t destsatoshis,uint32_t timestamp,uint32_t quotetime,int32_t DEXselector) { @@ -120,15 +157,15 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson) return(0); } -int32_t LP_quoteinfoinit(struct LP_quoteinfo *qp,struct LP_utxoinfo *utxo,char *destcoin,double price,uint64_t destsatoshis) +int32_t LP_quoteinfoinit(struct LP_quoteinfo *qp,struct LP_utxoinfo *utxo,char *destcoin,double price,uint64_t satoshis,uint64_t destsatoshis) { memset(qp,0,sizeof(*qp)); if ( qp->timestamp == 0 ) qp->timestamp = (uint32_t)time(NULL); safecopy(qp->destcoin,destcoin,sizeof(qp->destcoin)); - if ( (qp->txfee= LP_getestimatedrate(utxo->coin)*LP_AVETXSIZE) < LP_MIN_TXFEE ) - qp->txfee = LP_MIN_TXFEE; - qp->satoshis = destsatoshis / price + 0.49; + LP_txfees(&qp->txfee,&qp->desttxfee,utxo->coin,qp->destcoin); + qp->satoshis = satoshis;//(destsatoshis / price) + 0.49; + qp->destsatoshis = destsatoshis; if ( utxo->iambob == 0 || qp->txfee >= qp->satoshis || qp->txfee >= utxo->deposit.value || utxo->deposit.value < LP_DEPOSITSATOSHIS(qp->satoshis) ) { printf("quoteinit error.(%d %d %d %d) %.8f vs %.8f\n",utxo->iambob == 0,qp->txfee >= qp->satoshis,qp->txfee >= utxo->deposit.value,utxo->deposit.value < LP_DEPOSITSATOSHIS(qp->satoshis),dstr(utxo->deposit.value),dstr(LP_DEPOSITSATOSHIS(qp->satoshis))); @@ -138,9 +175,6 @@ int32_t LP_quoteinfoinit(struct LP_quoteinfo *qp,struct LP_utxoinfo *utxo,char * qp->vout = utxo->payment.vout; qp->txid2 = utxo->deposit.txid; qp->vout2 = utxo->deposit.vout; - qp->destsatoshis = destsatoshis; - if ( (qp->desttxfee= LP_getestimatedrate(qp->destcoin) * LP_AVETXSIZE) < LP_MIN_TXFEE ) - qp->desttxfee = LP_MIN_TXFEE; if ( qp->desttxfee >= qp->destsatoshis ) { printf("quoteinit desttxfee %.8f < %.8f destsatoshis\n",dstr(qp->desttxfee),dstr(qp->destsatoshis)); @@ -167,7 +201,7 @@ char *LP_quotereceived(cJSON *argjson) { struct LP_cacheinfo *ptr; double price; struct LP_quoteinfo Q; LP_quoteparse(&Q,argjson); - price = (double)(Q.destsatoshis + Q.desttxfee) / (Q.satoshis + Q.txfee); + price = (double)Q.destsatoshis / Q.satoshis; if ( (ptr= LP_cacheadd(Q.srccoin,Q.destcoin,Q.txid,Q.vout,price,&Q)) != 0 ) { ptr->Q = Q; @@ -176,27 +210,17 @@ char *LP_quotereceived(cJSON *argjson) } else return(clonestr("{\"error\":\"nullptr\"}")); } -char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,double profitmargin,char *base,char *rel,double price) +char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price) { bits256 zero; char *msg; cJSON *reqjson = cJSON_CreateObject(); - jaddbits256(reqjson,"pubkey",LP_mypubkey); + memset(zero.bytes,0,sizeof(zero)); + jaddbits256(reqjson,"pubkey",LP_mypub25519); jaddstr(reqjson,"base",base); jaddstr(reqjson,"rel",rel); jaddnum(reqjson,"price",price); - if ( pubsock >= 0 ) - { - jaddstr(reqjson,"method","postprice"); - //printf("%d pricepings.(%s)\n",pubsock,jprint(reqjson,0)); - msg = jprint(reqjson,1); - LP_send(pubsock,msg,(int32_t)strlen(msg)+1,1); - } - else - { - jaddstr(reqjson,"method","forward"); - jaddstr(reqjson,"method2","postprice"); - memset(zero.bytes,0,sizeof(zero)); - LP_forward(ctx,myipaddr,pubsock,profitmargin,zero,jprint(reqjson,1),1); - } + jaddstr(reqjson,"method","postprice"); + msg = jprint(reqjson,1); + LP_broadcast_message(pubsock,base,rel,zero,msg); return(clonestr("{\"result\":\"success\"}")); } @@ -234,7 +258,7 @@ int32_t LP_quote_checkmempool(struct LP_quoteinfo *qp) double LP_quote_validate(struct LP_utxoinfo **autxop,struct LP_utxoinfo **butxop,struct LP_quoteinfo *qp,int32_t iambob) { - double qprice; uint64_t srcvalue,srcvalue2,destvalue,destvalue2; + double qprice; uint64_t txfee,desttxfee,srcvalue,srcvalue2,destvalue,destvalue2; *autxop = *butxop = 0; if ( LP_iseligible(&srcvalue,&srcvalue2,1,qp->srccoin,qp->txid,qp->vout,qp->satoshis,qp->txid2,qp->vout2) == 0 ) { @@ -269,17 +293,20 @@ double LP_quote_validate(struct LP_utxoinfo **autxop,struct LP_utxoinfo **butxop return(-11); } qprice = ((double)qp->destsatoshis / qp->satoshis); - if ( qp->satoshis < (srcvalue / LP_MINVOL) ) + if ( qp->satoshis < (srcvalue / LP_MINVOL) || srcvalue < qp->txfee*LP_MINSIZE_TXFEEMULT ) { - printf("utxo payment %.8f is less than half covered by Q %.8f\n",dstr(srcvalue),dstr(qp->satoshis)); + printf("utxo payment %.8f is less than %f covered by Q %.8f or <10x txfee %.8f\n",dstr(srcvalue),1./LP_MINVOL,dstr(qp->satoshis),dstr(qp->txfee)); return(-12); } - if ( qp->destsatoshis < (destvalue / LP_MINCLIENTVOL) ) + if ( qp->destsatoshis < (destvalue / LP_MINCLIENTVOL) || destvalue < qp->desttxfee*LP_MINSIZE_TXFEEMULT ) { - printf("destsatoshis %.8f is less than half of value %.8f\n",dstr(qp->destsatoshis),dstr(destvalue)); + printf("destsatoshis %.8f is less than %f of value %.8f or < 10x txfee %.8f\n",dstr(qp->destsatoshis),1./LP_MINCLIENTVOL,dstr(destvalue),dstr(qp->desttxfee)); return(-13); } - printf("qprice %.8f <- %.8f/%.8f txfees.(%.8f %.8f)\n",qprice,dstr(qp->destsatoshis),dstr(qp->satoshis),dstr(qp->txfee),dstr(qp->desttxfee)); + LP_txfees(&txfee,&desttxfee,qp->srccoin,qp->destcoin); + printf("qprice %.8f <- %.8f/%.8f txfees.(%.8f %.8f) vs (%.8f %.8f)\n",qprice,dstr(qp->destsatoshis),dstr(qp->satoshis),dstr(qp->txfee),dstr(qp->desttxfee),dstr(txfee),dstr(desttxfee)); + if ( qp->txfee < LP_REQUIRED_TXFEE*txfee || qp->desttxfee < LP_REQUIRED_TXFEE*desttxfee ) + return(-14); return(qprice); } @@ -295,7 +322,7 @@ int32_t LP_arrayfind(cJSON *array,bits256 txid,int32_t vout) return(-1); } -double LP_query(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,char *method,struct LP_quoteinfo *qp) +double LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_quoteinfo *qp) { cJSON *reqjson; char *msg; int32_t i,flag = 0; double price = 0.; struct LP_utxoinfo *utxo; if ( strcmp(method,"request") == 0 ) @@ -311,27 +338,18 @@ double LP_query(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,c reqjson = LP_quotejson(qp); if ( bits256_nonz(qp->desthash) != 0 ) flag = 1; - //printf("QUERY.(%s)\n",jprint(reqjson,0)); - if ( IAMLP != 0 ) - { - jaddstr(reqjson,"method",method); - msg = jprint(reqjson,1); - LP_send(LP_mypubsock,msg,(int32_t)strlen(msg)+1,1); - } - else - { - jaddstr(reqjson,"method2",method); - jaddstr(reqjson,"method","forward"); - jaddbits256(reqjson,"pubkey",qp->srchash); - LP_forward(ctx,myipaddr,mypubsock,profitmargin,qp->srchash,jprint(reqjson,1),1); - } + jaddbits256(reqjson,"pubkey",qp->srchash); + jaddstr(reqjson,"method",method); + msg = jprint(reqjson,1); + printf("QUERY.(%s)\n",msg); + LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->srchash,msg); for (i=0; i<30; i++) { if ( (price= LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout)) > SMALLVAL ) { if ( flag == 0 || bits256_nonz(qp->desthash) != 0 ) { - //printf("break out of loop.%d price %.8f\n",i,price); + printf("break out of loop.%d price %.8f %s/%s\n",i,price,qp->srccoin,qp->destcoin); break; } } @@ -342,7 +360,7 @@ double LP_query(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,c int32_t LP_nanobind(void *ctx,char *pairstr) { - int32_t i,timeout,r,pairsock = -1; uint16_t mypullport; char bindaddr[128]; + int32_t i,r,pairsock = -1; uint16_t mypullport; char bindaddr[128]; if ( LP_canbind != 0 ) { if ( (pairsock= nn_socket(AF_SP,NN_PAIR)) < 0 ) @@ -358,9 +376,9 @@ int32_t LP_nanobind(void *ctx,char *pairstr) nanomsg_transportname(1,bindaddr,LP_myipaddr,r); if ( nn_bind(pairsock,bindaddr) >= 0 ) { - timeout = 100; - nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); - nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + //timeout = 1; + //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); printf("nanobind %s to %d\n",pairstr,pairsock); return(pairsock); } else printf("error binding to %s for %s\n",bindaddr,pairstr); @@ -372,10 +390,10 @@ int32_t LP_nanobind(void *ctx,char *pairstr) return(pairsock); } -int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJSON *argjson,char *myipaddr,char *base,char *rel,double profitmargin,double price,struct LP_quoteinfo *qp) +int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJSON *argjson,char *base,char *rel,double price,struct LP_quoteinfo *qp) { char pairstr[512],*msg; cJSON *retjson; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; struct basilisk_swap *swap; struct iguana_info *coin; - printf("LP_connectstartbob.(%s) with.(%s) %s\n",myipaddr,jprint(argjson,0),LP_myipaddr); + printf("LP_connectstartbob.(%s) with.(%s) %s\n",LP_myipaddr,jprint(argjson,0),LP_myipaddr); qp->quotetime = (uint32_t)time(NULL); if ( (coin= LP_coinfind(utxo->coin)) == 0 ) { @@ -383,11 +401,11 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ return(-1); } privkey = LP_privkey(utxo->coinaddr,coin->taddr); - if ( bits256_nonz(privkey) != 0 && qp->quotetime >= qp->timestamp-3 && qp->quotetime <= utxo->T.swappending && bits256_cmp(LP_mypubkey,qp->srchash) == 0 ) + if ( bits256_nonz(privkey) != 0 && qp->quotetime >= qp->timestamp-3 && qp->quotetime <= utxo->T.swappending && bits256_cmp(LP_mypub25519,qp->srchash) == 0 ) { if ( (pair= LP_nanobind(ctx,pairstr)) >= 0 ) { - LP_requestinit(&qp->R,qp->srchash,qp->desthash,base,qp->satoshis,rel,qp->destsatoshis,qp->timestamp,qp->quotetime,DEXselector); + LP_requestinit(&qp->R,qp->srchash,qp->desthash,base,qp->satoshis-qp->txfee,rel,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); swap = LP_swapinit(1,0,privkey,&qp->R,qp); swap->N.pair = pair; utxo->S.swap = swap; @@ -399,23 +417,16 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ jaddstr(retjson,"pair",pairstr); jaddnum(retjson,"requestid",qp->R.requestid); jaddnum(retjson,"quoteid",qp->R.quoteid); - char str[65]; printf("BOB pubsock.%d sends to (%s)\n",pubsock,bits256_str(str,utxo->S.otherpubkey)); - if ( pubsock >= 0 ) - { - msg = jprint(retjson,0); - LP_send(pubsock,msg,(int32_t)strlen(msg)+1,1); - } - jdelete(retjson,"method"); - jaddstr(retjson,"method2","connected"); - jaddstr(retjson,"method","forward"); - LP_forward(ctx,myipaddr,pubsock,profitmargin,utxo->S.otherpubkey,jprint(retjson,1),1); + char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,utxo->S.otherpubkey)); + msg = jprint(retjson,1); + LP_broadcast_message(pubsock,base,rel,utxo->S.otherpubkey,msg); retval = 0; } else printf("error launching swaploop\n"); } else printf("couldnt bind to any port %s\n",pairstr); } else { - printf("dest %.8f vs required %.8f (%d %d %d %d %d)\n",dstr(qp->destsatoshis),dstr(price*(utxo->S.satoshis-qp->txfee)),bits256_nonz(privkey) != 0 ,qp->timestamp == utxo->T.swappending-LP_RESERVETIME,qp->quotetime >= qp->timestamp-3,qp->quotetime < utxo->T.swappending,bits256_cmp(LP_mypubkey,qp->srchash) == 0); + printf("dest %.8f vs required %.8f (%d %d %d %d %d)\n",dstr(qp->destsatoshis),dstr(price*(utxo->S.satoshis-qp->txfee)),bits256_nonz(privkey) != 0 ,qp->timestamp == utxo->T.swappending-LP_RESERVETIME,qp->quotetime >= qp->timestamp-3,qp->quotetime < utxo->T.swappending,bits256_cmp(LP_mypub25519,qp->srchash) == 0); } if ( retval < 0 ) { @@ -428,33 +439,39 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ char *LP_connectedalice(cJSON *argjson) // alice { - cJSON *retjson; double bid,ask,price,qprice; int32_t timeout,pairsock = -1; char *pairstr; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,*butxo; struct LP_quoteinfo Q; struct basilisk_swap *swap; struct iguana_info *coin; + cJSON *retjson; double bid,ask,price,qprice; int32_t pairsock = -1; char *pairstr; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,*butxo; struct LP_quoteinfo Q; struct basilisk_swap *swap; struct iguana_info *coin; if ( LP_quoteparse(&Q,argjson) < 0 ) clonestr("{\"error\":\"cant parse quote\"}"); - if ( bits256_cmp(Q.desthash,LP_mypubkey) != 0 ) + if ( bits256_cmp(Q.desthash,LP_mypub25519) != 0 ) return(clonestr("{\"result\",\"update stats\"}")); printf("CONNECTED.(%s)\n",jprint(argjson,0)); if ( (qprice= LP_quote_validate(&autxo,&butxo,&Q,0)) <= SMALLVAL ) { LP_availableset(autxo); + LP_pendingswaps--; printf("quote validate error %.0f\n",qprice); return(clonestr("{\"error\":\"quote validation error\"}")); } - if ( (price= LP_myprice(&bid,&ask,Q.destcoin,Q.srccoin)) <= SMALLVAL || ask <= SMALLVAL ) + if ( LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin) <= SMALLVAL || bid <= SMALLVAL ) { printf("this node has no price for %s/%s (%.8f %.8f)\n",Q.destcoin,Q.srccoin,bid,ask); LP_availableset(autxo); + LP_pendingswaps--; return(clonestr("{\"error\":\"no price set\"}")); } - price = 1. / ask; - if ( qprice > price+0.00000001 ) + printf("%s/%s bid %.8f ask %.8f\n",Q.srccoin,Q.destcoin,bid,ask); + //if ( (price= ask) == 0. ) + price = bid; + /*if ( SATOSHIDEN*qprice > (SATOSHIDEN * price) * 1.001 + 10 ) { printf("qprice %.8f too big vs %.8f\n",qprice,price); LP_availableset(autxo); + LP_pendingswaps--; return(clonestr("{\"error\":\"quote price too expensive\"}")); - } + }*/ if ( (coin= LP_coinfind(Q.destcoin)) == 0 ) { + LP_pendingswaps--; return(clonestr("{\"error\":\"cant get alicecoin\"}")); } Q.privkey = LP_privkey(Q.destaddr,coin->taddr); @@ -465,10 +482,10 @@ char *LP_connectedalice(cJSON *argjson) // alice jaddstr(retjson,"error","couldnt create pairsock"); else if ( nn_connect(pairsock,pairstr) >= 0 ) { - timeout = 100; - nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); - nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis,Q.destcoin,Q.destsatoshis,Q.timestamp,Q.quotetime,DEXselector); + //timeout = 1; + //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); swap = LP_swapinit(0,0,Q.privkey,&Q.R,&Q); swap->N.pair = pairsock; autxo->S.swap = swap; @@ -485,6 +502,7 @@ char *LP_connectedalice(cJSON *argjson) // alice printf("connected result.(%s)\n",jprint(retjson,0)); if ( jobj(retjson,"error") != 0 ) LP_availableset(autxo); + else LP_pendingswaps++; return(jprint(retjson,1)); } else @@ -495,14 +513,14 @@ char *LP_connectedalice(cJSON *argjson) // alice } } -int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen,double profitmargin) +int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { char *method,*msg; cJSON *retjson; double qprice,price,bid,ask; struct LP_utxoinfo *autxo,*butxo; int32_t retval = -1; struct LP_quoteinfo Q; if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"request") == 0 ||strcmp(method,"connect") == 0) ) { - //printf("TRADECOMMAND.(%s)\n",jprint(argjson,0)); + printf("TRADECOMMAND.(%s)\n",jprint(argjson,0)); retval = 1; - if ( LP_quoteparse(&Q,argjson) == 0 && bits256_cmp(LP_mypubkey,Q.srchash) == 0 ) + if ( LP_quoteparse(&Q,argjson) == 0 && bits256_cmp(LP_mypub25519,Q.srchash) == 0 ) { if ( (price= LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin)) <= SMALLVAL || ask <= SMALLVAL ) { @@ -515,7 +533,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("quote validate error %.0f\n",qprice); return(-4); } - if ( qprice < price-0.00000001 ) + if ( qprice < (price - 0.00000001) * 0.9999 ) { printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin); return(-5); @@ -535,24 +553,17 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, jaddbits256(retjson,"desthash",butxo->S.otherpubkey); jaddbits256(retjson,"pubkey",butxo->S.otherpubkey); jaddstr(retjson,"method","reserved"); - if ( pubsock >= 0 ) - { - msg = jprint(retjson,0); - LP_send(pubsock,msg,(int32_t)strlen(msg)+1,1); - } - jdelete(retjson,"method"); - jaddstr(retjson,"method2","reserved"); - jaddstr(retjson,"method","forward"); - LP_forward(ctx,myipaddr,pubsock,profitmargin,butxo->S.otherpubkey,jprint(retjson,1),1); + msg = jprint(retjson,1); + printf("set swappending.%u accept qprice %.8f, min %.8f\n(%s)",butxo->T.swappending,qprice,price,msg); + LP_broadcast_message(pubsock,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,msg); butxo->T.lasttime = (uint32_t)time(NULL); - printf("set swappending.%u accept qprice %.8f, min %.8f\n",butxo->T.swappending,qprice,price); } else printf("warning swappending.%u swap.%p\n",butxo->T.swappending,butxo->S.swap); } else if ( strcmp(method,"connect") == 0 ) // bob { retval = 4; if ( butxo->T.swappending != 0 && butxo->S.swap == 0 ) - LP_connectstartbob(ctx,pubsock,butxo,argjson,myipaddr,Q.srccoin,Q.destcoin,profitmargin,qprice,&Q); + LP_connectstartbob(ctx,pubsock,butxo,argjson,Q.srccoin,Q.destcoin,qprice,&Q); else printf("pend.%u swap %p when connect came in (%s)\n",butxo->T.swappending,butxo->S.swap,jprint(argjson,0)); } } @@ -560,19 +571,16 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } -struct LP_utxoinfo *LP_bestutxo(double *ordermatchpricep,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,int64_t txfee,int64_t desttxfee) +struct LP_utxoinfo *LP_bestutxo(double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,uint64_t txfee,uint64_t desttxfee,uint64_t maxdestsatoshis) { - int64_t satoshis,destsatoshis; bits256 txid,pubkey; char *obookstr; cJSON *orderbook,*asks,*item; struct LP_utxoinfo *butxo,*bestutxo = 0; int32_t i,vout,numasks; double bestmetric=0.,metric,vol,price,bestprice = 0.; struct LP_pubkeyinfo *pubp; + int64_t satoshis,destsatoshis; uint64_t val,val2; bits256 txid,pubkey; char *obookstr; cJSON *orderbook,*asks,*item; struct LP_utxoinfo *butxo,*bestutxo = 0; int32_t i,n,j,vout,numasks; double bestmetric=0.,metric,vol,price,qprice,bestprice = 0.; struct LP_pubkeyinfo *pubp; *ordermatchpricep = 0.; - *bestdestsatoshisp = 0; + *bestsatoshisp = *bestdestsatoshisp = 0; if ( duration <= 0 ) duration = LP_ORDERBOOK_DURATION; if ( maxprice <= 0. || LP_priceinfofind(base) == 0 ) return(0); - if ( (desttxfee= LP_getestimatedrate(autxo->coin) * LP_AVETXSIZE) < LP_MIN_TXFEE ) - desttxfee = LP_MIN_TXFEE; - if ( (txfee= LP_getestimatedrate(base) * LP_AVETXSIZE) < LP_MIN_TXFEE ) - txfee = LP_MIN_TXFEE; + LP_txfees(&txfee,&desttxfee,base,autxo->coin); if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 ) { if ( (orderbook= cJSON_Parse(obookstr)) != 0 ) @@ -582,13 +590,14 @@ struct LP_utxoinfo *LP_bestutxo(double *ordermatchpricep,int64_t *bestdestsatosh for (i=0; i SMALLVAL && price <= maxprice ) + price = jdouble(item,"price"); + if ( LP_pricevalid(price) > 0 && price <= maxprice ) { - price *= 1.0001; - if ( price > maxprice ) - price = maxprice; + //price *= 1.0001; + //if ( price > maxprice ) + // price = maxprice; pubkey = jbits256(item,"pubkey"); - if ( bits256_cmp(pubkey,LP_mypubkey) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 && pubp->numerrors < LP_MAXPUBKEY_ERRORS ) + if ( bits256_cmp(pubkey,LP_mypub25519) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 && pubp->numerrors < LP_MAXPUBKEY_ERRORS ) { if ( bestprice == 0. ) // assumes price ordered asks bestprice = price; @@ -599,33 +608,59 @@ struct LP_utxoinfo *LP_bestutxo(double *ordermatchpricep,int64_t *bestdestsatosh metric = price / bestprice; if ( (butxo= LP_utxofind(1,txid,vout)) != 0 && (long long)(vol*SATOSHIDEN) == butxo->S.satoshis && LP_isavailable(butxo) > 0 && LP_ismine(butxo) == 0 )//&& butxo->T.bestflag == 0 ) { - destsatoshis = ((butxo->S.satoshis - txfee) * price); - if ( destsatoshis > autxo->payment.value-desttxfee-1 ) - destsatoshis = autxo->payment.value-desttxfee-1; - satoshis = (destsatoshis / price + 0.0000000049) - txfee; - if ( metric < 1.2 && destsatoshis > desttxfee && destsatoshis-desttxfee > (autxo->payment.value / LP_MINCLIENTVOL) && satoshis-txfee > (butxo->S.satoshis / LP_MINVOL) && satoshis <= butxo->payment.value-txfee ) + if ( LP_iseligible(&val,&val2,butxo->iambob,butxo->coin,butxo->payment.txid,butxo->payment.vout,butxo->S.satoshis,butxo->deposit.txid,butxo->deposit.vout) > 0 ) { - printf("value %.8f price %.8f/%.8f best %.8f destsatoshis %.8f * metric %.8f -> (%f)\n",dstr(autxo->payment.value),price,bestprice,bestmetric,dstr(destsatoshis),metric,dstr(destsatoshis) * metric * metric * metric); - metric = dstr(destsatoshis) * metric * metric * metric; - if ( bestmetric == 0. || metric < bestmetric ) + destsatoshis = ((butxo->S.satoshis - txfee) * price); + satoshis = (destsatoshis / price + 0.49) - txfee; + if ( satoshis <= 0 ) + continue; + qprice = (double)destsatoshis / satoshis; + n = (int32_t)((double)destsatoshis / desttxfee); + if ( n < 10 ) + n = 10; + else n = 3; + for (j=0; jS.satoshis,txfee,autxo->payment.value,maxdestsatoshis,desttxfee)) > price+SMALLVAL ) + break; } - } else printf("skip.(%d %d %d %d %d) metric %f destsatoshis %.8f value %.8f destvalue %.8f txfees %.8f %.8f sats %.8f\n",metric < 1.2,destsatoshis > desttxfee,destsatoshis-desttxfee > (autxo->payment.value / LP_MINCLIENTVOL),satoshis-txfee > (butxo->S.satoshis / LP_MINVOL),satoshis < butxo->payment.value-txfee,metric,dstr(destsatoshis),dstr(butxo->S.satoshis),dstr(autxo->payment.value),dstr(txfee),dstr(desttxfee),dstr(satoshis)); + //printf("j.%d/%d qprice %.8f vs price %.8f best.(%.8f %.8f)\n",j,n,qprice,price,dstr(satoshis),dstr(destsatoshis)); + if ( metric < 1.2 && destsatoshis > desttxfee && destsatoshis-desttxfee > (autxo->payment.value / LP_MINCLIENTVOL) && satoshis-txfee > (butxo->S.satoshis / LP_MINVOL) && satoshis <= butxo->payment.value-txfee ) + { + printf("value %.8f price %.8f/%.8f best %.8f destsatoshis %.8f * metric %.8f -> (%f)\n",dstr(autxo->payment.value),price,bestprice,bestmetric,dstr(destsatoshis),metric,dstr(destsatoshis) * metric * metric * metric); + metric = dstr(destsatoshis) * metric * metric * metric; + if ( bestmetric == 0. || metric < bestmetric ) + { + bestutxo = butxo; + *ordermatchpricep = price; + *bestdestsatoshisp = destsatoshis; + *bestsatoshisp = satoshis; + bestmetric = metric; + printf("set best!\n"); + } + } // else printf("skip.(%d %d %d %d %d) metric %f destsatoshis %.8f value %.8f destvalue %.8f txfees %.8f %.8f sats %.8f\n",metric < 1.2,destsatoshis > desttxfee,destsatoshis-desttxfee > (autxo->payment.value / LP_MINCLIENTVOL),satoshis-txfee > (butxo->S.satoshis / LP_MINVOL),satoshis < butxo->payment.value-txfee,metric,dstr(destsatoshis),dstr(butxo->S.satoshis),dstr(autxo->payment.value),dstr(txfee),dstr(desttxfee),dstr(satoshis)); + } + else + { + printf("ineligible.(%.8f %.8f)\n",price,dstr(butxo->S.satoshis)); + if ( butxo->T.spentflag == 0 ) + butxo->T.spentflag = (uint32_t)time(NULL); + } } else { if ( butxo != 0 ) printf("%llu %llu %d %d %d: ",(long long)(vol*SATOSHIDEN),(long long)butxo->S.satoshis,vol*SATOSHIDEN == butxo->S.satoshis,LP_isavailable(butxo) > 0,LP_ismine(butxo) == 0); printf("cant find butxo.%p or value mismatch %.8f != %.8f or bestflag.%d\n",butxo,vol,butxo!=0?dstr(butxo->S.satoshis):0,butxo->T.bestflag); - //if ( (butxo= LP_utxofind(1,txid,vout)) != 0 && (long long)(vol*SATOSHIDEN) == butxo->S.satoshis && LP_isavailable(butxo) > 0 && LP_ismine(butxo) == 0 && butxo->T.bestflag == 0 ) } } else printf("self trading or blacklisted peer\n"); - } else break; + } + else + { + if ( i == 0 ) + printf("maxprice %.8f vs %.8f\n",maxprice,price); + break; + } } } free_json(orderbook); @@ -634,6 +669,8 @@ struct LP_utxoinfo *LP_bestutxo(double *ordermatchpricep,int64_t *bestdestsatosh } if ( bestutxo == 0 || *ordermatchpricep == 0. || *bestdestsatoshisp == 0 ) return(0); + int32_t changed; + LP_mypriceset(&changed,autxo->coin,base,1. / *ordermatchpricep); return(bestutxo); } @@ -647,27 +684,25 @@ char *LP_bestfit(char *rel,double relvolume) return(jprint(LP_utxojson(autxo),1)); } -char *LP_ordermatch(char *base,int64_t txfee,double maxprice,char *rel,bits256 txid,int32_t vout,bits256 feetxid,int32_t feevout,int64_t desttxfee,int32_t duration) +char *LP_ordermatch(char *base,int64_t txfee,double maxprice,double maxvolume,char *rel,bits256 txid,int32_t vout,bits256 feetxid,int32_t feevout,int64_t desttxfee,int32_t duration) { - struct LP_quoteinfo Q; int64_t bestdestsatoshis = 0; double ordermatchprice = 0.; struct LP_utxoinfo *autxo,*bestutxo; - if ( desttxfee == 0 && (desttxfee= LP_getestimatedrate(rel) * LP_AVETXSIZE) < LP_MIN_TXFEE ) - desttxfee = LP_MIN_TXFEE; - if ( txfee == 0 && (txfee= LP_getestimatedrate(base) * LP_AVETXSIZE) < LP_MIN_TXFEE ) - txfee = LP_MIN_TXFEE; + struct LP_quoteinfo Q; int64_t bestsatoshis=0,bestdestsatoshis = 0; double ordermatchprice = 0.; struct LP_utxoinfo *autxo,*bestutxo; + txfee = LP_txfeecalc(base,txfee); + desttxfee = LP_txfeecalc(rel,desttxfee); if ( (autxo= LP_utxopairfind(0,txid,vout,feetxid,feevout)) == 0 ) return(clonestr("{\"error\":\"cant find alice utxopair\"}")); - if ( (bestutxo= LP_bestutxo(&ordermatchprice,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) + if ( (bestutxo= LP_bestutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,SATOSHIDEN*maxvolume)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) return(clonestr("{\"error\":\"cant find ordermatch utxo\"}")); - if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestdestsatoshis) < 0 ) + if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestsatoshis,bestdestsatoshis) < 0 ) return(clonestr("{\"error\":\"cant set ordermatch quote\"}")); - if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypubkey,autxo->coinaddr) < 0 ) + if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypub25519,autxo->coinaddr) < 0 ) return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); return(jprint(LP_quotejson(&Q),1)); } -char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration) +char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration) { - struct LP_utxoinfo *bobutxo,*aliceutxo; char *retstr; cJSON *bestitem=0; int32_t DEXselector=0; uint32_t expiration; double price; struct LP_pubkeyinfo *pubp; + struct LP_utxoinfo *bobutxo,*aliceutxo; cJSON *bestitem=0; int32_t DEXselector=0; uint32_t expiration; double price; struct LP_pubkeyinfo *pubp; if ( (aliceutxo= LP_utxopairfind(0,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) == 0 ) { char str[65],str2[65]; printf("dest.(%s)/v%d fee.(%s)/v%d\n",bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout); @@ -676,16 +711,16 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,st if ( (bobutxo= LP_utxopairfind(1,qp->txid,qp->vout,qp->txid2,qp->vout2)) == 0 ) return(clonestr("{\"error\":\"cant find bob utxopair\"}")); bobutxo->T.bestflag = (uint32_t)time(NULL); - if ( (retstr= LP_registerall(0)) != 0 ) - free(retstr); - price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"request",qp); + //if ( (retstr= LP_registerall(0)) != 0 ) + // free(retstr); + price = LP_query(ctx,myipaddr,mypubsock,"request",qp); bestitem = LP_quotejson(qp); - if ( price > SMALLVAL ) + if ( LP_pricevalid(price) > 0 ) { if ( price <= maxprice ) { - price = LP_query(ctx,myipaddr,mypubsock,profitmargin,"connect",qp); - LP_requestinit(&qp->R,qp->srchash,qp->desthash,bobutxo->coin,qp->satoshis,qp->destcoin,qp->destsatoshis,qp->timestamp,qp->quotetime,DEXselector); + price = LP_query(ctx,myipaddr,mypubsock,"connect",qp); + LP_requestinit(&qp->R,qp->srchash,qp->desthash,bobutxo->coin,qp->satoshis-qp->txfee,qp->destcoin,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); expiration = (uint32_t)time(NULL) + timeout; while ( time(NULL) < expiration ) { @@ -722,9 +757,9 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,st return(jprint(bestitem,0)); } -char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargin,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration) +char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration) { - int64_t desttxfee,txfee,bestdestsatoshis=0; struct LP_utxoinfo *autxo,*bestutxo = 0; double ordermatchprice=0.; struct LP_quoteinfo Q; + uint64_t desttxfee,txfee; int64_t bestsatoshis=0,bestdestsatoshis=0; struct LP_utxoinfo *autxo,*butxo,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; if ( duration <= 0 ) duration = LP_ORDERBOOK_DURATION; if ( timeout <= 0 ) @@ -733,21 +768,23 @@ char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,double profitmargi return(clonestr("{\"error\":\"invalid parameter\"}")); if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); - if ( (desttxfee= LP_getestimatedrate(rel) * LP_AVETXSIZE) < LP_MIN_TXFEE ) - desttxfee = LP_MIN_TXFEE; - if ( (txfee= LP_getestimatedrate(base) * LP_AVETXSIZE) < LP_MIN_TXFEE ) - txfee = LP_MIN_TXFEE; - if ( (bestutxo= LP_bestutxo(&ordermatchprice,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) + LP_txfees(&txfee,&desttxfee,base,rel); + if ( (bestutxo= LP_bestutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,SATOSHIDEN*relvolume)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) { printf("bestutxo.%p ordermatchprice %.8f bestdestsatoshis %.8f\n",bestutxo,ordermatchprice,dstr(bestdestsatoshis)); return(clonestr("{\"error\":\"cant find ordermatch utxo\"}")); } - if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestdestsatoshis) < 0 ) + if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestsatoshis,bestdestsatoshis) < 0 ) return(clonestr("{\"error\":\"cant set ordermatch quote\"}")); - if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypubkey,autxo->coinaddr) < 0 ) + if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypub25519,autxo->coinaddr) < 0 ) return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); + if ( (qprice= LP_quote_validate(&autxo,&butxo,&Q,0)) <= SMALLVAL ) + { + printf("quote validate error %.0f\n",qprice); + return(clonestr("{\"error\":\"quote validation error\"}")); + } printf("do quote.(%s)\n",jprint(LP_quotejson(&Q),1)); - return(LP_trade(ctx,myipaddr,mypubsock,profitmargin,&Q,maxprice,timeout,duration)); + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration)); } diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index 95c708348..5e7a26cc3 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -33,7 +33,13 @@ cJSON *LP_peerjson(struct LP_peerinfo *peer) cJSON *item = cJSON_CreateObject(); jaddstr(item,"ipaddr",peer->ipaddr); jaddnum(item,"port",peer->port); - jaddnum(item,"profit",peer->profitmargin); + if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) + { + jaddnum(item,"session",LP_sessionid); + if ( LP_mypeer != 0 ) + jaddnum(item,"numutxos",LP_mypeer->numutxos); + } else jaddnum(item,"session",peer->sessionid); + //jaddnum(item,"profit",peer->profitmargin); return(item); } @@ -48,26 +54,32 @@ char *LP_peers() return(jprint(peersjson,1)); } -struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,double profitmargin,int32_t numpeers,int32_t numutxos) +struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,int32_t numpeers,int32_t numutxos,uint32_t sessionid) { - uint32_t ipbits; int32_t maxsize,pushsock,subsock,timeout; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0; + uint32_t ipbits; int32_t pushsock,subsock,timeout; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0; +#ifdef LP_STRICTPEERS + if ( strncmp("5.9.253",ipaddr,strlen("5.9.253")) != 0 ) + return(0); +#endif ipbits = (uint32_t)calc_ipbits(ipaddr); expand_ipbits(checkip,ipbits); if ( strcmp(checkip,ipaddr) == 0 ) { if ( (peer= LP_peerfind(ipbits,port)) != 0 ) { - if ( profitmargin != 0. ) - peer->profitmargin = profitmargin; - if ( numpeers > peer->numpeers ) + /*if ( numpeers > peer->numpeers ) peer->numpeers = numpeers; if ( numutxos > peer->numutxos ) peer->numutxos = numutxos; + if ( peer->sessionid == 0 ) + peer->sessionid = sessionid;*/ } else { - printf("LPaddpeer %s\n",ipaddr); peer = calloc(1,sizeof(*peer)); + if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) + peer->sessionid = LP_sessionid; + else peer->sessionid = sessionid; peer->pushsock = peer->subsock = pushsock = subsock = -1; strcpy(peer->ipaddr,ipaddr); if ( pushport != 0 && subport != 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 ) @@ -75,10 +87,10 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char nanomsg_transportname(0,pushaddr,peer->ipaddr,pushport); if ( nn_connect(pushsock,pushaddr) >= 0 ) { - timeout = 100; + timeout = 1; nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); - maxsize = 2 * 1024 * 1024; - nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDBUF,&maxsize,sizeof(maxsize)); + //maxsize = 2 * 1024 * 1024; + //nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDBUF,&maxsize,sizeof(maxsize)); printf("connected to push.(%s) %d\n",pushaddr,pushsock); peer->connected = (uint32_t)time(NULL); peer->pushsock = pushsock; @@ -101,7 +113,7 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char printf("error connecting to push.(%s)\n",pushaddr); } } else printf("%s pushport.%u subport.%u pushsock.%d\n",ipaddr,pushport,subport,pushsock); - peer->profitmargin = profitmargin; + //peer->profitmargin = profitmargin; peer->ipbits = ipbits; peer->port = port; peer->ip_port = ((uint64_t)port << 32) | ipbits; @@ -113,16 +125,60 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char printf("_LPaddpeer %s -> numpeers.%d mypubsock.%d other.(%d %d)\n",ipaddr,mypeer->numpeers,mypubsock,numpeers,numutxos); } else peer->numpeers = 1; // will become mypeer portable_mutex_unlock(&LP_peermutex); - if ( mypubsock >= 0 ) + if ( IAMLP != 0 && mypubsock >= 0 ) { - char *msg = jprint(LP_peerjson(peer),1); - LP_send(mypubsock,msg,(int32_t)strlen(msg)+1,1); + struct iguana_info *coin,*ctmp; bits256 zero; char *msg,busaddr[64]; + msg = jprint(LP_peerjson(peer),1); + memset(zero.bytes,0,sizeof(zero)); + //LP_send(mypubsock,msg,(int32_t)strlen(msg)+1,1); + LP_broadcast_message(mypubsock,"","",zero,msg); + if ( 0 ) + { + HASH_ITER(hh,LP_coins,coin,ctmp) + { + if ( coin->bussock >= 0 ) + { + nanomsg_transportname(0,busaddr,peer->ipaddr,coin->busport); + nn_connect(coin->bussock,busaddr); + } + } + } } } } else printf("LP_addpeer: checkip.(%s) vs (%s)\n",checkip,ipaddr); return(peer); } +int32_t LP_coinbus(uint16_t coin_busport) +{ + struct LP_peerinfo *peer,*tmp; char busaddr[64]; int32_t timeout,bussock = -1; + return(-1); + if ( IAMLP != 0 && LP_mypeer != 0 && (bussock= nn_socket(AF_SP,NN_BUS)) >= 0 ) + { + timeout = 1; + nn_setsockopt(bussock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(bussock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + nanomsg_transportname(0,busaddr,LP_mypeer->ipaddr,coin_busport); + if ( nn_bind(bussock,busaddr) < 0 ) + { + printf("error binding to coin_busport.%s\n",busaddr); + nn_close(bussock); + } + else + { + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( LP_mypeer->port != peer->port || strcmp(LP_mypeer->ipaddr,peer->ipaddr) != 0 ) + { + nanomsg_transportname(0,busaddr,peer->ipaddr,coin_busport); + nn_connect(bussock,busaddr); + } + } + } + } + return(bussock); +} + int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now) { struct LP_peerinfo *peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; @@ -142,7 +198,7 @@ int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipa argipbits = (uint32_t)calc_ipbits(argipaddr); if ( (peer= LP_peerfind(argipbits,argport)) == 0 ) { - peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jdouble(item,"profit"),jint(item,"numpeers"),jint(item,"numutxos")); + peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session")); } if ( peer != 0 ) { @@ -158,11 +214,11 @@ int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipa return(n); } -void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport,double myprofit) +void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport) { char *retstr; struct LP_peerinfo *peer,*tmp; uint32_t now,flag = 0; peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport); - if ( (retstr= issue_LP_getpeers(destipaddr,destport,myipaddr,myport,myprofit,mypeer!=0?mypeer->numpeers:0,mypeer!=0?mypeer->numutxos:0)) != 0 ) + if ( (retstr= issue_LP_getpeers(destipaddr,destport,myipaddr,myport,mypeer!=0?mypeer->numpeers:0,mypeer!=0?mypeer->numutxos:0)) != 0 ) { //printf("got.(%s)\n",retstr); now = (uint32_t)time(NULL); @@ -174,9 +230,9 @@ void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr { if ( peer->lasttime != now ) { - printf("{%s:%u %.6f}.%d ",peer->ipaddr,peer->port,peer->profitmargin,peer->lasttime - now); + printf("{%s:%u}.%d ",peer->ipaddr,peer->port,peer->lasttime - now); flag++; - if ( (retstr= issue_LP_notify(destipaddr,destport,peer->ipaddr,peer->port,peer->profitmargin,peer->numpeers,0)) != 0 ) + if ( (retstr= issue_LP_notify(destipaddr,destport,peer->ipaddr,peer->port,peer->numpeers,0,peer->sessionid)) != 0 ) free(retstr); } } diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c new file mode 100644 index 000000000..a5982444d --- /dev/null +++ b/iguana/exchanges/LP_portfolio.c @@ -0,0 +1,577 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_portfolio.c +// marketmaker +// + +char LP_portfolio_base[16],LP_portfolio_rel[16]; +double LP_portfolio_relvolume; + +cJSON *LP_portfolio_entry(struct iguana_info *coin) +{ + cJSON *item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jaddstr(item,"address",coin->smartaddr); + jaddnum(item,"amount",dstr(coin->maxamount)); + jaddnum(item,"price",coin->price_kmd); + jaddnum(item,"kmd_equiv",dstr(coin->kmd_equiv)); + jaddnum(item,"perc",coin->perc); + jaddnum(item,"goal",coin->goal); + jaddnum(item,"goalperc",coin->goalperc); + jaddnum(item,"relvolume",coin->relvolume); + jaddnum(item,"force",coin->force); + jaddnum(item,"balanceA",dstr(coin->balanceA)); + jaddnum(item,"valuesumA",dstr(coin->valuesumA)); + if ( coin->valuesumA != 0 ) + jaddnum(item,"aliceutil",100. * (double)coin->balanceA/coin->valuesumA); + jaddnum(item,"balanceB",dstr(coin->balanceB)); + jaddnum(item,"valuesumB",dstr(coin->valuesumB)); + jaddnum(item,"balance",dstr(coin->maxamount)); + if ( coin->valuesumB != 0 ) + jaddnum(item,"bobutil",100. * (double)coin->balanceB/coin->valuesumB); + return(item); +} + +uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr) +{ + cJSON *array,*item; int32_t i,n; uint64_t valuesum,satoshisum,value; + valuesum = satoshisum = 0; + if ( (array= LP_listunspent(symbol,coinaddr)) != 0 ) + { + if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0 && is_cJSON_Array(array) != 0 ) + { + for (i=0; iinactive != 0 ) + continue; + if ( iter == 0 ) + { + LP_privkey_init(-1,coin,LP_mypriv25519,LP_mypub25519); + coin->balanceA = LP_balance(&coin->valuesumA,0,coin->symbol,coin->smartaddr); + coin->balanceB = LP_balance(&coin->valuesumB,1,coin->symbol,coin->smartaddr); + if ( strcmp(coin->symbol,"KMD") != 0 ) + coin->price_kmd = LP_price(coin->symbol,"KMD"); + else coin->price_kmd = 1.; + coin->maxamount = coin->valuesumA; + if ( coin->valuesumB > coin->maxamount ) + coin->maxamount = coin->valuesumB; + coin->kmd_equiv = coin->maxamount * coin->price_kmd; + kmdsum += coin->kmd_equiv; + goalsum += coin->goal; + } + else + { + coin->relvolume = 0.; + if ( kmdsum > SMALLVAL ) + coin->perc = 100. * coin->kmd_equiv / kmdsum; + if ( goalsum > SMALLVAL && coin->goal > SMALLVAL ) + { + coin->goalperc = 100. * coin->goal / goalsum; + if ( (coin->force= (coin->goalperc - coin->perc)) < 0. ) + { + coin->force *= -coin->force; + if ( coin->price_kmd > SMALLVAL ) + coin->relvolume = (dstr(coin->maxamount) * (coin->perc - coin->goalperc)) / 100.; + } else coin->force *= coin->force; + if ( coin->force > maxval ) + { + maxval = coin->force; + buycoin = coin; + } + if ( coin->force < minval ) + { + minval = coin->force; + sellcoin = coin; + } + } else coin->goalperc = coin->force = 0.; + jaddi(array,LP_portfolio_entry(coin)); + } + } + } + jaddstr(retjson,"result","success"); + jaddnum(retjson,"kmd_equiv",dstr(kmdsum)); + if ( buycoin != 0 ) + { + jaddstr(retjson,"buycoin",buycoin->symbol); + jaddnum(retjson,"buyforce",maxval); + } + if ( sellcoin != 0 ) + { + jaddstr(retjson,"sellcoin",sellcoin->symbol); + jaddnum(retjson,"sellforce",minval); + } + if ( LP_portfolio_relvolume > SMALLVAL ) + { + jaddstr(retjson,"base",LP_portfolio_base); + jaddstr(retjson,"rel",LP_portfolio_rel); + jaddnum(retjson,"relvolume",LP_portfolio_relvolume); + } + jadd(retjson,"portfolio",array); + return(jprint(retjson,1)); +} + +char *LP_portfolio_goal(char *symbol,double goal) +{ + struct iguana_info *coin,*tmp; int32_t iter,n = 0; double kmdbtc = 50.; + if ( strcmp(symbol,"*") == 0 ) + { + for (iter=0; iter<2; iter++) + { + HASH_ITER(hh,LP_coins,coin,tmp) + { + if ( coin->inactive != 0 ) + continue; + if ( iter == 0 ) + coin->goal = 0; + if ( coin->inactive == 0 && strcmp(coin->symbol,"KMD") != 0 && strcmp(coin->symbol,"BTC") != 0 ) + { + if ( iter == 0 ) + n++; + else coin->goal = (100. - kmdbtc) / n; + } + } + if ( n == 0 ) + break; + } + if ( (coin= LP_coinfind("KMD")) != 0 && coin->inactive == 0 ) + coin->goal = kmdbtc * 0.5; + if ( (coin= LP_coinfind("BTC")) != 0 && coin->inactive == 0 ) + coin->goal = kmdbtc * 0.5; + return(LP_portfolio()); + } + else if ( (coin= LP_coinfind(symbol)) != 0 && coin->inactive == 0 ) + { + coin->goal = goal; + printf("set %s goal %f\n",coin->symbol,goal); + return(LP_portfolio()); + } else return(clonestr("{\"error\":\"cant set goal for inactive coin\"}")); +} + +int32_t LP_autoprices; + +/*int32_t LP_autofill(char *base,char *rel,double maxprice,double totalrelvolume) +{ + struct LP_priceinfo *basepp,*relpp; + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + basepp->maxprices[relpp->ind] = maxprice; + basepp->relvols[relpp->ind] = totalrelvolume; + LP_autofills++; + return(0); + } + return(-1); +}*/ + +int32_t LP_autoprice(char *base,char *rel,double minprice,double margin,char *type) +{ + struct LP_priceinfo *basepp,*relpp; + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + basepp->minprices[relpp->ind] = minprice; + basepp->margins[relpp->ind] = margin; + LP_autoprices++; + return(0); + } + return(-1); +} + +void LP_autopriceset(void *ctx,int32_t dir,struct LP_priceinfo *relpp,struct LP_priceinfo *basepp,double price) +{ + double margin,minprice,oppomargin; int32_t changed; + margin = basepp->margins[relpp->ind]; + oppomargin = relpp->margins[basepp->ind]; + if ( margin != 0. || oppomargin != 0. ) + { + if ( margin == 0. ) + margin = oppomargin; + //printf("min %.8f %s/%s %.8f dir.%d margin %.8f (%.8f %.8f)\n",basepp->minprices[relpp->ind],relpp->symbol,basepp->symbol,price,dir,margin,1. / (price * (1. - margin)),(price * (1. + margin))); + if ( dir > 0 ) + price = 1. / (price * (1. - margin)); + else price = (price * (1. + margin)); + if ( (minprice= basepp->minprices[relpp->ind]) == 0. || price >= minprice ) + { + LP_mypriceset(&changed,relpp->symbol,basepp->symbol,price); + //printf("changed.%d\n",changed); + if ( changed != 0 ) + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,price); + } + } +} + +double LP_pricesparse(void *ctx,int32_t trexflag,char *retstr,struct LP_priceinfo *btcpp) +{ + //{"success":true,"message":"","result":[{"MarketName":"BTC-KMD","High":0.00040840,"Low":0.00034900,"Volume":328042.46061669,"Last":0.00037236,"BaseVolume":123.36439511,"TimeStamp":"2017-07-15T13:50:21.87","Bid":0.00035721,"Ask":0.00037069,"OpenBuyOrders":343,"OpenSellOrders":1690,"PrevDay":0.00040875,"Created":"2017-02-11T23:04:01.853"}, + //{"TradePairId":4762,"Label":"WAVES/BTC","AskPrice":0.00099989,"BidPrice":0.00097350,"Low":0.00095000,"High":0.00108838,"Volume":6501.24403100,"LastPrice":0.00098028,"BuyVolume":1058994.86554882,"SellVolume":2067.87377158,"Change":-7.46,"Open":0.00105926,"Close":0.00098028,"BaseVolume":6.52057452,"BuyBaseVolume":2.33098660,"SellBaseVolume":1167.77655709}, + int32_t i,j,n,iter; double price,kmdbtc,bid,ask,nxtkmd=0.; struct LP_priceinfo *coinpp,*refpp; char symbol[16],*name,*refcoin; cJSON *retjson,*array,*item; + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + //printf("got.(%s)\n",retstr); + kmdbtc = 0.; + refcoin = "BTC"; + refpp = btcpp; + if ( (array= jarray(&n,retjson,trexflag != 0 ? "result" : "Data")) != 0 ) + { + for (iter=0; iter<2; iter++) + { + for (i=0; i SMALLVAL && strcmp(symbol,"NXT") == 0 ) + nxtkmd = 0.5 * (bid + ask) / kmdbtc; + if ( (coinpp= LP_priceinfofind(symbol)) != 0 ) + { + coinpp->high[trexflag] = jdouble(item,"High"); + coinpp->low[trexflag] = jdouble(item,"Low"); + //coinpp->volume = jdouble(item,"Volume"); + //coinpp->btcvolume = jdouble(item,"BaseVolume"); + coinpp->last[trexflag] = jdouble(item,trexflag != 0 ? "Last" : "LastPrice"); + coinpp->bid[trexflag] = bid; + coinpp->ask[trexflag] = ask; + //coinpp->prevday = jdouble(item,"PrevDay"); + //printf("iter.%d trexflag.%d %s high %.8f, low %.8f, last %.8f hbla.(%.8f %.8f)\n",iter,trexflag,symbol,coinpp->high[trexflag],coinpp->low[trexflag],coinpp->last[trexflag],coinpp->bid[trexflag],coinpp->ask[trexflag]); + if ( coinpp->bid[trexflag] > SMALLVAL && coinpp->ask[trexflag] > SMALLVAL ) + { + price = 0.5 * (coinpp->bid[trexflag] + coinpp->ask[trexflag]); + if ( iter == 0 ) + { + if ( strcmp(symbol,"KMD") == 0 ) + kmdbtc = price; + } + else + { + if ( strcmp(symbol,"KMD") == 0 ) + continue; + //printf("(%s/%s) iter.%d trexflag.%d %s %.8f %.8f\n",refpp->symbol,coinpp->symbol,iter,trexflag,symbol,price,price/kmdbtc); + price /= kmdbtc; + } + if ( trexflag == 0 && coinpp->bid[1] > SMALLVAL && coinpp->ask[1] > SMALLVAL ) + { + //printf("have trex: iter.%d trexflag.%d %s %.8f %.8f\n",iter,trexflag,symbol,coinpp->bid[1],coinpp->ask[1]); + continue; + } + LP_autopriceset(ctx,1,refpp,coinpp,price); + LP_autopriceset(ctx,-1,coinpp,refpp,price); + } + } + } + } + } + refcoin = "KMD"; + if ( kmdbtc == 0. || (refpp= LP_priceinfofind("KMD")) == 0 ) + break; + } + } + free_json(retjson); + } + return(nxtkmd); +} + +static char *assetids[][3] = +{ + { "12071612744977229797", "UNITY", "10000" }, + { "15344649963748848799", "DEX", "1" }, + { "6883271355794806507", "PANGEA", "10000" }, + { "17911762572811467637", "JUMBLR", "10000" }, + { "17083334802666450484", "BET", "10000" }, + { "13476425053110940554", "CRYPTO", "1000" }, + { "6932037131189568014", "HODL", "1" }, + { "3006420581923704757", "SHARK", "10000" }, + { "17571711292785902558", "BOTS", "1" }, + { "10524562908394749924", "MGW", "1" }, +}; + +void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) +{ + char *retstr; cJSON *retjson,*bid,*ask; uint64_t bidsatoshis,asksatoshis; int32_t i; double nxtkmd,price; struct LP_priceinfo *kmdpp,*fiatpp,*nxtpp; + if ( (retstr= issue_curlt("https://bittrex.com/api/v1.1/public/getmarketsummaries",LP_HTTP_TIMEOUT*10)) == 0 ) + { + printf("trex error getting marketsummaries\n"); + sleep(60); + return; + } + nxtkmd = LP_pricesparse(ctx,1,retstr,btcpp); + free(retstr); + if ( (retstr= issue_curlt("https://www.cryptopia.co.nz/api/GetMarkets",LP_HTTP_TIMEOUT*10)) == 0 ) + { + printf("cryptopia error getting marketsummaries\n"); + sleep(60); + return; + } + LP_pricesparse(ctx,0,retstr,btcpp); + free(retstr); + if ( (kmdpp= LP_priceinfofind("KMD")) != 0 ) + { + for (i=0; i<32; i++) + { + if ( (fiatpp= LP_priceinfofind(CURRENCIES[i])) != 0 ) + { + if ( (retjson= LP_paxprice(CURRENCIES[i])) != 0 ) + { + //printf("(%s %.8f %.8f) ",CURRENCIES[i],jdouble(retjson,"price"),jdouble(retjson,"invprice")); + price = jdouble(retjson,"price"); + LP_autopriceset(ctx,1,kmdpp,fiatpp,price); + LP_autopriceset(ctx,-1,fiatpp,kmdpp,price); + free_json(retjson); + } + } + } + } + if ( nxtkmd > SMALLVAL ) + { + for (i=0; i (%s) nxtkmd %.8f %.8f %.8f\n",assetids[i][1],assetids[i][0],jprint(retjson,0),nxtkmd,0.5*dstr(bidsatoshis + asksatoshis),price); + free_json(retjson); + } + } + } + } +} + +int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,struct iguana_info *buy,struct iguana_info *sell,double relvolume,int32_t setbaserel) +{ + char *retstr2; double bid,ask,maxprice; uint32_t requestid,quoteid,iter,i; cJSON *retjson2; + requestid = quoteid = 0; + LP_myprice(&bid,&ask,buy->symbol,sell->symbol); + maxprice = ask; + if ( setbaserel != 0 ) + { + strcpy(LP_portfolio_base,""); + strcpy(LP_portfolio_rel,""); + LP_portfolio_relvolume = 0.; + } + printf("pending.%d base buy.%s, rel sell.%s relvolume %f maxprice %.8f (%.8f %.8f)\n",LP_pendingswaps,buy->symbol,sell->symbol,sell->relvolume,maxprice,bid,ask); + if ( LP_pricevalid(maxprice) > 0 ) + { + relvolume = sell->relvolume; + for (iter=0; iter<2; iter++) + { + if ( relvolume < dstr(LP_MIN_TXFEE) ) + break; + if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 ) + { + if ( (retstr2= LP_autotrade(ctx,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600)) != 0 ) + { + if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) + { + if ( (requestid= juint(retjson2,"requestid")) != 0 && (quoteid= juint(retjson2,"quoteid")) != 0 ) + { + + } + free_json(retjson2); + } + printf("%s relvolume %.8f LP_autotrade.(%s)\n",sell->symbol,relvolume,retstr2); + free(retstr2); + } + if ( requestid != 0 && quoteid != 0 ) + break; + } else printf("cant find alice %.8f %s\n",relvolume,sell->symbol); + if ( iter == 0 ) + { + for (i=0; i<100; i++) + { + relvolume *= .99; + if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 ) + { + printf("i.%d relvolume %.8f from %.8f\n",i,relvolume,sell->relvolume); + break; + } + } + } + } + } + else if ( setbaserel != 0 ) + { + strcpy(LP_portfolio_base,buy->symbol); + strcpy(LP_portfolio_rel,sell->symbol); + LP_portfolio_relvolume = sell->relvolume; + } + *requestidp = requestid; + *quoteidp = quoteid; + if ( requestid != 0 && quoteid != 0 ) + return(0); + else return(-1); +} + +struct LP_portfoliotrade { double metric; char buycoin[16],sellcoin[16]; }; + +int32_t LP_portfolio_order(struct LP_portfoliotrade *trades,int32_t max,cJSON *array) +{ + int32_t i,j,m,n = 0; cJSON *item; struct LP_portfoliotrade coins[256]; + memset(coins,0,sizeof(coins)); + if ( (m= cJSON_GetArraySize(array)) > 0 ) + { + for (i=j=0; i SMALLVAL && coins[j].buycoin[0] != 0 ) + j++; + } + if ( (m= j) > 1 ) + { + for (i=n=0; i 0. ) + { + trades[n].metric = (coins[i].metric - coins[j].metric); + strcpy(trades[n].buycoin,coins[i].buycoin); + strcpy(trades[n].sellcoin,coins[j].buycoin); + printf("buy %s %f, sell %s %f -> %f\n",trades[n].buycoin,coins[i].metric,trades[n].sellcoin,coins[j].metric,trades[n].metric); + } + else + { + trades[n].metric = (coins[j].metric - coins[i].metric); + strcpy(trades[n].buycoin,coins[j].buycoin); + strcpy(trades[n].sellcoin,coins[i].buycoin); + printf("buy %s %f, sell %s %f -> %f\n",trades[n].buycoin,coins[j].metric,trades[n].sellcoin,coins[i].metric,trades[n].metric); + } + n++; + if ( n >= max ) + break; + } + revsortds((void *)trades,n,sizeof(*trades)); + for (i=0; i %f\n",i,trades[i].buycoin,trades[i].sellcoin,trades[i].metric); + } + } + return(n); +} + +void prices_loop(void *ignore) +{ + char *retstr; cJSON *retjson,*array; char *buycoin,*sellcoin; struct iguana_info *buy,*sell; uint32_t requestid,quoteid; int32_t i,n,m; struct LP_portfoliotrade trades[256]; struct LP_priceinfo *btcpp; void *ctx = bitcoin_ctx(); + while ( 1 ) + { + if ( (btcpp= LP_priceinfofind("BTC")) == 0 ) + { + sleep(60); + continue; + } + if ( LP_autoprices != 0 ) + LP_autoprice_iter(ctx,btcpp); + if ( (retstr= LP_portfolio()) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (buycoin= jstr(retjson,"buycoin")) != 0 && (buy= LP_coinfind(buycoin)) != 0 && (sellcoin= jstr(retjson,"sellcoin")) != 0 && (sell= LP_coinfind(sellcoin)) != 0 && buy->inactive == 0 && sell->inactive == 0 ) + { + if ( LP_portfolio_trade(ctx,&requestid,"eid,buy,sell,sell->relvolume,1) < 0 ) + { + array = jarray(&m,retjson,"portfolio"); + if ( array != 0 && (n= LP_portfolio_order(trades,(int32_t)(sizeof(trades)/sizeof(*trades)),array)) > 0 ) + { + for (i=0; irelvolume,0) == 0 ) + break; + } + } + } + } + } + free_json(retjson); + } + free(retstr); + } + sleep(60); + } +} + + diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 1d7d239da..d68ae2257 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -26,9 +26,14 @@ struct LP_priceinfo char symbol[16]; uint64_t coinbits; int32_t ind,pad; - double diagval; + double diagval,high[2],low[2],last[2],bid[2],ask[2]; //volume,btcvolume,prevday; // mostly bittrex info double relvals[LP_MAXPRICEINFOS]; double myprices[LP_MAXPRICEINFOS]; + double minprices[LP_MAXPRICEINFOS]; // autoprice + double margins[LP_MAXPRICEINFOS]; + //double maxprices[LP_MAXPRICEINFOS]; // autofill of base/rel + //double relvols[LP_MAXPRICEINFOS]; + FILE *fps[LP_MAXPRICEINFOS]; } LP_priceinfos[LP_MAXPRICEINFOS]; int32_t LP_numpriceinfos; @@ -49,6 +54,13 @@ struct LP_pubkeyinfo uint32_t timestamp,istrusted,numerrors; } *LP_pubkeyinfos; +int32_t LP_pricevalid(double price) +{ + if ( price > SMALLVAL && isnan(price) == 0 && price < SATOSHIDEN ) + return(1); + else return(0); +} + struct LP_priceinfo *LP_priceinfofind(char *symbol) { int32_t i; struct LP_priceinfo *pp; uint64_t coinbits; @@ -167,7 +179,8 @@ cJSON *LP_pubkeyjson(struct LP_pubkeyinfo *pubp) base = LP_priceinfos[baseid].symbol; for (relid=0; relidmatrix[baseid][relid]) > SMALLVAL ) + price = pubp->matrix[baseid][relid]; + if ( LP_pricevalid(price) > 0 ) { item = cJSON_CreateArray(); jaddistr(item,base); @@ -197,7 +210,7 @@ char *LP_prices() void LP_prices_parse(cJSON *obj) { - struct LP_pubkeyinfo *pubp; struct LP_priceinfo *basepp; uint32_t timestamp; bits256 pubkey; cJSON *asks,*item; int32_t i,n,relid; char *base,*rel; double askprice; + struct LP_pubkeyinfo *pubp; struct LP_priceinfo *basepp,*relpp; uint32_t timestamp; bits256 pubkey; cJSON *asks,*item; int32_t i,n,relid; char *base,*rel; double askprice; pubkey = jbits256(obj,"pubkey"); if ( bits256_nonz(pubkey) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 ) { @@ -210,10 +223,18 @@ void LP_prices_parse(cJSON *obj) base = jstri(item,0); rel = jstri(item,1); askprice = jdoublei(item,2); - if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 ) + if ( LP_pricevalid(askprice) > 0 ) { - char str[65]; printf("%s %s/%s (%d/%d) %.8f\n",bits256_str(str,pubkey),base,rel,basepp->ind,relid,askprice); - pubp->matrix[basepp->ind][relid] = askprice; + if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 ) + { + char str[65]; printf("%s %s/%s (%d/%d) %.8f\n",bits256_str(str,pubkey),base,rel,basepp->ind,relid,askprice); + pubp->matrix[basepp->ind][relid] = askprice; + if ( (relpp= LP_priceinfofind(rel)) != 0 ) + { + dxblend(&basepp->relvals[relpp->ind],askprice,0.9); + dxblend(&relpp->relvals[basepp->ind],1. / askprice,0.9); + } + } } } } @@ -247,8 +268,10 @@ double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,i (*qp) = ptr->Q; if ( ptr->price == 0. && ptr->Q.satoshis != 0 ) { - printf("LP_pricecache: null ptr->price? "); ptr->price = (double)ptr->Q.destsatoshis / ptr->Q.satoshis; + if ( LP_pricevalid(ptr->price) <= 0 ) + ptr->price = 0.; + //printf("LP_pricecache: set %s/%s ptr->price %.8f\n",base,rel,ptr->price); } //printf("found %s/%s %.8f\n",base,rel,ptr->price); return(ptr->price); @@ -260,12 +283,15 @@ double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,i void LP_priceinfoupdate(char *base,char *rel,double price) { struct LP_priceinfo *basepp,*relpp; - if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + if ( LP_pricevalid(price) > 0 ) { - //dxblend(&basepp->relvals[relpp->ind],price,0.9); - //dxblend(&relpp->relvals[basepp->ind],1. / price,0.9); - basepp->relvals[relpp->ind] = price; - relpp->relvals[basepp->ind] = 1. / price; + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + //dxblend(&basepp->relvals[relpp->ind],price,0.9); + //dxblend(&relpp->relvals[basepp->ind],1. / price,0.9); + basepp->relvals[relpp->ind] = price; + relpp->relvals[basepp->ind] = 1. / price; + } } } @@ -275,9 +301,11 @@ double LP_myprice(double *bidp,double *askp,char *base,char *rel) *bidp = *askp = 0.; if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { - if ( (*askp= basepp->myprices[relpp->ind]) > SMALLVAL ) + *askp = basepp->myprices[relpp->ind]; + if ( LP_pricevalid(*askp) > 0 ) { - if ( (val= relpp->myprices[basepp->ind]) > SMALLVAL ) + val = relpp->myprices[basepp->ind]; + if ( LP_pricevalid(val) > 0 ) { *bidp = 1. / val; return((*askp + *bidp) * 0.5); @@ -290,7 +318,8 @@ double LP_myprice(double *bidp,double *askp,char *base,char *rel) } else { - if ( (val= relpp->myprices[basepp->ind]) > SMALLVAL ) + val = relpp->myprices[basepp->ind]; + if ( LP_pricevalid(val) > 0 ) { *bidp = 1. / val; *askp = 0.; @@ -325,14 +354,18 @@ char *LP_myprices() return(jprint(array,1)); } -int32_t LP_mypriceset(char *base,char *rel,double price) +int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) { struct LP_priceinfo *basepp,*relpp; struct LP_pubkeyinfo *pubp; - if ( base != 0 && rel != 0 && price > SMALLVAL && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + *changedp = 0; + if ( base != 0 && rel != 0 && LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { + if ( fabs(basepp->myprices[relpp->ind] - price) > SMALLVAL ) + *changedp = 1; basepp->myprices[relpp->ind] = price; // ask + //printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); //relpp->myprices[basepp->ind] = (1. / price); // bid - if ( (pubp= LP_pubkeyadd(LP_mypubkey)) != 0 ) + if ( (pubp= LP_pubkeyadd(LP_mypub25519)) != 0 ) { pubp->matrix[basepp->ind][relpp->ind] = price; //pubp->matrix[relpp->ind][basepp->ind] = (1. / price); @@ -425,24 +458,27 @@ struct LP_cacheinfo *LP_cacheadd(char *base,char *rel,bits256 txid,int32_t vout, char str[65]; struct LP_cacheinfo *ptr=0; if ( base == 0 || rel == 0 ) return(0); - if ( (ptr= LP_cachefind(base,rel,txid,vout)) == 0 ) + if ( LP_pricevalid(price) > 0 ) { - ptr = calloc(1,sizeof(*ptr)); - if ( LP_cachekey(ptr->key,base,rel,txid,vout) == sizeof(ptr->key) ) + if ( (ptr= LP_cachefind(base,rel,txid,vout)) == 0 ) { - portable_mutex_lock(&LP_cachemutex); - HASH_ADD(hh,LP_cacheinfos,key,sizeof(ptr->key),ptr); - portable_mutex_unlock(&LP_cachemutex); - } else printf("LP_cacheadd keysize mismatch?\n"); + ptr = calloc(1,sizeof(*ptr)); + if ( LP_cachekey(ptr->key,base,rel,txid,vout) == sizeof(ptr->key) ) + { + portable_mutex_lock(&LP_cachemutex); + HASH_ADD(hh,LP_cacheinfos,key,sizeof(ptr->key),ptr); + portable_mutex_unlock(&LP_cachemutex); + } else printf("LP_cacheadd keysize mismatch?\n"); + } + ptr->Q = *qp; + ptr->timestamp = (uint32_t)time(NULL); + if ( price != ptr->price ) + { + ptr->price = price; + LP_priceinfoupdate(base,rel,price); + printf("updated %s/v%d %s/%s %llu price %.8f\n",bits256_str(str,txid),vout,base,rel,(long long)qp->satoshis,price); + } else ptr->price = price; } - ptr->Q = *qp; - ptr->timestamp = (uint32_t)time(NULL); - if ( price != ptr->price ) - { - ptr->price = price; - LP_priceinfoupdate(base,rel,price); - printf("updated %s/v%d %s/%s %llu price %.8f\n",bits256_str(str,txid),vout,base,rel,(long long)qp->satoshis,price); - } else ptr->price = price; return(ptr); } @@ -475,7 +511,7 @@ static int _cmp_orderbook(const void *a,const void *b) cJSON *LP_orderbookjson(struct LP_orderbookentry *op) { cJSON *item = cJSON_CreateObject(); - if ( op->price > SMALLVAL ) + if ( LP_pricevalid(op->price) > 0 ) { jaddnum(item,"price",op->price); jaddnum(item,"volume",dstr(op->basesatoshis)); @@ -513,32 +549,6 @@ int32_t LP_orderbookfind(struct LP_orderbookentry **array,int32_t num,bits256 tx return(-1); } -int32_t LP_utxo_clientpublish(struct LP_utxoinfo *utxo) -{ - struct LP_peerinfo *peer,*tmp; cJSON *retjson; char *retstr; int32_t n = 0; - HASH_ITER(hh,LP_peerinfos,peer,tmp) - { - if ( (retstr= issue_LP_notifyutxo(peer->ipaddr,peer->port,utxo)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( jobj(retjson,"error") == 0 ) - { - //if ( strcmp("HUSH",utxo->coin) == 0 ) - // printf("clientpublish %s (%s)\n",peer->ipaddr,retstr); - utxo->T.lasttime = (uint32_t)time(NULL); - n++; - } - free_json(retjson); - } - free(retstr); - } - //if ( utxo->T.lasttime != 0 ) - // return(0); - } - return(n); -} - int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *rel,struct LP_orderbookentry *(**arrayp),int32_t num,int32_t cachednum,int32_t duration) { struct LP_utxoinfo *utxo,*tmp; struct LP_pubkeyinfo *pubp=0; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; uint32_t oldest; double price; int32_t baseid,relid; uint64_t basesatoshis,val,val2; @@ -568,7 +578,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char * { *arrayp = realloc(*arrayp,sizeof(*(*arrayp)) * (num+1)); (*arrayp)[num++] = op; - if ( bits256_cmp(utxo->pubkey,LP_mypubkey) == 0 && utxo->T.lasttime == 0 ) + if ( LP_ismine(utxo) > 0 && utxo->T.lasttime == 0 ) LP_utxo_clientpublish(utxo); } } @@ -597,13 +607,13 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) qsort(bids,numbids,sizeof(*bids),_cmp_orderbook); if ( numasks > 1 ) { - for (i=0; iprice); - printf(" -> "); + //for (i=0; iprice); + //printf(" -> "); qsort(asks,numasks,sizeof(*asks),_cmp_orderbook); - for (i=0; iprice); - printf("sorted asks.%d\n",numasks); + //for (i=0; iprice); + //printf("sorted asks.%d\n",numasks); } for (i=0; i SMALLVAL && origprice < price ) price = origprice; } - if ( price > SMALLVAL ) + if ( LP_pricevalid(price) > 0 ) { retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jaddstr(retjson,"method","postprice"); - jaddbits256(retjson,"pubkey",LP_mypubkey); + jaddbits256(retjson,"pubkey",LP_mypub25519); jaddstr(retjson,"base",base); jaddstr(retjson,"rel",rel); jaddnum(retjson,"price",price); @@ -661,21 +671,179 @@ void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveas LP_priceinfoupdate(base,rel,price); } +void LP_pricefname(char *fname,char *base,char *rel) +{ + sprintf(fname,"%s/PRICES/%s_%s",GLOBAL_DBDIR,base,rel); + OS_compatible_path(fname); +} + +void LP_priceitemadd(cJSON *retarray,uint32_t timestamp,double avebid,double aveask,double highbid,double lowask) +{ + cJSON *item = cJSON_CreateArray(); + jaddinum(item,timestamp); + jaddinum(item,avebid); + jaddinum(item,aveask); + jaddinum(item,highbid); + jaddinum(item,lowask); + jaddi(retarray,item); +} + +cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,int32_t timescale) +{ + cJSON *retarray; char askfname[1024],bidfname[1024]; uint64_t bidprice64,askprice64; uint32_t bidnow,asknow,bidi,aski,lastbidi,lastaski; int32_t numbids,numasks; double bidemit,askemit,bidsum,asksum,bid,ask,highbid,lowbid,highask,lowask,bidemit2,askemit2; FILE *askfp=0,*bidfp=0; + if ( timescale <= 0 ) + timescale = 60; + if ( lasttime == 0 ) + lasttime = (uint32_t)-1; + LP_pricefname(askfname,base,rel); + LP_pricefname(bidfname,rel,base); + retarray = cJSON_CreateArray(); + lastbidi = lastaski = 0; + numbids = numasks = 0; + bidsum = asksum = askemit = bidemit = highbid = lowbid = highask = lowask = 0.; + if ( (bidfp= fopen(bidfname,"rb")) != 0 && (askfp= fopen(askfname,"rb")) != 0 ) + { + while ( bidfp != 0 || askfp != 0 ) + { + bidi = aski = 0; + bidemit = askemit = bidemit2 = askemit2 = 0.; + if ( bidfp != 0 && fread(&bidnow,1,sizeof(bidnow),bidfp) == sizeof(bidnow) && fread(&bidprice64,1,sizeof(bidprice64),bidfp) == sizeof(bidprice64) ) + { + //printf("bidnow.%u %.8f\n",bidnow,dstr(bidprice64)); + if ( bidnow != 0 && bidprice64 != 0 && bidnow >= firsttime && bidnow <= lasttime ) + { + bidi = bidnow / timescale; + if ( bidi != lastbidi ) + { + if ( bidsum != 0. && numbids != 0 ) + { + bidemit = bidsum / numbids; + bidemit2 = highbid; + } + bidsum = highbid = lowbid = 0.; + numbids = 0; + } + if ( (bid= 1. / dstr(bidprice64)) != 0. ) + { + if ( bid > highbid ) + highbid = bid; + if ( lowbid == 0. || bid < lowbid ) + lowbid = bid; + bidsum += bid; + numbids++; + //printf("bidi.%u num.%d %.8f [%.8f %.8f]\n",bidi,numbids,bid,lowbid,highbid); + } + } + } else fclose(bidfp), bidfp = 0; + if ( askfp != 0 && fread(&asknow,1,sizeof(asknow),askfp) == sizeof(asknow) && fread(&askprice64,1,sizeof(askprice64),askfp) == sizeof(askprice64) ) + { + //printf("asknow.%u %.8f\n",asknow,dstr(askprice64)); + if ( asknow != 0 && askprice64 != 0 && asknow >= firsttime && asknow <= lasttime ) + { + aski = asknow / timescale; + if ( aski != lastaski ) + { + if ( asksum != 0. && numasks != 0 ) + { + askemit = asksum / numasks; + askemit2 = lowask; + } + asksum = highask = lowask = 0.; + numasks = 0; + } + if ( (ask= dstr(askprice64)) != 0. ) + { + if ( ask > highask ) + highask = ask; + if ( lowask == 0. || ask < lowask ) + lowask = ask; + asksum += ask; + numasks++; + //printf("aski.%u num.%d %.8f [%.8f %.8f]\n",aski,numasks,ask,lowask,highask); + } + } + } else fclose(askfp), askfp = 0; + if ( bidemit != 0. || askemit != 0. ) + { + if ( bidemit != 0. && askemit != 0. && lastbidi == lastaski ) + { + LP_priceitemadd(retarray,lastbidi * timescale,bidemit,askemit,bidemit2,askemit2); + highbid = lowbid = highask = lowask = 0.; + } + else + { + if ( bidemit != 0. ) + { + printf("bidonly %.8f %.8f\n",bidemit,highbid); + LP_priceitemadd(retarray,lastbidi * timescale,bidemit,0.,bidemit2,0.); + highbid = lowbid = 0.; + } + if ( askemit != 0. ) + { + printf("askonly %.8f %.8f\n",askemit,lowask); + LP_priceitemadd(retarray,lastaski * timescale,0.,askemit,0.,askemit2); + highask = lowask = 0.; + } + } + } + if ( bidi != 0 ) + lastbidi = bidi; + if ( aski != 0 ) + lastaski = aski; + } + } else printf("couldnt open either %s %p or %s %p\n",bidfname,bidfp,askfname,askfp); + if ( bidfp != 0 ) + fclose(bidfp); + if ( askfp != 0 ) + fclose(askfp); + return(retarray); +} + void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price) { - struct LP_priceinfo *basepp,*relpp; struct LP_pubkeyinfo *pubp; char str[65]; - if ( price > SMALLVAL && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkeyinfo *pubp; char str[65],fname[512]; FILE *fp; + //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); + if ( LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { - printf("PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); + if ( (fp= basepp->fps[relpp->ind]) == 0 ) + { + LP_pricefname(fname,base,rel); + fp = basepp->fps[relpp->ind] = OS_appendfile(fname); + } + if ( fp != 0 ) + { + now = (uint32_t)time(NULL); + price64 = price * SATOSHIDEN; + fwrite(&now,1,sizeof(now),fp); + fwrite(&price64,1,sizeof(price64),fp); + fflush(fp); + } + if ( (fp= relpp->fps[basepp->ind]) == 0 ) + { + sprintf(fname,"%s/PRICES/%s_%s",GLOBAL_DBDIR,rel,base); + fp = relpp->fps[basepp->ind] = OS_appendfile(fname); + } + if ( fp != 0 ) + { + now = (uint32_t)time(NULL); + price64 = (1. / price) * SATOSHIDEN; + fwrite(&now,1,sizeof(now),fp); + fwrite(&price64,1,sizeof(price64),fp); + fflush(fp); + } if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) { - pubp->matrix[basepp->ind][relpp->ind] = price; + if ( (rand() % 100) == 0 && fabs(pubp->matrix[basepp->ind][relpp->ind] - price) > SMALLVAL ) + printf("PRICEFEED UPDATE.(%-6s/%6s) %12.8f %s %12.8f\n",base,rel,price,bits256_str(str,pubkey),1./price); + { + pubp->matrix[basepp->ind][relpp->ind] = price; + dxblend(&basepp->relvals[relpp->ind],price,0.9); + dxblend(&relpp->relvals[basepp->ind],1. / price,0.9); + } pubp->timestamp = (uint32_t)time(NULL); } else printf("error creating pubkey entry\n"); - } else printf("error finding %s/%s %.8f\n",base,rel,price); + } + else if ( (rand() % 100) == 0 ) + printf("error finding %s/%s %.8f\n",base,rel,price); } - - - - diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 8f93bbc9b..9e25a6241 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -93,7 +93,7 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname); if ( (fp= fopen(fname,"wb")) != 0 ) { - fprintf(fp,"{\"src\":\"%s\",\"srcamount\":%.8f,\"dest\":\"%s\",\"destamount\":%.8f,\"requestid\":%u,\"quoteid\":%u,\"iambob\":%d,\"state\":%u,\"otherstate\":%u,\"expiration\":%u,\"dlocktime\":%u,\"plocktime\":%u",swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.requestid,swap->I.req.quoteid,swap->I.iambob,swap->I.statebits,swap->I.otherstatebits,swap->I.expiration,swap->bobdeposit.I.locktime,swap->bobpayment.I.locktime); + fprintf(fp,"{\"src\":\"%s\",\"srcamount\":%.8f,\"dest\":\"%s\",\"destamount\":%.8f,\"requestid\":%u,\"quoteid\":%u,\"iambob\":%d,\"state\":%u,\"otherstate\":%u,\"expiration\":%u,\"dlocktime\":%u,\"plocktime\":%u,\"Atxfee\":%llu,\"Btxfee\":%llu",swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.requestid,swap->I.req.quoteid,swap->I.iambob,swap->I.statebits,swap->I.otherstatebits,swap->I.expiration,swap->bobdeposit.I.locktime,swap->bobpayment.I.locktime,(long long)swap->I.Atxfee,(long long)swap->I.Btxfee); if ( memcmp(zeroes,swap->I.secretAm,20) != 0 ) { init_hexbytes_noT(secretAmstr,swap->I.secretAm,20); @@ -264,12 +264,14 @@ bits256 basilisk_swap_spendupdate(char *symbol,int32_t *sentflags,bits256 *txids { //printf("ALICE spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); sentflags[alicespent] = 1; + sentflags[bobspent] = 0; txids[alicespent] = spendtxid; } else if ( bobaddr != 0 && strcmp(destaddr,bobaddr) == 0 ) { //printf("BOB spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); sentflags[bobspent] = 1; + sentflags[alicespent] = 0; txids[bobspent] = spendtxid; } else @@ -278,11 +280,13 @@ bits256 basilisk_swap_spendupdate(char *symbol,int32_t *sentflags,bits256 *txids if ( aliceaddr != 0 ) { sentflags[bobspent] = 1; + sentflags[alicespent] = 0; txids[bobspent] = spendtxid; } else if ( bobaddr != 0 ) { sentflags[alicespent] = 1; + sentflags[bobspent] = 0; txids[alicespent] = spendtxid; } } @@ -365,13 +369,43 @@ int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflag return(0); } +uint32_t LP_extract(uint32_t requestid,uint32_t quoteid,char *rootfname,char *field) +{ + char fname[1024],*filestr,*redeemstr; long fsize; int32_t len; uint32_t t=0; cJSON *json; uint8_t redeem[1024]; + if ( strcmp(field,"dlocktime") == 0 ) + sprintf(fname,"%s.bobdeposit",rootfname); + else if ( strcmp(field,"plocktime") == 0 ) + sprintf(fname,"%s.bobpayment",rootfname); + if ( (filestr= OS_filestr(&fsize,fname)) != 0 ) + { + if ( (json= cJSON_Parse(filestr)) != 0 ) + { + if ( (redeemstr= jstr(json,"redeem")) != 0 && (len= (int32_t)strlen(redeemstr)) <= sizeof(redeem)*2 ) + { + len >>= 1; + decode_hex(redeem,len,redeemstr); + t = redeem[5]; + t = (t << 8) | redeem[4]; + t = (t << 8) | redeem[3]; + t = (t << 8) | redeem[2]; + //printf("extracted timestamp.%u\n",t); + } + } + free(filestr); + } + return(t); +} + cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid) { static void *ctx; - FILE *fp; int32_t sentflags[sizeof(txnames)/sizeof(*txnames)],i,n,j,len,needflag,secretstart,redeemlen,addflag,origfinishedflag = 0,finishedflag = 0,iambob = -1; int64_t srcamount,destamount=0,value,values[sizeof(txnames)/sizeof(*txnames)]; uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],pubkey33[33],redeemscript[1024],userdata[1024]; uint32_t plocktime,dlocktime,expiration=0,r,q,state,otherstate; char *secretstr,*srcstr,*deststr,str[65],src[64],dest[64],fname[512],*fstr,*dest33,*symbol,*txname,*Adest,*Bdest,*AAdest,*ABdest,destaddr[64],Adestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)]; long fsize; cJSON *txobj,*item,*sentobj,*array; bits256 checktxid,txid,pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,zero,privkey,rev,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)],signedtxid; struct iguana_info *bob=0,*alice=0; uint64_t txfee = 10000; + FILE *fp; int32_t sentflags[sizeof(txnames)/sizeof(*txnames)],i,n,j,Predeemlen,Dredeemlen,len,needflag,secretstart,redeemlen,addflag,origfinishedflag = 0,finishedflag = 0,iambob = -1; int64_t srcamount,destamount=0,value,values[sizeof(txnames)/sizeof(*txnames)]; uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],pubkey33[33],Predeemscript[1024],Dredeemscript[1024],redeemscript[1024],userdata[1024]; uint32_t plocktime,dlocktime,expiration=0,r,q,state,otherstate; char *secretstr,*srcstr,*deststr,str[65],src[64],dest[64],fname[512],*fstr,*dest33,*rstr,*symbol,*txname,*Adest,*Bdest,*AAdest,*ABdest,destaddr[64],Adestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)]; long fsize; cJSON *txobj,*item,*sentobj,*array; bits256 checktxid,txid,pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,zero,privkey,rev,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)],signedtxid; struct iguana_info *bob=0,*alice=0; uint64_t Atxfee=0,Btxfee=0; if ( ctx == 0 ) ctx = bitcoin_ctx(); bobpaymentaddr[0] = bobdepositaddr[0] = alicepaymentaddr[0] = 0; + memset(Predeemscript,0,sizeof(Predeemscript)); + memset(Dredeemscript,0,sizeof(Dredeemscript)); + Predeemlen = Dredeemlen = 0; memset(values,0,sizeof(values)); memset(txids,0,sizeof(txids)); memset(secretAm,0,sizeof(secretAm)); @@ -410,10 +444,14 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti // printf("%02x",pubkey33[i]); //printf(" <- %s dest33\n",dest33); } - plocktime = juint(item,"plocktime"); - dlocktime = juint(item,"dlocktime"); + if ( (plocktime= juint(item,"plocktime")) == 0 ) + plocktime = LP_extract(requestid,quoteid,fname,"plocktime"); + if ( (dlocktime= juint(item,"dlocktime")) == 0 ) + dlocktime = LP_extract(requestid,quoteid,fname,"dlocktime"); r = juint(item,"requestid"); q = juint(item,"quoteid"); + Atxfee = j64bits(item,"Atxfee"); + Btxfee = j64bits(item,"Btxfee"); pubA0 = jbits256(item,"pubA0"); pubB0 = jbits256(item,"pubB0"); pubB1 = jbits256(item,"pubB1"); @@ -497,7 +535,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti sprintf(fname,"%s/SWAPS/%u-%u.%s",GLOBAL_DBDIR,requestid,quoteid,txnames[i]), OS_compatible_path(fname); if ( (fstr= OS_filestr(&fsize,fname)) != 0 ) { - if ( finishedflag == 0 ) + if ( 0 && finishedflag == 0 ) printf("%s\n",fname); //printf("%s -> (%s)\n",fname,fstr); if ( (txobj= cJSON_Parse(fstr)) != 0 ) @@ -519,6 +557,16 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti txbytes[i] = clonestr(jstr(txobj,"tx")); //printf("[%s] TX.(%s)\n",txnames[i],txbytes[i]); } + if ( strcmp(txnames[i],"bobpayment") == 0 && (rstr= jstr(txobj,"redeem")) != 0 && (Predeemlen= is_hexstr(rstr,0)) > 0 ) + { + Predeemlen >>= 1; + decode_hex(Predeemscript,Predeemlen,rstr); + } + else if ( strcmp(txnames[i],"bobdeposit") == 0 && (rstr= jstr(txobj,"redeem")) != 0 && (Dredeemlen= is_hexstr(rstr,0)) > 0 ) + { + Dredeemlen >>= 1; + decode_hex(Dredeemscript,Dredeemlen,rstr); + } if ( (value= jdouble(txobj,"amount") * SATOSHIDEN) == 0 ) value = jdouble(txobj,"value") * SATOSHIDEN; values[i] = value; @@ -552,12 +600,13 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti } free_json(sentobj); } - printf("%s %s %.8f\n",txnames[i],bits256_str(str,txid),dstr(value)); + if ( finishedflag == 0 ) + printf("%s %s %.8f\n",txnames[i],bits256_str(str,txid),dstr(value)); } } } //else printf("no symbol\n"); free(fstr); - } else if ( finishedflag == 0 ) + } else if ( 0 && finishedflag == 0 ) printf("%s not finished\n",fname); } //printf("alicepayment.%s bobpayment.%s bobdeposit.%s\n",alicepaymentaddr,bobpaymentaddr,bobdepositaddr); @@ -566,6 +615,9 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti Adest = Bdest = AAdest = ABdest = 0; if ( bobcoin[0] == 0 || alicecoin[0] == 0 ) return(0); + Atxfee = LP_txfeecalc(alicecoin,Atxfee); + Btxfee = LP_txfeecalc(bobcoin,Btxfee); + //printf("%s %.8f txfee, %s %.8f txfee\n",alicecoin,dstr(Atxfee),bobcoin,dstr(Btxfee)); //printf("privAm.(%s) %p/%p\n",bits256_str(str,privAm),Adest,AAdest); //printf("privBn.(%s) %p/%p\n",bits256_str(str,privBn),Bdest,ABdest); if ( finishedflag == 0 && bobcoin[0] != 0 && alicecoin[0] != 0 ) @@ -596,6 +648,16 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti ABdest = Adestaddr; } } + if ( bob == 0 || alice == 0 ) + { + printf("Bob.%p is null or Alice.%p is null\n",bob,alice); + return(0); + } + if ( alice->inactive != 0 || bob->inactive != 0 ) + { + printf("Alice.%s inactive.%u or Bob.%s inactive.%u\n",alicecoin,alice->inactive,bobcoin,bob->inactive); + return(0); + } if ( sentflags[BASILISK_ALICEPAYMENT] == 0 && bits256_nonz(txids[BASILISK_ALICEPAYMENT]) != 0 ) { printf("txbytes.%p Apayment.%s\n",txbytes[BASILISK_ALICEPAYMENT],bits256_str(str,txids[BASILISK_ALICEPAYMENT])); @@ -626,7 +688,9 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti rev.bytes[j] = privAm.bytes[31 - j]; //revcalc_rmd160_sha256(secretAm,rev);//privAm); //vcalc_sha256(0,secretAm256,rev.bytes,sizeof(rev)); - redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,plocktime,pubA0,pubB0,pubB1,rev,privBn,secretAm,secretAm256,secretBn,secretBn256); + if ( Predeemlen != 0 ) + redeemlen = Predeemlen, memcpy(redeemscript,Predeemscript,Predeemlen); + else redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,plocktime,pubA0,pubB0,pubB1,rev,privBn,secretAm,secretAm256,secretBn,secretBn256); len = basilisk_swapuserdata(userdata,rev,0,myprivs[0],redeemscript,redeemlen); { char privaddr[64]; uint8_t privpub33[33]; @@ -636,7 +700,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti } for (j=0; j<32; j++) rev.bytes[j] = myprivs[0].bytes[31 - j]; - if ( (txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,txfee,"alicespend",bobcoin,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,0,pubkey33,1,expiration,&values[BASILISK_ALICESPEND],0,0,bobpaymentaddr,1)) != 0 ) + if ( (txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,Btxfee,"alicespend",bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,0,pubkey33,1,expiration,&values[BASILISK_ALICESPEND],0,0,bobpaymentaddr,1)) != 0 ) printf("alicespend.(%s)\n",txbytes[BASILISK_ALICESPEND]); } } @@ -657,11 +721,13 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti { //if ( txbytes[BASILISK_ALICECLAIM] == 0 ) { - redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,dlocktime,pubA0,pubB0,pubB1,privAm,zero,secretAm,secretAm256,secretBn,secretBn256); + if ( Dredeemlen != 0 ) + redeemlen = Dredeemlen, memcpy(redeemscript,Dredeemscript,Dredeemlen); + else redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,dlocktime,pubA0,pubB0,pubB1,privAm,zero,secretAm,secretAm256,secretBn,secretBn256); if ( redeemlen > 0 ) { len = basilisk_swapuserdata(userdata,zero,1,myprivs[0],redeemscript,redeemlen); - if ( (txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,txfee,"aliceclaim",bobcoin,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,0,pubkey33,0,expiration,&values[BASILISK_ALICECLAIM],0,0,bobdepositaddr,1)) != 0 ) + if ( (txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,Btxfee,"aliceclaim",bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,0,pubkey33,0,expiration,&values[BASILISK_ALICECLAIM],0,0,bobdepositaddr,1)) != 0 ) printf("privBn.(%s) aliceclaim.(%s)\n",bits256_str(str,privBn),txbytes[BASILISK_ALICECLAIM]); } } @@ -683,7 +749,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti privBn = basilisk_swap_privBn_extract(&txids[BASILISK_BOBREFUND],bobcoin,txids[BASILISK_BOBDEPOSIT],privBn); if ( bits256_nonz(txids[BASILISK_ALICEPAYMENT]) != 0 && bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 ) { - if ( (txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",alicecoin,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_ALICERECLAIM],alicepaymentaddr)) != 0 ) + if ( (txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",alicecoin,Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_ALICERECLAIM],alicepaymentaddr)) != 0 ) printf("privBn.(%s) alicereclaim.(%s)\n",bits256_str(str,privBn),txbytes[BASILISK_ALICERECLAIM]); } } @@ -713,7 +779,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti } if ( bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 ) { - if ( (txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",alicecoin,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_BOBSPEND],alicepaymentaddr)) != 0 ) + if ( (txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",alicecoin,Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_BOBSPEND],alicepaymentaddr)) != 0 ) printf("bobspend.(%s)\n",txbytes[BASILISK_BOBSPEND]); } } @@ -737,7 +803,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti if ( redeemlen > 0 ) { len = basilisk_swapuserdata(userdata,zero,1,myprivs[1],redeemscript,redeemlen); - if ( (txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,txfee,"bobrefund",bobcoin,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[1],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,0,pubkey33,0,expiration,&values[BASILISK_BOBRECLAIM],0,0,bobpaymentaddr,1)) != 0 ) + if ( (txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,Btxfee,"bobrefund",bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[1],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,0,pubkey33,0,expiration,&values[BASILISK_BOBRECLAIM],0,0,bobpaymentaddr,1)) != 0 ) { int32_t z; for (z=0; z<20; z++) @@ -767,7 +833,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti vcalc_sha256(0,secretBn256,privBn.bytes,sizeof(privBn)); redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,dlocktime,pubA0,pubB0,pubB1,privAm,privBn,secretAm,secretAm256,secretBn,secretBn256); len = basilisk_swapuserdata(userdata,privBn,0,myprivs[0],redeemscript,redeemlen); - if ( (txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,txfee,"bobrefund",bobcoin,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,0,pubkey33,1,expiration,&values[BASILISK_BOBREFUND],0,0,bobdepositaddr,1)) != 0 ) + if ( (txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,Btxfee,"bobrefund",bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,0,pubkey33,1,expiration,&values[BASILISK_BOBREFUND],0,0,bobdepositaddr,1)) != 0 ) printf("pubB1.(%s) bobrefund.(%s)\n",bits256_str(str,pubB1),txbytes[BASILISK_BOBREFUND]); } if ( txbytes[BASILISK_BOBREFUND] != 0 ) @@ -779,7 +845,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti depositspent = txids[BASILISK_BOBREFUND]; } } - } else printf("time %u vs expiration %u\n",(uint32_t)time(NULL),expiration); + } else printf("bobrefund's time %u vs expiration %u\n",(uint32_t)time(NULL),expiration); } } } diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index fc0df6fa8..e210b96df 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -48,17 +48,28 @@ char *LP_isitme(char *destip,uint16_t destport) } else return(0); } -char *issue_LP_getpeers(char *destip,uint16_t destport,char *ipaddr,uint16_t port,double profitmargin,int32_t numpeers,int32_t numutxos) +char *issue_LP_getpeers(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos) { - char url[512]; - sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&profit=%.6f&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,profitmargin,numpeers,numutxos); - return(LP_issue_curl("getpeers",destip,port,url)); + char url[512],*retstr; + sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,numpeers,numutxos); + retstr = LP_issue_curl("getpeers",destip,port,url); + //printf("%s -> getpeers.(%s)\n",destip,retstr); + return(retstr); } -char *issue_LP_getutxos(char *destip,uint16_t destport,char *coin,int32_t lastn,char *ipaddr,uint16_t port,double profitmargin,int32_t numpeers,int32_t numutxos) +char *issue_LP_numutxos(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos) +{ + char url[512],*retstr; + sprintf(url,"http://%s:%u/api/stats/numutxos?ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,numpeers,numutxos); + retstr = LP_issue_curl("numutxos",destip,port,url); + //printf("%s -> getpeers.(%s)\n",destip,retstr); + return(retstr); +} + +char *issue_LP_getutxos(char *destip,uint16_t destport,char *coin,int32_t lastn,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos) { char url[512]; - sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=%s&port=%u&profit=%.6f&numpeers=%d&numutxos=%d",destip,destport,coin,lastn,ipaddr,port,profitmargin,numpeers,numutxos); + sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,coin,lastn,ipaddr,port,numpeers,numutxos); return(LP_issue_curl("getutxos",destip,destport,url)); //return(issue_curlt(url,LP_HTTP_TIMEOUT)); } @@ -73,99 +84,16 @@ char *issue_LP_clientgetutxos(char *destip,uint16_t destport,char *coin,int32_t //return(retstr); } -char *issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,double profitmargin,int32_t numpeers,int32_t numutxos) +char *issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos,uint32_t sessionid) { char url[512],*retstr; if ( (retstr= LP_isitme(destip,destport)) != 0 ) return(retstr); - sprintf(url,"http://%s:%u/api/stats/notify?ipaddr=%s&port=%u&profit=%.6f&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,profitmargin,numpeers,numutxos); + sprintf(url,"http://%s:%u/api/stats/notify?ipaddr=%s&port=%u&numpeers=%d&numutxos=%d&session=%u",destip,destport,ipaddr,port,numpeers,numutxos,sessionid); return(LP_issue_curl("notify",destip,destport,url)); //return(issue_curlt(url,LP_HTTP_TIMEOUT)); } -char *issue_LP_notifyutxo(char *destip,uint16_t destport,struct LP_utxoinfo *utxo) -{ - char url[4096],str[65],str2[65],str3[65],*retstr; struct _LP_utxoinfo u; uint64_t val,val2; - if ( (retstr= LP_isitme(destip,destport)) != 0 ) - return(retstr); - if ( utxo->iambob == 0 ) - { - printf("issue_LP_notifyutxo trying to send Alice %s/v%d\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout); - return(0); - } - u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; - if ( LP_iseligible(&val,&val2,utxo->iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,u.txid,u.vout) > 0 ) - { - sprintf(url,"http://%s:%u/api/stats/notified?iambob=%d&pubkey=%s&profit=%.6f&coin=%s&txid=%s&vout=%d&value=%llu&txid2=%s&vout2=%d&value2=%llu&script=%s&address=%s×tamp=%u&gui=%s",destip,destport,utxo->iambob,bits256_str(str3,utxo->pubkey),utxo->S.profitmargin,utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,(long long)utxo->payment.value,bits256_str(str2,utxo->deposit.txid),utxo->deposit.vout,(long long)utxo->deposit.value,utxo->spendscript,utxo->coinaddr,(uint32_t)time(NULL),utxo->gui); - if ( strlen(url) > 1024 ) - printf("WARNING long url.(%s)\n",url); - return(LP_issue_curl("notifyutxo",destip,destport,url)); - //return(issue_curlt(url,LP_HTTP_TIMEOUT)); - } - else - { - printf("issue_LP_notifyutxo: ineligible utxo iambob.%d %.8f %.8f\n",utxo->iambob,dstr(val),dstr(val2)); - if ( utxo->T.spentflag == 0 ) - utxo->T.spentflag = (uint32_t)time(NULL); - return(0); - } -} - -/*char *issue_LP_register(char *destip,uint16_t destport,bits256 pubkey,char *ipaddr,uint16_t pushport) -{ - char url[512],str[65],*retstr; - sprintf(url,"http://%s:%u/api/stats/register?client=%s&pushaddr=%s&pushport=%u",destip,destport,bits256_str(str,pubkey),ipaddr,pushport); - //return(LP_issue_curl("register",destip,destport,url)); - retstr = issue_curlt(url,LP_HTTP_TIMEOUT); - //printf("register.(%s) -> (%s)\n",url,retstr!=0?retstr:""); - return(retstr); -}*/ - -char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired) -{ - char url[512],*retstr; - sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d",destip,destport,ispaired); - //return(LP_issue_curl("psock",destip,destport,url)); - retstr = issue_curlt(url,LP_HTTP_TIMEOUT*3); - return(retstr); -} - -uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired) -{ - uint16_t publicport = 0; char *retstr,*addr; cJSON *retjson; struct LP_peerinfo *peer,*tmp; - HASH_ITER(hh,LP_peerinfos,peer,tmp) - { - connectaddr[0] = publicaddr[0] = 0; - if ( peer->errors < LP_MAXPEER_ERRORS && (retstr= issue_LP_psock(peer->ipaddr,peer->port,ispaired)) != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (addr= jstr(retjson,"publicaddr")) != 0 ) - safecopy(publicaddr,addr,128); - if ( (addr= jstr(retjson,"connectaddr")) != 0 ) - safecopy(connectaddr,addr,128); - if ( publicaddr[0] != 0 && connectaddr[0] != 0 ) - publicport = juint(retjson,"publicport"); - free_json(retjson); - } - printf("got.(%s) connect.%s public.%s\n",retstr,connectaddr,publicaddr); - free(retstr); - } - if ( publicport != 0 ) - break; - } - return(publicport); -} - -char *issue_LP_lookup(char *destip,uint16_t destport,bits256 pubkey) -{ - char url[512],str[65]; - sprintf(url,"http://%s:%u/api/stats/lookup?client=%s",destip,destport,bits256_str(str,pubkey)); - //printf("getutxo.(%s)\n",url); - return(LP_issue_curl("lookup",destip,destport,url)); - //return(issue_curlt(url,LP_HTTP_TIMEOUT)); -} - char *issue_LP_getprices(char *destip,uint16_t destport) { char url[512]; @@ -181,7 +109,7 @@ cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params) if ( coin != 0 ) { //printf("issue.(%s, %s, %s, %s, %s)\n",coin->symbol,coin->serverport,coin->userpass,method,params); - if ( coin->inactive == 0 || strcmp(method,"importprivkey") == 0 ) + if ( coin->inactive == 0 || strcmp(method,"importprivkey") == 0 || strcmp(method,"validateaddress") == 0 ) { retstr = bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,method,params); if ( retstr != 0 && retstr[0] != 0 ) @@ -202,6 +130,39 @@ void LP_unspents_mark(char *symbol,cJSON *vins) printf("LOCK (%s)\n",jprint(vins,0)); } +char *NXTnodes[] = { "62.75.159.113", "91.44.203.238", "82.114.88.225", "78.63.207.76", "188.174.110.224", "91.235.72.49", "213.144.130.91", "209.222.98.250", "216.155.128.10", "178.33.203.157", "162.243.122.251", "69.163.47.173", "193.151.106.129", "78.94.2.74", "192.3.196.10", "173.33.112.87", "104.198.173.28", "35.184.154.126", "174.140.167.239", "23.88.113.131", "198.71.84.173", "178.150.207.53", "23.88.61.53", "192.157.233.106", "192.157.241.212", "23.89.192.88", "23.89.200.27", "192.157.241.139", "23.89.200.63", "23.89.192.98", "163.172.214.102", "176.9.85.5", "80.150.243.88", "80.150.243.92", "80.150.243.98", "109.70.186.198", "146.148.84.237", "104.155.56.82", "104.197.157.140", "37.48.73.249", "146.148.77.226", "84.57.170.200", "107.161.145.131", "80.150.243.97", "80.150.243.93", "80.150.243.100", "80.150.243.95", "80.150.243.91", "80.150.243.99", "80.150.243.96", "93.231.187.177", "212.237.23.85", "35.158.179.254", "46.36.66.41", "185.170.113.79", "163.172.68.112", "78.47.35.210", "77.90.90.75", "94.177.196.134", "212.237.22.215", "94.177.234.11", "167.160.180.199", "54.68.189.9", "94.159.62.14", "195.181.221.89", "185.33.145.94", "195.181.209.245", "195.181.221.38", "195.181.221.162", "185.33.145.12", "185.33.145.176", "178.79.128.235", "94.177.214.120", "94.177.199.41", "94.177.214.200", "94.177.213.201", "212.237.13.162", "195.181.221.236", "195.181.221.185", "185.28.103.187", "185.33.146.244", "217.61.123.71", "195.181.214.45", "195.181.212.99", "195.181.214.46", "195.181.214.215", "195.181.214.68", "217.61.123.118", "195.181.214.79", "217.61.123.14", "217.61.124.100", "195.181.214.111", "85.255.0.176", "81.2.254.116", "217.61.123.184", "195.181.212.231", "94.177.214.110", "195.181.209.164", "104.129.56.238", "85.255.13.64", "167.160.180.206", "217.61.123.226", "167.160.180.208", "93.186.253.127", "212.237.6.208", "94.177.207.190", "217.61.123.119", "85.255.1.245", "217.61.124.157", "37.59.57.141", "167.160.180.58", "104.223.53.14", "217.61.124.69", "195.181.212.103", "85.255.13.141", "104.207.133.204", "71.90.7.107", "107.150.18.108", "23.94.134.161", "80.150.243.13", "80.150.243.11", "185.81.165.52", "80.150.243.8" }; + + +cJSON *LP_assethbla(char *assetid) +{ + char url[1024],*retstr; int32_t n; cJSON *array,*bid=0,*ask=0,*retjson; + sprintf(url,"http://%s:7876/nxt?=%%2Fnxt&requestType=getBidOrders&asset=%s&firstIndex=0&lastIndex=0",NXTnodes[rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid); + if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + { + bid = cJSON_Parse(retstr); + free(retstr); + } + sprintf(url,"http://%s:7876/nxt?=%%2Fnxt&requestType=getAskOrders&asset=%s&firstIndex=0&lastIndex=0",NXTnodes[rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid); + if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + { + ask = cJSON_Parse(retstr); + free(retstr); + } + retjson = cJSON_CreateObject(); + if ( bid != 0 && ask != 0 ) + { + if ( (array= jarray(&n,bid,"bidOrders")) != 0 ) + jadd(retjson,"bid",jduplicate(jitem(array,0))); + if ( (array= jarray(&n,ask,"askOrders")) != 0 ) + jadd(retjson,"ask",jduplicate(jitem(array,0))); + } + if ( bid != 0 ) + free_json(bid); + if ( ask != 0 ) + free_json(ask); + return(retjson); +} + cJSON *LP_getinfo(char *symbol) { struct iguana_info *coin = LP_coinfind(symbol); @@ -214,10 +175,19 @@ cJSON *LP_getmempool(char *symbol) return(bitcoin_json(coin,"getrawmempool","[]")); } +cJSON *LP_paxprice(char *fiat) +{ + char buf[128],lfiat[65]; struct iguana_info *coin = LP_coinfind("KMD"); + strcpy(lfiat,fiat); + tolowercase(lfiat); + sprintf(buf,"[\"%s\", \"kmd\"]",lfiat); + return(bitcoin_json(coin,"paxprice",buf)); +} + cJSON *LP_gettxout(char *symbol,bits256 txid,int32_t vout) { char buf[128],str[65]; struct iguana_info *coin = LP_coinfind(symbol); - sprintf(buf,"\"%s\", %d, true",bits256_str(str,txid),vout); + sprintf(buf,"[\"%s\", %d, true]",bits256_str(str,txid),vout); return(bitcoin_json(coin,"gettxout",buf)); } @@ -245,7 +215,7 @@ cJSON *LP_getblockhashstr(char *symbol,char *blockhashstr) cJSON *LP_listunspent(char *symbol,char *coinaddr) { char buf[128]; struct iguana_info *coin = LP_coinfind(symbol); - sprintf(buf,"0, 99999999, [\"%s\"]",coinaddr); + sprintf(buf,"[0, 99999999, [\"%s\"]]",coinaddr); return(bitcoin_json(coin,"listunspent",buf)); } @@ -261,15 +231,35 @@ cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t count,int32_t ski cJSON *LP_validateaddress(char *symbol,char *address) { char buf[512]; struct iguana_info *coin = LP_coinfind(symbol); - sprintf(buf,"\"%s\"",address); + sprintf(buf,"[\"%s\"]",address); return(bitcoin_json(coin,"validateaddress",buf)); } cJSON *LP_importprivkey(char *symbol,char *wifstr,char *label,int32_t flag) { - char buf[512]; struct iguana_info *coin = LP_coinfind(symbol); - sprintf(buf,"[\"%s\", \"%s\", %s]",wifstr,label,flag < 0 ? "false" : "true"); - return(bitcoin_json(coin,"importprivkey",buf)); + static void *ctx; + char buf[512],address[64]; cJSON *retjson; struct iguana_info *coin; int32_t doneflag = 0; + coin = LP_coinfind(symbol); + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + bitcoin_wif2addr(ctx,coin->wiftaddr,coin->taddr,coin->pubtype,address,wifstr); + if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) + { + if ( jobj(retjson,"ismine") != 0 && is_cJSON_True(jobj(retjson,"ismine")) != 0 ) + { + doneflag = 1; + //printf("%s already ismine\n",address); + } + //printf("%s\n",jprint(retjson,0)); + free_json(retjson); + } + if ( doneflag == 0 ) + { + if ( coin->noimportprivkey_flag != 0 ) + sprintf(buf,"[\"%s\"]",wifstr); + else sprintf(buf,"\"%s\", \"%s\", %s",wifstr,label,flag < 0 ? "false" : "true"); + return(bitcoin_json(coin,"importprivkey",buf)); + } else return(cJSON_Parse("{\"result\":\"success\"}")); } int32_t LP_importaddress(char *symbol,char *address) @@ -302,27 +292,27 @@ int32_t LP_importaddress(char *symbol,char *address) double LP_getestimatedrate(char *symbol) { char buf[512],*retstr; double rate = 20; struct iguana_info *coin = LP_coinfind(symbol); - if ( coin != 0 ) + if ( coin != 0 && (strcmp(coin->symbol,"BTC") == 0 || coin->txfee == 0) ) { sprintf(buf,"[%d]",3); if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"estimatefee",buf)) != 0 ) { if ( retstr[0] != '-' ) { - coin->estimatedrate = rate = atof(retstr) / 1024.; - printf("estimated rate.(%s) %s -> %.8f\n",symbol,retstr,rate); + rate = atof(retstr) / 1024.; + //printf("estimated rate.(%s) %s -> %.8f\n",symbol,retstr,rate); } free(retstr); } - } - return(rate); + } else return((double)coin->txfee / LP_AVETXSIZE); + return(SATOSHIDEN * rate); } uint64_t LP_txfee(char *symbol) { uint64_t txfee = 0; if ( strcmp(symbol,"BTC") != 0 ) - txfee = 10000; + txfee = LP_MIN_TXFEE; return(txfee); } diff --git a/iguana/exchanges/LP_scan.c b/iguana/exchanges/LP_scan.c index 65c26cf22..045d4092e 100644 --- a/iguana/exchanges/LP_scan.c +++ b/iguana/exchanges/LP_scan.c @@ -119,16 +119,16 @@ uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_inf if ( n > 1 ) printf("LP_txinterestvalue warning: violation of 1 output assumption n.%d\n",n); } else printf("LP_txinterestvalue no addresses found?\n"); - //char str[65]; printf("%.8f <- %s.(%s) txobj.(%s)\n",dstr(value),symbol,bits256_str(str,txid),jprint(txobj,0)); + //char str[65]; printf("%s %.8f <- %s.(%s) txobj.(%s)\n",destaddr,dstr(value),coin->symbol,bits256_str(str,txid),jprint(txobj,0)); free_json(txobj); - } + } else { char str[65]; printf("null gettxout return %s/v%d\n",bits256_str(str,txid),vout); } return(value); } int32_t LP_transactioninit(struct iguana_info *coin,bits256 txid) { struct LP_transaction *tx; int32_t i,height,numvouts,numvins,spentvout; uint32_t timestamp,blocktime; cJSON *txobj,*vins,*vouts,*vout,*vin; bits256 spenttxid; char str[65]; - if ( (txobj=LP_gettx(coin->symbol,txid)) != 0 ) + if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 ) { height = LP_txheight(×tamp,&blocktime,coin,txid); if ( timestamp == 0 && height > 0 ) @@ -166,7 +166,7 @@ int32_t LP_transactioninit(struct iguana_info *coin,bits256 txid) } free_json(txobj); return(0); - } else printf("LP_transactioninit error for %s\n",bits256_str(str,txid)); + } else printf("LP_transactioninit error for %s %s\n",coin->symbol,bits256_str(str,txid)); return(-1); } @@ -222,15 +222,13 @@ uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout) { if ( bits256_nonz(tx->outpoints[vout].spendtxid) != 0 ) { - char str[65]; printf("%s/v%d is spent\n",bits256_str(str,txid),vout); + //char str[65]; printf("%s/v%d is spent\n",bits256_str(str,txid),vout); return(0); } else { - if ( coinaddr != 0 && strcmp(symbol,"KMD") == 0 ) - { + if ( coinaddr != 0 ) value = LP_txinterestvalue(&tx->outpoints[vout].interest,coinaddr,coin,txid,vout); - } //printf("return value %.8f + interest %.8f\n",dstr(tx->outpoints[vout].value),dstr(tx->outpoints[vout].interest)); return(tx->outpoints[vout].value + tx->outpoints[vout].interest); } @@ -290,7 +288,7 @@ int32_t LP_mempoolscan(char *symbol,bits256 searchtxid) return(-1); } -int32_t LP_numconfirms(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx) +int32_t LP_numconfirms(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,int32_t mempool) { struct iguana_info *coin; int32_t numconfirms = 100; //#ifndef BASILISK_DISABLEWAITTX @@ -303,7 +301,7 @@ int32_t LP_numconfirms(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx) numconfirms = jint(txobj,"confirmations"); free_json(txobj); } - else if ( LP_mempoolscan(rawtx->coin->symbol,rawtx->I.signedtxid) >= 0 ) + else if ( mempool != 0 && LP_mempoolscan(rawtx->coin->symbol,rawtx->I.signedtxid) >= 0 ) numconfirms = 0; //#endif return(numconfirms); diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index f4621aa5b..dcb67c8a9 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -113,6 +113,109 @@ FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basil }*/ return(fp); } +/*char *issue_LP_notifyutxo(char *destip,uint16_t destport,struct LP_utxoinfo *utxo) + { + char url[4096],str[65],str2[65],str3[65],*retstr; struct _LP_utxoinfo u; uint64_t val,val2; + if ( (retstr= LP_isitme(destip,destport)) != 0 ) + return(retstr); + if ( utxo->iambob == 0 ) + { + printf("issue_LP_notifyutxo trying to send Alice %s/v%d\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout); + return(0); + } + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( LP_iseligible(&val,&val2,utxo->iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,u.txid,u.vout) > 0 ) + { + sprintf(url,"http://%s:%u/api/stats/notified?iambob=%d&pubkey=%s&coin=%s&txid=%s&vout=%d&value=%llu&txid2=%s&vout2=%d&value2=%llu&script=%s&address=%s×tamp=%u&gui=%s",destip,destport,utxo->iambob,bits256_str(str3,utxo->pubkey),utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,(long long)utxo->payment.value,bits256_str(str2,utxo->deposit.txid),utxo->deposit.vout,(long long)utxo->deposit.value,utxo->spendscript,utxo->coinaddr,(uint32_t)time(NULL),utxo->gui); + if ( strlen(url) > 1024 ) + printf("WARNING long url.(%s)\n",url); + return(LP_issue_curl("notifyutxo",destip,destport,url)); + //return(issue_curlt(url,LP_HTTP_TIMEOUT)); + } + else + { + printf("issue_LP_notifyutxo: ineligible utxo iambob.%d %.8f %.8f\n",utxo->iambob,dstr(val),dstr(val2)); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + return(0); + } + }*/ + +/*char *issue_LP_lookup(char *destip,uint16_t destport,bits256 pubkey) + { + char url[512],str[65]; + sprintf(url,"http://%s:%u/api/stats/lookup?client=%s",destip,destport,bits256_str(str,pubkey)); + //printf("getutxo.(%s)\n",url); + return(LP_issue_curl("lookup",destip,destport,url)); + //return(issue_curlt(url,LP_HTTP_TIMEOUT)); + }*/ + + +/*if ( LP_canbind == 0 ) + { + //printf("check deadman %u vs %u\n",LP_deadman_switch,(uint32_t)time(NULL)); + if ( LP_deadman_switch < time(NULL)-PSOCK_KEEPALIVE ) + { + printf("DEAD man's switch %u activated at %u lag.%d, register forwarding again\n",LP_deadman_switch,(uint32_t)time(NULL),(uint32_t)(time(NULL) - LP_deadman_switch)); + if ( pullsock >= 0 ) + nn_close(pullsock); + pullsock = LP_initpublicaddr(ctx,&mypullport,pushaddr,myipaddr,mypullport,0); + LP_deadman_switch = (uint32_t)time(NULL); + strcpy(LP_publicaddr,pushaddr); + LP_publicport = mypullport; + LP_forwarding_register(LP_mypubkey,pushaddr,mypullport,MAX_PSOCK_PORT); + } + }*/ +/*if ( lastforward < now-3600 ) + { + if ( (retstr= LP_registerall(0)) != 0 ) + free(retstr); + //LP_forwarding_register(LP_mypubkey,pushaddr,pushport,10); + lastforward = now; + }*/ +//if ( IAMLP != 0 && (counter % 600) == 42 ) +// LP_hellos(); +/*if ( 0 && LP_canbind == 0 && (counter % (PSOCK_KEEPALIVE*MAINLOOP_PERSEC/2)) == 13 ) + { + char keepalive[128]; + sprintf(keepalive,"{\"method\":\"keepalive\"}"); + //printf("send keepalive to %s pullsock.%d\n",pushaddr,pullsock); + if ( /LP_send(pullsock,keepalive,(int32_t)strlen(keepalive)+1,0) < 0 ) + { + //LP_deadman_switch = 0; + } + }*/ + +/*int32_t nn_tests(void *ctx,int32_t pullsock,char *pushaddr,int32_t nnother) + { + int32_t sock,n,m,timeout,retval = -1; char msg[512],*retstr; + printf("nn_tests.(%s)\n",pushaddr); + if ( (sock= nn_socket(AF_SP,nnother)) >= 0 ) + { + if ( nn_connect(sock,pushaddr) < 0 ) + printf("connect error %s\n",nn_strerror(nn_errno())); + else + { + sleep(3); + timeout = 1; + nn_setsockopt(sock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + sprintf(msg,"{\"method\":\"nn_tests\",\"ipaddr\":\"%s\"}",pushaddr); + n = /LP_send(sock,msg,(int32_t)strlen(msg)+1,0); + sleep(3); + LP_pullsock_check(ctx,&retstr,"127.0.0.1",-1,pullsock,0.); + sprintf(msg,"{\"method\":\"nn_tests2\",\"ipaddr\":\"%s\"}",pushaddr); + m = /LP_send(pullsock,msg,(int32_t)strlen(msg)+1,0); + printf(">>>>>>>>>>>>>>>>>>>>>> sent %d+%d bytes -> pullsock.%d retstr.(%s)\n",n,m,pullsock,retstr!=0?retstr:""); + if ( retstr != 0 ) + { + free(retstr); + retval = 0; + } + } + nn_close(sock); + } + return(retval); + }*/ int32_t basilisk_swap_load(uint32_t requestid,uint32_t quoteid,bits256 *privkeyp,struct basilisk_request *rp,uint32_t *statebitsp,int32_t *optiondurationp) { @@ -685,7 +788,7 @@ int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t } else if ( (swap->I.statebits & 0x2000) == 0 ) { - if ( (swap->I.aliceconfirms == 0 && swap->aliceunconf != 0) || LP_numconfirms(swap,&swap->alicepayment) >= swap->I.aliceconfirms ) + if ( (swap->I.aliceconfirms == 0 && swap->aliceunconf != 0) || LP_numconfirms(swap,&swap->alicepayment,1) >= swap->I.aliceconfirms ) { swap->I.statebits |= 0x2000; printf("alicepayment confirmed\n"); @@ -711,7 +814,7 @@ int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t tradebot_swap_balancingtrade(swap,1); printf("Bob spends alicepayment aliceconfirms.%d\n",swap->I.aliceconfirms); swap->I.statebits |= 0x40000; - if ( LP_numconfirms(swap,&swap->bobspend) >= swap->I.aliceconfirms ) + if ( LP_numconfirms(swap,&swap->bobspend,1) >= swap->I.aliceconfirms ) { printf("bobspend confirmed\n"); swap->I.statebits |= 0x80000; @@ -734,7 +837,7 @@ int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t printf("Bob reclaimed own payment\n"); while ( 0 && (swap->I.statebits & 0x100000) == 0 ) // why wait for own tx? { - if ( LP_numconfirms(swap,&swap->bobreclaim) >= 1 ) + if ( LP_numconfirms(swap,&swap->bobreclaim,1) >= 1 ) { printf("bobreclaim confirmed\n"); swap->I.statebits |= 0x100000; @@ -762,7 +865,7 @@ int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t } else if ( (swap->I.statebits & 0x400) == 0 ) { - if ( basilisk_istrustedbob(swap) != 0 || (swap->I.bobconfirms == 0 && swap->depositunconf != 0) || LP_numconfirms(swap,&swap->bobdeposit) >= swap->I.bobconfirms ) + if ( basilisk_istrustedbob(swap) != 0 || (swap->I.bobconfirms == 0 && swap->depositunconf != 0) || LP_numconfirms(swap,&swap->bobdeposit,1) >= swap->I.bobconfirms ) { printf("bobdeposit confirmed\n"); swap->I.statebits |= 0x400; @@ -786,7 +889,7 @@ int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t } else if ( (swap->I.statebits & 0x10000) == 0 ) { - if ( basilisk_istrustedbob(swap) != 0 || (swap->I.bobconfirms == 0 && swap->paymentunconf != 0) || LP_numconfirms(swap,&swap->bobpayment) >= swap->I.bobconfirms ) + if ( basilisk_istrustedbob(swap) != 0 || (swap->I.bobconfirms == 0 && swap->paymentunconf != 0) || LP_numconfirms(swap,&swap->bobpayment,1) >= swap->I.bobconfirms ) { printf("bobpayment confirmed\n"); swap->I.statebits |= 0x10000; @@ -803,7 +906,7 @@ int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t else if ( (swap->I.statebits & 0x40000) == 0 ) { int32_t numconfs; - if ( (numconfs= LP_numconfirms(swap,&swap->alicespend)) >= swap->I.bobconfirms ) + if ( (numconfs= LP_numconfirms(swap,&swap->alicespend,1)) >= swap->I.bobconfirms ) { for (j=datalen=0; j<32; j++) data[datalen++] = swap->I.privAm.bytes[j]; diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 3ae4b853a..89edc2ce6 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -400,35 +400,56 @@ int32_t LP_mostprivs_verify(struct basilisk_swap *swap,uint8_t *data,int32_t dat int32_t LP_waitfor(int32_t pairsock,struct basilisk_swap *swap,int32_t timeout,int32_t (*verify)(struct basilisk_swap *swap,uint8_t *data,int32_t datalen)) { - void *data; int32_t datalen,retval = -1; uint32_t expiration = (uint32_t)time(NULL) + timeout; + struct nn_pollfd pfd; void *data; int32_t datalen,retval = -1; uint32_t expiration = (uint32_t)time(NULL) + timeout; while ( time(NULL) < expiration ) { - //printf("start wait\n"); - if ( (datalen= nn_recv(pairsock,&data,NN_MSG,0)) >= 0 ) + memset(&pfd,0,sizeof(pfd)); + pfd.fd = pairsock; + pfd.events = NN_POLLIN; + if ( nn_poll(&pfd,1,1) > 0 ) { - //printf("wait for got.%d\n",datalen); - retval = (*verify)(swap,data,datalen); - nn_freemsg(data); - //printf("retval.%d\n",retval); - return(retval); - } // else printf("error nn_recv\n"); + //printf("start wait\n"); + if ( (datalen= nn_recv(pairsock,&data,NN_MSG,0)) >= 0 ) + { + //printf("wait for got.%d\n",datalen); + retval = (*verify)(swap,data,datalen); + nn_freemsg(data); + //printf("retval.%d\n",retval); + return(retval); + } // else printf("error nn_recv\n"); + } } printf("waitfor timedout\n"); return(retval); } +int32_t swap_nn_send(int32_t sock,uint8_t *data,int32_t datalen,uint32_t flags,int32_t timeout) +{ + struct nn_pollfd pfd; int32_t i; + for (i=0; i 0 ) + return(nn_send(sock,data,datalen,flags)); + usleep(1000); + } + return(-1); +} + int32_t LP_waitsend(char *statename,int32_t timeout,int32_t pairsock,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen,int32_t (*verify)(struct basilisk_swap *swap,uint8_t *data,int32_t datalen),int32_t (*datagen)(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)) { int32_t datalen,sendlen,retval = -1; - printf("waitsend.%s\n",statename); + //printf("waitsend.%s timeout.%d\n",statename,timeout); if ( LP_waitfor(pairsock,swap,timeout,verify) == 0 ) { - printf("waited for %s\n",statename); + //printf("waited for %s\n",statename); if ( (datalen= (*datagen)(swap,data,maxlen)) > 0 ) { - if ( (sendlen= nn_send(pairsock,data,datalen,0)) == datalen ) + if ( (sendlen= swap_nn_send(pairsock,data,datalen,0,timeout)) == datalen ) { - printf("sent.%d after waitfor.%s\n",sendlen,statename); + //printf("sent.%d after waitfor.%s\n",sendlen,statename); retval = 0; } else printf("send %s error\n",statename); } else printf("%s datagen no data\n",statename); @@ -442,8 +463,8 @@ int32_t LP_sendwait(char *statename,int32_t timeout,int32_t pairsock,struct basi //printf("sendwait.%s\n",statename); if ( (datalen= (*datagen)(swap,data,maxlen)) > 0 ) { - //printf("generated %d for %s\n",datalen,statename); - if ( (sendlen= nn_send(pairsock,data,datalen,0)) == datalen ) + //printf("generated %d for %s, timeout.%d\n",datalen,statename,timeout); + if ( (sendlen= swap_nn_send(pairsock,data,datalen,0,timeout)) == datalen ) { //printf("sendwait.%s sent %d\n",statename,sendlen); if ( LP_waitfor(pairsock,swap,timeout,verify) == 0 ) @@ -451,7 +472,7 @@ int32_t LP_sendwait(char *statename,int32_t timeout,int32_t pairsock,struct basi //printf("waited! sendwait.%s sent %d\n",statename,sendlen); retval = 0; } else printf("didnt get %s\n",statename); - } else printf("send pubkeys error\n"); + } else printf("send %s error\n",statename); } else printf("no datagen for %s\n",statename); return(retval); } @@ -489,7 +510,7 @@ struct basilisk_rawtx *LP_swapdata_rawtx(struct basilisk_swap *swap,uint8_t *dat int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys) { - bits256 otherhash,myhash,txid; int32_t i,offset=0,datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr,redeemaddr[64],checkaddr[64]; uint32_t quoteid,msgbits; + bits256 otherhash,myhash,txid; int64_t txfee; int32_t i,offset=0,datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr,redeemaddr[64],checkaddr[64]; uint32_t quoteid,msgbits; for (i=0; i<32; i++) otherhash.bytes[i] = recvbuf[offset++]; for (i=0; i<32; i++) @@ -549,7 +570,17 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba if ( (vouts= jarray(&n,txobj,"vout")) != 0 && v < n ) { vout = jitem(vouts,v); - if ( j64bits(vout,"satoshis") == rawtx->I.amount && (skey= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(skey,"hex")) != 0 ) + if ( strcmp("BTC",rawtx->coin->symbol) == 0 && rawtx == &swap->otherfee ) + txfee = LP_MIN_TXFEE; + else + { + if ( strcmp(rawtx->coin->symbol,swap->bobcoin.symbol) == 0 ) + txfee = swap->I.Btxfee; + else if ( strcmp(rawtx->coin->symbol,swap->alicecoin.symbol) == 0 ) + txfee = swap->I.Atxfee; + else txfee = LP_MIN_TXFEE; + } + if ( j64bits(vout,"satoshis") >= rawtx->I.amount && (skey= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(skey,"hex")) != 0 ) { if ( (hexlen= (int32_t)strlen(hexstr) >> 1) < sizeof(rawtx->spendscript) ) { @@ -562,11 +593,10 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba { char str[65]; LP_swap_coinaddr(swap,rawtx->coin,rawtx->p2shaddr,data,datalen); - printf("got %s txid.%s (%s) -> %s\n",rawtx->name,bits256_str(str,rawtx->I.signedtxid),jprint(txobj,0),rawtx->p2shaddr); } else bitcoin_address(rawtx->p2shaddr,rawtx->coin->taddr,rawtx->coin->p2shtype,rawtx->spendscript,hexlen); } - } else printf("%s ERROR.(%s)\n",rawtx->name,jprint(txobj,0)); + } else printf("%s ERROR.(%s) txfees.[%.8f %.8f: %.8f] amount.%.8f -> %.8f\n",rawtx->name,jprint(txobj,0),dstr(swap->I.Atxfee),dstr(swap->I.Btxfee),dstr(txfee),dstr(rawtx->I.amount),dstr(rawtx->I.amount)-dstr(txfee)); } free_json(txobj); } @@ -664,14 +694,14 @@ int32_t LP_swapwait(uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t void LP_bobloop(void *_swap) { - uint8_t *data; int32_t maxlen,n; uint32_t expiration; struct basilisk_swap *swap = _swap; + uint8_t *data; int32_t maxlen,m,n; uint32_t expiration; struct basilisk_swap *swap = _swap; fprintf(stderr,"start swap iambob\n"); maxlen = 1024*1024 + sizeof(*swap); data = malloc(maxlen); expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; if ( swap != 0 ) { - if ( LP_waitsend("pubkeys",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) + if ( LP_waitsend("pubkeys",60,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) printf("error waitsend pubkeys\n"); else if ( LP_waitsend("choosei",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 ) printf("error waitsend choosei\n"); @@ -686,11 +716,11 @@ void LP_bobloop(void *_swap) basilisk_bobdeposit_refund(swap,swap->I.putduration); //printf("depositlen.%d\n",swap->bobdeposit.I.datalen); LP_swapsfp_update(&swap->I.req); - if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT,LP_verify_otherfee) < 0 ) + if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*3,LP_verify_otherfee) < 0 ) printf("error waiting for alicefee\n"); else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0) == 0 ) printf("error sending bobdeposit\n"); - else if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT,LP_verify_alicepayment) < 0 ) + else if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*3,LP_verify_alicepayment) < 0 ) printf("error waiting for alicepayment\n"); else { @@ -698,7 +728,10 @@ void LP_bobloop(void *_swap) printf("error bobscripts payment\n"); else { - while ( (n= LP_numconfirms(swap,&swap->alicepayment)) < 1 ) // sync with alice + if ( strcmp(swap->alicecoin.symbol,"BTC") == 0 ) + m = 0; + else m = 1; + while ( (n= LP_numconfirms(swap,&swap->alicepayment,1)) < m ) // sync with alice { char str[65];printf("%d waiting for alicepayment to be confirmed.%d %s %s\n",n,1,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid)); sleep(3); @@ -722,14 +755,14 @@ void LP_bobloop(void *_swap) void LP_aliceloop(void *_swap) { - uint8_t *data; int32_t maxlen,n; uint32_t expiration; struct basilisk_swap *swap = _swap; + uint8_t *data; int32_t maxlen,n,m; uint32_t expiration; struct basilisk_swap *swap = _swap; maxlen = 1024*1024 + sizeof(*swap); data = malloc(maxlen); expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; if ( swap != 0 ) { fprintf(stderr,"start swap iamalice pair.%d\n",swap->N.pair); - if ( LP_sendwait("pubkeys",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) + if ( LP_sendwait("pubkeys",60,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) printf("error LP_sendwait pubkeys\n"); else if ( LP_sendwait("choosei",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 ) printf("error LP_sendwait choosei\n"); @@ -742,30 +775,33 @@ void LP_aliceloop(void *_swap) LP_swapsfp_update(&swap->I.req); if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x80,data,maxlen,&swap->myfee,0x40,0) == 0 ) printf("error sending alicefee\n"); - else if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT,LP_verify_bobdeposit) < 0 ) + else if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*3,LP_verify_bobdeposit) < 0 ) printf("error waiting for bobdeposit\n"); else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0) == 0 ) printf("error sending alicepayment\n"); else { - while ( (n= LP_numconfirms(swap,&swap->alicepayment)) < 1 ) + if ( strcmp(swap->alicecoin.symbol,"BTC") == 0 ) + m = 0; + else m = 1; + while ( (n= LP_numconfirms(swap,&swap->alicepayment,1)) < m ) { char str[65];printf("%d waiting for alicepayment to be confirmed.%d %s %s\n",n,1,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.I.signedtxid)); sleep(LP_SWAPSTEP_TIMEOUT); } swap->sentflag = 1; - if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT,LP_verify_bobpayment) < 0 ) + if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*3,LP_verify_bobpayment) < 0 ) printf("error waiting for bobpayment\n"); else { - while ( (n= LP_numconfirms(swap,&swap->bobpayment)) < swap->I.bobconfirms ) + while ( (n= LP_numconfirms(swap,&swap->bobpayment,1)) < swap->I.bobconfirms ) { char str[65];printf("%d waiting for bobpayment to be confirmed.%d %s %s\n",n,swap->I.bobconfirms,swap->bobcoin.symbol,bits256_str(str,swap->bobpayment.I.signedtxid)); sleep(LP_SWAPSTEP_TIMEOUT); } if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x20000,data,maxlen,&swap->alicespend,0x40000,0) == 0 ) printf("error sending alicespend\n"); - while ( (n= LP_numconfirms(swap,&swap->alicespend)) < swap->I.aliceconfirms ) + while ( (n= LP_numconfirms(swap,&swap->alicespend,1)) < swap->I.aliceconfirms ) { char str[65];printf("%d waiting for alicespend to be confirmed.%d %s %s\n",n,swap->I.aliceconfirms,swap->bobcoin.symbol,bits256_str(str,swap->alicespend.I.signedtxid)); sleep(LP_SWAPSTEP_TIMEOUT); @@ -780,7 +816,11 @@ void LP_aliceloop(void *_swap) free(swap); } free(data); - nn_close(swap->N.pair); + if ( swap->N.pair >= 0 ) + { + nn_close(swap->N.pair); + swap->N.pair = -1; + } } bits256 instantdex_derivekeypair(void *ctx,bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash) @@ -870,8 +910,8 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx * rawtx->coin = coin; strcpy(rawtx->I.coinstr,coin->symbol); rawtx->I.numconfirms = numconfirms; - if ( (rawtx->I.amount= satoshis) < 10000 ) - rawtx->I.amount = 10000; + if ( (rawtx->I.amount= satoshis) < LP_MIN_TXFEE ) + rawtx->I.amount = LP_MIN_TXFEE; rawtx->I.vintype = vintype; // 0 -> std, 2 -> 2of2, 3 -> spend bobpayment, 4 -> spend bobdeposit rawtx->I.vouttype = vouttype; // 0 -> fee, 1 -> std, 2 -> 2of2, 3 -> bobpayment, 4 -> bobdeposit if ( rawtx->I.vouttype == 0 ) @@ -898,6 +938,8 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 { //FILE *fp; char fname[512]; uint8_t *alicepub33=0,*bobpub33=0; int32_t bobistrusted,aliceistrusted,jumblrflag=-2,x = -1; struct iguana_info *coin; + swap->I.Atxfee = qp->desttxfee; + swap->I.Btxfee = qp->txfee; swap->I.putduration = swap->I.callduration = INSTANTDEX_LOCKTIME; if ( optionduration < 0 ) swap->I.putduration -= optionduration; @@ -905,10 +947,10 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 swap->I.callduration += optionduration; swap->I.bobsatoshis = swap->I.req.srcamount; swap->I.alicesatoshis = swap->I.req.destamount; - if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < 10000 ) - swap->I.bobinsurance = 10000; - if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < 10000 ) - swap->I.aliceinsurance = 10000; + if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE ) + swap->I.bobinsurance = LP_MIN_TXFEE; + if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE ) + swap->I.aliceinsurance = LP_MIN_TXFEE; strcpy(swap->I.bobstr,swap->I.req.src); strcpy(swap->I.alicestr,swap->I.req.dest); swap->I.started = (uint32_t)time(NULL); @@ -1016,10 +1058,11 @@ struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 { struct basilisk_swap *swap; bits256 pubkey25519; uint8_t pubkey33[33]; swap = calloc(1,sizeof(*swap)); + swap->I.req.quoteid = rp->quoteid; swap->ctx = bitcoin_ctx(); vcalc_sha256(0,swap->I.orderhash.bytes,(uint8_t *)rp,sizeof(*rp)); swap->I.req = *rp; - printf("basilisk_thread_start request.%u iambob.%d (%s/%s)\n",rp->requestid,iambob,rp->src,rp->dest); + printf("basilisk_thread_start request.%u iambob.%d (%s/%s) quoteid.%u\n",rp->requestid,iambob,rp->src,rp->dest,rp->quoteid); bitcoin_pubkey33(swap->ctx,pubkey33,privkey); pubkey25519 = curve25519(privkey,curve25519_basepoint9()); swap->persistent_pubkey = pubkey25519; diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 529e279a3..2fcb6d89a 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -30,7 +30,8 @@ bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxi if ( is_hexstr(retstr,0) == 64 ) { decode_hex(txid.bytes,32,retstr); - sentflag = 1; + if ( bits256_cmp(txid,expectedtxid) == 0 || (bits256_nonz(expectedtxid) == 0 && bits256_nonz(txid) != 0) ) + sentflag = 1; } else if ( (retjson= cJSON_Parse(retstr)) != 0 ) { @@ -44,7 +45,7 @@ bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxi } free_json(retjson); } - char str[65]; printf("[%s] %s RETSTR.(%s) %s.%s\n",txname,txbytes,retstr,symbol,bits256_str(str,txid)); + char str[65]; printf("sentflag.%d [%s] %s RETSTR.(%s) %s.%s\n",sentflag,txname,txbytes,retstr,symbol,bits256_str(str,txid)); free(retstr); } if ( sentflag != 0 ) @@ -230,7 +231,7 @@ int32_t iguana_interpreter(struct iguana_info *coin,cJSON *logarray,int64_t nLoc return(0); } -bits256 iguana_str2priv(char *str) +bits256 iguana_str2priv(uint8_t wiftaddr,char *str) { bits256 privkey; int32_t n; uint8_t addrtype; //struct iguana_waccount *wacct=0; struct iguana_waddress *waddr; memset(&privkey,0,sizeof(privkey)); @@ -239,7 +240,7 @@ bits256 iguana_str2priv(char *str) n = (int32_t)strlen(str) >> 1; if ( n == sizeof(bits256) && is_hexstr(str,sizeof(bits256)) > 0 ) decode_hex(privkey.bytes,sizeof(privkey),str); - else if ( bitcoin_wif2priv(&addrtype,&privkey,str) != sizeof(bits256) ) + else if ( bitcoin_wif2priv(wiftaddr,&addrtype,&privkey,str) != sizeof(bits256) ) { //if ( (waddr= iguana_waddresssearch(&wacct,str)) != 0 ) // privkey = waddr->privkey; @@ -393,7 +394,7 @@ int64_t iguana_lockval(int32_t finalized,int64_t locktime) return(lockval); } -int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson) +int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson) { uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 65536; char *privkeystr,*signedtx = 0; bits256 privkeys[64],privkey,txid; cJSON *item; cJSON *txobj = 0; maxsize = 1000000; @@ -428,7 +429,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t taddr,uint8_t p privkeystr = jstr(item,0); if ( privkeystr == 0 || privkeystr[0] == 0 ) continue; - privkeys[i] = privkey = iguana_str2priv(privkeystr); + privkeys[i] = privkey = iguana_str2priv(wiftaddr,privkeystr); bitcoin_pubkey33(ctx,pubkeys[i],privkey); //if ( bits256_nonz(privkey) != 0 ) // iguana_ensure_privkey(coin,privkey); @@ -523,7 +524,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t taddr,uint8_t p return(complete); } -char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t vout,char *destaddr,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp,uint64_t satoshis,char *changeaddr,char *vinaddr,int32_t suppress_pubkeys) +char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t vout,char *destaddr,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp,uint64_t satoshis,char *changeaddr,char *vinaddr,int32_t suppress_pubkeys) { char *rawtxbytes=0,*signedtx=0,tmpaddr[64],hexstr[999],wifstr[128],txdestaddr[64],_destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *txobj,*vins,*item,*privkeys; int32_t completed,spendlen,ignore_cltverr=1; struct vin_info V[2]; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; bits256 txid; uint64_t value,change = 0; struct iguana_msgtx msgtx; *destamountp = 0; @@ -545,12 +546,37 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch #endif if ( satoshis != 0 ) { + if ( value < satoshis+txfee ) + { + if ( satoshis > value-txfee/2 ) + { + satoshis = value - txfee; + printf("reduce satoshis by txfee %.8f to %.8f\n",dstr(txfee),dstr(satoshis)); + } + else + { + printf("utxo %.8f too small for %.8f + %.8f\n",dstr(value),dstr(satoshis),dstr(txfee)); + return(0); + } + } if ( value > satoshis+txfee ) change = value - (satoshis + txfee); printf("utxo %.8f, destamount %.8f change %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(change),dstr(txfee)); } else if ( value > txfee ) satoshis = value - txfee; - else printf("unexpected small value %.8f vs txfee %.8f\n",dstr(value),dstr(txfee)); + else + { + printf("unexpected small value %.8f vs txfee %.8f\n",dstr(value),dstr(txfee)); + change = 0; + satoshis = value >> 1; + txfee = (value - satoshis); + printf("unexpected small value %.8f vs txfee %.8f -> %.8f %.8f\n",dstr(value),dstr(txfee),dstr(satoshis),dstr(txfee)); + } + if ( change < 6000 ) + { + satoshis += change; + change = 0; + } if ( destamountp != 0 ) *destamountp = satoshis; timestamp = (uint32_t)time(NULL); @@ -560,13 +586,13 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch { V[0].signers[1].privkey = *privkey2p; bitcoin_pubkey33(ctx,V[0].signers[1].pubkey,*privkey2p); - bitcoin_priv2wif(wifstr,*privkey2p,wiftype); + bitcoin_priv2wif(wiftaddr,wifstr,*privkey2p,wiftype); jaddistr(privkeys,wifstr); V[0].N = V[0].M = 2; } else V[0].N = V[0].M = 1; V[0].signers[0].privkey = privkey; bitcoin_pubkey33(ctx,V[0].signers[0].pubkey,privkey); - bitcoin_priv2wif(wifstr,privkey,wiftype); + bitcoin_priv2wif(wiftaddr,wifstr,privkey,wiftype); jaddistr(privkeys,wifstr); V[0].suppress_pubkeys = suppress_pubkeys; V[0].ignore_cltverr = ignore_cltverr; @@ -631,7 +657,7 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch completed = 0; memset(signedtxidp,0,sizeof(*signedtxidp)); //printf("locktime.%u sequenceid.%x rawtx.(%s) vins.(%s)\n",locktime,sequenceid,rawtxbytes,jprint(vins,0)); - if ( (completed= iguana_signrawtransaction(ctx,symbol,taddr,pubtype,p2shtype,isPoS,1000000,&msgtx,&signedtx,signedtxidp,V,1,rawtxbytes,vins,privkeys)) < 0 ) + if ( (completed= iguana_signrawtransaction(ctx,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,1000000,&msgtx,&signedtx,signedtxidp,V,1,rawtxbytes,vins,privkeys)) < 0 ) //if ( (signedtx= LP_signrawtx(symbol,signedtxidp,&completed,vins,rawtxbytes,privkeys,V)) == 0 ) printf("couldnt sign transaction.%s %s\n",name,bits256_str(str,*signedtxidp)); else if ( completed == 0 ) @@ -660,9 +686,11 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub bitcoin_address(changeaddr,coin->taddr,coin->pubtype,changermd160,20); //printf("changeaddr.(%s) vs destaddr.(%s)\n",changeaddr,rawtx->I.destaddr); } + if ( strcmp(str,"myfee") == 0 && strcmp(coin->symbol,"BTC") == 0 ) + txfee = LP_MIN_TXFEE; for (iter=0; iter<2; iter++) { - if ( (signedtx= basilisk_swap_bobtxspend(&rawtx->I.signedtxid,iter == 0 ? txfee : newtxfee,str,coin->symbol,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,privkey,0,0,0,0,0,rawtx->utxotxid,rawtx->utxovout,rawtx->I.destaddr,pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,rawtx->I.suppress_pubkeys)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&rawtx->I.signedtxid,iter == 0 ? txfee : newtxfee,str,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,privkey,0,0,0,0,0,rawtx->utxotxid,rawtx->utxovout,rawtx->I.destaddr,pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,rawtx->I.suppress_pubkeys)) != 0 ) { rawtx->I.datalen = (int32_t)strlen(signedtx) >> 1; if ( rawtx->I.datalen <= sizeof(rawtx->txbytes) ) @@ -675,18 +703,16 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub if ( strcmp(coin->symbol,"BTC") != 0 ) return(retval); len = rawtx->I.datalen; - if ( coin->estimatedrate == 0. ) - coin->estimatedrate = LP_getestimatedrate(coin->symbol); - newtxfee = coin->estimatedrate * len; - if ( newtxfee < LP_MIN_TXFEE ) - newtxfee = LP_MIN_TXFEE; + newtxfee = LP_txfeecalc(coin->symbol,0); printf("txfee %.8f -> newtxfee %.8f\n",dstr(txfee),dstr(newtxfee)); } else break; + if ( strcmp(str,"myfee") == 0 ) + break; } return(retval); } -int32_t basilisk_rawtx_sign(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,struct basilisk_swap *swap,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr,uint8_t *changermd160,char *vinaddr) +int32_t basilisk_rawtx_sign(char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,struct basilisk_swap *swap,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr,uint8_t *changermd160,char *vinaddr) { char *signedtx,*changeaddr = 0,_changeaddr[64]; int64_t txfee,newtxfee=0,destamount; uint32_t timestamp,locktime=0,sequenceid = 0xffffffff; int32_t iter,retval = -1; double estimatedrate; //char str2[65]; printf("%s rawtxsign.(%s/v%d)\n",dest->name,bits256_str(str2,dest->utxotxid),dest->utxovout); @@ -695,7 +721,7 @@ int32_t basilisk_rawtx_sign(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p locktime = swap->bobdeposit.I.locktime + 1, sequenceid = 0; else if ( dest == &swap->bobreclaim ) locktime = swap->bobpayment.I.locktime + 1, sequenceid = 0; - txfee = strcmp("BTC",symbol) == 0 ? 0 : 10000; + txfee = strcmp("BTC",symbol) == 0 ? 0 : LP_MIN_TXFEE; if ( changermd160 != 0 ) { changeaddr = _changeaddr; @@ -704,7 +730,7 @@ int32_t basilisk_rawtx_sign(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p } for (iter=0; iter<2; iter++) { - if ( (signedtx= basilisk_swap_bobtxspend(&dest->I.signedtxid,iter == 0 ? txfee : newtxfee,rawtx->name,symbol,taddr,pubtype,p2shtype,isPoS,wiftype,swap->ctx,privkey,privkey2,rawtx->redeemscript,rawtx->I.redeemlen,userdata,userdatalen,dest->utxotxid,dest->utxovout,dest->I.destaddr,rawtx->I.pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,dest->I.suppress_pubkeys)) != 0 ) + if ( (signedtx= basilisk_swap_bobtxspend(&dest->I.signedtxid,iter == 0 ? txfee : newtxfee,rawtx->name,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,wiftype,swap->ctx,privkey,privkey2,rawtx->redeemscript,rawtx->I.redeemlen,userdata,userdatalen,dest->utxotxid,dest->utxovout,dest->I.destaddr,rawtx->I.pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,dest->I.suppress_pubkeys)) != 0 ) { dest->I.datalen = (int32_t)strlen(signedtx) >> 1; if ( dest->I.datalen <= sizeof(dest->txbytes) ) @@ -740,7 +766,7 @@ int32_t basilisk_alicescript(uint8_t *redeemscript,int32_t *redeemlenp,uint8_t * return(n); } -char *basilisk_swap_Aspend(char *name,char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privAm,bits256 privBn,bits256 utxotxid,int32_t vout,uint8_t pubkey33[33],uint32_t expiration,int64_t *destamountp,char *vinaddr) +char *basilisk_swap_Aspend(char *name,char *symbol,uint64_t Atxfee,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privAm,bits256 privBn,bits256 utxotxid,int32_t vout,uint8_t pubkey33[33],uint32_t expiration,int64_t *destamountp,char *vinaddr) { char msigaddr[64],*signedtx = 0; int32_t spendlen,redeemlen; uint8_t tmp33[33],redeemscript[512],spendscript[128]; bits256 pubAm,pubBn,signedtxid; uint64_t txfee; if ( bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 ) @@ -758,8 +784,13 @@ char *basilisk_swap_Aspend(char *name,char *symbol,uint8_t taddr,uint8_t pubtype rev = privBn; for (i=0; i<32; i++) privBn.bytes[i] = rev.bytes[31 - i];*/ - txfee = LP_txfee(symbol); - signedtx = basilisk_swap_bobtxspend(&signedtxid,txfee,name,symbol,taddr,pubtype,p2shtype,isPoS,wiftype,ctx,privAm,&privBn,redeemscript,redeemlen,0,0,utxotxid,vout,0,pubkey33,1,expiration,destamountp,0,0,vinaddr,1); + if ( (txfee= Atxfee) == 0 ) + { + if ( (txfee= LP_getestimatedrate(symbol) * LP_AVETXSIZE) < LP_MIN_TXFEE ) + txfee = LP_MIN_TXFEE; + } + //txfee = LP_txfee(symbol); + signedtx = basilisk_swap_bobtxspend(&signedtxid,txfee,name,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,wiftype,ctx,privAm,&privBn,redeemscript,redeemlen,0,0,utxotxid,vout,0,pubkey33,1,expiration,destamountp,0,0,vinaddr,1); } return(signedtx); } @@ -816,6 +847,7 @@ int32_t basilisk_swap_getsigscript(char *symbol,uint8_t *script,int32_t maxlen,b return(scriptlen); } +#ifdef notnow bits256 _LP_swap_spendtxid(char *symbol,char *destaddr,char *coinaddr,bits256 utxotxid,int32_t vout) { char *retstr,*addr; cJSON *array,*item,*array2; int32_t i,n,m; bits256 spendtxid,txid; @@ -868,6 +900,7 @@ bits256 _LP_swap_spendtxid(char *symbol,char *destaddr,char *coinaddr,bits256 ut } return(spendtxid); } +#endif bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t vout) { @@ -880,12 +913,12 @@ bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t v printf("spend of %s/v%d detected\n",bits256_str(str,utxotxid),vout); return(spendtxid); //char str[65]; printf("swap %s spendtxid.(%s)\n",symbol,bits256_str(str,utxotxid)); - if ( 0 && strcmp("BTC",symbol) == 0 ) + if ( (0) && strcmp("BTC",symbol) == 0 ) { //[{"type":"sent","confirmations":379,"height":275311,"timestamp":1492084664,"txid":"8703c5517bc57db38134058370a14e99b8e662b99ccefa2061dea311bbd02b8b","vout":0,"amount":117.50945263,"spendtxid":"cf2509e076fbb9b22514923df916b7aacb1391dce9c7e1460b74947077b12510","vin":0,"paid":{"type":"paid","txid":"cf2509e076fbb9b22514923df916b7aacb1391dce9c7e1460b74947077b12510","height":275663,"timestamp":1492106024,"vouts":[{"RUDpN6PEBsE7ZFbGjUxk1W3QVsxnjBLYw6":117.50935263}]}}] - LP_swap_getcoinaddr(symbol,coinaddr,utxotxid,vout); + /*LP_swap_getcoinaddr(symbol,coinaddr,utxotxid,vout); if ( coinaddr[0] != 0 ) - spendtxid = _LP_swap_spendtxid(symbol,destaddr,coinaddr,utxotxid,vout); + spendtxid = _LP_swap_spendtxid(symbol,destaddr,coinaddr,utxotxid,vout);*/ } else { @@ -1099,7 +1132,7 @@ int32_t basilisk_bobpayment_reclaim(struct basilisk_swap *swap,int32_t delay) len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[1],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); memcpy(swap->I.userdata_bobreclaim,userdata,len); swap->I.userdata_bobreclaimlen = len; - if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->bobreclaim,&swap->bobpayment,swap->I.myprivs[1],0,userdata,len,1,swap->changermd160,swap->bobpayment.I.destaddr)) == 0 ) + if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.wiftaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->bobreclaim,&swap->bobpayment,swap->I.myprivs[1],0,userdata,len,1,swap->changermd160,swap->bobpayment.I.destaddr)) == 0 ) { //for (i=0; ibobreclaim.I.datalen; i++) // printf("%02x",swap->bobreclaim.txbytes[i]); @@ -1116,7 +1149,7 @@ int32_t basilisk_bobdeposit_refund(struct basilisk_swap *swap,int32_t delay) len = basilisk_swapuserdata(userdata,swap->I.privBn,0,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); memcpy(swap->I.userdata_bobrefund,userdata,len); swap->I.userdata_bobrefundlen = len; - if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0,swap->changermd160,swap->bobdeposit.I.destaddr)) == 0 ) + if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.wiftaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0,swap->changermd160,swap->bobdeposit.I.destaddr)) == 0 ) { for (i=0; ibobrefund.I.datalen; i++) printf("%02x",swap->bobrefund.txbytes[i]); @@ -1278,7 +1311,7 @@ void basilisk_alicepayment(struct basilisk_swap *swap,struct iguana_info *coin,s printf(" rmd160, ");*/ bitcoin_address(coinaddr,coin->taddr,coin->pubtype,swap->changermd160,20); //printf("%s suppress.%d fee.%d\n",coinaddr,alicepayment->I.suppress_pubkeys,swap->myfee.I.suppress_pubkeys); - basilisk_rawtx_gen(swap->ctx,"alicepayment",swap->I.started,swap->persistent_pubkey33,0,1,alicepayment,alicepayment->I.locktime,alicepayment->spendscript,alicepayment->I.spendlen,coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); + basilisk_rawtx_gen(swap->ctx,"alicepayment",swap->I.started,swap->persistent_pubkey33,0,1,alicepayment,alicepayment->I.locktime,alicepayment->spendscript,alicepayment->I.spendlen,swap->I.Atxfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); } int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) @@ -1303,11 +1336,11 @@ int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *d } if ( swap->myfee.I.datalen == 0 ) { - printf("generate fee\n"); + printf("generate fee %.8f\n",dstr(strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee)); bitcoin_address(coinaddr,swap->alicecoin.taddr,swap->alicecoin.pubtype,swap->changermd160,20); - if ( basilisk_rawtx_gen(swap->ctx,"myfee",swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,0,swap->myfee.spendscript,swap->myfee.I.spendlen,swap->myfee.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr) == 0 ) + if ( basilisk_rawtx_gen(swap->ctx,"myfee",swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,0,swap->myfee.spendscript,swap->myfee.I.spendlen,strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr) == 0 ) { - printf("rawtxsend\n"); + printf("rawtxsend %s %.8f\n",swap->myfee.coin->symbol,dstr(strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee)); swap->I.statebits |= LP_swapdata_rawtxsend(pairsock,swap,0x80,data,maxlen,&swap->myfee,0x40,0); LP_unspents_mark(swap->I.iambob!=0?swap->bobcoin.symbol:swap->alicecoin.symbol,swap->myfee.vins); //basilisk_txlog(swap,&swap->myfee,-1); @@ -1357,12 +1390,12 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da swap->aliceclaim.utxotxid = swap->bobdeposit.I.signedtxid = LP_broadcast_tx(swap->bobdeposit.name,swap->bobcoin.symbol,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen); if ( bits256_nonz(swap->bobdeposit.I.signedtxid) != 0 ) swap->depositunconf = 1; - basilisk_dontforget_update(swap,&swap->bobdeposit); len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); memcpy(swap->I.userdata_aliceclaim,userdata,len); swap->I.userdata_aliceclaimlen = len; bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr); + basilisk_dontforget_update(swap,&swap->bobdeposit); //LP_importaddress(swap->bobcoin.symbol,swap->bobdeposit.I.destaddr); /*for (i=0; ibobdeposit.I.datalen; i++) printf("%02x",swap->bobdeposit.txbytes[i]); @@ -1375,7 +1408,7 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da memcpy(swap->aliceclaim.I.pubkey33,swap->persistent_pubkey33,33); bitcoin_address(swap->aliceclaim.I.destaddr,swap->alicecoin.taddr,swap->alicecoin.pubtype,swap->persistent_pubkey33,33); retval = 0; - if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobdeposit.I.destaddr)) == 0 ) + if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.wiftaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobdeposit.I.destaddr)) == 0 ) { /*for (i=0; ibobdeposit.I.datalen; i++) printf("%02x",swap->bobdeposit.txbytes[i]); @@ -1421,12 +1454,12 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da swap->alicespend.utxotxid = swap->bobpayment.I.signedtxid = LP_broadcast_tx(swap->bobpayment.name,swap->bobpayment.coin->symbol,swap->bobpayment.txbytes,swap->bobpayment.I.datalen); if ( bits256_nonz(swap->bobpayment.I.signedtxid) != 0 ) swap->paymentunconf = 1; - basilisk_dontforget_update(swap,&swap->bobpayment); for (i=0; i<32; i++) revAm.bytes[i] = swap->I.privAm.bytes[31-i]; len = basilisk_swapuserdata(userdata,revAm,0,swap->I.myprivs[0],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); bitcoin_address(swap->bobpayment.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr); + basilisk_dontforget_update(swap,&swap->bobpayment); //LP_importaddress(swap->bobcoin.symbol,swap->bobpayment.I.destaddr); /*for (i=0; ibobpayment.I.datalen; i++) printf("%02x",swap->bobpayment.txbytes[i]); @@ -1440,7 +1473,7 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da memcpy(swap->alicespend.I.pubkey33,swap->persistent_pubkey33,33); bitcoin_address(swap->alicespend.I.destaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->persistent_pubkey33,33); //char str[65],str2[65]; printf("bobpaid privAm.(%s) myprivs[0].(%s)\n",bits256_str(str,swap->I.privAm),bits256_str(str2,swap->I.myprivs[0])); - if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->alicepayment.I.destaddr)) == 0 ) + if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.wiftaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->alicepayment.I.destaddr)) == 0 ) { /*for (i=0; ibobpayment.I.datalen; i++) printf("%02x",swap->bobpayment.txbytes[i]); diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 7c77c9980..f13b1e436 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -20,7 +20,7 @@ int32_t LP_ismine(struct LP_utxoinfo *utxo) { - if ( utxo != 0 && bits256_cmp(utxo->pubkey,LP_mypubkey) == 0 ) + if ( utxo != 0 && bits256_cmp(utxo->pubkey,LP_mypub25519) == 0 ) return(1); else return(0); } @@ -114,6 +114,8 @@ int32_t LP_utxoaddptrs(struct LP_utxoinfo *ptrs[],int32_t n,struct LP_utxoinfo * int32_t LP_utxocollisions(struct LP_utxoinfo *ptrs[],struct LP_utxoinfo *refutxo) { int32_t iambob,n = 0; struct LP_utxoinfo *utxo; struct _LP_utxoinfo u; + if ( refutxo == 0 ) + return(0); portable_mutex_lock(&LP_utxomutex); for (iambob=0; iambob<=1; iambob++) { @@ -175,24 +177,27 @@ void LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey) void LP_availableset(struct LP_utxoinfo *utxo) { struct LP_utxoinfo *ptrs[8]; int32_t i,n,count = 0; struct _LP_utxoinfo u; - memset(ptrs,0,sizeof(ptrs)); - if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 ) - { - for (i=0; i 0 ) + if ( utxo != 0 ) { - u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; - char str[65],str2[65]; printf("UTXO.[%d] AVAIL %s/v%d %s/v%d collisions.%d\n",utxo->iambob,bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,u.txid),u.vout,n); + memset(ptrs,0,sizeof(ptrs)); + if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 ) + { + for (i=0; i 0 ) + { + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + char str[65],str2[65]; printf("UTXO.[%d] AVAIL %s/v%d %s/v%d collisions.%d\n",utxo->iambob,bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,u.txid),u.vout,n); + } } } int32_t LP_utxopurge(int32_t allutxos) { char str[65]; struct LP_utxoinfo *utxo,*tmp; int32_t iambob,n = 0; - printf("LP_utxopurge mypub.(%s)\n",bits256_str(str,LP_mypubkey)); + printf("LP_utxopurge mypub.(%s)\n",bits256_str(str,LP_mypub25519)); portable_mutex_lock(&LP_utxomutex); for (iambob=0; iambob<=1; iambob++) { @@ -228,11 +233,13 @@ int32_t LP_utxopurge(int32_t allutxos) cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo) { struct _LP_utxoinfo u; - jaddstr(item,"method","notified"); + jaddstr(item,"method","utxo"); + if ( utxo == 0 ) + return(item); if ( utxo->gui[0] != 0 ) jaddstr(item,"gui",utxo->gui); jaddstr(item,"coin",utxo->coin); - jaddnum(item,"now",time(NULL)); + //jaddnum(item,"now",time(NULL)); jaddnum(item,"iambob",utxo->iambob); jaddstr(item,"address",utxo->coinaddr); jaddbits256(item,"txid",utxo->payment.txid); @@ -250,13 +257,13 @@ cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo) jaddnum(item,"pending",utxo->T.swappending); if ( utxo->iambob != 0 ) { - jaddbits256(item,"srchash",LP_mypubkey); + jaddbits256(item,"srchash",utxo->pubkey);//LP_mypub25519); if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) jaddbits256(item,"desthash",utxo->S.otherpubkey); } else { - jaddbits256(item,"desthash",LP_mypubkey); + jaddbits256(item,"desthash",utxo->pubkey);//LP_mypub25519); if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) jaddbits256(item,"srchash",utxo->S.otherpubkey); } @@ -264,6 +271,7 @@ cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo) jaddstr(item,"swap","in progress"); if ( utxo->T.spentflag != 0 ) jaddnum(item,"spent",utxo->T.spentflag); + jaddnum(item,"session",utxo->T.sessionid); return(item); } @@ -272,7 +280,7 @@ cJSON *LP_utxojson(struct LP_utxoinfo *utxo) cJSON *item = cJSON_CreateObject(); item = LP_inventoryjson(item,utxo); jaddbits256(item,"pubkey",utxo->pubkey); - jaddnum(item,"profit",utxo->S.profitmargin); + //jaddnum(item,"profit",utxo->S.profitmargin); jaddstr(item,"base",utxo->coin); jaddstr(item,"script",utxo->spendscript); return(item); @@ -280,16 +288,26 @@ cJSON *LP_utxojson(struct LP_utxoinfo *utxo) int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol,bits256 txid,int32_t vout,uint64_t satoshis,bits256 txid2,int32_t vout2) { - uint64_t val,val2=0,threshold=0; int32_t iter; char destaddr[64],destaddr2[64]; struct LP_utxoinfo *utxo; + //struct LP_utxoinfo *utxo; + uint64_t val,val2=0,txfee,threshold=0; int32_t bypass = 0; char destaddr[64],destaddr2[64]; struct iguana_info *coin = LP_coinfind(symbol); destaddr[0] = destaddr2[0] = 0; - if ( (val= LP_txvalue(destaddr,symbol,txid,vout)) >= satoshis ) - { - threshold = (iambob != 0) ? LP_DEPOSITSATOSHIS(satoshis) : LP_DEXFEE(satoshis); - if ( (val2= LP_txvalue(destaddr2,symbol,txid2,vout2)) >= threshold ) + if ( coin != 0 && IAMLP != 0 && coin->inactive != 0 ) + bypass = 1; + if ( bypass != 0 ) + val = satoshis; + else val = LP_txvalue(destaddr,symbol,txid,vout); + txfee = LP_txfeecalc(symbol,0); + if ( val >= satoshis && val > (1+LP_MINSIZE_TXFEEMULT)*txfee ) + { + threshold = (iambob != 0) ? LP_DEPOSITSATOSHIS(satoshis) : (LP_DEXFEE(satoshis) + txfee); + if ( bypass != 0 ) + val2 = threshold; + else val2 = LP_txvalue(destaddr2,symbol,txid2,vout2); + if ( val2 >= threshold ) { - if ( strcmp(destaddr,destaddr2) != 0 ) + if ( bypass == 0 && strcmp(destaddr,destaddr2) != 0 ) printf("mismatched %s destaddr (%s) vs (%s)\n",symbol,destaddr,destaddr2); - else if ( (iambob == 0 && val2 > val) || (iambob != 0 && val2 <= satoshis) ) + else if ( bypass == 0 && ((iambob == 0 && val2 > val) || (iambob != 0 && val2 <= satoshis)) ) printf("iambob.%d ineligible due to offsides: val %.8f and val2 %.8f vs %.8f diff %lld\n",iambob,dstr(val),dstr(val2),dstr(satoshis),(long long)(val2 - val)); else { @@ -299,8 +317,8 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol } } // else printf("no val2\n"); } - char str[65],str2[65]; printf("spent.%d %s txid or value %.8f < %.8f or val2 %.8f < %.8f, %s/v%d %s/v%d\n",iambob,symbol,dstr(val),dstr(satoshis),dstr(val2),dstr(threshold),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2); - for (iter=0; iter<2; iter++) + // char str[65],str2[65]; printf("spent.%d %s txid or value %.8f < %.8f or val2 %.8f < %.8f, %s/v%d %s/v%d or < 10x txfee %.8f\n",iambob,symbol,dstr(val),dstr(satoshis),dstr(val2),dstr(threshold),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2,dstr(txfee)); + /*for (iter=0; iter<2; iter++) { if ( (utxo= LP_utxofind(iter,txid,vout)) != 0 ) { @@ -326,7 +344,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol if ( utxo->T.spentflag == 0 ) utxo->T.spentflag = (uint32_t)time(NULL); } - } + }*/ *valp = val; *val2p = val2; return(0); @@ -334,20 +352,13 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol char *LP_utxos(int32_t iambob,struct LP_peerinfo *mypeer,char *symbol,int32_t lastn) { - int32_t i,firsti,n; uint64_t val,val2; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo,*tmp; cJSON *utxosjson = cJSON_CreateArray(); - i = 0; - n = mypeer != 0 ? mypeer->numutxos : 0; + int32_t i,n,m; uint64_t val,val2; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo,*tmp; cJSON *utxosjson = cJSON_CreateArray(); + //n = mypeer != 0 ? mypeer->numutxos : 0; if ( lastn <= 0 ) lastn = LP_PROPAGATION_SLACK * 2; - if ( lastn >= n ) - firsti = -1; - else firsti = (lastn - n); - //printf("LP_utxos iambob.%d symbol.%s firsti.%d lastn.%d\n",iambob,symbol==0?"":symbol,firsti,lastn); HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp) { //char str[65]; printf("check %s.%s\n",utxo->coin,bits256_str(str,utxo->payment.txid)); - if ( i++ < firsti ) - continue; if ( (symbol == 0 || symbol[0] == 0 || strcmp(symbol,utxo->coin) == 0) && utxo->T.spentflag == 0 ) { u = (iambob != 0) ? utxo->deposit : utxo->fee; @@ -358,6 +369,12 @@ char *LP_utxos(int32_t iambob,struct LP_peerinfo *mypeer,char *symbol,int32_t la } else jaddi(utxosjson,LP_utxojson(utxo)); } } + if ( (n= cJSON_GetArraySize(utxosjson)) > lastn ) + { + m = n - lastn; + for (i=0; i= %d\n",utxo->T.spentflag,LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout),dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis); if ( strcmp(symbol,utxo->coin) != 0 ) continue; - //char str[65]; printf("s%u %d [%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",utxo->T.spentflag,LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout),dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis); if ( LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 ) { - if ( utxo->S.satoshis >= destsatoshis && (bestutxo == 0 || utxo->S.satoshis < bestutxo->S.satoshis) ) + if ( utxo->S.satoshis >= destsatoshis/2 && (bestutxo == 0 || (bestutxo->S.satoshis < destsatoshis && utxo->S.satoshis >= destsatoshis) || (bestutxo->S.satoshis >= destsatoshis && utxo->S.satoshis < bestutxo->S.satoshis)) ) { if ( LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout) == 0 ) { - if ( utxo->T.spentflag == 0 ) - utxo->T.spentflag = (uint32_t)time(NULL); + //if ( utxo->T.spentflag == 0 ) + // utxo->T.spentflag = (uint32_t)time(NULL); continue; } bestutxo = utxo; - } + } //else printf("skip alice utxo %.8f vs dest %.8f\n",dstr(utxo->S.satoshis),dstr(destsatoshis)); } } return(bestutxo); @@ -404,11 +424,13 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector) { - cJSON *argjson; struct _LP_utxoinfo u; char *msg; + //cJSON *argjson; struct _LP_utxoinfo u; char *msg; + if ( utxo == 0 ) + return; utxo->T.spentflag = (uint32_t)time(NULL); if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 ) LP_mypeer->numutxos--; - if ( LP_mypubsock >= 0 ) + /*if ( LP_mypubsock >= 0 ) { argjson = cJSON_CreateObject(); jaddstr(argjson,"method","checktxid"); @@ -423,8 +445,8 @@ void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector) jaddnum(argjson,"checkvout",u.vout); } msg = jprint(argjson,1); - LP_send(LP_mypubsock,msg,(int32_t)strlen(msg)+1,1); - } + /LP_send(LP_mypubsock,msg,(int32_t)strlen(msg)+1,1); + }*/ } char *LP_spentcheck(cJSON *argjson) @@ -458,40 +480,96 @@ char *LP_spentcheck(cJSON *argjson) return(clonestr("{\"error\":\"cant find txid to check spent status\"}")); } -struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *spendscript,char *coinaddr,bits256 pubkey,double profitmargin,char *gui) +void LP_utxo_clientpublish(struct LP_utxoinfo *utxo) { - uint64_t val,val2=0,tmpsatoshis,bigtxfee = 100000; int32_t spendvini,selector; bits256 spendtxid; char *msg; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; - if ( symbol == 0 || symbol[0] == 0 || spendscript == 0 || spendscript[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 ) + bits256 zero; char *msg; + if ( LP_isunspent(utxo) > 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + msg = jprint(LP_utxojson(utxo),1); + LP_broadcast_message(LP_mypubsock,utxo->coin,"",zero,msg); + } + /*struct LP_peerinfo *peer,*tmp; cJSON *retjson; char *retstr; int32_t n = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) { - printf("malformed addutxo %d %d %d %d %d %d %d %d %d\n", symbol == 0,spendscript == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(txid2) == 0,vout < 0,vout2 < 0,value <= 0,value2 <= 0); + if ( (retstr= issue_LP_notifyutxo(peer->ipaddr,peer->port,utxo)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,"error") == 0 ) + { + utxo->T.lasttime = (uint32_t)time(NULL); + n++; + } + free_json(retjson); + } + free(retstr); + } + //if ( utxo->T.lasttime != 0 ) + // return(0); + } + return(n);*/ +} + +struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *spendscript,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid) +{ + uint64_t val,val2=0,tmpsatoshis,txfee; cJSON *txobj; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; + if ( symbol == 0 || symbol[0] == 0 || spendscript == 0 || spendscript[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 || sessionid == 0 ) + { + printf("session.%u malformed addutxo %d %d %d %d %d %d %d %d %d\n",sessionid,symbol == 0,spendscript == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(txid2) == 0,vout < 0,vout2 < 0,value <= 0,value2 <= 0); return(0); } - if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + if ( (coin= LP_coinfind(symbol)) == 0 || (IAMLP == 0 && coin->inactive != 0) ) + { + printf("LP_utxoadd reject inactive %s\n",symbol); return(0); - if ( iambob != 0 && value2 < 9 * (value >> 3) + bigtxfee ) // big txfee padding + } + txfee = LP_txfeecalc(coin->symbol,0); + if ( iambob != 0 && value2 < 9 * (value >> 3) + 2*txfee ) // big txfee padding { - if ( value2 > bigtxfee+20000 ) - tmpsatoshis = (((value2 - bigtxfee) / 9) << 3); + if ( value2 > 2*txfee ) + tmpsatoshis = (((value2 - 2*txfee) / 9) << 3); else return(0); - } else tmpsatoshis = value; + } else tmpsatoshis = (value - txfee); char str[65],str2[65],dispflag = (iambob == 0); - if ( iambob == 0 && bits256_cmp(pubkey,LP_mypubkey) != 0 ) + if ( iambob == 0 && bits256_cmp(pubkey,LP_mypub25519) != 0 ) { printf("trying to add Alice utxo when not mine? %s/v%d\n",bits256_str(str,txid),vout); return(0); } if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,tmpsatoshis,txid2,vout2) <= 0 ) { - // iambob.0 utxoadd COQUI inactive.0 got ineligible txid value 1.20000000, value2 0.01000000, tmpsatoshis 1.20000000 printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f, value2 %.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(value2),dstr(tmpsatoshis)); return(0); } + numconfirms = -1; + if ( (txobj= LP_gettx(symbol,txid)) != 0 ) + { + numconfirms = jint(txobj,"confirmations"); + free_json(txobj); + } + if ( numconfirms <= 0 ) + { + printf("LP_utxoadd reject numconfirms.%d\n",numconfirms); + return(0); + } + numconfirms = -1; + if ( (txobj= LP_gettx(symbol,txid2)) != 0 ) + { + numconfirms = jint(txobj,"confirmations"); + free_json(txobj); + } + if ( numconfirms <= 0 ) + { + printf("LP_utxoadd reject2 numconfirms.%d\n",numconfirms); + return(0); + } if ( dispflag != 0 ) printf("%.8f %.8f %s iambob.%d %s utxoadd.(%.8f %.8f) %s %s\n",dstr(val),dstr(val2),coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2)); dispflag = 1; if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,txid,vout,txid2,vout2)) >= 0 ) { - printf("utxoadd selector.%d in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); + printf("utxoadd selector.%d spent in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); return(0); } if ( (utxo= LP_utxofinds(iambob,txid,vout,txid2,vout2)) != 0 ) @@ -516,13 +594,18 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit utxo = 0; } } - else if ( profitmargin > SMALLVAL ) - utxo->S.profitmargin = profitmargin; if ( utxo != 0 ) + { + if ( utxo->T.sessionid == 0 ) + utxo->T.sessionid = sessionid; + //else if ( profitmargin > SMALLVAL ) + // utxo->S.profitmargin = profitmargin; + utxo->T.lasttime = (uint32_t)time(NULL); return(utxo); + } } utxo = calloc(1,sizeof(*utxo)); - utxo->S.profitmargin = profitmargin; + //utxo->S.profitmargin = profitmargin; utxo->pubkey = pubkey; safecopy(utxo->gui,gui,sizeof(utxo->gui)); safecopy(utxo->coin,symbol,sizeof(utxo->coin)); @@ -546,6 +629,10 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit } LP_utxosetkey(utxo->key,txid,vout); LP_utxosetkey(utxo->key2,txid2,vout2); + if ( LP_ismine(utxo) > 0 ) + utxo->T.sessionid = LP_sessionid; + else utxo->T.sessionid = sessionid; + printf("U.%d %s %.8f %.8f addutxo.%d pubkey.%s session.%u\n",LP_mypeer!=0?LP_mypeer->numutxos:-1,symbol,dstr(value),dstr(value2),LP_ismine(utxo) > 0,bits256_str(str,utxo->pubkey),utxo->T.sessionid); portable_mutex_lock(&LP_utxomutex); HASH_ADD_KEYPTR(hh,LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo); if ( _LP_utxo2find(iambob,txid2,vout2) == 0 ) @@ -553,13 +640,14 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit portable_mutex_unlock(&LP_utxomutex); if ( iambob != 0 ) { - if ( mypubsock >= 0 ) - { - msg = jprint(LP_utxojson(utxo),1); - LP_send(mypubsock,msg,(int32_t)strlen(msg)+1,1); - } else LP_utxo_clientpublish(utxo); - if ( LP_mypeer != 0 && LP_ismine(utxo) > 0 ) + if ( LP_mypeer != 0 ) LP_mypeer->numutxos++; + if ( LP_ismine(utxo) > 0 ) + { + LP_utxo_clientpublish(utxo); + if ( LP_mypeer != 0 ) + utxo->T.lasttime = (uint32_t)time(NULL); + } } return(utxo); } @@ -573,7 +661,12 @@ struct LP_utxoinfo *LP_utxoaddjson(int32_t iambob,int32_t pubsock,cJSON *argjson return(0); } portable_mutex_lock(&LP_UTXOmutex); - utxo = LP_utxoadd(iambob,pubsock,jstr(argjson,"coin"),jbits256(argjson,"txid"),jint(argjson,"vout"),j64bits(argjson,"value"),jbits256(argjson,"txid2"),jint(argjson,"vout2"),j64bits(argjson,"value2"),jstr(argjson,"script"),jstr(argjson,"address"),jbits256(argjson,"pubkey"),jdouble(argjson,"profit"),jstr(argjson,"gui")); + utxo = LP_utxoadd(iambob,pubsock,jstr(argjson,"coin"),jbits256(argjson,"txid"),jint(argjson,"vout"),j64bits(argjson,"value"),jbits256(argjson,"txid2"),jint(argjson,"vout2"),j64bits(argjson,"value2"),jstr(argjson,"script"),jstr(argjson,"address"),jbits256(argjson,"pubkey"),jstr(argjson,"gui"),juint(argjson,"session")); + if ( LP_ismine(utxo) > 0 && utxo->T.lasttime == 0 ) + { + utxo->T.lasttime = (uint32_t)time(NULL); + printf("set lasttime!\n"); + } portable_mutex_unlock(&LP_UTXOmutex); return(utxo); } @@ -597,18 +690,14 @@ int32_t LP_utxosparse(char *destipaddr,uint16_t destport,char *retstr,uint32_t n subport = argport + 2; argipbits = (uint32_t)calc_ipbits(argipaddr); if ( (peer= LP_peerfind(argipbits,argport)) == 0 ) - peer = LP_addpeer(0,-1,argipaddr,argport,pushport,subport,jdouble(item,"profit"),jint(item,"numpeers"),jint(item,"numutxos")); + peer = LP_addpeer(0,-1,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session")); } if ( jobj(item,"txid") != 0 ) { txid = jbits256(item,"txid"); //printf("parse.(%s)\n",jprint(item,0)); if ( (utxo= LP_utxoaddjson(1,-1,item)) != 0 ) - { - //if ( strcmp(utxo->coin,"HUSH") == 0 ) - // printf("%s set lasttime (%s)\n",destipaddr,jprint(item,0)); utxo->T.lasttime = now; - } } } if ( (destpeer= LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport)) != 0 ) @@ -621,7 +710,7 @@ int32_t LP_utxosparse(char *destipaddr,uint16_t destport,char *retstr,uint32_t n return(n); } -int32_t LP_utxosquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *coin,int32_t lastn,char *myipaddr,uint16_t myport,double myprofit) +int32_t LP_utxosquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *coin,int32_t lastn,char *myipaddr,uint16_t myport,int32_t maxentries) { char *retstr; struct LP_peerinfo *peer; uint32_t now; int32_t retval = -1; peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport); @@ -629,8 +718,8 @@ int32_t LP_utxosquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipa coin = ""; //printf("utxo query.(%s)\n",destipaddr); if ( IAMLP != 0 ) - retstr = issue_LP_getutxos(destipaddr,destport,coin,lastn,myipaddr,myport,myprofit,mypeer != 0 ? mypeer->numpeers : 0,mypeer != 0 ? mypeer->numutxos : 0); - else retstr = issue_LP_clientgetutxos(destipaddr,destport,coin,100); + retstr = issue_LP_getutxos(destipaddr,destport,coin,lastn,myipaddr,myport,mypeer != 0 ? mypeer->numpeers : 0,maxentries); + else retstr = issue_LP_clientgetutxos(destipaddr,destport,coin,maxentries); if ( retstr != 0 ) { now = (uint32_t)time(NULL); @@ -668,7 +757,7 @@ cJSON *LP_inventory(char *symbol,int32_t iambob) else myipaddr = "127.0.0.1"; HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp) { - //char str[65]; printf("iambob.%d iterate %s\n",iambob,bits256_str(str,LP_mypubkey)); + //char str[65]; printf("iambob.%d iterate %s\n",iambob,bits256_str(str,LP_mypub25519)); if ( LP_isunspent(utxo) != 0 && strcmp(symbol,utxo->coin) == 0 && utxo->iambob == iambob && LP_ismine(utxo) > 0 ) { u = (iambob != 0) ? utxo->deposit : utxo->fee; @@ -676,7 +765,10 @@ cJSON *LP_inventory(char *symbol,int32_t iambob) { if ( utxo->T.spentflag == 0 ) utxo->T.spentflag = (uint32_t)time(NULL); + continue; } + if ( iambob != 0 ) + LP_utxo_clientpublish(utxo); jaddi(array,LP_inventoryjson(cJSON_CreateObject(),utxo)); } //else printf("skip %s %d %d %d %d\n",bits256_str(str,utxo->pubkey),LP_isunspent(utxo) != 0,strcmp(symbol,utxo->coin) == 0,utxo->iambob == iambob,LP_ismine(utxo) > 0); @@ -696,14 +788,15 @@ int32_t LP_maxvalue(uint64_t *values,int32_t n) return(maxi); } -int32_t LP_nearestvalue(uint64_t *values,int32_t n,uint64_t targetval) +int32_t LP_nearestvalue(int32_t iambob,uint64_t *values,int32_t n,uint64_t targetval) { int32_t i,mini = -1; int64_t dist; uint64_t mindist = (1 << 31); for (i=0; i= 0 && dist < mindist ) { mini = i; @@ -713,9 +806,9 @@ int32_t LP_nearestvalue(uint64_t *values,int32_t n,uint64_t targetval) return(mini); } -uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub,uint8_t *pubkey33) +uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub) { - char *script; struct LP_utxoinfo *utxo; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,n,iambob,vout,depositvout; uint64_t *values=0,satoshis,depositval,targetval,value,total = 0; + char *script; struct LP_utxoinfo *utxo; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,n,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,depositval,targetval,value,total = 0; if ( coin == 0 ) { printf("coin not active\n"); @@ -724,6 +817,7 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr //printf("privkey init.(%s) %s\n",coin->symbol,coin->smartaddr); if ( coin->inactive == 0 && (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 ) { + txfee = LP_txfeecalc(coin->symbol,0); if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) { for (iambob=0; iambob<=1; iambob++) @@ -738,14 +832,20 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr { item = jitem(array,i); satoshis = SATOSHIDEN * jdouble(item,"amount"); - if ( LP_inventory_prevent(iambob,jbits256(item,"txid"),juint(item,"vout")) == 0 ) + if ( satoshis == 0 ) + satoshis = SATOSHIDEN * jdouble(item,"value"); + if ( LP_inventory_prevent(iambob,jbits256(item,"txid"),juint(item,"vout")) == 0 && jint(item,"confirmations") > 0 ) + { + //printf("%s\n",jprint(item,0)); values[i] = satoshis; - else used++; + } else used++; //printf("%.8f ",dstr(satoshis)); } //printf("array.%d\n",n); while ( used < n-1 ) { + //for (i=0; i= 0 ) { @@ -756,12 +856,20 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr depositval = values[i]; values[i] = 0, used++; if ( iambob == 0 ) - targetval = (depositval / 776) + 100000; - else targetval = (depositval / 9) * 8 + 100000; - //printf("i.%d %.8f target %.8f\n",i,dstr(depositval),dstr(targetval)); - if ( (i= LP_nearestvalue(values,n,targetval)) < 0 && iambob != 0 ) - targetval /= 4; - if ( (i= LP_nearestvalue(values,n,targetval)) >= 0 ) + targetval = (depositval / 776) + txfee; + else targetval = (depositval / 9) * 8 + 2*txfee; + if ( depositval < (1+LP_MINSIZE_TXFEEMULT)*txfee ) + continue; + //printf("iambob.%d i.%d %.8f target %.8f\n",iambob,i,dstr(depositval),dstr(targetval)); + i = -1; + if ( iambob != 0 ) + { + if ( (i= LP_nearestvalue(iambob,values,n,targetval)) < 0 ) + targetval /= 4; + if ( targetval < txfee*(1+LP_MINSIZE_TXFEEMULT) ) + continue; + } + if ( i >= 0 || (i= LP_nearestvalue(iambob,values,n,targetval)) >= 0 ) { item = jitem(array,i); txid = jbits256(item,"txid"); @@ -773,20 +881,20 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr portable_mutex_lock(&LP_UTXOmutex); if ( iambob != 0 ) { - if ( (utxo= LP_utxoadd(1,mypubsock,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,script,coin->smartaddr,mypub,LP_mypeer != 0 ? LP_mypeer->profitmargin : 0.01,LP_gui)) != 0 ) + if ( (utxo= LP_utxoadd(1,mypubsock,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,script,coin->smartaddr,mypub,LP_gui,LP_sessionid)) != 0 ) { } } else { - if ( (utxo= LP_utxoadd(0,mypubsock,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,script,coin->smartaddr,mypub,0.,LP_gui)) != 0 ) + if ( (utxo= LP_utxoadd(0,mypubsock,coin->symbol,deposittxid,depositvout,depositval,txid,vout,value,script,coin->smartaddr,mypub,LP_gui,LP_sessionid)) != 0 ) { } } portable_mutex_unlock(&LP_UTXOmutex); total += value; - } - } + } else printf("scriptmismatch.(%s) vs %s\n",script,jprint(item,0)); + } //else printf("nothing near i.%d\n",i); } else break; } if ( iambob == 1 ) @@ -802,26 +910,39 @@ uint64_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypr bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguana_info *coin,char *passphrase,char *wifstr) { static uint32_t counter; - bits256 privkey,userpub,userpass; char tmpstr[128]; cJSON *retjson; uint8_t tmptype,rmd160[20]; + bits256 privkey,userpub,userpass,checkkey; char tmpstr[128]; cJSON *retjson; uint8_t tmptype,rmd160[20]; if ( passphrase != 0 && passphrase[0] != 0 ) conv_NXTpassword(privkey.bytes,pubkeyp->bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); else { - privkey = iguana_wif2privkey(wifstr); - //printf("WIF.(%s) -> %s\n",wifstr,bits256_str(str,privkey)); + bitcoin_wif2priv(coin->wiftaddr,&tmptype,&privkey,wifstr); + if ( 0 ) + { + char str[65],str2[65]; + checkkey = iguana_wif2privkey(wifstr); + if ( bits256_cmp(checkkey,privkey) != 0 ) + printf("WIF.(%s) -> %s or %s?\n",wifstr,bits256_str(str,privkey),bits256_str(str2,checkkey)); + } } - iguana_priv2pub(ctx,pubkey33,coin->smartaddr,privkey,coin->taddr,coin->pubtype); + bitcoin_priv2pub(ctx,coin->pubkey33,coin->smartaddr,privkey,coin->taddr,coin->pubtype); if ( coin->counter == 0 ) { coin->counter++; - bitcoin_priv2wif(tmpstr,privkey,coin->wiftype); + bitcoin_priv2wif(coin->wiftaddr,tmpstr,privkey,coin->wiftype); bitcoin_addr2rmd160(coin->taddr,&tmptype,rmd160,coin->smartaddr); LP_privkeyadd(privkey,rmd160); if ( 0 && (coin->pubtype != 60 || strcmp(coin->symbol,"KMD") == 0) ) printf("%s (%s) %d wif.(%s) (%s)\n",coin->symbol,coin->smartaddr,coin->pubtype,tmpstr,passphrase); if ( counter++ == 0 ) { - bitcoin_priv2wif(USERPASS_WIFSTR,privkey,188); + bitcoin_priv2wif(coin->wiftaddr,USERPASS_WIFSTR,privkey,188); + bitcoin_wif2priv(coin->wiftaddr,&tmptype,&checkkey,USERPASS_WIFSTR); + if ( bits256_cmp(checkkey,privkey) != 0 ) + { + char str[65],str2[65]; + printf("FATAL ERROR converting USERPASS_WIFSTR %s -> %s != %s\n",USERPASS_WIFSTR,bits256_str(str,checkkey),bits256_str(str2,privkey)); + exit(-1); + } conv_NXTpassword(userpass.bytes,pubkeyp->bytes,(uint8_t *)USERPASS_WIFSTR,(int32_t)strlen(USERPASS_WIFSTR)); userpub = curve25519(userpass,curve25519_basepoint9()); printf("userpass.(%s)\n",bits256_str(USERPASS,userpub)); @@ -835,8 +956,9 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan } } } - LP_mypubkey = *pubkeyp = curve25519(privkey,curve25519_basepoint9()); - //printf("privkey.(%s) -> LP_mypubkey.(%s)\n",bits256_str(str,privkey),bits256_str(str2,LP_mypubkey)); + LP_mypub25519 = *pubkeyp = curve25519(privkey,curve25519_basepoint9()); + LP_mypriv25519 = privkey; + //printf("privkey.(%s) -> LP_mypub25519.(%s)\n",bits256_str(str,privkey),bits256_str(str2,LP_mypub25519)); return(privkey); } @@ -851,7 +973,7 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase,int32_t inito if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 ) privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,""); if ( coin->inactive == 0 && initonly == 0 ) - LP_privkey_init(pubsock,coin,privkey,pubkey,pubkey33); + LP_privkey_init(pubsock,coin,privkey,pubkey); } } diff --git a/iguana/exchanges/SVM/.tmpmarker b/iguana/exchanges/SVM/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/SVM/models/.tmpmarker b/iguana/exchanges/SVM/models/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/SVM/rawfeatures/.tmpmarker b/iguana/exchanges/SVM/rawfeatures/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/autofill b/iguana/exchanges/autofill new file mode 100755 index 000000000..47afea4f1 --- /dev/null +++ b/iguana/exchanges/autofill @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autofill\",\"base\":\"KMD\",\"rel\":\"BTC\",\"price\":0.0005,\"relvolume\":0.1}" diff --git a/iguana/exchanges/autoprice b/iguana/exchanges/autoprice new file mode 100755 index 000000000..e612d19a9 --- /dev/null +++ b/iguana/exchanges/autoprice @@ -0,0 +1,9 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTC\",\"margin\":0.0001}" +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BTC\",\"rel\":\"KMD\",\"margin\":0.0001}" +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"HUSH\",\"margin\":0.01}" +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"HUSH\",\"rel\":\"KMD\",\"margin\":0.01}" +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"USD\",\"margin\":0.01}" +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"USD\",\"rel\":\"KMD\",\"margin\":0.01}" +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"JUMBLR\",\"margin\":0.01}" +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"JUMBLR\",\"rel\":\"KMD\",\"margin\":0.01}" diff --git a/iguana/exchanges/cancelorder b/iguana/exchanges/cancelorder new file mode 100755 index 000000000..31f46e020 --- /dev/null +++ b/iguana/exchanges/cancelorder @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":9999999.99}" diff --git a/iguana/exchanges/coins b/iguana/exchanges/coins index 225cc88e9..fd34a1ba3 100644 --- a/iguana/exchanges/coins +++ b/iguana/exchanges/coins @@ -1,3 +1,2 @@ -export coins="[{\"coin\":\"REVS\",\"active\":1, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":1, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\", \"name\":\"dogecoin\", \"pubtype\":30, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\", \"name\":\"digibyte\", \"pubtype\":30, \"p2shtype\":5, \"wiftype\":128, \"txfee\":10000}, {\"coin\":\"MZC\", \"name\":\"mazacoin\", \"pubtype\":50, \"p2shtype\":9, \"wiftype\":224, \"txfee\":0}, {\"coin\":\"SYS\", \"name\":\"syscoin\", \"pubtype\":0, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000}, {\"coin\":\"UNO\", \"name\":\"unobtanium\", \"pubtype\":130, \"p2shtype\":30, \"wiftype\":224, \"txfee\":1000000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"ZEC\", \"name\":\"zcash\", \"pubtype\":184, \"p2shtype\":189, \"wiftype\":128, \"txfee\":10000}, {\"coin\":\"BTM\", \"name\":\"bitmark\", \"pubtype\":85, \"p2shtype\":5, \"wiftype\":213, \"txfee\":0}, {\"coin\":\"CARB\", \"name\":\"carboncoin\", \"pubtype\":47, \"p2shtype\":5, \"wiftype\":175, \"txfee\":0}, {\"coin\":\"ANC\", \"name\":\"anoncoin\", \"pubtype\":23, \"p2shtype\":5, \"wiftype\":151, \"txfee\":2000000}, {\"coin\":\"FRK\", \"name\":\"franko\", \"pubtype\":35, \"p2shtype\":5, \"wiftype\":163, \"txfee\":0}, {\"coin\":\"GAME\", \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]" -#, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}]" +export coins="[{\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"Mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\", \"name\": \"syscoin\",\"rpcport\":8368,\"pubtype\":0, \"p2shtype\":5, \"wiftype\":128, \"txfee\":10000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":50000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\", \"name\":\"dogecoin\", \"pubtype\":30, \"p2shtype\":22, \"wiftype\":158, \"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"MZC\", \"name\":\"mazacoin\", \"pubtype\":50, \"p2shtype\":9, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"UNO\", \"name\":\"unobtanium\", \"pubtype\":130, \"p2shtype\":30, \"wiftype\":224, \"txfee\":1000000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"BTM\", \"name\":\"bitmark\", \"pubtype\":85, \"p2shtype\":5, \"wiftype\":213, \"txfee\":10000}, {\"coin\":\"CARB\", \"name\":\"carboncoin\", \"pubtype\":47, \"p2shtype\":5, \"wiftype\":175, \"txfee\":10000}, {\"coin\":\"ANC\", \"name\":\"anoncoin\", \"pubtype\":23, \"p2shtype\":5, \"wiftype\":151, \"txfee\":2000000}, {\"coin\":\"FRK\", \"name\":\"franko\", \"pubtype\":35, \"p2shtype\":5, \"wiftype\":163, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}]" diff --git a/iguana/exchanges/confs/.tmpmarker b/iguana/exchanges/confs/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/debug b/iguana/exchanges/debug new file mode 100755 index 000000000..02017001a --- /dev/null +++ b/iguana/exchanges/debug @@ -0,0 +1,8 @@ +source passphrase +source coins +pkill -15 marketmaker; +git pull; +cd ..; +./m_mm; +gdb -args ./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" + diff --git a/iguana/exchanges/deletemessages b/iguana/exchanges/deletemessages new file mode 100755 index 000000000..ad1269cd8 --- /dev/null +++ b/iguana/exchanges/deletemessages @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"deletemessages\",\"firsti\":0,\"num\":10}" diff --git a/iguana/exchanges/forward b/iguana/exchanges/forward deleted file mode 100755 index 966e6af67..000000000 --- a/iguana/exchanges/forward +++ /dev/null @@ -1,2 +0,0 @@ -source userpass -curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"6578099f6474d9b8bd66a7a136b922029a989818ec0309aee962dd6ac1862b74\",\"method\":\"forward\",\"method2\":\"getprice\",\"base\":\"REVS\",\"rel\":\"KMD\"}" diff --git a/iguana/exchanges/genesis/.tmpmarker b/iguana/exchanges/genesis/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/getcoin b/iguana/exchanges/getcoin new file mode 100755 index 000000000..88ce8912e --- /dev/null +++ b/iguana/exchanges/getcoin @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"getcoin\",\"coin\":\"LTC\"}" diff --git a/iguana/exchanges/getmessages b/iguana/exchanges/getmessages new file mode 100755 index 000000000..85d246c51 --- /dev/null +++ b/iguana/exchanges/getmessages @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"getmessages\",\"firsti\":0,\"num\":10}" diff --git a/iguana/exchanges/goal b/iguana/exchanges/goal new file mode 100755 index 000000000..3fd9dee0f --- /dev/null +++ b/iguana/exchanges/goal @@ -0,0 +1,4 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"goal\",\"coin\":\"KMD\",\"val\":99}" +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"goal\",\"coin\":\"BTC\",\"val\":10}" +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"goal\",\"coin\":\"REVS\",\"val\":1}" diff --git a/iguana/exchanges/goals b/iguana/exchanges/goals new file mode 100755 index 000000000..b9735de5f --- /dev/null +++ b/iguana/exchanges/goals @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"goal\"}" diff --git a/iguana/exchanges/install b/iguana/exchanges/install index b1ce26149..bd9f680bd 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,4 @@ -cp register registerall trade ordermatch bestfit orderbook autotrade client run_osx client_osx run coins disable enable forward myprice myprices getcoins getpeers getpeersIP getprices getutxos help inv lookup pub setprice status utxos ../dexscripts +cp goals goal portfolio autoprice deletemessages getmessages debug register registerall trade ordermatch bestfit orderbook autotrade client run_osx client_osx run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices getutxos help inv setprice status utxos ../dexscripts cd ../dexscripts -echo now in dexscripts directory where you can make customized scripts that wont conflict with git pull #cp ../exchanges/passphrase ../exchanges/userpass . echo you will need to have a passphrase file with your passphrase and userpass file with userpass value in dexscripts dir diff --git a/iguana/exchanges/lookup b/iguana/exchanges/lookup deleted file mode 100755 index af9cdd645..000000000 --- a/iguana/exchanges/lookup +++ /dev/null @@ -1,2 +0,0 @@ -source userpass -curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"6578099f6474d9b8bd66a7a136b922029a989818ec0309aee962dd6ac1862b74\",\"method\":\"forward\",\"method2\":\"lookup\",\"client\":\"$1\"}" diff --git a/iguana/exchanges/message b/iguana/exchanges/message index 595ce00ad..701f63049 100755 --- a/iguana/exchanges/message +++ b/iguana/exchanges/message @@ -1,2 +1,2 @@ source userpass -curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"$1\",\"method\":\"forward\",\"method2\":\"message\",\"message\":\"some sort of message\"}" +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"$1\",\"method\":\"sendmessage\",\"message\":\"some sort of message\"}" diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index 1babc9d76..91b2df3dc 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -24,7 +24,7 @@ #include #include "OS_portable.h" #define MAX(a,b) ((a) > (b) ? (a) : (b)) -char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,double profitmargin,cJSON *argjson,char *remoteaddr,uint16_t port); +char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port); #include "stats.c" void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]); @@ -179,10 +179,10 @@ char *iguana_walletpassphrase(char *passphrase,int32_t timeout) return(bitcoind_RPC(0,"",url,0,"listunspent",postdata)); }*/ -/*char *issue_LP_intro(char *destip,uint16_t destport,char *ipaddr,uint16_t port,double profitmargin,int32_t numpeers) +/*char *issue_LP_intro(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers) { char url[512]; - sprintf(url,"http://%s:%u/api/stats/intro?ipaddr=%s&port=%u&profit=%.6f&numpeers=%d",destip,destport,ipaddr,port,profitmargin,numpeers); + sprintf(url,"http://%s:%u/api/stats/intro?ipaddr=%s&port=%u&numpeers=%d",destip,destport,ipaddr,port,numpeers); printf("(%s)\n",url); return(issue_curl(url)); }*/ @@ -790,15 +790,20 @@ void LP_main(void *ptr) if ( (passphrase= jstr(argjson,"passphrase")) != 0 ) { profitmargin = jdouble(argjson,"profitmargin"); - LPinit(7779,7780,7781,profitmargin,passphrase,jint(argjson,"client"),jstr(argjson,"userhome"),argjson); + LP_profitratio += profitmargin; + LPinit(7779,7780,7781,7782,passphrase,jint(argjson,"client"),jstr(argjson,"userhome"),argjson); } } int main(int argc, const char * argv[]) { - char *base,*rel,*name,*exchange,*apikey,*apisecret,*blocktrail,*retstr,*baseaddr,*reladdr,*passphrase; + char dirname[512],*base,*rel,*name,*exchange,*apikey,*apisecret,*blocktrail,*retstr,*baseaddr,*reladdr,*passphrase; double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid,incr; cJSON *retjson,*loginjson; int32_t i; + OS_init(); + sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/SWAPS",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/PRICES",GLOBAL_DBDIR), OS_ensure_directory(dirname); if ( argc > 1 && (retjson= cJSON_Parse(argv[1])) != 0 ) { if ( (passphrase= jstr(retjson,"passphrase")) == 0 ) diff --git a/iguana/exchanges/numutxos b/iguana/exchanges/numutxos new file mode 100755 index 000000000..b20de95fc --- /dev/null +++ b/iguana/exchanges/numutxos @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"numutxos\"}" diff --git a/iguana/exchanges/portfolio b/iguana/exchanges/portfolio new file mode 100755 index 000000000..2265e0fc2 --- /dev/null +++ b/iguana/exchanges/portfolio @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"portfolio\"}" diff --git a/iguana/exchanges/pricearray b/iguana/exchanges/pricearray new file mode 100755 index 000000000..8a01248af --- /dev/null +++ b/iguana/exchanges/pricearray @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"pricearray\",\"base\":\"KMD\",\"rel\":\"BTC\",\"timescale\":60}" diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c index 64e4f985e..92794c535 100644 --- a/iguana/exchanges/stats.c +++ b/iguana/exchanges/stats.c @@ -21,11 +21,12 @@ #include #include -#include "OS_portable.h" +#include "../../crypto777/OS_portable.h" #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define STATS_DESTDIR "/var/www/html" #define STATS_DEST "/var/www/html/DEXstats.json" #include "DEXstats.h" +char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char *remoteaddr,uint16_t port); #ifndef WIN32 #ifndef MSG_NOSIGNAL @@ -307,7 +308,7 @@ extern void *bitcoin_ctx(); char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr,char *filetype,uint16_t port) { static void *ctx; - cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; double profitmargin = 0.; char *myipaddr="127.0.0.1",symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr,*filestr,*token = 0; int32_t i,j,n,num=0; + cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; char *myipaddr="127.0.0.1",symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr,*filestr,*token = 0; int32_t i,j,n,num=0; //printf("rpcparse.(%s)\n",urlstr); if ( ctx == 0 ) ctx = bitcoin_ctx(); @@ -493,7 +494,7 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po if ( userpass != 0 && jstr(argjson,"userpass") == 0 ) jaddstr(argjson,"userpass",userpass); //printf("after urlconv.(%s) argjson.(%s)\n",jprint(json,0),jprint(argjson,0)); - if ( (retstr= stats_JSON(ctx,myipaddr,-1,profitmargin,argjson,remoteaddr,port)) != 0 ) + if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 ) { if ( (retitem= cJSON_Parse(retstr)) != 0 ) jaddi(retarray,retitem); @@ -516,7 +517,7 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po //printf("ARGJSON.(%s)\n",jprint(arg,0)); if ( userpass != 0 && jstr(arg,"userpass") == 0 ) jaddstr(arg,"userpass",userpass); - retstr = stats_JSON(ctx,myipaddr,-1,profitmargin,arg,remoteaddr,port); + retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port); } free_json(argjson); free_json(json); @@ -558,7 +559,7 @@ void stats_rpcloop(void *args) uint16_t port; char filetype[128],content_type[128]; int32_t recvlen,flag,bindsock,postflag=0,contentlen,sock,remains,numsent,jsonflag=0,hdrsize,len; socklen_t clilen; char helpname[512],remoteaddr[64],*buf,*retstr,*space; - struct sockaddr_in cli_addr; uint32_t ipbits,i,size = IGUANA_MAXPACKETSIZE + 512; + struct sockaddr_in cli_addr; uint32_t ipbits,i,size = 32*IGUANA_MAXPACKETSIZE + 512; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; if ( jsonbuf == 0 ) @@ -665,7 +666,7 @@ void stats_rpcloop(void *args) if ( retstr != 0 ) { char *response,hdrs[1024]; - //printf("RETURN.(%s)\n",retstr); + //printf("RETURN.(%s) jsonflag.%d postflag.%d\n",retstr,jsonflag,postflag); if ( jsonflag != 0 || postflag != 0 ) { response = malloc(strlen(retstr)+1024+1+1); @@ -677,6 +678,7 @@ void stats_rpcloop(void *args) if ( retstr != space ) free(retstr); retstr = response; + //printf("RET.(%s)\n",retstr); } remains = (int32_t)strlen(retstr); i = 0; @@ -726,8 +728,8 @@ void stats_kvjson(FILE *logfp,int32_t height,int32_t savedheight,uint32_t timest void komodo_kvupdate(FILE *logfp,struct komodo_state *sp,int32_t ht,bits256 txid,int32_t vout,uint8_t *opretbuf,int32_t opretlen,uint64_t value) { - static bits256 zeroes; - uint32_t flags; bits256 pubkey,refpubkey,sig; cJSON *kvjson; char decodestr[10000]; int32_t i,refvaluesize,hassig,coresize,haspubkey,height,kvheight; uint16_t keylen,valuesize,newflag = 0; uint8_t *key,*valueptr,keyvalue[10000]; + //static bits256 zeroes; + uint32_t flags; bits256 pubkey,sig; cJSON *kvjson; char decodestr[10000]; int32_t i,hassig,coresize,haspubkey,height; uint16_t keylen,valuesize; uint8_t *key,*valueptr; // bits256 refpubkey; int32_t refvaluesize,kvheight; uint16_t newflag = 0; uint8_t keyvalue[10000]; iguana_rwnum(0,&opretbuf[1],sizeof(keylen),&keylen); iguana_rwnum(0,&opretbuf[3],sizeof(valuesize),&valuesize); iguana_rwnum(0,&opretbuf[5],sizeof(height),&height); @@ -830,7 +832,7 @@ void komodo_eventadd_kmdheight(struct komodo_state *sp,char *symbol,int32_t heig void stats_pricefeed(struct komodo_state *sp,char *symbol,int32_t ht,uint32_t *pvals,int32_t numpvals) { - struct tai T; int32_t seconds,datenum,n; cJSON *argjson; + struct tai T; int32_t seconds,datenum; cJSON *argjson; if ( ht > 300000 && pvals[32] != 0 ) { datenum = OS_conv_unixtime(&T,&seconds,sp->SAVEDTIMESTAMP); @@ -930,7 +932,7 @@ int32_t komodo_parsestatefile(FILE *logfp,struct komodo_state *sp,FILE *fp,char { if ( fread(opret,1,olen,fp) != olen ) errs++; - if ( 0 && matched != 0 ) + if ( (0) && matched != 0 ) { int32_t i; for (i=0; iblocks.maxbits = numitems; } -static int _decreasing_double(const void *a,const void *b) -{ -#define double_a (*(double *)a) -#define double_b (*(double *)b) - if ( double_b > double_a ) - return(1); - else if ( double_b < double_a ) - return(-1); - return(0); -#undef double_a -#undef double_b -} - -static int32_t revsortds(double *buf,uint32_t num,int32_t size) -{ - qsort(buf,num,size,_decreasing_double); - return(0); -} - double iguana_metric(struct iguana_peer *addr,uint32_t now,double decay) { int32_t duration; double metric = addr->recvblocks * addr->recvtotal; diff --git a/iguana/iguana_sign.c b/iguana/iguana_sign.c index 3e96145c2..b1fee7f0e 100755 --- a/iguana/iguana_sign.c +++ b/iguana/iguana_sign.c @@ -1276,7 +1276,7 @@ cJSON *bitcoin_txcreate(char *symbol,int32_t isPoS,int64_t locktime,uint32_t txv cJSON *json = cJSON_CreateObject(); jaddnum(json,"version",txversion); if ( locktime == 0 && strcmp(symbol,"KMD") == 0 ) - locktime = (uint32_t)time(NULL); + locktime = (uint32_t)time(NULL) - 55; jaddnum(json,"locktime",locktime); if ( isPoS != 0 ) jaddnum(json,"timestamp",timestamp == 0 ? time(NULL) : timestamp); diff --git a/iguana/m_LP_StaticNanoMsg b/iguana/m_LP_StaticNanoMsg index b88e05e45..f121efc88 100755 --- a/iguana/m_LP_StaticNanoMsg +++ b/iguana/m_LP_StaticNanoMsg @@ -6,7 +6,7 @@ cd secp256k1; ./m_unix; cd .. cd ../crypto777; make -f m_LP_StaticNanoMsg all; make -f m_LP_StaticNanoMsg clean; cd ../iguana clang -g -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 -DUSE_STATIC_NANOMSG *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c -clang -g -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 -DUSE_STATIC_NANOMSG main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +clang -g -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 -DUSE_STATIC_NANOMSG main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a ../OSlibs/linux/$(uname -m)/libnanomsg-static.a -lcurl -lssl -lcrypto -lpthread -lz -lm -lanl -lrt -lnsl diff --git a/iguana/m_MM_StaticNanoMsg b/iguana/m_MM_StaticNanoMsg new file mode 100644 index 000000000..df84288ea --- /dev/null +++ b/iguana/m_MM_StaticNanoMsg @@ -0,0 +1,7 @@ +#!/bin/bash +#./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery +rm -f marketmaker +git pull +cd secp256k1; ./m_unix; cd .. +cd ../crypto777; make -f m_LP_StaticNanoMsg all; make -f m_LP_StaticNanoMsg clean; cd ../iguana +gcc -g -o marketmaker -I../crypto777 exchanges/mm.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a ../OSlibs/linux/$(uname -m)/libnanomsg-static.a -lcurl -lpthread -lm diff --git a/osx_deploy.sh b/osx_deploy.sh index 4a7efa802..9fa0f5733 100755 --- a/osx_deploy.sh +++ b/osx_deploy.sh @@ -6,13 +6,21 @@ TMP_DIR=~/tmp/iguana mkdir -p $TMP_DIR echo "making $TMP_DIR" -binaries=("iguana") +binaries=("iguana" "marketmaker") for binary in "${binaries[@]}"; do echo "copying $binary to $TMP_DIR" - cp agents/$binary $TMP_DIR + if [ "$binary" = "iguana" ] + then + cp agents/$binary $TMP_DIR + fi + + if [ "$binary" = "marketmaker" ] + then + cp iguana/$binary $TMP_DIR + fi # find the dylibs to copy for iguana DYLIBS=`otool -L $TMP_DIR/$binary | grep "/usr/local" | awk -F' ' '{ print $1 }'`