diff --git a/.gitignore b/.gitignore index 593be70c7..4f2ba20d2 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 @@ -208,3 +219,270 @@ iguana/DB/SWAPS/467927158-3437055573 iguana/DB/SWAPS/270159951-1269722638 iguana/DB/SWAPS/244991424-1008712592 + +iguana/confs/1cc0270abba7f4463a3dcb9908b9d875691a6773fe3cc1b4302233ed76665300 + +iguana/autoAPI.md + +iguana/confs/5228bcea7ae2515a29c3844673de6ee2acba53bf45724744a00ff4306f192912 + +iguana/confs/630929d976025fafde221c7358eb5805f4359bad3c6b8bd50ad3f6e0a9b5ce78 + +iguana/confs/5f3283a017c31e52443d61cb43944e2157f7c03eb12d701ebf4a35a695688e1f + + +iguana/DB/SWAPS/1313603851-3952777544 + +iguana/DB/SWAPS/1923456555-3815385469 + +iguana/DB/SWAPS/897416195-4050269921 + +iguana/DB/SWAPS/2465996447-4202128826 + +iguana/DB/SWAPS/3078036996-3700749298 + +iguana/DB/SWAPS/1061498231-3266306388 + +iguana/DB/SWAPS/1060082251-3390546616 + +iguana/SVM/rawfeatures/BTCD_BTC + +iguana/DB/SWAPS/1032184933-1028220623 + +iguana/DB/SWAPS/771249356-2746947221 + +iguana/DB/SWAPS/2311778512-3235676199 + +iguana/DB/SWAPS/3385048746-2109923340 + +iguana/DB/SWAPS/1739581643-2099619754 + +iguana/DB/SWAPS/2247429570-1367058185 + +iguana/DB/SWAPS/3178831915-912907861 + +iguana/DB/SWAPS/445514331-1083446761 + +iguana/DB/SWAPS/2510768478-2766365035 + +iguana/DB/SWAPS/2072817844-2263105627 + +iguana/DB/SWAPS/230888617-1894645930 + +iguana/DB/SWAPS/3606847984-2574036327 + +iguana/DB/SWAPS/2384443255-1263480722 + +iguana/DB/SWAPS/845549832-3630913950 + +iguana/DB/SWAPS/2050938501-203733478 + +iguana/DB/SWAPS/3434672913-3981690962 + +iguana/DB/SWAPS/2840127595-1174059534 + +iguana/DB/SWAPS/2448551545-1211445977 + +*.alicepayment + +*.myfee + +iguana/DB/SWAPS/1313312572-123661666 + +iguana/DB/SWAPS/3408402932-4088991610 + +iguana/DB/SWAPS/3772541120-2007204891 + +iguana/DB/SWAPS/784303571-1929722462 + +iguana/DB/SWAPS/3221116355-3522779294 + +iguana/DB/SWAPS/1703578312-1139459191 + +iguana/DB/SWAPS/1192374491-1050242469 + +iguana/DB/SWAPS/4244307493-1619487751 + +iguana/DB/SWAPS/3213119432-553439289 + +iguana/DB/SWAPS/3854521391-612984356 + +iguana/DB/SWAPS/3611231334-1171171579 + +iguana/DB/SWAPS/1505015888-2633757068 + +iguana/DB/SWAPS/3430299677-3087427598 + +iguana/DB/SWAPS/2275651697-591036515 + +iguana/DB/SWAPS/2180638961-896149751 + +iguana/DB/SWAPS/2349180798-2344225091 + +iguana/DB/SWAPS/1395238080-4120976642 + +iguana/DB/SWAPS/1914406677-1452353494 + +iguana/DB/SWAPS/3193054754-2514575257 + +iguana/DB/SWAPS/3004995589-1950720855 + +iguana/3193054754-2514575257 + +iguana/DB/SWAPS/2912654530-2125064238 + +iguana/DB/SWAPS/3448271011-3628813832 + +iguana/DB/SWAPS/3448271011-3628813832 + +iguana/DB/SWAPS/403615495-1237768524 + +iguana/DB/SWAPS/3448271011-3628813832 + +iguana/DB/SWAPS/403615495-1237768524 + +iguana/DB/SWAPS/3448271011-3628813832 + +iguana/DB/SWAPS/246664144-1570119145 + +iguana/DB/SWAPS/171316098-410428064 + +iguana/DB/SWAPS/178665381-1950467641 + +iguana/DB/SWAPS/4126499968-376410338 + +iguana/DB/SWAPS/1518259123-2214130634 + +iguana/DB/SWAPS/152114847-907489057 + +iguana/DB/SWAPS/61119357-1960547076 + +iguana/DB/SWAPS/26534791-3105729230 + +*.finished + +iguana/DB/SWAPS/2279906047-2580050792 + +iguana/DB/SWAPS/1672096208-4211948211 + +iguana/DB/SWAPS/3062665554-3128383014 + +iguana/DB/SWAPS/2668150969-2698996317 + +iguana/DB/SWAPS/3462690702-2419919594 + +iguana/DB/SWAPS/543051861-1532200070 + +iguana/DB/SWAPS/442294237-2721246052 + +iguana/DB/SWAPS/1247864366-3828803132 + +iguana/DB/SWAPS/2910626293-1439062588 + +iguana/DB/SWAPS/3893087081-2278083649 + +iguana/DB/SWAPS/2990527454-48620696 + +iguana/DB/SWAPS/217534954-2300638414 + +iguana/DB/SWAPS/2780026367-3028893038 + +iguana/DB/SWAPS/467080987-1442519493 + +iguana/DB/SWAPS/1504818827-1454232932 + +iguana/DB/SWAPS/4093850898-2949785771 + +iguana/DB/SWAPS.old/1247864366-3828803132 + +iguana/DB/SWAPS.old/.tmpmarker + +iguana/DB/SWAPS/2723832060-1788071166 + +iguana/DB/SWAPS/3210648667-2626363704 + +iguana/DB/SWAPS/415703857-2769362858 + +iguana/3193054754-2514575257 + +iguana/DB/SWAPS/2723832060-1788071166 + + + +iguana/DB/SWAPS/3213598586-2281632307 + +iguana/DB/SWAPS/2686675855-3655454671 + +iguana/DB/SWAPS/1878868608-154367763 + +iguana/DB/SWAPS/1306454711-1938980379 + +iguana/DB/SWAPS/912783809-2523701920 + +iguana/DB/SWAPS/1238069553-2363573428 + +iguana/DB/SWAPS/2895470622-2170247626 + +iguana/confs/ed476386688e486f359ce67e44ce4268a875125527e122ea9126ebc54f473d31 + +iguana/confs/f6e8e8ab82ed33b2de063d6820dcaefb99b95cf1aef6527b8f27e1e5b1fe882d + +iguana/e + +iguana/a + +iguana/t + +iguana/stats + +iguana/DEXstats + +iguana/DEXstats.dSYM/Contents/Info.plist + +iguana/DEXstats.dSYM/Contents/Resources/DWARF/DEXstats + +iguana/confs/dc54d862abd6809d9fd200759538014248f18a5a69e7bc22c0a1f2111a896157 + +iguana/confs/589983f94d17d8e0dc6fbf3fce34b20efc81183c0ab0158cf81a60f03711e15c + +iguana/confs/67201409eb7644e398c8090ac6e3ccf4b69d186b8478aa8488211e9b474dd245 + +iguana/confs/982dfa0e535a6e856cca3cd919af03f50050408fcfed1cd71bb4aa1e2e69070f + +iguana/confs/aa45c35599c9c75a9788fa9740ce8713cc457919e6f6f7d8d8115da5193f5722 + +iguana/confs/ab828d4425655df6bf409f0e23be49ae4a19b2c974008385b18a7a9c79b0314c + +iguana/confs/b29fa937dd00ed7dd73ff4eef8b49bd3103ebddaee9fae05f44ffed42c5a4611 + +iguana/confs/LTC_hdrs.txt + +iguana/confs/LTC_oldhdrs.txt + +iguana/DB/LTC_peers.dat + +iguana/debug.log + +iguana/DB/LTC/.tmpmarker + +iguana/DB/purgeable/LTC/.tmpmarker + +iguana/DB/SWAPS/654629381-1010651560 + +iguana/DB/SWAPS/1780095668-2225891679 + +iguana/DB/SWAPS/3085356347-2346291696 + +iguana/DB/SWAPS/1819165332-1507632737 + +iguana/DB/SWAPS/283982730-556239841 + +iguana/marketmaker.dSYM/Contents/Info.plist + +iguana/client + +iguana/marketmaker.dSYM/Contents/Resources/DWARF/marketmaker + +iguana/confs/97f18454bb61e9eb7a827cfbefe42fbf7ae2832dc74c4812bdaef8bcf5c10474 + +iguana/DB/PRICES/.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/OSlibs/win/libcrypto-1_1.dll b/OSlibs/win/libcrypto-1_1.dll new file mode 100644 index 000000000..4b16b67be Binary files /dev/null and b/OSlibs/win/libcrypto-1_1.dll differ diff --git a/OSlibs/win/libcurl.dll b/OSlibs/win/libcurl.dll new file mode 100644 index 000000000..8c80e23eb Binary files /dev/null and b/OSlibs/win/libcurl.dll differ diff --git a/OSlibs/win/libcurl.exp b/OSlibs/win/libcurl.exp new file mode 100644 index 000000000..a2b9da989 Binary files /dev/null and b/OSlibs/win/libcurl.exp differ diff --git a/OSlibs/win/libcurl.lib b/OSlibs/win/libcurl.lib new file mode 100644 index 000000000..c2b00f3c8 Binary files /dev/null and b/OSlibs/win/libcurl.lib differ diff --git a/OSlibs/win/libssl-1_1.dll b/OSlibs/win/libssl-1_1.dll new file mode 100644 index 000000000..dee38788d Binary files /dev/null and b/OSlibs/win/libssl-1_1.dll differ diff --git a/OSlibs/win/x64/libcurl.dll b/OSlibs/win/x64/libcurl.dll new file mode 100644 index 000000000..c77ec1f0f Binary files /dev/null and b/OSlibs/win/x64/libcurl.dll differ diff --git a/OSlibs/win/x64/libcurl.lib b/OSlibs/win/x64/libcurl.lib new file mode 100644 index 000000000..92f23798c Binary files /dev/null and b/OSlibs/win/x64/libcurl.lib differ diff --git a/OSlibs/win/x64/release/libcurl.dll b/OSlibs/win/x64/release/libcurl.dll new file mode 100644 index 000000000..c77ec1f0f Binary files /dev/null and b/OSlibs/win/x64/release/libcurl.dll differ diff --git a/OSlibs/win/x64/release/libcurl.exp b/OSlibs/win/x64/release/libcurl.exp new file mode 100644 index 000000000..fc2bcb28c Binary files /dev/null and b/OSlibs/win/x64/release/libcurl.exp differ diff --git a/OSlibs/win/x64/release/libcurl.lib b/OSlibs/win/x64/release/libcurl.lib new file mode 100644 index 000000000..92f23798c Binary files /dev/null and b/OSlibs/win/x64/release/libcurl.lib differ diff --git a/README.md b/README.md index 2d49a0b55..2d172e790 100755 --- a/README.md +++ b/README.md @@ -12,6 +12,28 @@ docs.supernet.org | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/ --- + +## Crosscompile iguana/marketmaker (barterDEX): +System requirements: Crossbuilding was tested on debian 7 and 8. + +Install mingw-w64: + +`sudo apt-get install mingw-w64` + +Clone the windows-crossbuild branch: +`git clone https://github.com/ca333/supernet && cd supernet && git checkout windows-cross` + +Build iguana (LP) and marketmaker: +``` +cd iguana +./m_LP_win_cross +./m_mm_win_cross +``` + +`iguana.exe` is built into `supernet/agents/` and `marketmaker.exe` into `supernet/iguana/` + +--- + Codebase is going under radical changes now and versions from mid-May should be used unless you are doing advanced testing. There will be four layers: gecko: abstracted bitcoin compatible blockchains that run via basilisk lite mode or as iguana core full network peers. I will try to get a geckochain to simultaneously have both virtual basilisk nodes and private iguana nodes, but at first will probably need to choose which mode a new chain will be and transition between the two via special suspend and resume functions that allow migration from virtual to physical. Each specific geckochain will be able to be enhanced into a datachain. @@ -35,7 +57,7 @@ komodo: this is the top secret project I cant talk about publicly yet *** all external dependencies have been removed, except for -lpthread and -lm -##For native (win32, win64)## +## For native (win32, win64) TOOL_DIR := /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin MINGW := i586-mingw32 The above two definitions need to be changed to match the mingw install on your system. m_win32 and m_win64 just invokes the makefile in mingw32 and mingw64 @@ -223,3 +245,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/basilisk/basilisk.c b/basilisk/basilisk.c index ba880e2e6..a2a6d2200 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -33,6 +33,55 @@ int32_t basilisk_notarycmd(char *cmd) else return(0); }*/ +cJSON *basilisk_utxosweep(struct supernet_info *myinfo,char *symbol,int64_t *satoshis,uint64_t limit,int32_t maxvins,char *coinaddr) +{ + int32_t i,n,numvins = 0; char *retstr; uint64_t value,biggest = 0; struct iguana_info *coin=0; cJSON *item,*biggestitem=0,*array,*utxos = 0; + coin = iguana_coinfind(symbol); + if ( (retstr= dex_listunspent(myinfo,coin,0,0,symbol,coinaddr)) != 0 ) + { + //printf("(%s)\n",retstr); + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + n = cJSON_GetArraySize(array); + for (i=0; i biggest ) + { + //fprintf(stderr,"biggest! "); + if ( biggestitem != 0 ) + free_json(biggestitem); + biggestitem = jduplicate(item); + *satoshis = biggest = value; + } //else fprintf(stderr,"> "); + } + } + free_json(array); + if ( utxos == 0 && biggestitem != 0 ) + { + fprintf(stderr,"add biggest.(%s)\n",jprint(biggestitem,0)); + jaddi(utxos,biggestitem); + } + } + free(retstr); + } + return(utxos); +} + uint32_t basilisk_calcnonce(struct supernet_info *myinfo,uint8_t *data,int32_t datalen,uint32_t nBits) { int32_t i,numiters = 0; bits256 hash,hash2,threshold; uint32_t basilisktag; @@ -872,7 +921,7 @@ int32_t basilisk_issued_purge(struct supernet_info *myinfo,int32_t timepad) void basilisks_loop(void *arg) { static uint32_t counter; - struct iguana_info *relay; struct supernet_info *myinfo = arg; int32_t iter; double startmilli,endmilli; struct dpow_info *dp; + struct iguana_info *relay; struct supernet_info *myinfo = arg; int32_t i,iter; double startmilli,endmilli; struct dpow_info *dp; iter = 0; relay = iguana_coinfind("RELAY"); printf("start basilisk loop\n"); @@ -925,7 +974,9 @@ void basilisks_loop(void *arg) if ( myinfo->expiration != 0 && (myinfo->dexsock >= 0 || myinfo->IAMLP != 0 || myinfo->DEXactive > time(NULL)) ) { //fprintf(stderr,"H "); - basilisk_requests_poll(myinfo); + for (i=0; i<100; i++) + if ( basilisk_requests_poll(myinfo) <= 0 ) + break; } //printf("RELAYID.%d endmilli %f vs now %f\n",myinfo->NOTARY.RELAYID,endmilli,startmilli); while ( OS_milliseconds() < endmilli ) @@ -942,6 +993,7 @@ void basilisks_init(struct supernet_info *myinfo) portable_mutex_init(&myinfo->bu_mutex); portable_mutex_init(&myinfo->allcoins_mutex); portable_mutex_init(&myinfo->basilisk_mutex); + portable_mutex_init(&myinfo->smart_mutex); portable_mutex_init(&myinfo->DEX_mutex); portable_mutex_init(&myinfo->DEX_swapmutex); portable_mutex_init(&myinfo->DEX_reqmutex); @@ -1071,6 +1123,7 @@ ARRAY_OBJ_INT(tradebot,goals,currencies,vals,targettime) return(clonestr("{\"result\":\"success\"}")); } else return(clonestr("{\"error\":\"no currencies or vals\"}")); } + HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr) { uint32_t msgid,width,channel; char *retstr; @@ -1130,7 +1183,7 @@ HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr) HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) { - char *retstr=0,*symbol,*coinaddr,*infostr; cJSON *retjson,*sobj,*info,*addrs,*txoutjson,*txjson,*array; uint32_t basilisktag,blocktime; bits256 txid,blockhash; struct basilisk_item *ptr,Lptr; uint64_t value; int32_t timeoutmillis,vout,height,n,m; + char *retstr=0,*symbol,*coinaddr,*infostr; cJSON *retjson,*sobj,*info,*addrs,*txoutjson,*txjson,*array; uint32_t basilisktag,blocktime,numtx=0; bits256 txid,blockhash; struct basilisk_item *ptr,Lptr; uint64_t value; int32_t timeoutmillis,vout,height,n,m; if ( vals == 0 ) return(clonestr("{\"error\":\"null valsobj\"}")); //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) @@ -1150,7 +1203,15 @@ HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) { if ( (txoutjson= dpow_gettxout(myinfo,coin,txid,vout)) != 0 ) { - if ( (coinaddr= jstr(txoutjson,"address")) != 0 && (value= SATOSHIDEN*jdouble(txoutjson,"value")) != 0 ) + if ( (value= SATOSHIDEN*jdouble(txoutjson,"value")) == 0 ) + value = SATOSHIDEN*jdouble(txoutjson,"amount"); + if ( (coinaddr= jstr(txoutjson,"address")) == 0 ) + { + if ( (sobj= jobj(txoutjson,"scriptPubKey")) != 0 && (addrs= jarray(&n,sobj,"addresses")) != 0 && n > 0 ) + coinaddr = jstri(addrs,0); + printf("no address, check addrs %p coinaddr.%p\n",sobj,coinaddr); + } + if ( coinaddr != 0 && value != 0 ) { retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); @@ -1158,7 +1219,7 @@ HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) jadd64bits(retjson,"satoshis",value); jaddnum(retjson,"value",dstr(value)); jaddnum(retjson,"amount",dstr(value)); - height = dpow_getchaintip(myinfo,&blockhash,&blocktime,0,0,coin); + height = dpow_getchaintip(myinfo,&blockhash,&blocktime,0,&numtx,coin); jaddnum(retjson,"height",height); jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); jaddbits256(retjson,"txid",txid); @@ -1167,22 +1228,26 @@ HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) } else { + printf("missing fields.(%s)\n",jprint(txoutjson,0)); free_json(txoutjson); return(clonestr("{\"error\":\"return from gettxout missing fields\"}")); } free_json(txoutjson); return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"null return from gettxout\"}")); + } //else return(clonestr("{\"error\":\"null return from gettxout\"}")); } - if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) - basilisktag = rand(); - if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) - timeoutmillis = BASILISK_TIMEOUT; - if ( coin->FULLNODE > 0 && (ptr= basilisk_bitcoinvalue(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + else { - retstr = ptr->retstr, ptr->retstr = 0; - ptr->finished = OS_milliseconds() + 10000; - return(retstr); + if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) + basilisktag = rand(); + if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) + timeoutmillis = BASILISK_TIMEOUT; + if ( coin->FULLNODE > 0 && (ptr= basilisk_bitcoinvalue(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + { + retstr = ptr->retstr, ptr->retstr = 0; + ptr->finished = OS_milliseconds() + 10000; + return(retstr); + } } } if ( myinfo->reqsock >= 0 ) @@ -1195,6 +1260,9 @@ HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); + if ( (height= jint(txoutjson,"height")) == 0 && coin != 0 ) + height = coin->longestchain - jint(txoutjson,"confirmations"); + jaddnum(retjson,"height",height); if ( (array= jarray(&n,txoutjson,"vout")) != 0 && vout < n && (txjson= jitem(array,vout)) != 0 ) { //printf("txjson.(%s)\n",jprint(txjson,0)); @@ -1293,16 +1361,16 @@ HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr) STRING_ARG(jumblr,setpassphrase,passphrase) { - cJSON *retjson; char KMDaddr[64],BTCaddr[64],wifstr[64]; bits256 privkey; struct iguana_info *coinbtc; - if ( passphrase == 0 || passphrase[0] == 0 || (coin= iguana_coinfind("KMD")) == 0 || coin->FULLNODE >= 0 ) + cJSON *retjson,*tmp; char KMDaddr[64],BTCaddr[64],wifstr[64],*smartaddrs; bits256 privkey; struct iguana_info *coinbtc; + if ( passphrase == 0 || passphrase[0] == 0 || (coin= iguana_coinfind("KMD")) == 0 )//|| coin->FULLNODE >= 0 ) return(clonestr("{\"error\":\"no passphrase or no native komodod\"}")); else { safecopy(myinfo->jumblr_passphrase,passphrase,sizeof(myinfo->jumblr_passphrase)); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); - privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); - smartaddress_add(myinfo,privkey,BTCaddr,KMDaddr); + privkey = jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,JUMBLR_DEPOSITPREFIX); + smartaddress_add(myinfo,privkey,"deposit","KMD",0.,0.); myinfo->jumblr_depositkey = curve25519(privkey,curve25519_basepoint9()); bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); if ( coin->FULLNODE < 0 ) @@ -1316,17 +1384,35 @@ STRING_ARG(jumblr,setpassphrase,passphrase) jumblr_importprivkey(myinfo,coinbtc,wifstr); jaddnum(retjson,"BTCdeposits",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); } - privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); - smartaddress_add(myinfo,privkey,BTCaddr,KMDaddr); + privkey = jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,""); + smartaddress_add(myinfo,privkey,"jumblr","KMD",0.,0.); myinfo->jumblr_pubkey = curve25519(privkey,curve25519_basepoint9()); jaddstr(retjson,"KMDjumblr",KMDaddr); jaddstr(retjson,"BTCjumblr",BTCaddr); if ( coinbtc != 0 ) jaddnum(retjson,"BTCjumbled",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + if ( (smartaddrs= InstantDEX_smartaddresses(myinfo,0,0,0)) != 0 ) + { + if ( (tmp= cJSON_Parse(smartaddrs)) != 0 ) + jadd(retjson,"smartaddresses",tmp); + free(smartaddrs); + } return(jprint(retjson,1)); } } +ZERO_ARGS(jumblr,runsilent) +{ + myinfo->runsilent = 1; + return(clonestr("{\"result\":\"success\",\"mode\":\"runsilent\"}")); +} + +ZERO_ARGS(jumblr,totransparent) +{ + myinfo->runsilent = 0; + return(clonestr("{\"result\":\"success\",\"mode\":\"totransparent\"}")); +} + ZERO_ARGS(jumblr,status) { cJSON *retjson; char KMDaddr[64],BTCaddr[64]; struct jumblr_item *ptr,*tmp; struct iguana_info *coinbtc; int64_t received,deposited,jumblred,step_t2z,step_z2z,step_z2t,finished,pending,maxval,minval; @@ -1335,14 +1421,15 @@ ZERO_ARGS(jumblr,status) jumblr_opidsupdate(myinfo,coin); retjson = cJSON_CreateObject(); step_t2z = step_z2z = step_z2t = deposited = finished = pending = 0; - jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); + jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,JUMBLR_DEPOSITPREFIX); + jaddstr(retjson,"mode",myinfo->runsilent == 0 ? "totransparent" : "runsilent"); jaddstr(retjson,"KMDdeposit",KMDaddr); jaddstr(retjson,"BTCdeposit",BTCaddr); if ( (coinbtc= iguana_coinfind("BTC")) != 0 ) jaddnum(retjson,"BTCdeposits",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); received = jumblr_receivedby(myinfo,coin,KMDaddr); deposited = jumblr_balance(myinfo,coin,KMDaddr); - jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); + jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,""); jaddstr(retjson,"KMDjumblr",KMDaddr); jaddstr(retjson,"BTCjumblr",BTCaddr); if ( coinbtc != 0 ) @@ -1603,7 +1690,7 @@ TWO_STRINGS(basilisk,refresh,symbol,address) STRING_ARRAY_OBJ_STRING(basilisk,utxorawtx,symbol,utxos,vals,ignore) { - char *destaddr,*changeaddr; uint64_t satoshis,txfee; int32_t completed,sendflag,timelock; + char *destaddr,*changeaddr; int64_t satoshis,txfee; int32_t completed,sendflag,timelock; timelock = jint(vals,"timelock"); sendflag = jint(vals,"sendflag"); satoshis = jdouble(vals,"amount") * SATOSHIDEN; @@ -1612,11 +1699,33 @@ STRING_ARRAY_OBJ_STRING(basilisk,utxorawtx,symbol,utxos,vals,ignore) if ( destaddr != 0 && changeaddr != 0 && symbol != 0 && (coin= iguana_coinfind(symbol)) != 0 ) { txfee = jdouble(vals,"txfee") * SATOSHIDEN; - return(iguana_utxorawtx(myinfo,coin,timelock,destaddr,changeaddr,satoshis,txfee,&completed,sendflag,utxos)); + return(iguana_utxorawtx(myinfo,coin,timelock,destaddr,changeaddr,&satoshis,1,txfee,&completed,sendflag,utxos,0)); } return(clonestr("{\"error\":\"invalid coin or address specified\"}")); } +HASH_ARRAY_STRING(basilisk,utxocombine,ignore,vals,symbol) +{ + char *coinaddr,*retstr=0; cJSON *utxos; int64_t satoshis,limit,txfee; int32_t maxvins,completed,sendflag,timelock; + timelock = 0; + if ( (maxvins= jint(vals,"maxvins")) == 0 ) + maxvins = 20; + sendflag = jint(vals,"sendflag"); + coinaddr = jstr(vals,"coinaddr"); + limit = jdouble(vals,"maxamount") * SATOSHIDEN; + if ( limit > 0 && symbol != 0 && symbol[0] != 0 && (utxos= basilisk_utxosweep(myinfo,symbol,&satoshis,limit,maxvins,coinaddr)) != 0 && cJSON_GetArraySize(utxos) > 0 ) + { + if ( coinaddr != 0 && symbol != 0 && (coin= iguana_coinfind(symbol)) != 0 ) + { + txfee = jdouble(vals,"txfee") * SATOSHIDEN; + retstr = iguana_utxorawtx(myinfo,coin,timelock,coinaddr,coinaddr,&satoshis,1,txfee,&completed,sendflag,utxos,0); + } + free_json(utxos); + } + if ( retstr == 0 ) + return(clonestr("{\"error\":\"invalid coin or address specified or no available utxos\"}")); + return(retstr); +} //int64_t iguana_verifytimelock(struct supernet_info *myinfo,struct iguana_info *coin,uint32_t timelocked,char *destaddr,bits256 txid,int32_t vout) THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume) @@ -1699,21 +1808,21 @@ HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr) { uint8_t serialized[512]; bits256 privkey; char buf[512],BTCaddr[64],KMDaddr[64]; struct basilisk_request R; int32_t jumblr,iambob,optionhours; cJSON *reqjson; uint32_t datalen=0,DEX_channel; struct iguana_info *bobcoin,*alicecoin; myinfo->DEXactive = (uint32_t)time(NULL) + 3*BASILISK_TIMEOUT + 60; - jadd64bits(vals,"minamount",jdouble(vals,"minprice") * jdouble(vals,"amount") * SATOSHIDEN * SATOSHIDEN); + jadd64bits(vals,"minamount",jdouble(vals,"minprice") * jdouble(vals,"amount") * SATOSHIDEN); if ( jobj(vals,"desthash") == 0 ) jaddbits256(vals,"desthash",hash); jadd64bits(vals,"satoshis",jdouble(vals,"amount") * SATOSHIDEN); jadd64bits(vals,"destsatoshis",jdouble(vals,"destamount") * SATOSHIDEN); jaddnum(vals,"timestamp",time(NULL)); if ( (jumblr= jint(vals,"usejumblr")) != 0 ) - privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,jumblr == 1 ? JUMBLR_DEPOSITPREFIX : ""); + privkey = jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,jumblr == 1 ? JUMBLR_DEPOSITPREFIX : ""); else privkey = myinfo->persistent_priv; hash = curve25519(privkey,curve25519_basepoint9()); if ( jobj(vals,"srchash") == 0 ) jaddbits256(vals,"srchash",hash); printf("service.(%s)\n",jprint(vals,0)); memset(&R,0,sizeof(R)); - if ( basilisk_request_create(&R,vals,hash,juint(vals,"timestamp")) == 0 ) + if ( basilisk_request_create(&R,vals,hash,juint(vals,"timestamp"),juint(vals,"DEXselector")) == 0 ) { iambob = bitcoin_coinptrs(hash,&bobcoin,&alicecoin,R.src,R.dest,privkey,GENESIS_PUBKEY); if ( (optionhours= jint(vals,"optionhours")) != 0 ) @@ -1748,6 +1857,7 @@ HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr) memset(hash.bytes,0,sizeof(hash)); msgid = (uint32_t)time(NULL); DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + myinfo->DEXtrades++; // not exact but allows a one side initiated self-trade basilisk_channelsend(myinfo,hash,hash,DEX_channel,msgid,serialized,datalen,60); sleep(3); /*while ( numiters < 10 && (crc= basilisk_crcsend(myinfo,0,buf,sizeof(buf),hash,myinfo->myaddr.persistent,DEX_channel,msgid,serialized,datalen,crcs)) == 0 ) @@ -1787,7 +1897,8 @@ int32_t InstantDEX_process_channelget(struct supernet_info *myinfo,void *ptr,int INT_ARG(InstantDEX,incoming,requestid) { - cJSON *retjson,*retarray; bits256 zero; uint32_t DEX_channel,msgid,now; int32_t retval,width,drift=3; uint8_t data[32768]; + static uint32_t counter; + cJSON *retjson,*retarray; bits256 zero; uint32_t DEX_channel,msgid,now,n = myinfo->numsmartaddrs+1; int32_t retval,width,drift=3; bits256 pubkey; uint8_t data[32768]; now = (uint32_t)time(NULL); memset(&zero,0,sizeof(zero)); width = (now - myinfo->DEXpoll) + 2*drift; @@ -1795,11 +1906,15 @@ INT_ARG(InstantDEX,incoming,requestid) width = 2*drift+1; else if ( width > 64 ) width = 64; + if ( (counter % n) == n-1 ) + pubkey = myinfo->myaddr.persistent; + else pubkey = myinfo->smartaddrs[counter % n].pubkey; + counter++; myinfo->DEXpoll = now; retjson = cJSON_CreateObject(); DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); msgid = (uint32_t)time(NULL) + drift; - if ( (retarray= basilisk_channelget(myinfo,zero,myinfo->myaddr.persistent,DEX_channel,msgid,width)) != 0 ) + if ( (retarray= basilisk_channelget(myinfo,zero,pubkey,DEX_channel,msgid,width)) != 0 ) { //printf("GOT.(%s)\n",jprint(retarray,0)); if ( (retval= basilisk_process_retarray(myinfo,0,InstantDEX_process_channelget,data,sizeof(data),DEX_channel,msgid,retarray,InstantDEX_incoming_func)) > 0 ) @@ -1811,7 +1926,7 @@ INT_ARG(InstantDEX,incoming,requestid) else { jaddstr(retjson,"error","cant do InstantDEX channelget"); - printf("error channelget\n"); + //char str[65]; printf("error channelget %s %x\n",bits256_str(str,pubkey),msgid); } return(jprint(retjson,1)); } @@ -1862,6 +1977,11 @@ ZERO_ARGS(InstantDEX,getswaplist) return(basilisk_swaplist(myinfo)); } - - +DOUBLE_ARG(InstantDEX,DEXratio,ratio) +{ + if ( ratio < 0.95 || ratio > 1.01 ) + return(clonestr("{\"result\":\"error\",\"description\":\"DEXratio must be between 0.95 and 1.01\"}")); + myinfo->DEXratio = ratio; + return(clonestr("{\"result\":\"success\"}")); +} #include "../includes/iguana_apiundefs.h" diff --git a/basilisk/basilisk.h b/basilisk/basilisk.h index b15b9032f..8d0c3da9d 100755 --- a/basilisk/basilisk.h +++ b/basilisk/basilisk.h @@ -16,8 +16,8 @@ #ifndef H_BASILISK_H #define H_BASILISK_H -#define BASILISK_DISABLESENDTX -#define BASILISK_DISABLEWAITTX +//#define BASILISK_DISABLESENDTX +//#define BASILISK_DISABLEWAITTX #include "../iguana/iguana777.h" @@ -42,6 +42,10 @@ #define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" #define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" +#define JUMBLR_INCR 99.65 +#define JUMBLR_FEE 0.001 +#define JUMBLR_TXFEE 0.01 + struct basilisk_swap; struct basilisk_rawtxinfo @@ -60,7 +64,7 @@ struct basilisk_rawtx struct iguana_msgtx msgtx; struct basilisk_rawtxinfo I; struct iguana_info *coin; - char vinstr[8192]; + char vinstr[8192],p2shaddr[64]; cJSON *vins; uint8_t txbytes[16384],spendscript[512],redeemscript[1024],extraspace[4096]; }; @@ -79,6 +83,12 @@ struct basilisk_swapinfo int32_t choosei,otherchoosei,cutverified,otherverifiedcut,numpubs,havestate,otherhavestate,pad2; uint8_t secretAm[20],secretBn[20]; uint8_t secretAm256[32],secretBn256[32]; + uint8_t userdata_aliceclaim[256],userdata_aliceclaimlen; + uint8_t userdata_alicereclaim[256],userdata_alicereclaimlen; + uint8_t userdata_alicespend[256],userdata_alicespendlen; + uint8_t userdata_bobspend[256],userdata_bobspendlen; + uint8_t userdata_bobreclaim[256],userdata_bobreclaimlen; + uint8_t userdata_bobrefund[256],userdata_bobrefundlen; }; struct basilisk_value { bits256 txid; int64_t value; int32_t height; int16_t vout; char coinaddr[64]; }; diff --git a/basilisk/basilisk_DEX.c b/basilisk/basilisk_DEX.c index 5ec6fcaed..17ed0816e 100755 --- a/basilisk/basilisk_DEX.c +++ b/basilisk/basilisk_DEX.c @@ -116,6 +116,8 @@ int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,struct basilisk_r memcpy(rp->src,&serialized[len],sizeof(rp->src)), len += sizeof(rp->src); memcpy(rp->dest,&serialized[len],sizeof(rp->dest)), len += sizeof(rp->dest); } + //len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->DEXselector),&rp->DEXselector); + //len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->extraspace),&rp->extraspace); if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid ) printf(" basilisk_rwDEXquote.%d: quoteid.%u mismatch calc %u rp.%p\n",rwflag,rp->quoteid,basilisk_quoteid(rp),rp); if ( basilisk_requestid(rp) != rp->requestid ) @@ -159,11 +161,16 @@ cJSON *basilisk_requestjson(struct basilisk_request *rp) jadd64bits(item,"minamount",rp->minamount); jaddstr(item,"dest",rp->dest); if ( rp->destamount != 0 ) - jadd64bits(item,"destamount",rp->destamount); + { + //jadd64bits(item,"destamount",rp->destamount); + jadd64bits(item,"destsatoshis",rp->destamount); + //printf("DESTSATOSHIS.%llu\n",(long long)rp->destamount); + } jaddnum(item,"quotetime",rp->quotetime); jaddnum(item,"timestamp",rp->timestamp); jaddnum(item,"requestid",rp->requestid); jaddnum(item,"quoteid",rp->quoteid); + //jaddnum(item,"DEXselector",rp->DEXselector); jaddnum(item,"optionhours",rp->optionhours); jaddnum(item,"profit",(double)rp->profitmargin / 1000000.); if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid ) @@ -192,7 +199,7 @@ cJSON *basilisk_requestjson(struct basilisk_request *rp) return(item); } -int32_t basilisk_request_create(struct basilisk_request *rp,cJSON *valsobj,bits256 desthash,uint32_t timestamp) +int32_t basilisk_request_create(struct basilisk_request *rp,cJSON *valsobj,bits256 desthash,uint32_t timestamp,int32_t DEXselector) { char *dest,*src; uint32_t i; memset(rp,0,sizeof(*rp)); @@ -212,6 +219,7 @@ int32_t basilisk_request_create(struct basilisk_request *rp,cJSON *valsobj,bits2 rp->srchash = jbits256(valsobj,"srchash"); rp->optionhours = jint(valsobj,"optionhours"); rp->profitmargin = jdouble(valsobj,"profit") * 1000000; + //rp->DEXselector = DEXselector; strncpy(rp->src,src,sizeof(rp->src)-1); strncpy(rp->dest,dest,sizeof(rp->dest)-1); //if ( jstr(valsobj,"relay") != 0 ) @@ -231,14 +239,15 @@ int32_t basilisk_request_create(struct basilisk_request *rp,cJSON *valsobj,bits2 char *basilisk_start(struct supernet_info *myinfo,bits256 privkey,struct basilisk_request *_rp,uint32_t statebits,int32_t optionduration) { - cJSON *retjson; bits256 tmpprivkey; struct basilisk_request *rp=0; int32_t i,srcmatch,destmatch; + cJSON *retjson; char typestr[64]; bits256 tmpprivkey; double bidasks[2]; struct basilisk_request *rp=0; int32_t i,srcmatch,destmatch; if ( _rp->requestid == myinfo->lastdexrequestid ) { - //printf("filter duplicate r%u\n",_rp->requestid); + printf("filter duplicate r%u\n",_rp->requestid); return(clonestr("{\"error\":\"filter duplicate requestid\"}")); } - srcmatch = smartaddress_pubkey(myinfo,&tmpprivkey,_rp->srchash) >= 0; - destmatch = smartaddress_pubkey(myinfo,&tmpprivkey,_rp->desthash) >= 0; + srcmatch = smartaddress_pubkey(myinfo,typestr,bidasks,&tmpprivkey,_rp->src,_rp->srchash) >= 0; + destmatch = smartaddress_pubkey(myinfo,typestr,bidasks,&tmpprivkey,_rp->dest,_rp->desthash) >= 0; + char str[65],str2[65]; printf("%s srcmatch.%d %s destmatch.%d\n",bits256_str(str,_rp->srchash),srcmatch,bits256_str(str2,_rp->desthash),destmatch); if ( srcmatch != 0 || destmatch != 0 ) { for (i=0; inumswaps; i++) @@ -273,12 +282,12 @@ char *basilisk_start(struct supernet_info *myinfo,bits256 privkey,struct basilis } else return(clonestr("{\"error\":\"unexpected basilisk_start not mine and amrelay\"}")); } -void basilisk_requests_poll(struct supernet_info *myinfo) +int32_t basilisk_requests_poll(struct supernet_info *myinfo) { static uint32_t lastpoll; - char *retstr; uint8_t data[32768]; cJSON *outerarray,*retjson; uint32_t msgid,channel; int32_t datalen,i,n; struct basilisk_request issueR; bits256 privkey; double hwm = 0.; - if ( myinfo->IAMNOTARY != 0 || time(NULL) < lastpoll+20 || (myinfo->IAMLP == 0 && myinfo->DEXactive < time(NULL)) ) - return; + char *retstr,typestr[64]; uint8_t data[32768]; cJSON *outerarray,*retjson; uint32_t msgid,channel; int32_t datalen,i,n,retval = 0; struct basilisk_request issueR; bits256 privkey; double bidasks[2],hwm = 0.; + if ( myinfo->IAMNOTARY != 0 || time(NULL) < lastpoll+5 || (myinfo->IAMLP == 0 && myinfo->DEXactive < time(NULL)) ) + return(retval); lastpoll = (uint32_t)time(NULL); memset(&issueR,0,sizeof(issueR)); memset(&myinfo->DEXaccept,0,sizeof(myinfo->DEXaccept)); @@ -290,6 +299,7 @@ void basilisk_requests_poll(struct supernet_info *myinfo) { if ( (outerarray= jarray(&n,retjson,"responses")) != 0 ) { + retval++; for (i=0; i 0. ) { myinfo->DEXaccept = issueR; - if ( smartaddress_pubkey(myinfo,&privkey,issueR.srchash) >= 0 ) + if ( smartaddress_pubkey(myinfo,typestr,bidasks,&privkey,issueR.src,issueR.srchash) >= 0 ) { - printf("matched dex_smartpubkey\n"); - dex_channelsend(myinfo,issueR.srchash,issueR.desthash,channel,0x4000000,(void *)&issueR.requestid,sizeof(issueR.requestid)); // 60 - dpow_nanomsg_update(myinfo); - dex_updateclient(myinfo); - if ( (retstr= basilisk_start(myinfo,privkey,&issueR,1,issueR.optionhours * 3600)) != 0 ) - free(retstr); + if ( myinfo->DEXtrades > 0 ) + { + dex_channelsend(myinfo,issueR.srchash,issueR.desthash,channel,0x4000000,(void *)&issueR.requestid,sizeof(issueR.requestid)); // 60 + dpow_nanomsg_update(myinfo); + dex_updateclient(myinfo); + if ( (retstr= basilisk_start(myinfo,privkey,&issueR,1,issueR.optionhours * 3600)) != 0 ) + free(retstr); + } } - else if ( issueR.requestid != myinfo->lastdexrequestid )//if ( issueR.quoteid == 0 ) + else if ( myinfo->IAMLP != 0 && issueR.requestid != myinfo->lastdexrequestid )//if ( issueR.quoteid == 0 ) { issueR.quoteid = basilisk_quoteid(&issueR); issueR.desthash = myinfo->myaddr.persistent; @@ -324,6 +336,7 @@ void basilisk_requests_poll(struct supernet_info *myinfo) free(retstr); } //else printf("basilisk_requests_poll unexpected hwm issueR\n"); } + return(retval); } struct basilisk_relay *basilisk_request_ensure(struct supernet_info *myinfo,uint32_t senderipbits,int32_t numrequests) @@ -471,9 +484,10 @@ char *basilisk_respond_accept(struct supernet_info *myinfo,bits256 privkey,uint3 retstr = clonestr("{\"error\":\"couldnt find to requestid to choose\"}"); return(retstr); } + cJSON *basilisk_unspents(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) { - cJSON *unspents=0,*array=0; char *retstr; + cJSON *unspents=0,*array=0,*json,*ismine; char *retstr; int32_t valid = 0; if ( coin->FULLNODE > 0 ) { array = cJSON_CreateArray(); @@ -481,15 +495,24 @@ cJSON *basilisk_unspents(struct supernet_info *myinfo,struct iguana_info *coin,c unspents = iguana_listunspents(myinfo,coin,array,0,0,""); free_json(array); } - else if ( coin->FULLNODE == 0 ) + else { - if ( (retstr= dex_listunspent(myinfo,coin,0,0,coin->symbol,coinaddr)) != 0 ) + if ( coin->FULLNODE < 0 && (retstr= dpow_validateaddress(myinfo,coin,coinaddr)) != 0 ) { - unspents = cJSON_Parse(retstr); + json = cJSON_Parse(retstr); + if ( (ismine= jobj(json,"ismine")) != 0 && is_cJSON_True(ismine) != 0 ) + valid = 1; free(retstr); } + if ( coin->FULLNODE == 0 || valid == 0 ) + { + if ( (retstr= dex_listunspent(myinfo,coin,0,0,coin->symbol,coinaddr)) != 0 ) + { + unspents = cJSON_Parse(retstr); + free(retstr); + } + } else unspents = dpow_listunspent(myinfo,coin,coinaddr); } - else unspents = dpow_listunspent(myinfo,coin,coinaddr); return(unspents); } diff --git a/basilisk/basilisk_MSG.c b/basilisk/basilisk_MSG.c index 6619c4db0..0fba54c91 100755 --- a/basilisk/basilisk_MSG.c +++ b/basilisk/basilisk_MSG.c @@ -98,7 +98,7 @@ char *basilisk_iterate_MSG(struct supernet_info *myinfo,uint32_t channel,uint32_ // char str[65],str2[65]; printf("MSGiterate (%s) -> (%s)\n",bits256_str(str,srchash),bits256_str(str2,desthash)); array = cJSON_CreateArray(); portable_mutex_lock(&myinfo->messagemutex); - printf("iterate_MSG width.%d channel.%d msgid.%d src.%llx -> %llx\n",origwidth,channel,msgid,(long long)srchash.txid,(long long)desthash.txid); + //printf("iterate_MSG width.%d channel.%d msgid.%d src.%llx -> %llx\n",origwidth,channel,msgid,(long long)srchash.txid,(long long)desthash.txid); for (i=0; i duplicates/4 ) + if ( strcmp(coin->chain->symbol,"BTC") == 0 && cJSON_GetArraySize(vins) > duplicates/2 ) { free(rawtx); rawtx = 0; @@ -602,7 +602,7 @@ char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coi free_json(vins); return(rawtx); } - //printf("duplicatesTX.(%s)\n",rawtx); + printf("splitfunds tx.(%s) vins.(%s)\n",rawtx,jprint(vins,0)); if ( signedtxidp != 0 ) { if ( (signedtx= iguana_signrawtx(myinfo,coin,0,signedtxidp,completedp,vins,rawtx,0,0)) != 0 ) @@ -658,9 +658,9 @@ int64_t iguana_verifytimelock(struct supernet_info *myinfo,struct iguana_info *c } return(-2); } -char *iguana_utxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t timelock,char *destaddr,char *changeaddr,uint64_t satoshis,uint64_t txfee,int32_t *completedp,int32_t sendflag,cJSON *utxos) +char *iguana_utxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t timelock,char *destaddr,char *changeaddr,int64_t *satoshis,int32_t numoutputs,uint64_t txfee,int32_t *completedp,int32_t sendflag,cJSON *utxos,cJSON *privkeys) { - uint8_t script[35],p2shscript[128],rmd160[20],addrtype; bits256 txid; int32_t p2shlen,iter,spendlen; cJSON *retjson,*txcopy,*txobj=0,*vins=0; char *rawtx=0,*signedtx=0; uint32_t timelocked = 0; + uint8_t script[35],p2shscript[128],rmd160[20],addrtype; bits256 txid; int32_t i,p2shlen,iter,spendlen; cJSON *retjson,*txcopy,*txobj=0,*vins=0; char *rawtx=0,*signedtx=0; uint32_t timelocked = 0; *completedp = 0; if ( iguana_addressvalidate(coin,&addrtype,destaddr) < 0 || iguana_addressvalidate(coin,&addrtype,changeaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); @@ -687,15 +687,17 @@ char *iguana_utxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,int spendlen = bitcoin_p2shspend(script,0,rmd160); printf("timelock.%d spend timelocked %u\n",timelock,timelocked); } - bitcoin_txoutput(txobj,script,spendlen,satoshis); + for (i=0; i 0 ) + bitcoin_txoutput(txobj,script,spendlen,satoshis[i]); for (iter=0; iter<2; iter++) { txcopy = jduplicate(txobj); - if ( (rawtx= iguana_calcutxorawtx(myinfo,coin,&vins,txobj,satoshis,changeaddr,txfee,utxos,"",0,0)) != 0 ) + if ( (rawtx= iguana_calcutxorawtx(myinfo,coin,&vins,txobj,satoshis,numoutputs,changeaddr,txfee,utxos,"",0,0)) != 0 ) { if ( iter == 1 || txfee != 0 ) jaddstr(retjson,"rawtx",rawtx); - if ( (signedtx= iguana_signrawtx(myinfo,coin,0,&txid,completedp,vins,rawtx,0,0)) != 0 ) + if ( (signedtx= iguana_signrawtx(myinfo,coin,0,&txid,completedp,vins,rawtx,privkeys,0)) != 0 ) { if ( (iter == 1 || txfee != 0) && *completedp != 0 ) { @@ -703,10 +705,9 @@ char *iguana_utxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,int jaddstr(retjson,"signedtx",signedtx); if ( sendflag != 0 ) { - //printf("send signedtx.(%s)\n",signedtx); txid = iguana_sendrawtransaction(myinfo,coin,signedtx); jaddbits256(retjson,"sent",txid); - } + } else printf("dont send signedtx.(%s)\n",signedtx); } } else printf("error signing raw utxorawtx tx\n"); } else printf("null rawtx from calcutxorawtx\n"); @@ -740,9 +741,15 @@ char *iguana_utxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,int if ( txobj != 0 ) free_json(txobj); if ( rawtx != 0 ) + { + jaddstr(retjson,"rawtx",rawtx); free(rawtx); + } if ( signedtx != 0 ) + { + jaddstr(retjson,"signedtx",signedtx); free(signedtx); + } return(jprint(retjson,1)); } @@ -774,7 +781,7 @@ char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coi addresses = iguana_getaddressesbyaccount(myinfo,coin,"*"); jadd(valsobj,"addresses",addresses); } - printf("use addresses.(%s)\n",jprint(addresses,0)); + printf("use addresses.(%s) (%s)\n",jprint(addresses,0),spendscriptstr!=0?spendscriptstr:"no script"); //printf("(%s) vals.(%s) change.(%s) spend.%s\n",coin->symbol,jprint(valsobj,0),changeaddr,spendscriptstr); if ( changeaddr == 0 || changeaddr[0] == 0 || spendscriptstr == 0 || spendscriptstr[0] == 0 ) return(clonestr("{\"error\":\"invalid changeaddr or spendscript or addresses\"}")); diff --git a/basilisk/basilisk_swap.c b/basilisk/basilisk_swap.c index 9b3abc4d5..a142f8a12 100755 --- a/basilisk/basilisk_swap.c +++ b/basilisk/basilisk_swap.c @@ -18,7 +18,8 @@ make sure to broadcast deposit before claiming refund, or to just skip it if neither is done */ -#define DEX_SLEEP 1 +#define DEX_SLEEP 10 +#define BASILISK_DEFAULT_NUMCONFIRMS 5 // Todo: monitor blockchains, ie complete extracting scriptsig // mode to autocreate required outputs @@ -105,6 +106,45 @@ Alice spends bobdeposit in 2*INSTANTDEX_LOCKTIME //Bobdeposit includes a covered put option for alicecoin, duration INSTANTDEX_LOCKTIME //alicepayment includes a covered call option for alicecoin, duration (2*INSTANTDEX_LOCKTIME - elapsed) + +/* in case of following states, some funds remain unclaimable, but all identified cases are due to one or both sides not spending when they were the only eligible party: + + Bob failed to claim deposit during exclusive period and since alice put in the claim, the alicepayment is unspendable. if alice is nice, she can send privAm to Bob. +Apaymentspent.(0000000000000000000000000000000000000000000000000000000000000000) alice.0 bob.0 +paymentspent.(f91da4e001360b95276448e7b01904d9ee4d15862c5af7f5c7a918df26030315) alice.0 bob.1 +depositspent.(f34e04ad74e290f63f3d0bccb7d0d50abfa54eea58de38816fdc596a19767add) alice.1 bob.0 + + */ + +int32_t basilisk_istrustedbob(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + // for BTC and if trusted LP + return(0); +} + +int32_t basilisk_priviextract(struct supernet_info *myinfo,struct iguana_info *coin,char *name,bits256 *destp,uint8_t secret160[20],bits256 srctxid,int32_t srcvout) +{ + bits256 txid,privkey; char str[65]; int32_t i,vini,scriptlen; uint8_t rmd160[20],scriptsig[IGUANA_MAXSCRIPTSIZE]; + memset(privkey.bytes,0,sizeof(privkey)); + // use dex_listtransactions! + if ( (vini= iguana_vinifind(myinfo,coin,&txid,srctxid,srcvout)) >= 0 ) + { + if ( (scriptlen= iguana_scriptsigextract(myinfo,coin,scriptsig,sizeof(scriptsig),txid,vini)) > 32 ) + { + for (i=0; i<32; i++) + privkey.bytes[i] = scriptsig[scriptlen - 33 + i]; + revcalc_rmd160_sha256(rmd160,privkey);//.bytes,sizeof(privkey)); + if ( memcmp(secret160,rmd160,sizeof(rmd160)) == sizeof(rmd160) ) + { + *destp = privkey; + printf("basilisk_priviextract found privi %s (%s)\n",name,bits256_str(str,privkey)); + return(0); + } + } + } + return(-1); +} + void revcalc_rmd160_sha256(uint8_t rmd160[20],bits256 revhash) { bits256 hash; int32_t i; @@ -139,30 +179,28 @@ bits256 basilisk_revealkey(bits256 privkey,bits256 pubkey) return(reveal); } -int32_t basilisk_bobscript(uint8_t *rmd160,uint8_t *redeemscript,int32_t *redeemlenp,uint8_t *script,int32_t n,uint32_t *locktimep,int32_t *secretstartp,struct basilisk_swapinfo *swap,int32_t depositflag) +int32_t basilisk_swap_bobredeemscript(int32_t depositflag,int32_t *secretstartp,uint8_t *redeemscript,uint32_t locktime,bits256 pubA0,bits256 pubB0,bits256 pubB1,bits256 privAm,bits256 privBn,uint8_t *secretAm,uint8_t *secretAm256,uint8_t *secretBn,uint8_t *secretBn256) { - uint8_t pubkeyA[33],pubkeyB[33],*secret160,*secret256; bits256 privkey,cltvpub,destpub; int32_t i; + int32_t i,n=0; bits256 cltvpub,destpub,privkey; uint8_t pubkeyA[33],pubkeyB[33],secret160[20],secret256[32]; if ( depositflag != 0 ) { - *locktimep = swap->started + swap->putduration + swap->callduration; - pubkeyA[0] = 0x02, cltvpub = swap->pubA0; - pubkeyB[0] = 0x03, destpub = swap->pubB0; - privkey = swap->privBn; - secret160 = swap->secretBn; - secret256 = swap->secretBn256; + pubkeyA[0] = 0x02, cltvpub = pubA0; + pubkeyB[0] = 0x03, destpub = pubB0; + privkey = privBn; + memcpy(secret160,secretBn,20); + memcpy(secret256,secretBn256,32); } else { - *locktimep = swap->started + swap->putduration; - pubkeyA[0] = 0x03, cltvpub = swap->pubB1; - pubkeyB[0] = 0x02, destpub = swap->pubA0; - privkey = swap->privAm; - secret160 = swap->secretAm; - secret256 = swap->secretAm256; + pubkeyA[0] = 0x03, cltvpub = pubB1; + pubkeyB[0] = 0x02, destpub = pubA0; + privkey = privAm; + memcpy(secret160,secretAm,20); + memcpy(secret256,secretAm256,32); } //for (i=0; i<32; i++) // printf("%02x",secret256[i]); - //printf(" <- secret256 depositflag.%d\n",depositflag); + //printf(" <- secret256 depositflag.%d nonz.%d\n",depositflag,bits256_nonz(privkey)); if ( bits256_nonz(cltvpub) == 0 || bits256_nonz(destpub) == 0 ) return(-1); for (i=0; i<20; i++) @@ -173,7 +211,7 @@ int32_t basilisk_bobscript(uint8_t *rmd160,uint8_t *redeemscript,int32_t *redeem memcpy(pubkeyA+1,cltvpub.bytes,sizeof(cltvpub)); memcpy(pubkeyB+1,destpub.bytes,sizeof(destpub)); redeemscript[n++] = SCRIPT_OP_IF; - n = bitcoin_checklocktimeverify(redeemscript,n,*locktimep); + n = bitcoin_checklocktimeverify(redeemscript,n,locktime); #ifdef DISABLE_CHECKSIG n = bitcoin_secret256spend(redeemscript,n,cltvpub); #else @@ -217,12 +255,23 @@ int32_t basilisk_bobscript(uint8_t *rmd160,uint8_t *redeemscript,int32_t *redeem n = bitcoin_pubkeyspend(redeemscript,n,pubkeyB); #endif redeemscript[n++] = SCRIPT_OP_ENDIF; - *redeemlenp = n; - calc_rmd160_sha256(rmd160,redeemscript,n); - n = bitcoin_p2shspend(script,0,rmd160); - //for (i=0; istarted + swap->putduration + swap->callduration; + else *locktimep = swap->started + swap->putduration; + *redeemlenp = n = basilisk_swap_bobredeemscript(depositflag,secretstartp,redeemscript,*locktimep,swap->pubA0,swap->pubB0,swap->pubB1,swap->privAm,swap->privBn,swap->secretAm,swap->secretAm256,swap->secretBn,swap->secretBn256); + if ( n > 0 ) + { + calc_rmd160_sha256(rmd160,redeemscript,n); + n = bitcoin_p2shspend(script,0,rmd160); + //for (i=0; i 0 && numconfirms >= 0 ) return(numconfirms); + printf("basilisk_confirmsobj height.%d numconfirms.%d (%s)\n",height,numconfirms,jprint(item,0)); return(-1); } @@ -264,14 +314,17 @@ int32_t basilisk_numconfirms(struct supernet_info *myinfo,struct basilisk_swap * jaddstr(argjson,"coin",rawtx->coin->symbol); if ( (valstr= basilisk_value(myinfo,rawtx->coin,0,0,swap->persistent_pubkey,argjson,0)) != 0 ) { - //char str[65]; printf("%s %s valstr.(%s)\n",rawtx->name,bits256_str(str,rawtx->I.actualtxid),valstr); + char str[65]; printf("basilisk_numconfirms required.%d %s %s valstr.(%s)\n",rawtx->I.numconfirms,rawtx->name,bits256_str(str,rawtx->I.actualtxid),valstr); + //basilisk_numconfirms required.0 alicespend 29a2a6b4a61b1da82096d533c71b6762d61a82ca771a633269d97c0ccb94fe85 valstr.({"result":"success","numconfirms":0,"address":"1JGvZ67oTdM7kCya4J8kj1uErbSRAoq3wH","satoshis":"1413818","value":0.01413818,"height":462440,"txid":"29a2a6b4a61b1da82096d533c71b6762d61a82ca771a633269d97c0ccb94fe85","vout":0,"coin":"BTC"}) + if ( (valuearray= cJSON_Parse(valstr)) != 0 ) { - if ( is_cJSON_Array(valuearray) != 0 ) + if ( valstr[0] == '[' && is_cJSON_Array(valuearray) != 0 ) { n = cJSON_GetArraySize(valuearray); for (i=0; i= 0 ) break; } @@ -281,12 +334,13 @@ int32_t basilisk_numconfirms(struct supernet_info *myinfo,struct basilisk_swap * free(valstr); } free_json(argjson); + printf("numconfirms.%d returned\n",retval); return(retval); } bits256 basilisk_swap_broadcast(char *name,struct supernet_info *myinfo,struct basilisk_swap *swap,struct iguana_info *coin,uint8_t *data,int32_t datalen) { - bits256 txid; char *signedtx,*retstr; + bits256 txid; char *signedtx,*retstr; int32_t i; memset(txid.bytes,0,sizeof(txid)); if ( data != 0 && datalen != 0 ) { @@ -298,20 +352,24 @@ bits256 basilisk_swap_broadcast(char *name,struct supernet_info *myinfo,struct b #endif signedtx = malloc(datalen*2 + 1); init_hexbytes_noT(signedtx,data,datalen); - if ( (retstr= basilisk_sendrawtransaction(myinfo,coin,signedtx)) != 0 ) + for (i=0; i<3; i++) { - if ( is_hexstr(retstr,0) == 64 ) - { - decode_hex(txid.bytes,32,retstr); - free(retstr); - printf("sendrawtransaction %s.(%s)\n",name,bits256_str(str,txid)); - } - else + if ( (retstr= basilisk_sendrawtransaction(myinfo,coin,signedtx)) != 0 ) { - printf("sendrawtransaction %s error.(%s)\n",name,retstr); - free(retstr); - } - } else printf("sendrawtransaction %s got null return\n",name); + if ( is_hexstr(retstr,0) == 64 ) + { + decode_hex(txid.bytes,32,retstr); + free(retstr); + printf("sendrawtransaction %s.(%s)\n",name,bits256_str(str,txid)); + break; + } + else + { + printf("sendrawtransaction %s error.(%s)\n",name,retstr); + free(retstr); + } + } else printf("sendrawtransaction %s got null return\n",name); + } free(signedtx); } return(txid); @@ -389,7 +447,7 @@ int32_t _basilisk_rawtx_sign(struct supernet_info *myinfo,int32_t height,uint32_ free(signedtx); if ( dest->I.completed != 0 ) retval = 0; - else printf("couldnt sign transaction %s\n",rawtx->name); + else printf("couldnt complete sign transaction %s\n",rawtx->name); } else printf("error signing\n"); free(rawtxbytes); } else printf("error making rawtx\n"); @@ -412,7 +470,7 @@ int32_t basilisk_rawtx_sign(struct supernet_info *myinfo,int32_t height,struct b cJSON *basilisk_privkeyarray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins) { - cJSON *privkeyarray,*item,*sobj; struct iguana_waddress *waddr; struct iguana_waccount *wacct; char coinaddr[64],account[128],wifstr[64],str[65],*hexstr; uint8_t script[1024]; int32_t i,n,len,vout; bits256 txid,privkey; + cJSON *privkeyarray,*item,*sobj; struct iguana_waddress *waddr; struct iguana_waccount *wacct; char coinaddr[64],account[128],wifstr[64],str[65],typestr[64],*hexstr; uint8_t script[1024]; int32_t i,n,len,vout; bits256 txid,privkey; double bidasks[2]; privkeyarray = cJSON_CreateArray(); //printf("%s persistent.(%s) (%s) change.(%s) scriptstr.(%s)\n",coin->symbol,myinfo->myaddr.BTC,coinaddr,coin->changeaddr,scriptstr); if ( (n= cJSON_GetArraySize(vins)) > 0 ) @@ -442,7 +500,7 @@ cJSON *basilisk_privkeyarray(struct supernet_info *myinfo,struct iguana_info *co bitcoin_priv2wif(wifstr,waddr->privkey,coin->chain->wiftype); jaddistr(privkeyarray,waddr->wifstr); } - else if ( smartaddress(myinfo,&privkey,coinaddr) >= 0 ) + else if ( smartaddress(myinfo,typestr,bidasks,&privkey,coin->symbol,coinaddr) >= 0 ) { bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); jaddistr(privkeyarray,wifstr); @@ -506,8 +564,12 @@ int32_t _basilisk_rawtx_gen(char *str,struct supernet_info *myinfo,uint32_t swap jaddstr(valsobj,"spendscript",scriptstr); jaddstr(valsobj,"changeaddr",rawtx->coin->changeaddr); jadd64bits(valsobj,"satoshis",rawtx->I.amount); + if ( strcmp(rawtx->coin->symbol,"BTC") == 0 && txfee > 0 && txfee < 50000 ) + txfee = 50000; jadd64bits(valsobj,"txfee",txfee); jaddnum(valsobj,"minconf",minconf); + if ( locktime == 0 ) + locktime = (uint32_t)time(NULL) - 777; jaddnum(valsobj,"locktime",locktime); jaddnum(valsobj,"timeout",30000); jaddnum(valsobj,"timestamp",swapstarted+delay); @@ -516,11 +578,11 @@ int32_t _basilisk_rawtx_gen(char *str,struct supernet_info *myinfo,uint32_t swap jaddistr(addresses,coinaddr); jadd(valsobj,"addresses",addresses); rawtx->I.locktime = locktime; - //printf("%s locktime.%u\n",rawtx->name,locktime); + printf("%s locktime.%u\n",rawtx->name,locktime); V = calloc(256,sizeof(*V)); if ( (retstr= basilisk_bitcoinrawtx(myinfo,rawtx->coin,"",basilisktag,jint(valsobj,"timeout"),valsobj,V)) != 0 ) { - //printf("%s %s basilisk_bitcoinrawtx.(%s)\n",rawtx->name,str,retstr); + printf("%s %s basilisk_bitcoinrawtx.(%s) txfee %.8f\n",rawtx->name,str,retstr,dstr(txfee)); flag = 0; if ( (retarray= cJSON_Parse(retstr)) != 0 ) { @@ -550,7 +612,7 @@ int32_t _basilisk_rawtx_gen(char *str,struct supernet_info *myinfo,uint32_t swap free(retarray); } else printf("error parsing.(%s)\n",retstr); free(retstr); - } else printf("error creating %s feetx\n",iambob != 0 ? "BOB" : "ALICE"); + } else printf("error creating %s %s\n",iambob != 0 ? "BOB" : "ALICE",rawtx->name); free_json(valsobj); free(V); return(retval); @@ -643,6 +705,7 @@ int32_t basilisk_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,str { decode_hex(rawtx->spendscript,hexlen,hexstr); rawtx->I.spendlen = hexlen; + bitcoin_address(rawtx->p2shaddr,rawtx->coin->chain->p2shtype,rawtx->spendscript,hexlen); if ( swap != 0 ) basilisk_txlog(swap->myinfoptr,swap,rawtx,-1); // bobdeposit, bobpayment or alicepayment retval = 0; @@ -654,6 +717,31 @@ int32_t basilisk_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,str return(retval); } +void basilisk_swap_coinaddr(struct supernet_info *myinfo,struct basilisk_swap *swap,struct iguana_info *coin,char *coinaddr,uint8_t *data,int32_t datalen) +{ + cJSON *txobj,*vouts,*vout,*addresses,*item,*skey; uint8_t extraspace[8192]; bits256 signedtxid; struct iguana_msgtx msgtx; char *addr; int32_t n,m,suppress_pubkeys = 0; + if ( (txobj= bitcoin_data2json(coin,coin->longestchain,&signedtxid,&msgtx,extraspace,sizeof(extraspace),data,datalen,0,suppress_pubkeys)) != 0 ) + { + //char str[65]; printf("got txid.%s (%s)\n",bits256_str(str,signedtxid),jprint(txobj,0)); + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n > 0 ) + { + vout = jitem(vouts,0); + //printf("VOUT.(%s)\n",jprint(vout,0)); + if ( (skey= jobj(vout,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 ) + { + item = jitem(addresses,0); + //printf("item.(%s)\n",jprint(item,0)); + if ( (addr= jstr(item,0)) != 0 ) + { + safecopy(coinaddr,addr,64); + //printf("extracted.(%s)\n",coinaddr); + } + } + } + free_json(txobj); + } +} + int32_t basilisk_swapuserdata(uint8_t *userdata,bits256 privkey,int32_t ifpath,bits256 signpriv,uint8_t *redeemscript,int32_t redeemlen) { int32_t i,len = 0; @@ -679,12 +767,215 @@ int32_t basilisk_swapuserdata(uint8_t *userdata,bits256 privkey,int32_t ifpath,b OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF*/ +void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,int32_t scriptlen) +{ + int32_t i; char scriptstr[513]; + if ( scriptlen != 0 ) + { + for (i=0; iI.req.requestid,swap->I.req.quoteid,rawtx->name), OS_compatible_path(fname); + coinaddr[0] = secretAmstr[0] = secretAm256str[0] = secretBnstr[0] = secretBn256str[0] = 0; + memset(zeroes,0,sizeof(zeroes)); + if ( rawtx != 0 && (fp= fopen(fname,"wb")) != 0 ) + { + fprintf(fp,"{\"name\":\"%s\",\"coin\":\"%s\"",rawtx->name,rawtx->coin->symbol); + if ( rawtx->I.datalen > 0 ) + { + fprintf(fp,",\"tx\":\""); + for (i=0; iI.datalen; i++) + fprintf(fp,"%02x",rawtx->txbytes[i]); + fprintf(fp,"\",\"txid\":\"%s\"",bits256_str(str,bits256_doublesha256(0,rawtx->txbytes,rawtx->I.datalen))); + if ( rawtx == &swap->bobdeposit || rawtx == &swap->bobpayment ) + { + basilisk_swap_coinaddr(myinfo,swap,swap->bobcoin,coinaddr,rawtx->txbytes,rawtx->I.datalen); + if ( coinaddr[0] != 0 ) + { + if ( swap->bobcoin != 0 && swap->bobcoin->FULLNODE < 0 ) + { + if ( (tmp= dpow_importaddress(myinfo,swap->bobcoin,coinaddr)) != 0 ) + free(tmp); + } + if ( rawtx == &swap->bobdeposit ) + safecopy(swap->Bdeposit,coinaddr,sizeof(swap->Bdeposit)); + else safecopy(swap->Bpayment,coinaddr,sizeof(swap->Bpayment)); + } + } + } + if ( swap->Bdeposit[0] != 0 ) + fprintf(fp,",\"%s\":\"%s\"","Bdeposit",swap->Bdeposit); + if ( swap->Bpayment[0] != 0 ) + fprintf(fp,",\"%s\":\"%s\"","Bpayment",swap->Bpayment); + fprintf(fp,",\"expiration\":%u",swap->I.expiration); + fprintf(fp,",\"iambob\":%d",swap->I.iambob); + fprintf(fp,",\"bobcoin\":\"%s\"",swap->bobcoin->symbol); + fprintf(fp,",\"alicecoin\":\"%s\"",swap->alicecoin->symbol); + fprintf(fp,",\"lock\":%u",locktime); + fprintf(fp,",\"amount\":%.8f",dstr(rawtx->I.amount)); + if ( bits256_nonz(triggertxid) != 0 ) + fprintf(fp,",\"trigger\":\"%s\"",bits256_str(str,triggertxid)); + if ( bits256_nonz(swap->I.pubAm) != 0 && bits256_nonz(swap->I.pubBn) != 0 ) + { + basilisk_alicescript(redeemscript,&len,script,0,coinaddr,swap->alicecoin->chain->p2shtype,swap->I.pubAm,swap->I.pubBn); + if ( swap->alicecoin != 0 && swap->alicecoin->FULLNODE < 0 ) + { + if ( (tmp= dpow_importaddress(myinfo,swap->alicecoin,coinaddr)) != 0 ) + free(tmp); + } + fprintf(fp,",\"Apayment\":\"%s\"",coinaddr); + } + /*basilisk_dontforget_userdata("Aclaim",fp,swap->I.userdata_aliceclaim,swap->I.userdata_aliceclaimlen); + basilisk_dontforget_userdata("Areclaim",fp,swap->I.userdata_alicereclaim,swap->I.userdata_alicereclaimlen); + basilisk_dontforget_userdata("Aspend",fp,swap->I.userdata_alicespend,swap->I.userdata_alicespendlen); + basilisk_dontforget_userdata("Bspend",fp,swap->I.userdata_bobspend,swap->I.userdata_bobspendlen); + basilisk_dontforget_userdata("Breclaim",fp,swap->I.userdata_bobreclaim,swap->I.userdata_bobreclaimlen); + basilisk_dontforget_userdata("Brefund",fp,swap->I.userdata_bobrefund,swap->I.userdata_bobrefundlen);*/ + fprintf(fp,"}\n"); + fclose(fp); + } + 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); + if ( memcmp(zeroes,swap->I.secretAm,20) != 0 ) + { + init_hexbytes_noT(secretAmstr,swap->I.secretAm,20); + fprintf(fp,",\"secretAm\":\"%s\"",secretAmstr); + } + if ( memcmp(zeroes,swap->I.secretAm256,32) != 0 ) + { + init_hexbytes_noT(secretAm256str,swap->I.secretAm256,32); + fprintf(fp,",\"secretAm256\":\"%s\"",secretAm256str); + } + if ( memcmp(zeroes,swap->I.secretBn,20) != 0 ) + { + init_hexbytes_noT(secretBnstr,swap->I.secretBn,20); + fprintf(fp,",\"secretBn\":\"%s\"",secretBnstr); + } + if ( memcmp(zeroes,swap->I.secretBn256,32) != 0 ) + { + init_hexbytes_noT(secretBn256str,swap->I.secretBn256,32); + fprintf(fp,",\"secretBn256\":\"%s\"",secretBn256str); + } + for (i=0; i<2; i++) + if ( bits256_nonz(swap->I.myprivs[i]) != 0 ) + fprintf(fp,",\"myprivs%d\":\"%s\"",i,bits256_str(str,swap->I.myprivs[i])); + if ( bits256_nonz(swap->I.privAm) != 0 ) + fprintf(fp,",\"privAm\":\"%s\"",bits256_str(str,swap->I.privAm)); + if ( bits256_nonz(swap->I.privBn) != 0 ) + fprintf(fp,",\"privBn\":\"%s\"",bits256_str(str,swap->I.privBn)); + if ( bits256_nonz(swap->I.pubA0) != 0 ) + fprintf(fp,",\"pubA0\":\"%s\"",bits256_str(str,swap->I.pubA0)); + if ( bits256_nonz(swap->I.pubB0) != 0 ) + fprintf(fp,",\"pubB0\":\"%s\"",bits256_str(str,swap->I.pubB0)); + if ( bits256_nonz(swap->I.pubB1) != 0 ) + fprintf(fp,",\"pubB1\":\"%s\"",bits256_str(str,swap->I.pubB1)); + if ( bits256_nonz(swap->bobdeposit.I.actualtxid) != 0 ) + fprintf(fp,",\"Bdeposit\":\"%s\"",bits256_str(str,swap->bobdeposit.I.actualtxid)); + if ( bits256_nonz(swap->bobrefund.I.actualtxid) != 0 ) + fprintf(fp,",\"Brefund\":\"%s\"",bits256_str(str,swap->bobrefund.I.actualtxid)); + if ( bits256_nonz(swap->aliceclaim.I.actualtxid) != 0 ) + fprintf(fp,",\"Aclaim\":\"%s\"",bits256_str(str,swap->aliceclaim.I.actualtxid)); + + if ( bits256_nonz(swap->bobpayment.I.actualtxid) != 0 ) + fprintf(fp,",\"Bpayment\":\"%s\"",bits256_str(str,swap->bobpayment.I.actualtxid)); + if ( bits256_nonz(swap->alicespend.I.actualtxid) != 0 ) + fprintf(fp,",\"Aspend\":\"%s\"",bits256_str(str,swap->alicespend.I.actualtxid)); + if ( bits256_nonz(swap->bobreclaim.I.actualtxid) != 0 ) + fprintf(fp,",\"Breclaim\":\"%s\"",bits256_str(str,swap->bobreclaim.I.actualtxid)); + + if ( bits256_nonz(swap->alicepayment.I.actualtxid) != 0 ) + fprintf(fp,",\"Apayment\":\"%s\"",bits256_str(str,swap->alicepayment.I.actualtxid)); + if ( bits256_nonz(swap->bobspend.I.actualtxid) != 0 ) + fprintf(fp,",\"Bspend\":\"%s\"",bits256_str(str,swap->bobspend.I.actualtxid)); + if ( bits256_nonz(swap->alicereclaim.I.actualtxid) != 0 ) + fprintf(fp,",\"Areclaim\":\"%s\"",bits256_str(str,swap->alicereclaim.I.actualtxid)); + + if ( bits256_nonz(swap->otherfee.I.actualtxid) != 0 ) + fprintf(fp,",\"otherfee\":\"%s\"",bits256_str(str,swap->otherfee.I.actualtxid)); + if ( bits256_nonz(swap->myfee.I.actualtxid) != 0 ) + fprintf(fp,",\"myfee\":\"%s\"",bits256_str(str,swap->myfee.I.actualtxid)); + fprintf(fp,",\"dest33\":\""); + for (i=0; i<33; i++) + fprintf(fp,"%02x",swap->persistent_pubkey33[i]); + fprintf(fp,"\"}\n"); + fclose(fp); + } +} + +void basilisk_dontforget_update(struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *rawtx) +{ + bits256 triggertxid; + memset(triggertxid.bytes,0,sizeof(triggertxid)); + if ( rawtx == 0 ) + { + basilisk_dontforget(myinfo,swap,0,0,triggertxid); + return; + } + if ( rawtx == &swap->myfee ) + basilisk_dontforget(myinfo,swap,&swap->myfee,0,triggertxid); + else if ( rawtx == &swap->otherfee ) + basilisk_dontforget(myinfo,swap,&swap->otherfee,0,triggertxid); + else if ( rawtx == &swap->bobdeposit ) + { + basilisk_dontforget(myinfo,swap,&swap->bobdeposit,0,triggertxid); + basilisk_dontforget(myinfo,swap,&swap->bobrefund,swap->bobdeposit.I.locktime,triggertxid); + } + else if ( rawtx == &swap->bobrefund ) + basilisk_dontforget(myinfo,swap,&swap->bobrefund,swap->bobdeposit.I.locktime,triggertxid); + else if ( rawtx == &swap->aliceclaim ) + { + basilisk_dontforget(myinfo,swap,&swap->bobrefund,0,triggertxid); + basilisk_dontforget(myinfo,swap,&swap->aliceclaim,0,swap->bobrefund.I.actualtxid); + } + else if ( rawtx == &swap->alicepayment ) + { + basilisk_dontforget(myinfo,swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid); + } + else if ( rawtx == &swap->bobspend ) + { + basilisk_dontforget(myinfo,swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid); + basilisk_dontforget(myinfo,swap,&swap->bobspend,0,swap->alicepayment.I.actualtxid); + } + else if ( rawtx == &swap->alicereclaim ) + { + basilisk_dontforget(myinfo,swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid); + basilisk_dontforget(myinfo,swap,&swap->alicereclaim,0,swap->bobrefund.I.actualtxid); + } + else if ( rawtx == &swap->bobpayment ) + { + basilisk_dontforget(myinfo,swap,&swap->bobpayment,0,triggertxid); + basilisk_dontforget(myinfo,swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid); + } + else if ( rawtx == &swap->alicespend ) + { + basilisk_dontforget(myinfo,swap,&swap->bobpayment,0,triggertxid); + basilisk_dontforget(myinfo,swap,&swap->alicespend,0,triggertxid); + } + else if ( rawtx == &swap->bobreclaim ) + basilisk_dontforget(myinfo,swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid); +} + int32_t basilisk_verify_bobdeposit(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { uint8_t userdata[512]; int32_t i,retval,len = 0; static bits256 zero; struct basilisk_swap *swap = ptr; if ( basilisk_rawtx_spendscript(swap,swap->bobcoin->longestchain,&swap->bobdeposit,0,data,datalen,0) == 0 ) { + swap->bobdeposit.I.signedtxid = basilisk_swap_broadcast(swap->bobdeposit.name,myinfo,swap,swap->bobdeposit.coin,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen); + if ( bits256_nonz(swap->bobdeposit.I.signedtxid) != 0 ) + swap->depositunconf = 1; + basilisk_dontforget_update(myinfo,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; if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->longestchain,swap,&swap->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1)) == 0 ) { for (i=0; ibobdeposit.I.datalen; i++) @@ -705,6 +996,8 @@ int32_t basilisk_bobdeposit_refund(struct supernet_info *myinfo,struct basilisk_ { uint8_t userdata[512]; int32_t i,retval,len = 0; char str[65]; 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(myinfo,swap->bobcoin->longestchain,swap,&swap->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0)) == 0 ) { for (i=0; ibobrefund.I.datalen; i++) @@ -728,6 +1021,8 @@ int32_t basilisk_bobpayment_reclaim(struct supernet_info *myinfo,struct basilisk uint8_t userdata[512]; int32_t i,retval,len = 0; static bits256 zero; printf("basilisk_bobpayment_reclaim\n"); 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(myinfo,swap->bobcoin->longestchain,swap,&swap->bobreclaim,&swap->bobpayment,swap->I.myprivs[1],0,userdata,len,1)) == 0 ) { for (i=0; ibobreclaim.I.datalen; i++) @@ -745,9 +1040,15 @@ int32_t basilisk_verify_bobpaid(struct supernet_info *myinfo,void *ptr,uint8_t * memset(revAm.bytes,0,sizeof(revAm)); if ( basilisk_rawtx_spendscript(swap,swap->bobcoin->longestchain,&swap->bobpayment,0,data,datalen,0) == 0 ) { + swap->bobpayment.I.signedtxid = basilisk_swap_broadcast(swap->bobpayment.name,myinfo,swap,swap->bobpayment.coin,swap->bobpayment.txbytes,swap->bobpayment.I.datalen); + if ( bits256_nonz(swap->bobpayment.I.signedtxid) != 0 ) + swap->paymentunconf = 1; + basilisk_dontforget_update(myinfo,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); + memcpy(swap->I.userdata_alicespend,userdata,len); + swap->I.userdata_alicespendlen = len; 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(myinfo,swap->bobcoin->longestchain,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1)) == 0 ) { @@ -777,6 +1078,16 @@ int32_t basilisk_alicepayment_spend(struct supernet_info *myinfo,struct basilisk printf("alicepayment_spend\n"); swap->alicepayment.I.spendlen = basilisk_alicescript(swap->alicepayment.redeemscript,&swap->alicepayment.I.redeemlen,swap->alicepayment.spendscript,0,swap->alicepayment.I.destaddr,swap->alicecoin->chain->p2shtype,swap->I.pubAm,swap->I.pubBn); printf("alicepayment_spend len.%d\n",swap->alicepayment.I.spendlen); + if ( swap->I.iambob == 0 ) + { + memcpy(swap->I.userdata_alicereclaim,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen); + swap->I.userdata_alicereclaimlen = swap->alicepayment.I.spendlen; + } + else + { + memcpy(swap->I.userdata_bobspend,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen); + swap->I.userdata_bobspendlen = swap->alicepayment.I.spendlen; + } if ( (retval= basilisk_rawtx_sign(myinfo,swap->alicecoin->longestchain,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1)) == 0 ) { for (i=0; iI.datalen; i++) @@ -790,101 +1101,17 @@ int32_t basilisk_alicepayment_spend(struct supernet_info *myinfo,struct basilisk return(-1); } -int32_t basilisk_bobpayment_spendclone(struct supernet_info *myinfo,struct iguana_info *bobcoin,struct basilisk_rawtx *dest,struct basilisk_rawtx *src,uint32_t swapstarted,uint8_t *changepubkey33,uint32_t quoteid,uint64_t amount,bits256 privAm,bits256 myprivs0,uint8_t *data,int32_t datalen,int32_t jumblrflag) -{ - bits256 revAm; uint8_t userdata[512]; int32_t i,len,numconfirms = 0,retval = -1; uint32_t sequenceid = 0xffffffff; - basilisk_rawtx_setparms("bobpayment",quoteid,src,bobcoin,numconfirms,0,amount,3,0,jumblrflag); - dest->I.suppress_pubkeys = 1; - basilisk_rawtx_gen("bobpayment",myinfo,swapstarted,changepubkey33,1,1,src,src->I.locktime,src->spendscript,src->I.spendlen,bobcoin->chain->txfee,1,0); - if ( basilisk_rawtx_spendscript(0,bobcoin->longestchain,src,0,data,datalen,0) == 0 ) - { - memset(revAm.bytes,0,sizeof(revAm)); - for (i=0; i<32; i++) - revAm.bytes[i] = privAm.bytes[31-i]; - len = basilisk_swapuserdata(userdata,revAm,0,myprivs0,src->redeemscript,src->I.redeemlen); - if ( (retval= _basilisk_rawtx_sign(myinfo,bobcoin->longestchain,swapstarted,src->I.locktime,sequenceid,dest,src,myprivs0,0,userdata,len,1)) == 0 ) - { - } - } - return(retval); -} - -int32_t basilisk_bobpayment_reclaimclone(struct supernet_info *myinfo,struct iguana_info *bobcoin,struct basilisk_rawtx *dest,struct basilisk_rawtx *src,uint32_t swapstarted,uint8_t *changepubkey33,uint32_t quoteid,uint64_t amount,bits256 myprivs1,uint8_t *data,int32_t datalen,int32_t jumblrflag) -{ - bits256 zero; uint8_t userdata[512]; int32_t len,numconfirms = 0,retval = -1; uint32_t sequenceid = 0xffffffff; - basilisk_rawtx_setparms("bobpayment",quoteid,src,bobcoin,numconfirms,0,amount,3,0,jumblrflag); - dest->I.suppress_pubkeys = 1; - basilisk_rawtx_gen("bobpayment",myinfo,swapstarted,changepubkey33,1,1,src,src->I.locktime,src->spendscript,src->I.spendlen,bobcoin->chain->txfee,1,0); - if ( basilisk_rawtx_spendscript(0,bobcoin->longestchain,src,0,data,datalen,0) == 0 ) - { - memset(zero.bytes,0,sizeof(zero)); - len = basilisk_swapuserdata(userdata,zero,1,myprivs1,src->redeemscript,src->I.redeemlen); - if ( (retval= _basilisk_rawtx_sign(myinfo,bobcoin->longestchain,swapstarted,src->I.locktime,sequenceid,dest,src,myprivs1,0,userdata,len,1)) == 0 ) - { - } - } - return(retval); -} - -int32_t basilisk_bobdeposit_refundclone(struct supernet_info *myinfo,struct iguana_info *bobcoin,struct basilisk_rawtx *dest,struct basilisk_rawtx *src,uint32_t swapstarted,uint8_t *changepubkey33,uint32_t quoteid,uint64_t amount,bits256 myprivs0,bits256 privBn,uint8_t *data,int32_t datalen,int32_t jumblrflag) -{ - uint8_t userdata[512]; int32_t len,numconfirms = 0,retval = -1; uint32_t sequenceid = 0xffffffff; - basilisk_rawtx_setparms("bobdeposit",quoteid,src,bobcoin,numconfirms,0,amount,4,0,jumblrflag); - dest->I.suppress_pubkeys = 1; - basilisk_rawtx_gen("bobdeposit",myinfo,swapstarted,changepubkey33,1,1,src,src->I.locktime,src->spendscript,src->I.spendlen,bobcoin->chain->txfee,1,0); - if ( basilisk_rawtx_spendscript(0,bobcoin->longestchain,src,0,data,datalen,0) == 0 ) - { - len = basilisk_swapuserdata(userdata,privBn,0,myprivs0,src->redeemscript,src->I.redeemlen); - if ( (retval= _basilisk_rawtx_sign(myinfo,bobcoin->longestchain,swapstarted,src->I.locktime,sequenceid,dest,src,myprivs0,0,userdata,len,0)) == 0 ) - { - } - } - return(retval); -} - -int32_t basilisk_bobdeposit_claimclone(struct supernet_info *myinfo,struct iguana_info *bobcoin,struct basilisk_rawtx *dest,struct basilisk_rawtx *src,uint32_t swapstarted,uint8_t *changepubkey33,uint32_t quoteid,uint64_t amount,bits256 myprivs0,uint8_t *data,int32_t datalen,int32_t jumblrflag) -{ - bits256 zero; uint8_t userdata[512]; int32_t len,numconfirms = 0,retval = -1; uint32_t sequenceid = 0xffffffff; - basilisk_rawtx_setparms("bobdeposit",quoteid,src,bobcoin,numconfirms,0,amount,4,0,jumblrflag); - dest->I.suppress_pubkeys = 1; - basilisk_rawtx_gen("bobdeposit",myinfo,swapstarted,changepubkey33,1,1,src,src->I.locktime,src->spendscript,src->I.spendlen,bobcoin->chain->txfee,1,0); - if ( basilisk_rawtx_spendscript(0,bobcoin->longestchain,src,0,data,datalen,0) == 0 ) - { - memset(zero.bytes,0,sizeof(zero)); - len = basilisk_swapuserdata(userdata,zero,1,myprivs0,src->redeemscript,src->I.redeemlen); - if ( (retval= _basilisk_rawtx_sign(myinfo,bobcoin->longestchain,swapstarted,src->I.locktime,sequenceid,dest,src,myprivs0,0,userdata,len,1)) == 0 ) - { - } - } - return(retval); -} - -//basilisk_alicepayment_clone(myinfo,&dest,&src,swapstarted,changepubkey33,alicecoin,quoteid,amount,privAm,pubAm,privBn,pubBn); - -int32_t basilisk_alicepayment_spendclone(struct supernet_info *myinfo,struct iguana_info *alicecoin,struct basilisk_rawtx *dest,struct basilisk_rawtx *src,uint32_t swapstarted,uint8_t *changepubkey33,uint32_t quoteid,uint64_t amount,bits256 privAm,bits256 privBn,int32_t jumblrflag) -{ - uint8_t pubAm33[33],pubBn33[33]; bits256 pubAm,pubBn; int32_t retval,numconfirms = 0; uint32_t sequenceid = 0xffffffff; - bitcoin_pubkey33(myinfo->ctx,pubAm33,privAm); - memcpy(pubAm.bytes,pubAm33+1,32); - bitcoin_pubkey33(myinfo->ctx,pubBn33,privBn); - memcpy(pubBn.bytes,pubBn33+1,32); - memset(src,0,sizeof(*src)); - memset(dest,0,sizeof(*dest)); - basilisk_rawtx_setparms("alicepayment",quoteid,src,alicecoin,numconfirms,0,amount,2,0,jumblrflag); - src->I.spendlen = basilisk_alicescript(src->redeemscript,&src->I.redeemlen,src->spendscript,0,src->I.destaddr,alicecoin->chain->p2shtype,pubAm,pubBn); - basilisk_rawtx_gen("alicepayment",myinfo,swapstarted,changepubkey33,0,1,src,src->I.locktime,src->spendscript,src->I.spendlen,alicecoin->chain->txfee,1,0); - if ( (retval= _basilisk_rawtx_sign(myinfo,alicecoin->longestchain,swapstarted,src->I.locktime,sequenceid,dest,src,privAm,&privBn,0,0,1)) == 0 ) - { - - } - return(retval); -} - int32_t basilisk_verify_alicepaid(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { struct basilisk_swap *swap = ptr; if ( basilisk_rawtx_spendscript(swap,swap->alicecoin->longestchain,&swap->alicepayment,0,data,datalen,0) == 0 ) + { + swap->alicepayment.I.signedtxid = basilisk_swap_broadcast(swap->alicepayment.name,myinfo,swap,swap->alicepayment.coin,swap->alicepayment.txbytes,swap->alicepayment.I.datalen); + if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 ) + swap->aliceunconf = 1; + basilisk_dontforget_update(myinfo,swap,&swap->alicepayment); return(0); + } else return(-1); } @@ -917,6 +1144,7 @@ int32_t basilisk_bobscripts_set(struct supernet_info *myinfo,struct basilisk_swa if ( depositflag == 0 ) { swap->bobpayment.I.spendlen = basilisk_bobscript(swap->bobpayment.I.rmd160,swap->bobpayment.redeemscript,&swap->bobpayment.I.redeemlen,swap->bobpayment.spendscript,0,&swap->bobpayment.I.locktime,&swap->bobpayment.I.secretstart,&swap->I,0); + bitcoin_address(swap->bobpayment.p2shaddr,swap->bobcoin->chain->p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); //for (i=0; ibobpayment.redeemlen; i++) // printf("%02x",swap->bobpayment.redeemscript[i]); //printf(" <- bobpayment.%d\n",i); @@ -952,6 +1180,7 @@ int32_t basilisk_bobscripts_set(struct supernet_info *myinfo,struct basilisk_swa else { swap->bobdeposit.I.spendlen = basilisk_bobscript(swap->bobdeposit.I.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.I.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.I.locktime,&swap->bobdeposit.I.secretstart,&swap->I,1); + bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin->chain->p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); if ( genflag != 0 && (swap->bobdeposit.I.datalen == 0 || swap->bobrefund.I.datalen == 0) ) { for (i=0; i<3; i++) @@ -1013,6 +1242,7 @@ int32_t basilisk_verify_privi(struct supernet_info *myinfo,void *ptr,uint8_t *da vcalc_sha256(0,swap->I.secretBn256,privkey.bytes,sizeof(privkey)); printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256)); } + basilisk_dontforget_update(myinfo,swap,0); char str[65]; printf("privi verified.(%s)\n",bits256_str(str,privkey)); return(0); } @@ -1034,7 +1264,7 @@ void basilisk_swapgotdata(struct supernet_info *myinfo,struct basilisk_swap *swa for (i=0; inummessages; i++) if ( crc32 == swap->messages[i].crc32 && msgbits == swap->messages[i].msgbits && bits256_cmp(srchash,swap->messages[i].srchash) == 0 && bits256_cmp(desthash,swap->messages[i].desthash) == 0 ) return; - printf(" new message.[%d] datalen.%d Q.%x msg.%x [%llx]\n",swap->nummessages,datalen,quoteid,msgbits,*(long long *)data); + //printf(" new message.[%d] datalen.%d Q.%x msg.%x [%llx]\n",swap->nummessages,datalen,quoteid,msgbits,*(long long *)data); swap->messages = realloc(swap->messages,sizeof(*swap->messages) * (swap->nummessages + 1)); mp = &swap->messages[swap->nummessages++]; mp->crc32 = crc32; @@ -1055,7 +1285,7 @@ void basilisk_swapgotdata(struct supernet_info *myinfo,struct basilisk_swap *swa FILE *basilisk_swap_save(struct supernet_info *myinfo,struct basilisk_swap *swap,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit) { - FILE *fp=0; char fname[512]; + FILE *fp=0; /*char fname[512]; sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,rp->requestid,rp->quoteid), OS_compatible_path(fname); if ( (fp= fopen(fname,"rb+")) == 0 ) { @@ -1070,7 +1300,7 @@ FILE *basilisk_swap_save(struct supernet_info *myinfo,struct basilisk_swap *swap } else if ( reinit != 0 ) { - } + }*/ return(fp); } @@ -1120,20 +1350,22 @@ void basilisk_swaps_init(struct supernet_info *myinfo) if ( M.datalen < 100000 ) { M.data = malloc(M.datalen); - fread(M.data,1,M.datalen,fp); - if ( calc_crc32(0,M.data,M.datalen) == M.crc32 ) + if ( fread(M.data,1,M.datalen,fp) == M.datalen ) { - if ( iter == 1 ) + if ( calc_crc32(0,M.data,M.datalen) == M.crc32 ) { - if ( swap == 0 ) + if ( iter == 1 ) { - swap = basilisk_thread_start(myinfo,privkey,&R,statebits,optionduration,1); - swap->I.choosei = swap->I.otherchoosei = -1; + if ( swap == 0 ) + { + swap = basilisk_thread_start(myinfo,privkey,&R,statebits,optionduration,1); + swap->I.choosei = swap->I.otherchoosei = -1; + } + if ( swap != 0 ) + basilisk_swapgotdata(myinfo,swap,M.crc32,M.srchash,M.desthash,M.quoteid,M.msgbits,M.data,M.datalen,1); } - if ( swap != 0 ) - basilisk_swapgotdata(myinfo,swap,M.crc32,M.srchash,M.desthash,M.quoteid,M.msgbits,M.data,M.datalen,1); - } - } else printf("crc mismatch %x vs %x\n",calc_crc32(0,M.data,M.datalen),M.crc32); + } else printf("crc mismatch %x vs %x\n",calc_crc32(0,M.data,M.datalen),M.crc32); + } else printf("error reading M.datalen %d\n",M.datalen); free(M.data), M.data = 0; } } @@ -1144,7 +1376,7 @@ void basilisk_swaps_init(struct supernet_info *myinfo) } } } - } + } else myinfo->swapsfp = fopen(fname,"wb+"); } void basilisk_psockinit(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t amlp); @@ -1165,12 +1397,23 @@ int32_t basilisk_swapget(struct supernet_info *myinfo,struct basilisk_swap *swap desthash.bytes[i] = ptr[offset++]; offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),"eid); offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&_msgbits); - crc32 = calc_crc32(0,&ptr[offset],size-offset); if ( size > offset ) { - //printf("size.%d offset.%d datalen.%d\n",size,offset,size-offset); - basilisk_swapgotdata(myinfo,swap,crc32,srchash,desthash,quoteid,_msgbits,&ptr[offset],size-offset,0); + crc32 = calc_crc32(0,&ptr[offset],size-offset); + if ( size > offset ) + { + //printf("size.%d offset.%d datalen.%d\n",size,offset,size-offset); + basilisk_swapgotdata(myinfo,swap,crc32,srchash,desthash,quoteid,_msgbits,&ptr[offset],size-offset,0); + } } + else if ( bits256_nonz(srchash) == 0 && bits256_nonz(desthash) == 0 ) + { + if ( swap->aborted == 0 ) + { + swap->aborted = (uint32_t)time(NULL); + printf("got abort signal from other side\n"); + } + } else printf("basilisk_swapget: got strange packet\n"); if ( ptr != 0 ) nn_freemsg(ptr), ptr = 0; } @@ -1185,12 +1428,12 @@ int32_t basilisk_swapget(struct supernet_info *myinfo,struct basilisk_swap *swap if ( swap->I.iambob == 0 && swap->lasttime != 0 && time(NULL) > swap->lasttime+360 ) { printf("nothing received for a while from Bob, try new sockets\n"); - if ( swap->pushsock >= 0 ) + if ( swap->pushsock >= 0 ) // nn_close(swap->pushsock), swap->pushsock = -1; - if ( swap->subsock >= 0 ) + if ( swap->subsock >= 0 ) // nn_close(swap->subsock), swap->subsock = -1; swap->connected = 0; - basilisk_psockinit(myinfo,swap,0); + basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); } mp = &swap->messages[i]; if ( msgbits != 0x80000000 ) @@ -1222,10 +1465,11 @@ uint32_t basilisk_swapsend(struct supernet_info *myinfo,struct basilisk_swap *sw if ( sentbytes < 0 ) { if ( swap->pushsock >= 0 ) - nn_close(swap->pushsock), swap->pushsock = -1; - if ( swap->subsock >= 0 ) + nn_close(swap->pushsock), swap->pushsock = -1; //, + if ( swap->subsock >= 0 ) // nn_close(swap->subsock), swap->subsock = -1; - swap->connected = 0; + swap->connected = swap->I.iambob != 0 ? -1 : 0; + swap->aborted = (uint32_t)time(NULL); } } //else printf("send.[%d] %x offset.%d datalen.%d [%llx]\n",sentbytes,msgbits,offset,datalen,*(long long *)data); @@ -1233,26 +1477,23 @@ uint32_t basilisk_swapsend(struct supernet_info *myinfo,struct basilisk_swap *sw return(nextbits); } -int32_t basilisk_priviextract(struct supernet_info *myinfo,struct iguana_info *coin,char *name,bits256 *destp,uint8_t secret160[20],bits256 srctxid,int32_t srcvout) +void basilisk_swap_sendabort(struct supernet_info *myinfo,struct basilisk_swap *swap) { - bits256 txid,privkey; char str[65]; int32_t i,vini,scriptlen; uint8_t rmd160[20],scriptsig[IGUANA_MAXSCRIPTSIZE]; - memset(privkey.bytes,0,sizeof(privkey)); - if ( (vini= iguana_vinifind(myinfo,coin,&txid,srctxid,srcvout)) >= 0 ) + uint32_t msgbits = 0; uint8_t buf[sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2]; int32_t sentbytes,offset=0; + memset(buf,0,sizeof(buf)); + offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); + offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits); + if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset ) { - if ( (scriptlen= iguana_scriptsigextract(myinfo,coin,scriptsig,sizeof(scriptsig),txid,vini)) > 0 ) + if ( sentbytes < 0 ) { - for (i=0; i<32; i++) - privkey.bytes[i] = scriptsig[scriptlen - 33 + i]; - revcalc_rmd160_sha256(rmd160,privkey);//.bytes,sizeof(privkey)); - if ( memcmp(secret160,rmd160,sizeof(rmd160)) == sizeof(rmd160) ) - { - *destp = privkey; - printf("found privi %s (%s)\n",name,bits256_str(str,privkey)); - return(0); - } + if ( swap->pushsock >= 0 ) // + nn_close(swap->pushsock), swap->pushsock = -1; + if ( swap->subsock >= 0 ) // + nn_close(swap->subsock), swap->subsock = -1; + swap->connected = 0; } - } - return(-1); + } else printf("basilisk_swap_sendabort\n"); } int32_t basilisk_privBn_extract(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) @@ -1261,13 +1502,13 @@ int32_t basilisk_privBn_extract(struct supernet_info *myinfo,struct basilisk_swa { printf("extracted privBn from blockchain\n"); } - if ( basilisk_swapget(myinfo,swap,0x40000000,data,maxlen,basilisk_verify_privi) == 0 ) + else if ( basilisk_swapget(myinfo,swap,0x40000000,data,maxlen,basilisk_verify_privi) == 0 ) { - if ( bits256_nonz(swap->I.privBn) != 0 && swap->alicereclaim.I.datalen == 0 ) - { - char str[65]; printf("have privBn.%s\n",bits256_str(str,swap->I.privBn)); - return(basilisk_alicepayment_spend(myinfo,swap,&swap->alicereclaim)); - } + } + if ( bits256_nonz(swap->I.privBn) != 0 && swap->alicereclaim.I.datalen == 0 ) + { + char str[65]; printf("got privBn.%s\n",bits256_str(str,swap->I.privBn)); + return(basilisk_alicepayment_spend(myinfo,swap,&swap->alicereclaim)); } return(-1); } @@ -1276,11 +1517,11 @@ int32_t basilisk_privAm_extract(struct supernet_info *myinfo,struct basilisk_swa { if ( basilisk_priviextract(myinfo,swap->bobcoin,"privAm",&swap->I.privAm,swap->I.secretAm,swap->bobpayment.I.actualtxid,0) == 0 ) { - + printf("extracted privAm from blockchain\n"); } if ( bits256_nonz(swap->I.privAm) != 0 && swap->bobspend.I.datalen == 0 ) { - char str[65]; printf("have privAm.%s\n",bits256_str(str,swap->I.privAm)); + char str[65]; printf("got privAm.%s\n",bits256_str(str,swap->I.privAm)); return(basilisk_alicepayment_spend(myinfo,swap,&swap->bobspend)); } return(-1); @@ -1363,12 +1604,9 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx * rawtx->I.vouttype = vouttype; // 0 -> fee, 1 -> std, 2 -> 2of2, 3 -> bobpayment, 4 -> bobdeposit if ( rawtx->I.vouttype == 0 ) { - if ( jumblrflag == 0 ) - { - if ( strcmp(coin->symbol,"BTC") == 0 && (quoteid % 10) == 0 ) - decode_hex(rawtx->I.rmd160,20,TIERNOLAN_RMD160); - else decode_hex(rawtx->I.rmd160,20,INSTANTDEX_RMD160); - } else decode_hex(rawtx->I.rmd160,20,JUMBLR_RMD160); + if ( strcmp(coin->symbol,"BTC") == 0 && (quoteid % 10) == 0 ) + decode_hex(rawtx->I.rmd160,20,TIERNOLAN_RMD160); + else decode_hex(rawtx->I.rmd160,20,INSTANTDEX_RMD160); bitcoin_address(rawtx->I.destaddr,rawtx->coin->chain->pubtype,rawtx->I.rmd160,20); } if ( pubkey33 != 0 ) @@ -1456,14 +1694,15 @@ int32_t basilisk_swap_loadtx(struct basilisk_rawtx *rawtx,FILE *fp,char *bobcoin struct basilisk_swap *bitcoin_swapinit(struct supernet_info *myinfo,bits256 privkey,uint8_t *pubkey33,bits256 pubkey25519,struct basilisk_swap *swap,int32_t optionduration,uint32_t statebits,int32_t reinit) { - FILE *fp; char fname[512]; uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag,x = -1; + FILE *fp; char fname[512]; uint8_t *alicepub33=0,*bobpub33=0; int32_t errs=0,jumblrflag,x = -1; if ( reinit != 0 ) { sprintf(fname,"%s/SWAPS/%u-%u.swap",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname); printf("reinit.(%s)\n",fname); if ( (fp= fopen(fname,"rb")) != 0 ) { - fread(&swap->I,1,sizeof(swap->I),fp); + if ( fread(&swap->I,1,sizeof(swap->I),fp) != sizeof(swap->I) ) + errs++; if ( swap->bobcoin == 0 ) swap->bobcoin = iguana_coinfind(swap->I.req.dest); if ( swap->alicecoin == 0 ) @@ -1482,9 +1721,12 @@ struct basilisk_swap *bitcoin_swapinit(struct supernet_info *myinfo,bits256 priv basilisk_swap_loadtx(&swap->bobrefund,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); basilisk_swap_loadtx(&swap->alicereclaim,fp,swap->bobcoin->symbol,swap->alicecoin->symbol);*/ } else printf("missing coins (%p %p)\n",swap->bobcoin,swap->alicecoin); - fread(swap->privkeys,1,sizeof(swap->privkeys),fp); - fread(swap->otherdeck,1,sizeof(swap->otherdeck),fp); - fread(swap->deck,1,sizeof(swap->deck),fp); + if ( fread(swap->privkeys,1,sizeof(swap->privkeys),fp) != sizeof(swap->privkeys) ) + errs++; + if ( fread(swap->otherdeck,1,sizeof(swap->otherdeck),fp) != sizeof(swap->otherdeck) ) + errs++; + if ( fread(swap->deck,1,sizeof(swap->deck),fp) != sizeof(swap->deck) ) + errs++; fclose(fp); } else printf("cant find.(%s)\n",fname); } @@ -1535,23 +1777,37 @@ struct basilisk_swap *bitcoin_swapinit(struct supernet_info *myinfo,bits256 priv free(swap); return(0); } - swap->I.bobconfirms = (1*0 + sqrt(dstr(swap->I.bobsatoshis) * .1)); - swap->I.aliceconfirms = swap->I.bobconfirms * 3; - if ( swap->I.bobconfirms == 0 ) + if ( strcmp("BTC",swap->bobcoin->symbol) == 0 ) + { + swap->I.bobconfirms = (1*0 + sqrt(dstr(swap->I.bobsatoshis) * .1)); + swap->I.aliceconfirms = MIN(BASILISK_DEFAULT_NUMCONFIRMS,swap->I.bobconfirms * 3); + } + else if ( strcmp("BTC",swap->alicecoin->symbol) == 0 ) + { + swap->I.aliceconfirms = (1*0 + sqrt(dstr(swap->I.alicesatoshis) * .1)); + swap->I.bobconfirms = MIN(BASILISK_DEFAULT_NUMCONFIRMS,swap->I.bobconfirms * 3); + } + else + { + swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS; + swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS; + } + /*if ( swap->I.bobconfirms == 0 ) swap->I.bobconfirms = swap->bobcoin->chain->minconfirms; if ( swap->I.aliceconfirms == 0 ) - swap->I.aliceconfirms = swap->alicecoin->chain->minconfirms; + swap->I.aliceconfirms = swap->alicecoin->chain->minconfirms;*/ jumblrflag = (bits256_cmp(pubkey25519,myinfo->jumblr_pubkey) == 0 || bits256_cmp(pubkey25519,myinfo->jumblr_depositkey) == 0); + printf(">>>>>>>>>> jumblrflag.%d <<<<<<<<< use smart address, %.8f bobconfs.%d, %.8f aliceconfs.%d\n",jumblrflag,dstr(swap->I.bobsatoshis),swap->I.bobconfirms,dstr(swap->I.alicesatoshis),swap->I.aliceconfirms); if ( swap->I.iambob != 0 ) { - basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,swap->bobcoin,0,0,swap->I.bobsatoshis/INSTANTDEX_DECKSIZE,0,0,jumblrflag); - basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,swap->alicecoin,0,0,swap->I.alicesatoshis/INSTANTDEX_DECKSIZE,0,0,jumblrflag); + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,swap->bobcoin,0,0,swap->I.bobsatoshis/INSTANTDEX_INSURANCEDIV,0,0,jumblrflag); + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,swap->alicecoin,0,0,swap->I.alicesatoshis/INSTANTDEX_INSURANCEDIV,0,0,jumblrflag); bobpub33 = pubkey33; } else { - basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,swap->bobcoin,0,0,swap->I.bobsatoshis/INSTANTDEX_DECKSIZE,0,0,jumblrflag); - basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,swap->alicecoin,0,0,swap->I.alicesatoshis/INSTANTDEX_DECKSIZE,0,0,jumblrflag); + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,swap->bobcoin,0,0,swap->I.bobsatoshis/INSTANTDEX_INSURANCEDIV,0,0,jumblrflag); + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,swap->alicecoin,0,0,swap->I.alicesatoshis/INSTANTDEX_INSURANCEDIV,0,0,jumblrflag); alicepub33 = pubkey33; } basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + (swap->I.bobsatoshis>>3) + swap->bobcoin->txfee,4,0,jumblrflag); @@ -1567,13 +1823,13 @@ struct basilisk_swap *bitcoin_swapinit(struct supernet_info *myinfo,bits256 priv basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag); swap->bobreclaim.I.suppress_pubkeys = 1; swap->bobreclaim.I.locktime = swap->I.started + swap->I.putduration + 1; - basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis+swap->alicecoin->txfee,2,0,jumblrflag); basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag); swap->bobspend.I.suppress_pubkeys = 1; basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag); swap->alicereclaim.I.suppress_pubkeys = 1; printf("IAMBOB.%d\n",swap->I.iambob); + return(swap); } // end of alice/bob code @@ -1613,7 +1869,7 @@ void basilisk_swap_purge(struct supernet_info *myinfo,struct basilisk_swap *swap { int32_t i,n; // while still in orderbook, wait - return; + //return; portable_mutex_lock(&myinfo->DEX_swapmutex); n = myinfo->numswaps; for (i=0; iI.statebits) ) + { + retval = iguana_rwnum(0,data,sizeof(swap->I.statebits),&statebits); + if ( statebits != swap->I.statebits ) + { + printf("statebits.%x != %x\n",statebits,swap->I.statebits); + return(-1); + } + } + return(retval); +} + int32_t basilisk_verify_choosei(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { int32_t otherchoosei=-1,i,len = 0; struct basilisk_swap *swap = ptr; @@ -1733,39 +2004,20 @@ int32_t basilisk_verify_privkeys(struct supernet_info *myinfo,void *ptr,uint8_t return(errs); } -void basilisk_dontforget(struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,int32_t locktime,bits256 triggertxid) +uint32_t basilisk_swapdata_rawtxsend(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend) { - char fname[512],str[65]; FILE *fp; int32_t i; - sprintf(fname,"%s/SWAPS/%u-%u.%s",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid,rawtx->name), OS_compatible_path(fname); - if ( (fp= fopen(fname,"wb")) != 0 ) + uint8_t sendbuf[32768]; int32_t sendlen; + if ( basilisk_swapdata_rawtx(myinfo,swap,data,maxlen,rawtx) != 0 ) { - fprintf(fp,"{\"name\":\"%s\",\"coin\":\"%s\"",rawtx->name,rawtx->coin->symbol); - if ( rawtx->I.datalen > 0 ) - { - fprintf(fp,",\"tx\":\""); - for (i=0; iI.datalen; i++) - fprintf(fp,"%02x",rawtx->txbytes[i]); - fprintf(fp,"\",\"txid\":\"%s\"",bits256_str(str,bits256_doublesha256(0,rawtx->txbytes,rawtx->I.datalen))); - } - fprintf(fp,",\"lock\":%u",locktime); - if ( bits256_nonz(triggertxid) != 0 ) - fprintf(fp,",\"trigger\":\"%s\"",bits256_str(str,triggertxid)); - fprintf(fp,"}\n"); - fclose(fp); - } -} - -uint32_t basilisk_swapdata_rawtxsend(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend) -{ - uint8_t sendbuf[32768]; int32_t sendlen; bits256 triggertxid; - if ( basilisk_swapdata_rawtx(myinfo,swap,data,maxlen,rawtx) != 0 ) - { - if ( bits256_nonz(rawtx->I.signedtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) + if ( bits256_nonz(rawtx->I.signedtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) { char str[65],str2[65]; rawtx->I.actualtxid = basilisk_swap_broadcast(rawtx->name,myinfo,swap,rawtx->coin,rawtx->txbytes,rawtx->I.datalen); if ( bits256_cmp(rawtx->I.actualtxid,rawtx->I.signedtxid) != 0 ) + { printf("%s rawtxsend %s vs %s\n",rawtx->name,bits256_str(str,rawtx->I.signedtxid),bits256_str(str2,rawtx->I.actualtxid)); + rawtx->I.actualtxid = rawtx->I.signedtxid; + } if ( bits256_nonz(rawtx->I.actualtxid) != 0 && msgbits != 0 ) { sendlen = 0; @@ -1778,35 +2030,7 @@ uint32_t basilisk_swapdata_rawtxsend(struct supernet_info *myinfo,struct basilis memcpy(&sendbuf[sendlen],rawtx->redeemscript,rawtx->I.redeemlen); sendlen += rawtx->I.redeemlen; } - memset(triggertxid.bytes,0,sizeof(triggertxid)); - if ( swap->I.iambob != 0 ) - { - if ( rawtx == &swap->bobdeposit ) - { - basilisk_dontforget(myinfo,swap,&swap->bobdeposit,0,triggertxid); - basilisk_dontforget(myinfo,swap,&swap->bobrefund,0,triggertxid); - } - else if ( rawtx == &swap->bobpayment ) - { - basilisk_dontforget(myinfo,swap,&swap->bobpayment,0,triggertxid); - basilisk_dontforget(myinfo,swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid); - } - else if ( rawtx == &swap->bobspend ) - basilisk_dontforget(myinfo,swap,&swap->bobspend,0,triggertxid); - } - else - { - if ( rawtx == &swap->alicepayment ) - { - basilisk_dontforget(myinfo,swap,&swap->alicepayment,0,triggertxid); - } - else if ( rawtx == &swap->alicespend ) - { - basilisk_dontforget(myinfo,swap,&swap->alicespend,0,triggertxid); - //basilisk_alicepayment_spend(myinfo,swap,&swap->alicereclaim); - basilisk_dontforget(myinfo,swap,&swap->alicereclaim,0,swap->bobrefund.I.actualtxid); - } - } + basilisk_dontforget_update(myinfo,swap,rawtx); //printf("sendlen.%d datalen.%d redeemlen.%d\n",sendlen,rawtx->datalen,rawtx->redeemlen); if ( suppress_swapsend == 0 ) return(basilisk_swapsend(myinfo,swap,msgbits,sendbuf,sendlen,nextbits,rawtx->I.crcs)); @@ -1818,7 +2042,8 @@ uint32_t basilisk_swapdata_rawtxsend(struct supernet_info *myinfo,struct basilis } } return(nextbits); - } else printf("error from basilisk_swapdata_rawtx.%s %p len.%d\n",rawtx->name,rawtx->txbytes,rawtx->I.datalen); + } else if ( swap->I.iambob == 0 ) + printf("error from basilisk_swapdata_rawtx.%s %p len.%d\n",rawtx->name,rawtx->txbytes,rawtx->I.datalen); return(0); } @@ -1941,13 +2166,15 @@ void basilisk_sendmostprivs(struct supernet_info *myinfo,struct basilisk_swap *s int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { - int32_t j,datalen,retval = 0; - while ( ((swap->I.otherstatebits & 0x80) == 0 || (swap->I.statebits & 0x80) == 0) && retval == 0 && time(NULL) < swap->I.expiration ) + int32_t j,datalen,retval = 0; uint32_t savestatebits=0,saveotherbits=0; + if ( swap->I.iambob != 0 ) + swap->I.statebits |= 0x80; + while ( swap->aborted == 0 && ((swap->I.otherstatebits & 0x80) == 0 || (swap->I.statebits & 0x80) == 0) && retval == 0 && time(NULL) < swap->I.expiration ) { if ( swap->connected == 0 ) basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); - printf("D r%u/q%u swapstate.%x otherstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits); - if ( (swap->I.statebits & 0x80) == 0 ) // wait for fee + printf("D r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL))); + if ( swap->I.iambob != 0 && (swap->I.statebits & 0x80) == 0 ) // wait for fee { if ( basilisk_swapget(myinfo,swap,0x80,data,maxlen,basilisk_verify_otherfee) == 0 ) { @@ -1956,24 +2183,29 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap basilisk_sendstate(myinfo,swap,data,maxlen); } } + else if ( swap->I.iambob == 0 ) + swap->I.statebits |= 0x80; basilisk_sendstate(myinfo,swap,data,maxlen); basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); if ( (swap->I.otherstatebits & 0x80) != 0 && (swap->I.statebits & 0x80) != 0 ) break; - sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); basilisk_sendstate(myinfo,swap,data,maxlen); if ( (swap->I.otherstatebits & 0x80) == 0 ) basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40,0); } basilisk_swap_saveupdate(myinfo,swap); - while ( retval == 0 && time(NULL) < swap->I.expiration ) // both sides have setup required data and paid txfee + while ( swap->aborted == 0 && retval == 0 && time(NULL) < swap->I.expiration ) // both sides have setup required data and paid txfee { basilisk_swap_saveupdate(myinfo,swap); if ( swap->connected == 0 ) basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); //if ( (rand() % 30) == 0 ) - printf("E r%u/q%u swapstate.%x otherstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits); + printf("E r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL))); if ( swap->I.iambob != 0 ) { //printf("BOB\n"); @@ -1994,7 +2226,7 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap } else if ( (swap->I.statebits & 0x2000) == 0 ) { - if ( basilisk_numconfirms(myinfo,swap,&swap->alicepayment) >= swap->I.aliceconfirms ) + if ( (swap->I.aliceconfirms == 0 && swap->aliceunconf != 0) || basilisk_numconfirms(myinfo,swap,&swap->alicepayment) >= swap->I.aliceconfirms ) { swap->I.statebits |= 0x2000; printf("alicepayment confirmed\n"); @@ -2018,13 +2250,13 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap else { tradebot_swap_balancingtrade(myinfo,swap,1); - printf("Bob spends alicepayment\n"); + printf("Bob spends alicepayment aliceconfirms.%d\n",swap->I.aliceconfirms); swap->I.statebits |= 0x40000; - while ( basilisk_numconfirms(myinfo,swap,&swap->bobspend) < swap->I.aliceconfirms ) + if ( basilisk_numconfirms(myinfo,swap,&swap->bobspend) >= swap->I.aliceconfirms ) { printf("bobspend confirmed\n"); swap->I.statebits |= 0x80000; - printf("Bob confirms spend of Alice's payment\n"); + printf("Bob confirming spend of Alice's payment\n"); sleep(DEX_SLEEP); } retval = 1; @@ -2071,7 +2303,7 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap } else if ( (swap->I.statebits & 0x400) == 0 ) { - if ( basilisk_numconfirms(myinfo,swap,&swap->bobdeposit) >= swap->I.bobconfirms ) + if ( basilisk_istrustedbob(myinfo,swap) != 0 || (swap->I.bobconfirms == 0 && swap->depositunconf != 0) || basilisk_numconfirms(myinfo,swap,&swap->bobdeposit) >= swap->I.bobconfirms ) { printf("bobdeposit confirmed\n"); swap->I.statebits |= 0x400; @@ -2095,7 +2327,7 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap } else if ( (swap->I.statebits & 0x10000) == 0 ) { - if ( basilisk_numconfirms(myinfo,swap,&swap->bobpayment) >= swap->I.bobconfirms ) + if ( basilisk_istrustedbob(myinfo,swap) != 0 || (swap->I.bobconfirms == 0 && swap->paymentunconf != 0) || basilisk_numconfirms(myinfo,swap,&swap->bobpayment) >= swap->I.bobconfirms ) { printf("bobpayment confirmed\n"); swap->I.statebits |= 0x10000; @@ -2104,22 +2336,23 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap else if ( (swap->I.statebits & 0x20000) == 0 ) { printf("alicespend bobpayment\n"); - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->alicespend,0x20000,0) != 0 && basilisk_numconfirms(myinfo,swap,&swap->alicespend) > 0 ) + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->alicespend,0x20000,0) != 0 )//&& (swap->aliceunconf != 0 || basilisk_numconfirms(myinfo,swap,&swap->alicespend) > 0) ) { - for (j=datalen=0; j<32; j++) - data[datalen++] = swap->I.privAm.bytes[j]; - swap->I.statebits |= basilisk_swapsend(myinfo,swap,0x40000,data,datalen,0x20000,swap->I.crcs_mypriv); - printf("send privAm %x\n",swap->I.statebits); + swap->I.statebits |= 0x20000; } } else if ( (swap->I.statebits & 0x40000) == 0 ) { - if ( basilisk_numconfirms(myinfo,swap,&swap->alicespend) >= swap->I.bobconfirms ) + int32_t numconfs; + if ( (numconfs= basilisk_numconfirms(myinfo,swap,&swap->alicespend)) >= swap->I.bobconfirms ) { - swap->I.statebits |= 0x40000; + for (j=datalen=0; j<32; j++) + data[datalen++] = swap->I.privAm.bytes[j]; + printf("send privAm %x\n",swap->I.statebits); + swap->I.statebits |= basilisk_swapsend(myinfo,swap,0x40000,data,datalen,0x20000,swap->I.crcs_mypriv); printf("Alice confirms spend of Bob's payment\n"); retval = 1; - } + } else printf("alicespend numconfs.%d < %d\n",numconfs,swap->I.bobconfirms); } if ( swap->bobdeposit.I.locktime != 0 && time(NULL) > swap->bobdeposit.I.locktime ) { @@ -2132,7 +2365,7 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap retval = 1; } } - else if ( basilisk_privBn_extract(myinfo,swap,data,maxlen) == 0 ) + else if ( swap->aborted != 0 || basilisk_privBn_extract(myinfo,swap,data,maxlen) == 0 ) { printf("Alice reclaims her payment\n"); swap->I.statebits |= 0x40000000; @@ -2147,7 +2380,10 @@ int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap } if ( (rand() % 30) == 0 ) printf("finished swapstate.%x other.%x\n",swap->I.statebits,swap->I.otherstatebits); - sleep(DEX_SLEEP + (swap->I.iambob == 0)); + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; basilisk_sendstate(myinfo,swap,data,maxlen); basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); } @@ -2169,12 +2405,12 @@ cJSON *swapjson(struct supernet_info *myinfo,struct basilisk_swap *swap) void basilisk_psockinit(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t amlp) { - char keystr[64],databuf[1024],*retstr,*retstr2,*datastr,*pushaddr=0,*subaddr=0; cJSON *retjson,*addrjson; uint8_t data[512]; int32_t datalen,timeout,pushsock = -1,subsock = -1; + char keystr[64],databuf[1024],pubkeystr[128],*retstr,*retstr2,*datastr,*pushaddr=0,*subaddr=0; cJSON *retjson,*addrjson; uint8_t data[512]; int32_t datalen,timeout,pushsock = -1,subsock = -1; if ( swap->connected == 1 ) return; if ( swap->pushsock < 0 && swap->subsock < 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 && (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 ) { - timeout = 100; + timeout = 1000; nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); timeout = 1; nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); @@ -2182,13 +2418,13 @@ void basilisk_psockinit(struct supernet_info *myinfo,struct basilisk_swap *swap, swap->pushsock = pushsock; swap->subsock = subsock; } - if ( swap->subsock < 0 || swap->pushsock < 0 ) + if ( (subsock= swap->subsock) < 0 || (pushsock= swap->pushsock) < 0 ) { printf("error getting nn_sockets\n"); return; } sprintf(keystr,"%08x-%08x",swap->I.req.requestid,swap->I.req.quoteid); - if ( (retstr= _dex_kvsearch(myinfo,"KV",keystr)) != 0 ) + if ( swap->connected == 0 && (retstr= _dex_kvsearch(myinfo,"KV",keystr)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { @@ -2211,13 +2447,15 @@ void basilisk_psockinit(struct supernet_info *myinfo,struct basilisk_swap *swap, } free_json(retjson); } - printf("KVsearch.(%s) connected.%d socks.(%d %d)\n",retstr,swap->connected,swap->pushsock,swap->subsock); + printf("KVsearch.(%s) -> (%s) connected.%d socks.(%d %d) amlp.%d\n",keystr,retstr,swap->connected,swap->pushsock,swap->subsock,amlp); free(retstr); } - if ( swap->connected == 0 && amlp != 0 ) + printf("connected.%d amlp.%d subsock.%d pushsock.%d\n",swap->connected,amlp,subsock,pushsock); + if ( swap->connected <= 0 && amlp != 0 && subsock >= 0 && pushsock >= 0 ) { if ( (retstr= _dex_psock(myinfo,"{}")) != 0 ) { + printf("psock returns.(%s)\n",retstr); // {"result":"success","pushaddr":"tcp://5.9.102.210:30002","subaddr":"tcp://5.9.102.210:30003","randipbits":3606291758,"coin":"KMD","tag":"6952562460568228137"} if ( (retjson= cJSON_Parse(retstr)) != 0 ) { @@ -2225,44 +2463,98 @@ void basilisk_psockinit(struct supernet_info *myinfo,struct basilisk_swap *swap, subaddr = jstr(retjson,"subaddr"); if ( pushaddr != 0 && subaddr != 0 ) { - if ( nn_connect(pushsock,pushaddr) >= 0 && nn_connect(subsock,subaddr) >= 0 ) + if ( nn_connect(pushsock,pushaddr) >= 0 ) { - swap->connected = 1; - sprintf((char *)data,"{\"push\":\"%s\",\"sub\":\"%s\"}",pushaddr,subaddr); - datalen = (int32_t)strlen((char *)data) + 1; - printf("datalen.%d (%s)\n",datalen,(char *)data); - init_hexbytes_noT(databuf,data,datalen); - printf("%s -> %s\n",keystr,databuf); - if ( (retstr2= _dex_kvupdate(myinfo,"KV",keystr,databuf,1)) != 0 ) + printf("connected to %d pushaddr.(%s)\n",pushsock,pushaddr); + if ( nn_connect(subsock,subaddr) >= 0 ) { - printf("KVupdate.(%s)\n",retstr2); - free(retstr2); - } - } + swap->connected = 1; + init_hexbytes_noT(pubkeystr,myinfo->persistent_pubkey33,33); + sprintf((char *)data,"{\"push\":\"%s\",\"sub\":\"%s\",\"trade\":[\"%s\", %.8f, \"%s\", %.8f],\"pub\":\"%s\"}",pushaddr,subaddr,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),pubkeystr); + datalen = (int32_t)strlen((char *)data) + 1; + printf("datalen.%d (%s)\n",datalen,(char *)data); + init_hexbytes_noT(databuf,data,datalen); + printf("%s -> %s\n",keystr,databuf); + if ( (retstr2= _dex_kvupdate(myinfo,"KV",keystr,databuf,1)) != 0 ) + { + printf("KVupdate.(%s)\n",retstr2); + free(retstr2); + } + } else printf("nn_connect error to %d subaddr.(%s)\n",subsock,subaddr); + } else printf("nn_connect error to %d pushaddr.(%s)\n",pushsock,pushaddr); } + else printf("missing addr (%p) (%p) (%s)\n",pushaddr,subaddr,jprint(retjson,0)); free_json(retjson); - } + } else printf("Error parsing psock.(%s)\n",retstr); free(retstr); + } else printf("error issuing _dex_psock\n"); + } +} + +int32_t basilisk_alicetxs(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t i,retval = -1; + printf("alicetxs\n"); + for (i=0; i<3; i++) + { + if ( swap->alicepayment.I.datalen == 0 ) + basilisk_alicepayment(myinfo,swap,swap->alicepayment.coin,&swap->alicepayment,swap->I.pubAm,swap->I.pubBn); + if ( swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.spendlen == 0 ) + { + printf("error alice generating payment.%d\n",swap->alicepayment.I.spendlen); + sleep(20); + } + else + { + retval = 0; + for (i=0; ialicepayment.I.datalen; i++) + printf("%02x",swap->alicepayment.txbytes[i]); + printf(" ALICE PAYMENT created\n"); + iguana_unspents_mark(myinfo,swap->alicecoin,swap->alicepayment.vins); + basilisk_txlog(myinfo,swap,&swap->alicepayment,-1); + break; + } + } + if ( swap->myfee.I.datalen == 0 ) + { + printf("generate fee\n"); + if ( basilisk_rawtx_gen("myfee",myinfo,swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,0,swap->myfee.spendscript,swap->myfee.I.spendlen,swap->myfee.coin->chain->txfee,1,0) == 0 ) + { + swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40,0); + iguana_unspents_mark(myinfo,swap->I.iambob!=0?swap->bobcoin:swap->alicecoin,swap->myfee.vins); + basilisk_txlog(myinfo,swap,&swap->myfee,-1); + for (i=0; imyfee.I.spendlen; i++) + printf("%02x",swap->myfee.txbytes[i]); + printf(" fee %p %x\n",swap->myfee.txbytes,swap->I.statebits); + swap->I.statebits |= 0x40; + } + else + { + printf("error creating myfee\n"); + return(-2); } } + if ( swap->alicepayment.I.datalen != 0 && swap->alicepayment.I.spendlen > 0 && swap->myfee.I.datalen != 0 && swap->myfee.I.spendlen > 0 ) + return(0); + return(-1); } void basilisk_swaploop(void *_swap) { - uint8_t *data; uint32_t expiration; uint32_t channel; int32_t iters,retval=0,i,j,datalen,maxlen; struct supernet_info *myinfo; struct basilisk_swap *swap = _swap; + uint8_t *data; uint32_t expiration,savestatebits=0,saveotherbits=0; uint32_t channel; int32_t iters,retval=0,j,datalen,maxlen; struct supernet_info *myinfo; struct basilisk_swap *swap = _swap; myinfo = swap->myinfoptr; fprintf(stderr,"start swap\n"); maxlen = 1024*1024 + sizeof(*swap); data = malloc(maxlen); - expiration = (uint32_t)time(NULL) + 600; + expiration = (uint32_t)time(NULL) + 300; myinfo->DEXactive = expiration; channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); - while ( (swap->I.statebits & (0x08|0x02)) != (0x08|0x02) && time(NULL) < expiration ) + while ( swap->aborted == 0 && (swap->I.statebits & (0x08|0x02)) != (0x08|0x02) && time(NULL) < expiration ) { dex_channelsend(myinfo,swap->I.req.srchash,swap->I.req.desthash,channel,0x4000000,(void *)&swap->I.req.requestid,sizeof(swap->I.req.requestid)); //,60); if ( swap->connected == 0 ) basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); - if ( swap->connected != 0 ) + if ( swap->connected > 0 ) { printf("A r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits); basilisk_sendstate(myinfo,swap,data,maxlen); @@ -2273,14 +2565,17 @@ void basilisk_swaploop(void *_swap) if ( (swap->I.statebits & (0x08|0x02)) == (0x08|0x02) ) break; } - sleep(DEX_SLEEP); + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; } if ( swap->connected == 0 ) { printf("couldnt establish connection\n"); retval = -1; } - while ( retval == 0 && (swap->I.statebits & 0x20) == 0 && time(NULL) < expiration ) + while ( swap->aborted == 0 && retval == 0 && (swap->I.statebits & 0x20) == 0 ) { if ( swap->connected == 0 ) basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); @@ -2293,7 +2588,12 @@ void basilisk_swaploop(void *_swap) swap->I.statebits |= 0x20; break; } - sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + if ( time(NULL) > expiration ) + break; } myinfo->DEXactive = swap->I.expiration; if ( time(NULL) >= expiration ) @@ -2301,9 +2601,14 @@ void basilisk_swaploop(void *_swap) retval = -1; myinfo->DEXactive = 0; } + if ( swap->aborted != 0 ) + { + printf("swap aborted before tx sent\n"); + retval = -1; + } printf("C r%u/q%u swapstate.%x retval.%d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,retval); iters = 0; - while ( retval == 0 && (swap->I.statebits & 0x40) == 0 && iters++ < 10 ) // send fee + while ( swap->aborted == 0 && retval == 0 && (swap->I.statebits & 0x40) == 0 && iters++ < 10 ) // send fee { if ( swap->connected == 0 ) basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); @@ -2312,7 +2617,17 @@ void basilisk_swaploop(void *_swap) //printf("swapget\n"); basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); //printf("after swapget\n"); - if ( swap->myfee.I.datalen == 0 ) + if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen == 0 ) + { + printf("bobscripts set\n"); + if ( basilisk_bobscripts_set(myinfo,swap,1,1) < 0 ) + { + sleep(DEX_SLEEP); + printf("bobscripts set error\n"); + continue; + } + } + if ( swap->I.iambob == 0 ) { /*for (i=0; i<20; i++) printf("%02x",swap->secretAm[i]); @@ -2344,63 +2659,14 @@ void basilisk_swaploop(void *_swap) for (i=0; i<32; i++) printf("%02x",swap->pubB1.bytes[i]); printf(" <- pubB1\n");*/ - basilisk_txlog(myinfo,swap,0,-1); - if ( swap->I.iambob != 0 ) - { - printf("bobscripts set\n"); - if ( basilisk_bobscripts_set(myinfo,swap,1,1) < 0 ) - { - sleep(DEX_SLEEP); - printf("bobscripts set error\n"); - continue; - } - } - else - { - for (i=0; i<3; i++) - { - //if ( swap->alicepayment.txbytes != 0 && swap->alicepayment.I.spendlen != 0 ) - // break; - basilisk_alicepayment(myinfo,swap,swap->alicepayment.coin,&swap->alicepayment,swap->I.pubAm,swap->I.pubBn); - if ( swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.spendlen == 0 ) - { - printf("error alice generating payment.%d\n",swap->alicepayment.I.spendlen); - sleep(DEX_SLEEP); - } - else - { - retval = 0; - for (i=0; ialicepayment.I.datalen; i++) - printf("%02x",swap->alicepayment.txbytes[i]); - printf(" ALICE PAYMENT created\n"); - iguana_unspents_mark(myinfo,swap->alicecoin,swap->alicepayment.vins); - basilisk_txlog(myinfo,swap,&swap->alicepayment,-1); - break; - } - } - } - printf("generate fee\n"); - if ( basilisk_rawtx_gen("myfee",myinfo,swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,0,swap->myfee.spendscript,swap->myfee.I.spendlen,swap->myfee.coin->chain->txfee,1,0) == 0 ) - { - printf("done generate fee\n"); - swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40,0); - iguana_unspents_mark(myinfo,swap->I.iambob!=0?swap->bobcoin:swap->alicecoin,swap->myfee.vins); - basilisk_txlog(myinfo,swap,&swap->myfee,-1); - for (i=0; imyfee.I.spendlen; i++) - printf("%02x",swap->myfee.txbytes[i]); - printf(" fee %p %x\n",swap->myfee.txbytes,swap->I.statebits); - swap->I.statebits |= 0x40; - if ( swap->alicepayment.I.datalen != 0 && swap->alicepayment.I.spendlen > 0 ) - break; - } - else + if ( (retval= basilisk_alicetxs(myinfo,swap,data,maxlen)) != 0 ) { - printf("error creating myfee\n"); - retval = -6; + printf("basilisk_alicetxs error\n"); + break; } } } - if ( (swap->I.statebits & 0x40) == 0 ) + if ( swap->I.iambob == 0 && (swap->I.statebits & 0x40) == 0 ) { printf("couldnt send fee\n"); retval = -8; @@ -2412,22 +2678,25 @@ void basilisk_swaploop(void *_swap) printf("ALICE's error %d %d %d\n",swap->myfee.I.datalen,swap->alicepayment.I.datalen,swap->alicepayment.I.datalen); retval = -7; } - else if ( swap->I.iambob != 0 && (swap->myfee.I.datalen == 0 || swap->bobpayment.I.datalen == 0 || swap->bobdeposit.I.datalen == 0) ) + else if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen == 0 ) //swap->bobpayment.I.datalen == 0 { printf("BOB's error %d %d %d\n",swap->myfee.I.datalen,swap->bobpayment.I.datalen,swap->bobdeposit.I.datalen); retval = -7; } } - while ( retval == 0 && basilisk_swapiteration(myinfo,swap,data,maxlen) == 0 ) + while ( swap->aborted == 0 && retval == 0 && basilisk_swapiteration(myinfo,swap,data,maxlen) == 0 ) { - sleep(DEX_SLEEP); + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; basilisk_sendstate(myinfo,swap,data,maxlen); basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); basilisk_swap_saveupdate(myinfo,swap); if ( time(NULL) > swap->I.expiration ) break; } - if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen != 0 ) + if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen != 0 && bits256_nonz(swap->bobdeposit.I.actualtxid) != 0 ) { printf("BOB waiting for confirm state.%x\n",swap->I.statebits); sleep(60); // wait for confirm/propagation of msig @@ -2446,6 +2715,8 @@ void basilisk_swaploop(void *_swap) } basilisk_swap_saveupdate(myinfo,swap); } + if ( retval != 0 ) + basilisk_swap_sendabort(myinfo,swap); printf("end of atomic swap\n"); if ( swapcompleted(myinfo,swap) > 0 ) // only if swap completed { @@ -2458,10 +2729,34 @@ void basilisk_swaploop(void *_swap) free(data); } +cJSON *basilisk_swapjson(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + cJSON *item = cJSON_CreateObject(); + jaddnum(item,"requestid",swap->I.req.requestid); + jaddnum(item,"quoteid",swap->I.req.quoteid); + jaddnum(item,"state",swap->I.statebits); + jaddnum(item,"otherstate",swap->I.otherstatebits); + jadd(item,"request",basilisk_requestjson(&swap->I.req)); + return(item); +} + struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit) { - int32_t i,m,n; uint8_t pubkey33[33]; bits256 pubkey25519; uint32_t channel,starttime; cJSON *retarray,*item,*msgobj; struct basilisk_swap *swap = 0; + int32_t i,m,n,iter; uint8_t pubkey33[33]; bits256 pubkey25519; uint32_t channel,starttime; cJSON *retarray,*item,*msgobj; struct iguana_info *coin; double pending=0.; struct basilisk_swap *swap = 0; // statebits 1 -> client, 0 -> LP + if ( myinfo->numswaps > 0 ) + { + if ( (coin= iguana_coinfind(rp->src)) == 0 || coin->FULLNODE >= 0 ) + { + printf("dont have SRC coin.%s or not native and already swap pending\n",rp->src); + return(0); + } + if ( (coin= iguana_coinfind(rp->dest)) == 0 || coin->FULLNODE >= 0 ) + { + printf("dont have DEST coin.%s or not native and already swap pending\n",rp->dest); + return(0); + } + } portable_mutex_lock(&myinfo->DEX_swapmutex); for (i=0; inumswaps; i++) if ( myinfo->swaps[i]->I.req.requestid == rp->requestid ) @@ -2485,7 +2780,19 @@ struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,bits256 m = n = 0; if ( bitcoin_swapinit(myinfo,privkey,pubkey33,pubkey25519,swap,optionduration,statebits,reinit) != 0 ) { - basilisk_psockinit(myinfo,swap,statebits == 0); + for (iter=0; iter<16; iter++) + { + basilisk_psockinit(myinfo,swap,statebits == 0); + sleep(3); + if ( swap->connected > 0 ) + break; + sleep(10); + /*basilisk_sendstate(myinfo,swap,data,sizeof(data)); + basilisk_swapget(myinfo,swap,0x80000000,data,sizeof(data),basilisk_verify_statebits); + if ( swap->connected > 0 ) + break; + printf("loopback didntwork with %d %d\n",swap->pushsock,swap->subsock);*/ + } if ( reinit != 0 ) { if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)basilisk_swaploop,(void *)swap) != 0 ) @@ -2498,12 +2805,17 @@ struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,bits256 { starttime = (uint32_t)time(NULL); printf("statebits.%x m.%d n.%d\n",statebits,m,n); - while ( statebits == 0 && m <= n/2 && time(NULL) < starttime+2*BASILISK_MSGDURATION ) + while ( statebits == 0 && m <= n/2 && time(NULL) < starttime+7*BASILISK_MSGDURATION ) { + uint32_t msgid; uint8_t data[1024]; int32_t datalen; m = n = 0; sleep(DEX_SLEEP); printf("waiting for offer to be accepted\n"); channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + datalen = basilisk_rwDEXquote(1,data,rp); + msgid = (uint32_t)time(NULL); + printf("other req.%d >>>>>>>>>>> send response (%llx -> %llx) last.%u r.%u quoteid.%u\n",i,(long long)rp->desthash.txid,(long long)rp->srchash.txid,myinfo->lastdexrequestid,rp->requestid,rp->quoteid); + dex_channelsend(myinfo,rp->desthash,rp->srchash,channel,msgid,data,datalen); if ( (retarray= basilisk_channelget(myinfo,rp->srchash,rp->desthash,channel,0x4000000,30)) != 0 ) { if ( is_cJSON_Array(retarray) != 0 && (n= cJSON_GetArraySize(retarray)) > 0 ) @@ -2527,25 +2839,26 @@ struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,bits256 { //for (i=0; iI.req); i++) // fprintf(stderr,"%02x",((uint8_t *)&swap->I.req)[i]); - fprintf(stderr," M.%d N.%d launch.%d %d %p\n",m,n,myinfo->numswaps,(int32_t)(sizeof(myinfo->swaps)/sizeof(*myinfo->swaps)),&swap->I.req); + fprintf(stderr," M.%d N.%d launch.%d %d %p reinit.%d\n",m,n,myinfo->numswaps,(int32_t)(sizeof(myinfo->swaps)/sizeof(*myinfo->swaps)),&swap->I.req,reinit); if ( (swap->fp= basilisk_swap_save(myinfo,swap,privkey,rp,statebits,optionduration,reinit)) != 0 ) { - if ( reinit == 0 ) + } + if ( reinit == 0 ) + { + if ( myinfo->swapsfp == 0 ) { - if ( myinfo->swapsfp == 0 ) - { - char fname[512]; - sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); - if ( (myinfo->swapsfp= fopen(fname,"rb+")) == 0 ) - myinfo->swapsfp = fopen(fname,"wb+"); - else fseek(myinfo->swapsfp,0,SEEK_END); - } - if ( myinfo->swapsfp != 0 ) - { - fwrite(&rp->requestid,1,sizeof(rp->requestid),myinfo->swapsfp); - fwrite(&rp->quoteid,1,sizeof(rp->quoteid),myinfo->swapsfp); - fflush(myinfo->swapsfp); - } + char fname[512]; + sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (myinfo->swapsfp= fopen(fname,"rb+")) == 0 ) + myinfo->swapsfp = fopen(fname,"wb+"); + else fseek(myinfo->swapsfp,0,SEEK_END); + printf("LIST fp.%p\n",myinfo->swapsfp); + } + if ( myinfo->swapsfp != 0 ) + { + fwrite(&rp->requestid,1,sizeof(rp->requestid),myinfo->swapsfp); + fwrite(&rp->quoteid,1,sizeof(rp->quoteid),myinfo->swapsfp); + fflush(myinfo->swapsfp); } } if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)basilisk_swaploop,(void *)swap) != 0 ) @@ -2553,7 +2866,18 @@ struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,bits256 } myinfo->swaps[myinfo->numswaps++] = swap; - } else printf("%u/%u offer wasnt accepted statebits.%d m.%d n.%d\n",rp->requestid,rp->quoteid,statebits,m,n); + } + else + { + if ( statebits != 0 ) + { + if ( (coin= iguana_coinfind(rp->src)) != 0 ) + { + + } + } + printf("%u/%u offer wasnt accepted statebits.%d m.%d n.%d pending %.8f\n",rp->requestid,rp->quoteid,statebits,m,n,pending); + } } } } @@ -2561,25 +2885,1152 @@ struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,bits256 return(swap); } -char *basilisk_swaplist(struct supernet_info *myinfo) +/////////////// remember functions + +cJSON *basilisk_nullretjson(cJSON *retjson) { - char fname[512]; FILE *fp; struct basilisk_request R; int32_t optionduration; uint32_t quoteid,requestid,statebits; cJSON *retjson,*array; bits256 privkey; - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); - if ( (fp= fopen(fname,"rb")) != 0 ) + char *outstr; + if ( retjson != 0 ) { - while ( fread(&requestid,1,sizeof(requestid),fp) == sizeof(requestid) && fread("eid,1,sizeof(quoteid),fp) == sizeof(quoteid) ) + outstr = jprint(retjson,0); + if ( strcmp(outstr,"{}") == 0 ) + { + free_json(retjson); + retjson = 0; + } + free(outstr); + } + return(retjson); +} + +cJSON *basilisk_swapgettxout(struct supernet_info *myinfo,char *symbol,bits256 trigger,int32_t vout) +{ + char *retstr; cJSON *retjson=0; struct iguana_info *coin; + if ( ((coin= iguana_coinfind(symbol)) == 0 || coin->FULLNODE == 0) && iguana_isnotarychain(symbol) >= 0 ) + { + if ( (retstr= dex_gettxout(myinfo,0,0,0,trigger,symbol,vout)) != 0 ) + { + //printf("dexgettxout.(%s)\n",retstr); + retjson = cJSON_Parse(retstr); + free(retstr); + } + if ( 0 && strcmp("BTC",symbol) == 0 ) + printf("%s gettxout.(%s)\n",symbol,jprint(retjson,0)); + } + else + { + retjson = dpow_gettxout(myinfo,coin,trigger,vout); + //printf("need to verify passthru has this info\n"); + //printf("dpowgettxout.(%s)\n",jprint(retjson,0)); + } + return(basilisk_nullretjson(retjson)); +} + +cJSON *basilisk_swapgettx(struct supernet_info *myinfo,char *symbol,bits256 txid) +{ + char *retstr; cJSON *retjson=0; struct iguana_info *coin; + if ( ((coin= iguana_coinfind(symbol)) == 0 || coin->FULLNODE == 0) && iguana_isnotarychain(symbol) >= 0 ) + { + if ( (retstr= dex_gettransaction(myinfo,0,0,0,txid,symbol)) != 0 ) + { + retjson = cJSON_Parse(retstr); + free(retstr); + } + //if ( strcmp("BTC",symbol) == 0 ) + // printf("%s gettx.(%s)\n",symbol,jprint(retjson,0)); + } else retjson = dpow_gettransaction(myinfo,coin,txid); + return(basilisk_nullretjson(retjson)); +} + +int32_t basilisk_swap_txdestaddr(char *destaddr,bits256 txid,int32_t vout,cJSON *txobj) +{ + int32_t n,m,retval = -1; cJSON *vouts,*item,*addresses,*skey; char *addr; + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && vout < n ) + { + item = jitem(vouts,vout); + if ( (skey= jobj(item,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 ) { - if ( basilisk_swap_load(requestid,quoteid,&privkey,&R,&statebits,&optionduration) == 0 ) + item = jitem(addresses,0); + if ( (addr= jstr(item,0)) != 0 ) { - jaddi(array,basilisk_requestjson(&R)); + safecopy(destaddr,addr,64); + retval = 0; } + //printf("item.(%s) -> dest.(%s)\n",jprint(item,0),destaddr); } - fclose(fp); } - jaddstr(retjson,"result","success"); - jadd(retjson,"swaps",array); + return(retval); +} + +int32_t basilisk_swap_getcoinaddr(struct supernet_info *myinfo,char *symbol,char *coinaddr,bits256 txid,int32_t vout) +{ + cJSON *retjson; + coinaddr[0] = 0; + if ( (retjson= basilisk_swapgettx(myinfo,symbol,txid)) != 0 ) + { + basilisk_swap_txdestaddr(coinaddr,txid,vout,retjson); + free_json(retjson); + } + return(coinaddr[0] != 0); +} + +int32_t basilisk_swap_getsigscript(struct supernet_info *myinfo,char *symbol,uint8_t *script,int32_t maxlen,bits256 txid,int32_t vini) +{ + cJSON *retjson,*vins,*item,*skey; int32_t n,scriptlen = 0; char *hexstr; + if ( (retjson= basilisk_swapgettx(myinfo,symbol,txid)) != 0 ) + { + if ( (vins= jarray(&n,retjson,"vin")) != 0 && vini < n ) + { + item = jitem(vins,vini); + if ( (skey= jobj(item,"scriptSig")) != 0 && (hexstr= jstr(skey,"hex")) != 0 && (scriptlen= (int32_t)strlen(hexstr)) < maxlen*2 ) + { + scriptlen >>= 1; + decode_hex(script,scriptlen,hexstr); + //char str[65]; printf("%s/v%d sigscript.(%s)\n",bits256_str(str,txid),vini,hexstr); + } + } + free_json(retjson); + } + return(scriptlen); +} + +int64_t basilisk_txvalue(struct supernet_info *myinfo,char *symbol,bits256 txid,int32_t vout) +{ + cJSON *txobj,*vouts,*item; int32_t n; int64_t value = 0; + //char str[65]; printf("%s txvalue.(%s)\n",symbol,bits256_str(str,txid)); + if ( (txobj= basilisk_swapgettx(myinfo,symbol,txid)) != 0 ) + { + //printf("txobj.(%s)\n",jprint(txobj,0)); + if ( (vouts= jarray(&n,txobj,"vout")) != 0 ) + { + item = jitem(vouts,vout); + if ( (value= jdouble(item,"amount") * SATOSHIDEN) == 0 ) + value = jdouble(item,"value") * SATOSHIDEN; + } + free_json(txobj); + } + return(value); +} + +bits256 dex_swap_spendtxid(struct supernet_info *myinfo,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; + memset(&spendtxid,0,sizeof(spendtxid)); + if ( (retstr= dex_listtransactions(myinfo,0,0,0,symbol,coinaddr,100,0)) != 0 ) + { + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i %s\n",bits256_str(str,spendtxid),destaddr); + break; + } + } + } + } + free_json(array); + } + free(retstr); + } + return(spendtxid); +} + +bits256 basilisk_swap_spendtxid(struct supernet_info *myinfo,char *symbol,char *destaddr,bits256 utxotxid,int32_t vout) +{ + bits256 spendtxid,txid; char *catstr,*addr; cJSON *array,*item,*item2,*txobj,*vins; int32_t i,n,m; char coinaddr[64],str[65]; struct iguana_info *coin = iguana_coinfind(symbol); + // listtransactions or listspents + destaddr[0] = 0; + coinaddr[0] = 0; + memset(&spendtxid,0,sizeof(spendtxid)); + //char str[65]; printf("swap %s spendtxid.(%s)\n",symbol,bits256_str(str,utxotxid)); + if ( (coin == 0 || coin->FULLNODE >= 0) && iguana_isnotarychain(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}]}}] + basilisk_swap_getcoinaddr(myinfo,symbol,coinaddr,utxotxid,vout); + if ( coinaddr[0] != 0 ) + spendtxid = dex_swap_spendtxid(myinfo,symbol,destaddr,coinaddr,utxotxid,vout); + } + else if ( coin != 0 ) + { + if ( (array= dpow_listtransactions(myinfo,coin,destaddr,1000,0)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0 ) + { + for (i=0; i jint(item,"vout") ) + { + item2 = jitem(vins,jint(item,"vout")); + if ( bits256_cmp(utxotxid,jbits256(item2,"txid")) == 0 && vout == jint(item2,"vout") ) + { + spendtxid = txid; + break; + } + } + } + } + } + if ( i == n ) + printf("dpowlist: native couldnt find spendtxid for %s\n",bits256_str(str,utxotxid)); + } + free_json(array); + } + if ( bits256_nonz(spendtxid) != 0 ) + return(spendtxid); + } + if ( iguana_isnotarychain(symbol) >= 0 ) + { + basilisk_swap_getcoinaddr(myinfo,symbol,coinaddr,utxotxid,vout); + printf("fallback use DEX for native (%s) (%s)\n",coinaddr,bits256_str(str,utxotxid)); + if ( coinaddr[0] != 0 ) + { + spendtxid = dex_swap_spendtxid(myinfo,symbol,destaddr,coinaddr,utxotxid,vout); + printf("spendtxid.(%s)\n",bits256_str(str,spendtxid)); + } + } + } + return(spendtxid); +} + +bits256 basilisk_swap_sendrawtransaction(struct supernet_info *myinfo,char *txname,char *symbol,char *txbytes) +{ + char *retstr; bits256 txid; int32_t i,sentflag = 0; + memset(&txid,0,sizeof(txid)); + for (i=0; i<3; i++) + { + if ( (retstr= _dex_sendrawtransaction(myinfo,symbol,txbytes)) != 0 ) + { + if ( is_hexstr(retstr,0) == 64 ) + { + decode_hex(txid.bytes,32,retstr); + sentflag = 1; + } + char str[65]; printf("[%s] %s RETSTR.(%s) %s.%s\n",txname,txbytes,retstr,symbol,bits256_str(str,txid)); + free(retstr); + } + if ( sentflag != 0 ) + break; + } + return(txid); +} + +char *basilisk_swap_bobtxspend(char *name,struct supernet_info *myinfo,char *symbol,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t vout,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp) +{ + char *rawtxbytes=0,*signedtx=0,str[65],hexstr[999],wifstr[128],destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *utxoobj,*txobj,*vins,*item,*sobj,*privkeys; int32_t height,completed,spendlen,ignore_cltverr=1,suppress_pubkeys=1; struct vin_info *V; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; struct iguana_info *coin; bits256 txid,signedtxid; uint64_t destamount; + *destamountp = 0; + if ( finalseqid == 0 ) + locktime = expiration; + //printf("bobtxspend.%s redeem.[%d]\n",symbol,redeemlen); + if ( redeemlen < 0 || (coin= iguana_coinfind(symbol)) == 0 ) + return(0); + if ( (utxoobj= basilisk_swapgettxout(myinfo,symbol,utxotxid,vout)) == 0 ) + { + printf("basilisk_swap_bobtxspend.%s utxo already spent or doesnt exist\n",name); + return(0); + } + if ( (destamount= jdouble(utxoobj,"amount")*SATOSHIDEN) == 0 && (destamount= jdouble(utxoobj,"value")*SATOSHIDEN) == 0 ) + { + printf("%s %s basilisk_swap_bobtxspend.%s strange utxo.(%s)\n",symbol,bits256_str(str,utxotxid),name,jprint(utxoobj,0)); + free_json(utxoobj); + return(0); + } else free_json(utxoobj); + *destamountp = destamount; + if ( destamount > 10000 ) + destamount -= 10000; + if ( strcmp(symbol,"BTC") == 0 ) + { + if ( destamount > 40000 ) + destamount -= 40000; + } + height = coin->longestchain; + timestamp = (uint32_t)time(NULL); + V = calloc(256,sizeof(*V)); + privkeys = cJSON_CreateArray(); + if ( privkey2p != 0 ) + { + V[0].signers[1].privkey = *privkey2p; + bitcoin_pubkey33(myinfo->ctx,V[0].signers[1].pubkey,*privkey2p); + bitcoin_priv2wif(wifstr,*privkey2p,coin->chain->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(myinfo->ctx,V[0].signers[0].pubkey,privkey); + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + jaddistr(privkeys,wifstr); + V[0].suppress_pubkeys = suppress_pubkeys; + V[0].ignore_cltverr = ignore_cltverr; + if ( redeemlen != 0 ) + memcpy(V[0].p2shscript,redeemscript,redeemlen), V[0].p2shlen = redeemlen; + txobj = bitcoin_txcreate(coin->symbol,coin->chain->isPoS,locktime,1,timestamp); + vins = cJSON_CreateArray(); + item = cJSON_CreateObject(); + if ( userdata != 0 && userdatalen > 0 ) + { + memcpy(V[0].userdata,userdata,userdatalen); + V[0].userdatalen = userdatalen; + init_hexbytes_noT(hexstr,userdata,userdatalen); + jaddstr(item,"userdata",hexstr); + } + jaddbits256(item,"txid",utxotxid); + jaddnum(item,"vout",vout); + sobj = cJSON_CreateObject(); + bitcoin_address(destaddr,coin->chain->pubtype,pubkey33,33); + bitcoin_addr2rmd160(&addrtype,rmd160,destaddr); + /*int32_t i; + for (i=0; i<33; i++) + printf("%02x",pubkey33[i]); + printf(" pubkey33 ->\n"); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" destaddr.(%s)\n",destaddr); + calc_rmd160_sha256(rmd160,pubkey33,33); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- vs direct calc\n");*/ + spendlen = bitcoin_standardspend(spendscript,0,rmd160); + init_hexbytes_noT(hexstr,spendscript,spendlen); + jaddstr(sobj,"hex",hexstr); + jadd(item,"scriptPubKey",sobj); + jaddnum(item,"suppress",suppress_pubkeys); + jaddnum(item,"sequence",sequenceid); + if ( redeemlen != 0 ) + { + init_hexbytes_noT(hexstr,redeemscript,redeemlen); + jaddstr(item,"redeemScript",hexstr); + } + jaddi(vins,item); + jdelete(txobj,"vin"); + jadd(txobj,"vin",vins); + txobj = bitcoin_txoutput(txobj,spendscript,spendlen,destamount); + if ( (rawtxbytes= bitcoin_json2hex(myinfo,coin,&txid,txobj,V)) != 0 ) + { + //printf("locktime.%u sequenceid.%x rawtx.(%s) vins.(%s)\n",locktime,sequenceid,rawtxbytes,jprint(vins,0)); + if ( (signedtx= iguana_signrawtx(myinfo,coin,height,&signedtxid,&completed,vins,rawtxbytes,privkeys,V)) == 0 ) + printf("couldnt sign transaction\n"); + else if ( completed == 0 ) + printf("incomplete signing\n"); + else printf("%s -> %s\n",name,bits256_str(str,signedtxid)); + free(rawtxbytes); + } else printf("error making rawtx\n"); + free_json(privkeys); + free_json(txobj); + free(V); + return(signedtx); +} + +char *basilisk_swap_Aspend(char *name,struct supernet_info *myinfo,char *symbol,bits256 privAm,bits256 privBn,bits256 utxotxid,int32_t vout,uint8_t pubkey33[33],uint32_t expiration,int64_t *destamountp) +{ + char msigaddr[64],*signedtx = 0; int32_t spendlen,redeemlen; uint8_t tmp33[33],redeemscript[512],spendscript[128]; bits256 pubAm,pubBn; struct iguana_info *coin = iguana_coinfind(symbol); + if ( coin != 0 && bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 ) + { + pubAm = bitcoin_pubkey33(myinfo->ctx,tmp33,privAm); + pubBn = bitcoin_pubkey33(myinfo->ctx,tmp33,privBn); + //char str[65]; + //printf("pubAm.(%s)\n",bits256_str(str,pubAm)); + //printf("pubBn.(%s)\n",bits256_str(str,pubBn)); + spendlen = basilisk_alicescript(redeemscript,&redeemlen,spendscript,0,msigaddr,coin->chain->p2shtype,pubAm,pubBn); + //char str[65]; printf("%s utxo.(%s) redeemlen.%d spendlen.%d\n",msigaddr,bits256_str(str,utxotxid),redeemlen,spendlen); + /*rev = privAm; + for (i=0; i<32; i++) + privAm.bytes[i] = rev.bytes[31 - i]; + rev = privBn; + for (i=0; i<32; i++) + privBn.bytes[i] = rev.bytes[31 - i];*/ + signedtx = basilisk_swap_bobtxspend(name,myinfo,symbol,privAm,&privBn,redeemscript,redeemlen,0,0,utxotxid,vout,pubkey33,1,expiration,destamountp); + } + return(signedtx); +} + +bits256 basilisk_swap_privbob_extract(struct supernet_info *myinfo,char *symbol,bits256 spendtxid,int32_t vini,int32_t revflag) +{ + bits256 privkey; int32_t i,scriptlen,siglen; uint8_t script[1024]; // from Bob refund of Bob deposit + memset(&privkey,0,sizeof(privkey)); + if ( (scriptlen= basilisk_swap_getsigscript(myinfo,symbol,script,(int32_t)sizeof(script),spendtxid,vini)) > 0 ) + { + siglen = script[0]; + for (i=0; i<32; i++) + { + if ( revflag != 0 ) + privkey.bytes[31 - i] = script[siglen+2+i]; + else privkey.bytes[i] = script[siglen+2+i]; + } + char str[65]; printf("extracted privbob.(%s)\n",bits256_str(str,privkey)); + } + return(privkey); +} + +bits256 basilisk_swap_privBn_extract(struct supernet_info *myinfo,bits256 *bobrefundp,char *bobcoin,bits256 bobdeposit,bits256 privBn) +{ + char destaddr[64]; + if ( bits256_nonz(privBn) == 0 ) + { + if ( bits256_nonz(bobdeposit) != 0 ) + *bobrefundp = basilisk_swap_spendtxid(myinfo,bobcoin,destaddr,bobdeposit,0); + if ( bits256_nonz(*bobrefundp) != 0 ) + privBn = basilisk_swap_privbob_extract(myinfo,bobcoin,*bobrefundp,0,0); + } + return(privBn); +} + +bits256 basilisk_swap_spendupdate(struct supernet_info *myinfo,char *symbol,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t vout,char *aliceaddr,char *bobaddr) +{ + bits256 spendtxid,txid; char destaddr[64]; + txid = txids[utxoind]; + memset(&spendtxid,0,sizeof(spendtxid)); + /*if ( aliceaddr != 0 ) + printf("aliceaddr.(%s)\n",aliceaddr); + if ( bobaddr != 0 ) + printf("bobaddr.(%s)\n",bobaddr);*/ + if ( bits256_nonz(txid) != 0 ) + { + //char str[65]; + spendtxid = basilisk_swap_spendtxid(myinfo,symbol,destaddr,txid,vout); + if ( bits256_nonz(spendtxid) != 0 ) + { + sentflags[utxoind] = 1; + if ( aliceaddr != 0 && strcmp(destaddr,aliceaddr) == 0 ) + { + //printf("ALICE spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); + sentflags[alicespent] = 1; + 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; + txids[bobspent] = spendtxid; + } + else + { + //printf("OTHER dest spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); + if ( aliceaddr != 0 ) + { + sentflags[bobspent] = 1; + txids[bobspent] = spendtxid; + } + else if ( bobaddr != 0 ) + { + sentflags[alicespent] = 1; + txids[alicespent] = spendtxid; + } + } + } + } else printf("utxoind.%d null txid\n",utxoind); + return(spendtxid); +} + +#define BASILISK_ALICESPEND 0 +#define BASILISK_BOBSPEND 1 +#define BASILISK_BOBPAYMENT 2 +#define BASILISK_ALICEPAYMENT 3 +#define BASILISK_BOBDEPOSIT 4 +#define BASILISK_OTHERFEE 5 +#define BASILISK_MYFEE 6 +#define BASILISK_BOBREFUND 7 +#define BASILISK_BOBRECLAIM 8 +#define BASILISK_ALICERECLAIM 9 +#define BASILISK_ALICECLAIM 10 +//0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0 +char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" }; + +int32_t basilisk_isbobcoin(int32_t iambob,int32_t ind) +{ + switch ( ind ) + { + case BASILISK_MYFEE: return(iambob); break; + case BASILISK_OTHERFEE: return(!iambob); break; + case BASILISK_BOBSPEND: + case BASILISK_ALICEPAYMENT: + case BASILISK_ALICERECLAIM: + case BASILISK_ALICECLAIM: return(0); + break; + case BASILISK_BOBDEPOSIT: + case BASILISK_ALICESPEND: + case BASILISK_BOBPAYMENT: + case BASILISK_BOBREFUND: + case BASILISK_BOBRECLAIM: return(1); + break; + default: return(-1); break; + } +} + +// add blocktrail presence requirement for BTC +int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflags,bits256 paymentspent,bits256 Apaymentspent,bits256 depositspent) +{ + int32_t i,n = 0; + for (i=0; i (%s)\n",fname,fstr); + if ( (txobj= cJSON_Parse(fstr)) != 0 ) + { + paymentspent = jbits256(txobj,"paymentspent"); + Apaymentspent = jbits256(txobj,"Apaymentspent"); + depositspent = jbits256(txobj,"depositspent"); + if ( (array= jarray(&n,txobj,"values")) != 0 ) + for (i=0; i (%s)\n",fname,fstr); + if ( (txobj= cJSON_Parse(fstr)) != 0 ) + { + //printf("TXOBJ.(%s)\n",jprint(txobj,0)); + iambob = jint(txobj,"iambob"); + txid = jbits256(txobj,"txid"); + if ( bits256_nonz(txid) == 0 ) + continue; + txids[i] = txid; + if ( jobj(txobj,"tx") != 0 ) + { + txbytes[i] = clonestr(jstr(txobj,"tx")); + //printf("[%s] TX.(%s)\n",txnames[i],txbytes[i]); + } + if ( (value= jdouble(txobj,"amount") * SATOSHIDEN) == 0 ) + value = jdouble(txobj,"value") * SATOSHIDEN; + values[i] = value; + if ( (symbol= jstr(txobj,"coin")) != 0 ) + { + if ( i == BASILISK_ALICESPEND || i == BASILISK_BOBPAYMENT || i == BASILISK_BOBDEPOSIT || i == BASILISK_BOBREFUND || i == BASILISK_BOBRECLAIM || i == BASILISK_ALICECLAIM ) + safecopy(bobcoin,symbol,sizeof(bobcoin)); + else if ( i == BASILISK_BOBSPEND || i == BASILISK_ALICEPAYMENT || i == BASILISK_ALICERECLAIM ) + safecopy(alicecoin,symbol,sizeof(alicecoin)); + if ( finishedflag == 0 ) + { + if ( (sentobj= basilisk_swapgettx(myinfo,symbol,txid)) == 0 ) + { + //printf("%s %s ready to broadcast\n",symbol,bits256_str(str2,txid)); + } + else + { + checktxid = jbits256(sentobj,"txid"); + if ( bits256_nonz(checktxid) == 0 ) + checktxid = jbits256(sentobj,"hash"); + if ( bits256_cmp(checktxid,txid) == 0 ) + { + //printf(">>>>>> %s txid %s\n",jprint(sentobj,0),bits256_str(str,txid)); + sentflags[i] = 1; + } + free_json(sentobj); + } + printf("%s %s %.8f\n",txnames[i],bits256_str(str,txid),dstr(value)); + } + } + } //else printf("no symbol\n"); + free(fstr); + } else if ( finishedflag == 0 ) + printf("%s not finished\n",fname); + } + //printf("iambob.%d src.%s dest.%s bob.%s alice.%s pubA0.(%s)\n",iambob,src,dest,bobcoin,alicecoin,bits256_str(str,pubA0)); + Adestaddr[0] = destaddr[0] = 0; + Adest = Bdest = AAdest = ABdest = 0; + if ( bobcoin[0] == 0 || alicecoin[0] == 0 ) + return(0); + //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 ) + { + if ( iambob == 0 ) + { + if ( (coin= iguana_coinfind(alicecoin)) != 0 ) + { + bitcoin_address(Adestaddr,coin->chain->pubtype,pubkey33,33); + AAdest = Adestaddr; + } + if ( (coin= iguana_coinfind(bobcoin)) != 0 ) + { + bitcoin_address(destaddr,coin->chain->pubtype,pubkey33,33); + Adest = destaddr; + } + } + else + { + if ( (coin= iguana_coinfind(bobcoin)) != 0 ) + { + bitcoin_address(destaddr,coin->chain->pubtype,pubkey33,33); + Bdest = destaddr; + } + if ( (coin= iguana_coinfind(alicecoin)) != 0 ) + { + bitcoin_address(Adestaddr,coin->chain->pubtype,pubkey33,33); + ABdest = Adestaddr; + } + } + 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])); + if ( txbytes[BASILISK_ALICEPAYMENT] != 0 ) + sentflags[BASILISK_ALICEPAYMENT] = 1; + else if ( (sentobj= basilisk_swapgettx(myinfo,alicecoin,txids[BASILISK_ALICEPAYMENT])) != 0 ) + { + sentflags[BASILISK_ALICEPAYMENT] = 1; + free_json(sentobj); + } + } + paymentspent = basilisk_swap_spendupdate(myinfo,bobcoin,sentflags,txids,BASILISK_BOBPAYMENT,BASILISK_ALICESPEND,BASILISK_BOBRECLAIM,0,Adest,Bdest); + Apaymentspent = basilisk_swap_spendupdate(myinfo,alicecoin,sentflags,txids,BASILISK_ALICEPAYMENT,BASILISK_ALICERECLAIM,BASILISK_BOBSPEND,0,AAdest,ABdest); + depositspent = basilisk_swap_spendupdate(myinfo,bobcoin,sentflags,txids,BASILISK_BOBDEPOSIT,BASILISK_ALICECLAIM,BASILISK_BOBREFUND,0,Adest,Bdest); + finishedflag = basilisk_swap_isfinished(iambob,txids,sentflags,paymentspent,Apaymentspent,depositspent); + if ( iambob == 0 ) + { + if ( sentflags[BASILISK_ALICESPEND] == 0 ) + { + if ( sentflags[BASILISK_BOBPAYMENT] != 0 && bits256_nonz(paymentspent) == 0 ) + { + //if ( txbytes[BASILISK_ALICESPEND] == 0 ) + { + if ( bits256_nonz(txids[BASILISK_BOBPAYMENT]) != 0 ) + { + // alicespend + for (j=0; j<32; j++) + 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); + len = basilisk_swapuserdata(userdata,rev,0,myprivs[0],redeemscript,redeemlen); + printf("alicespend len.%d redeemlen.%d\n",len,redeemlen); + if ( (txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend("alicespend",myinfo,bobcoin,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,pubkey33,1,expiration,&values[BASILISK_ALICESPEND])) != 0 ) + printf("alicespend.(%s)\n",txbytes[BASILISK_ALICESPEND]); + } + } + if ( txbytes[BASILISK_ALICESPEND] != 0 ) + { + txids[BASILISK_ALICESPEND] = basilisk_swap_sendrawtransaction(myinfo,"alicespend",bobcoin,txbytes[BASILISK_ALICESPEND]); + if ( bits256_nonz(txids[BASILISK_ALICESPEND]) != 0 ) // tested + { + sentflags[BASILISK_ALICESPEND] = 1; + paymentspent = txids[BASILISK_ALICESPEND]; + } + } + } + } + if ( sentflags[BASILISK_ALICECLAIM] == 0 && sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(depositspent) == 0 ) + { + if ( time(NULL) > expiration ) + { + //if ( txbytes[BASILISK_ALICECLAIM] == 0 ) + { + 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("aliceclaim",myinfo,bobcoin,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,pubkey33,0,expiration,&values[BASILISK_ALICECLAIM])) != 0 ) + printf("privBn.(%s) aliceclaim.(%s)\n",bits256_str(str,privBn),txbytes[BASILISK_ALICECLAIM]); + } + } + if ( txbytes[BASILISK_ALICECLAIM] != 0 ) + { + txids[BASILISK_ALICECLAIM] = basilisk_swap_sendrawtransaction(myinfo,"aliceclaim",bobcoin,txbytes[BASILISK_ALICECLAIM]); + if ( bits256_nonz(txids[BASILISK_ALICECLAIM]) != 0 ) // tested + { + sentflags[BASILISK_ALICECLAIM] = 1; + depositspent = txids[BASILISK_ALICECLAIM]; + } + } + } else printf("now %u before expiration %u\n",(uint32_t)time(NULL),expiration); + } + if ( sentflags[BASILISK_ALICEPAYMENT] != 0 && bits256_nonz(Apaymentspent) == 0 && sentflags[BASILISK_ALICECLAIM] == 0 ) + { + //if ( txbytes[BASILISK_ALICERECLAIM] == 0 ) + { + privBn = basilisk_swap_privBn_extract(myinfo,&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",myinfo,alicecoin,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_ALICERECLAIM])) != 0 ) + printf("privBn.(%s) alicereclaim.(%s)\n",bits256_str(str,privBn),txbytes[BASILISK_ALICERECLAIM]); + } + } + if ( txbytes[BASILISK_ALICERECLAIM] != 0 ) + { + txids[BASILISK_ALICERECLAIM] = basilisk_swap_sendrawtransaction(myinfo,"alicereclaim",alicecoin,txbytes[BASILISK_ALICERECLAIM]); + if ( bits256_nonz(txids[BASILISK_ALICERECLAIM]) != 0 ) // tested + { + sentflags[BASILISK_ALICERECLAIM] = 1; + Apaymentspent = txids[BASILISK_ALICERECLAIM]; + } + } + } + } + else if ( iambob == 1 ) + { + if ( sentflags[BASILISK_BOBSPEND] == 0 && bits256_nonz(Apaymentspent) == 0 ) + { + printf("try to bobspend aspend.%s have privAm.%d\n",bits256_str(str,txids[BASILISK_ALICESPEND]),bits256_nonz(privAm)); + if ( bits256_nonz(txids[BASILISK_ALICESPEND]) != 0 || bits256_nonz(privAm) != 0 ) + { + //if ( txbytes[BASILISK_BOBSPEND] == 0 ) + { + if ( bits256_nonz(privAm) == 0 ) + { + privAm = basilisk_swap_privbob_extract(myinfo,bobcoin,txids[BASILISK_ALICESPEND],0,1); + } + if ( bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 ) + { + if ( (txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",myinfo,alicecoin,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_BOBSPEND])) != 0 ) + printf("bobspend.(%s)\n",txbytes[BASILISK_BOBSPEND]); + } + } + if ( txbytes[BASILISK_BOBSPEND] != 0 ) + { + txids[BASILISK_BOBSPEND] = basilisk_swap_sendrawtransaction(myinfo,"bobspend",alicecoin,txbytes[BASILISK_BOBSPEND]); + if ( bits256_nonz(txids[BASILISK_BOBSPEND]) != 0 ) // tested + { + sentflags[BASILISK_BOBSPEND] = 1; + Apaymentspent = txids[BASILISK_BOBSPEND]; + } + } + } + } + if ( sentflags[BASILISK_BOBRECLAIM] == 0 && sentflags[BASILISK_BOBPAYMENT] != 0 && bits256_nonz(txids[BASILISK_BOBPAYMENT]) != 0 && time(NULL) > expiration && bits256_nonz(paymentspent) == 0 ) + { + //if ( txbytes[BASILISK_BOBRECLAIM] == 0 ) + { + // bobreclaim + redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,plocktime,pubA0,pubB0,pubB1,zero,privBn,secretAm,secretAm256,secretBn,secretBn256); + if ( redeemlen > 0 ) + { + len = basilisk_swapuserdata(userdata,zero,1,myprivs[1],redeemscript,redeemlen); + if ( (txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend("bobrefund",myinfo,bobcoin,myprivs[1],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,pubkey33,0,expiration,&values[BASILISK_BOBRECLAIM])) != 0 ) + { + int32_t z; + for (z=0; z<20; z++) + printf("%02x",secretAm[z]); + printf(" secretAm, myprivs[1].(%s) bobreclaim.(%s)\n",bits256_str(str,myprivs[1]),txbytes[BASILISK_BOBRECLAIM]); + } + } + } + if ( txbytes[BASILISK_BOBRECLAIM] != 0 ) + { + txids[BASILISK_BOBRECLAIM] = basilisk_swap_sendrawtransaction(myinfo,"bobreclaim",bobcoin,txbytes[BASILISK_BOBRECLAIM]); + if ( bits256_nonz(txids[BASILISK_BOBRECLAIM]) != 0 ) // tested + { + sentflags[BASILISK_BOBRECLAIM] = 1; + paymentspent = txids[BASILISK_BOBRECLAIM]; + } + } + } + if ( sentflags[BASILISK_BOBREFUND] == 0 && sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(depositspent) == 0 ) + { + if ( bits256_nonz(paymentspent) != 0 || time(NULL) > expiration ) + { + printf("do the refund!\n"); + //if ( txbytes[BASILISK_BOBREFUND] == 0 ) + { + revcalc_rmd160_sha256(secretBn,privBn); + 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("bobrefund",myinfo,bobcoin,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,pubkey33,1,expiration,&values[BASILISK_BOBREFUND])) != 0 ) + printf("pubB1.(%s) bobrefund.(%s)\n",bits256_str(str,pubB1),txbytes[BASILISK_BOBREFUND]); + } + if ( txbytes[BASILISK_BOBREFUND] != 0 ) + { + txids[BASILISK_BOBREFUND] = basilisk_swap_sendrawtransaction(myinfo,"bobrefund",bobcoin,txbytes[BASILISK_BOBREFUND]); + if ( bits256_nonz(txids[BASILISK_BOBREFUND]) != 0 ) // tested + { + sentflags[BASILISK_BOBREFUND] = 1; + depositspent = txids[BASILISK_BOBREFUND]; + } + } + } else printf("time %u vs expiration %u\n",(uint32_t)time(NULL),expiration); + } + } + } + //printf("finish.%d iambob.%d REFUND %d %d %d %d\n",finishedflag,iambob,sentflags[BASILISK_BOBREFUND] == 0,sentflags[BASILISK_BOBDEPOSIT] != 0,bits256_nonz(txids[BASILISK_BOBDEPOSIT]) != 0,bits256_nonz(depositspent) == 0); + if ( sentflags[BASILISK_ALICESPEND] != 0 || sentflags[BASILISK_BOBRECLAIM] != 0 ) + sentflags[BASILISK_BOBPAYMENT] = 1; + if ( sentflags[BASILISK_ALICERECLAIM] != 0 || sentflags[BASILISK_BOBSPEND] != 0 ) + sentflags[BASILISK_ALICEPAYMENT] = 1; + if ( sentflags[BASILISK_ALICECLAIM] != 0 || sentflags[BASILISK_BOBREFUND] != 0 ) + sentflags[BASILISK_BOBDEPOSIT] = 1; + for (i=0; inumswaps; i++) + if ( (swap= myinfo->swaps[i]) != 0 && swap->I.req.requestid == requestid && swap->I.req.quoteid == quoteid ) + { + jaddi(array,basilisk_swapjson(myinfo,swap)); + flag = 1; + break; + } + if ( flag == 0 ) + { + if ( (item= basilisk_remember(myinfo,KMDtotals,BTCtotals,requestid,quoteid)) != 0 ) + { + jaddi(array,item); + if ( 1 && (status= jstr(item,"status")) != 0 && strcmp(status,"pending") == 0 ) + break; + } + } + } + fclose(fp); + } + jaddstr(retjson,"result","success"); + jadd(retjson,"swaps",array); + if ( cJSON_GetArraySize(array) > 0 ) + { + totalsobj = cJSON_CreateObject(); + for (Btotal=i=0; i 0 && Btotal < 0 ) + jaddnum(retjson,"avebuy",(double)-Btotal/Ktotal); + else if ( Ktotal < 0 && Btotal > 0 ) + jaddnum(retjson,"avesell",(double)-Btotal/Ktotal); + } + array = cJSON_CreateArray(); + for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) + { + if ( myinfo->linfos[i].base[0] != 0 && myinfo->linfos[i].rel[0] != 0 ) + jaddi(array,linfo_json(&myinfo->linfos[i])); + } + jadd(retjson,"quotes",array); return(jprint(retjson,1)); } diff --git a/basilisk/basilisk_tradebot.c b/basilisk/basilisk_tradebot.c index 5d16548dc..2635cde97 100755 --- a/basilisk/basilisk_tradebot.c +++ b/basilisk/basilisk_tradebot.c @@ -228,7 +228,9 @@ struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *r rp->desthash = jbits256(reqjson,"desthash"); rp->srcamount = j64bits(reqjson,"srcamount"); rp->minamount = j64bits(reqjson,"minamount"); - rp->destamount = j64bits(reqjson,"destamount"); + //rp->destamount = j64bits(reqjson,"destamount"); + rp->destamount = j64bits(reqjson,"destsatoshis"); + //printf("parse DESTSATOSHIS.%llu (%s)\n",(long long)rp->destamount,jprint(reqjson,0)); requestid = juint(reqjson,"requestid"); quoteid = juint(reqjson,"quoteid"); //if ( jstr(reqjson,"relay") != 0 ) @@ -279,7 +281,7 @@ int32_t basilisk_request_cmpref(struct basilisk_request *ref,struct basilisk_req double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk_request *issueR,struct basilisk_request *list,int32_t n) { - int32_t i,noquoteflag=0,havequoteflag=0,myrequest=0,maxi=-1; int64_t balance=0,destamount,minamount = 0,maxamount = 0; bits256 privkey; uint32_t pendingid=0; struct basilisk_swap *active; double metric = 0.; + int32_t i,noquoteflag=0,havequoteflag=0,myrequest=0,maxi=-1; int64_t balance=0,destamount,minamount = 0,maxamount = 0; bits256 privkey; uint32_t pendingid=0; struct basilisk_swap *active; double metric = 0.,bidasks[2]; char typestr[64]; memset(issueR,0,sizeof(*issueR)); minamount = list[0].minamount; //printf("need to verify null quoteid is list[0] requestid.%u quoteid.%u\n",list[0].requestid,list[0].quoteid); @@ -289,7 +291,7 @@ double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk return(0.); pendingid = active->I.req.quoteid; } - if ( smartaddress_pubkey(myinfo,&privkey,list[0].srchash) >= 0 ) + if ( smartaddress_pubkey(myinfo,typestr,bidasks,&privkey,list[0].src,list[0].srchash) >= 0 ) myrequest = 1; for (i=0; i= 0 ) + if ( smartaddress_pubkey(myinfo,typestr,bidasks,&privkey,list[i].dest,list[i].desthash) >= 0 ) myrequest |= 2; havequoteflag++; if ( pendingid == 0 ) @@ -305,6 +307,7 @@ double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk if ( list[i].destamount > maxamount ) { maxamount = list[i].destamount; + //printf("set maxamount %llu\n",(long long)maxamount); maxi = i; } } @@ -313,28 +316,39 @@ double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk } } else noquoteflag++; } - // MVP -> USD myrequest.0 pendingid.0 noquoteflag.1 havequoteflag.0 maxi.-1 0.00000000 - double retvals[4],refprice=0.,profitmargin,aveprice,destvolume; cJSON *retjson; char *retstr; + struct iguana_info *coin; char coinaddr[64]; double retvals[4],refprice=0.,profitmargin,aveprice,destvolume; destvolume = dstr(maxamount); + //printf("destvolume <- %.8f\n",dstr(destvolume)); if ( fabs(destvolume) < SMALLVAL ) { if ( (destvolume= dstr(minamount)) == 0 ) { aveprice = instantdex_avehbla(myinfo,retvals,list[0].src,list[0].dest,1.3 * dstr(list[0].srcamount)); destvolume = aveprice * dstr(list[0].srcamount); - } + printf("set destvolume %.8f\n",destvolume); + } // else printf("destvolume %.8f <- minamount\n",destvolume); } - printf("%s -> %s myrequest.%d pendingid.%u noquoteflag.%d havequoteflag.%d maxi.%d %.8f destvol %f\n",list[0].src,list[0].dest,myrequest,pendingid,noquoteflag,havequoteflag,maxi,dstr(maxamount),destvolume); + printf("<<<<<<< %s -> %s myrequest.%d pendingid.%u noquoteflag.%d havequoteflag.%d maxi.%d %.8f destvol %.8f\n",list[0].src,list[0].dest,myrequest,pendingid,noquoteflag,havequoteflag,maxi,dstr(maxamount),destvolume); if ( myinfo->IAMLP != 0 && myrequest == 0 && pendingid == 0 && noquoteflag != 0 && ((profitmargin= tradebot_liquidity_active(myinfo,&refprice,"DEX",list[0].src,list[0].dest,destvolume)) > 0. || refprice != 0.) ) { - if ( profitmargin == 0 || (aveprice= instantdex_avehbla(myinfo,retvals,list[0].src,list[0].dest,1.3 * dstr(list[0].srcamount))) == 0. || refprice > aveprice ) + if ( profitmargin == 0. || (aveprice= instantdex_avehbla(myinfo,retvals,list[0].src,list[0].dest,.1 * dstr(list[0].srcamount))) == 0. || refprice > aveprice ) aveprice = refprice; if ( fabs(aveprice) < SMALLVAL ) return(0); + if ( strcmp("BTC",list[0].src) == 0 ) + aveprice = (1. / aveprice); //retvals[0] = avebid, retvals[1] = bidvol, retvals[2] = aveask, retvals[3] = askvol; - destamount = (1.0 - profitmargin) * aveprice * list[0].srcamount * SATOSHIDEN; - printf("aveprice %f dest %.8f avebid %f bidvol %f, aveask %f askvol %f\n",aveprice,dstr(destamount),retvals[0],retvals[1],retvals[2],retvals[3]); - if ( (retstr= InstantDEX_available(myinfo,iguana_coinfind(list[0].dest),0,0,list[0].dest)) != 0 ) + destamount = (1.0 - profitmargin) * aveprice * list[0].srcamount; + if ( destamount > minamount ) + destamount = minamount + ((destamount - minamount) * (1 + (rand() % 100))) / 100.; + printf("%s/%s pm %f aveprice %f src %.8f dest %.8f avebid %f bidvol %f, aveask %f askvol %f\n",list[0].src,list[0].dest,profitmargin,aveprice,dstr(list[0].srcamount),dstr(destamount),retvals[0],retvals[1],retvals[2],retvals[3]); + if ( (coin= iguana_coinfind(list[0].dest)) != 0 ) + { + bitcoin_address(coinaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); + balance = jumblr_balance(myinfo,coin,coinaddr); + printf("%s %s balance %.8f destamount %.8f aveprice %.8f maxamount %.8f minamount %.8f\n",list[0].dest,coinaddr,dstr(balance),dstr(destamount),aveprice,dstr(maxamount),dstr(minamount)); + } + /*if ( (retstr= InstantDEX_available(myinfo,iguana_coinfind(list[0].dest),0,0,list[0].dest)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { @@ -342,9 +356,7 @@ double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk free_json(retjson); } free(retstr); - } - // BTC balance 0.00500000 destamount 0.00041951 aveprice 0.00421619 minamount 0.00020000 - printf("%s balance %.8f destamount %.8f aveprice %.8f maxamount %.8f minamount %.8f\n",list[0].dest,dstr(balance),dstr(destamount),aveprice,dstr(maxamount),dstr(minamount)); + }*/ if ( balance > destamount && (int64_t)destamount > 0 && destamount >= minamount ) // max? { metric = 1.; @@ -357,12 +369,12 @@ double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk } else if ( myrequest != 0 && pendingid == 0 && maxi >= 0 ) // automatch best quote { - if ( minamount != 0 && maxamount >= minamount && time(NULL) > list[0].timestamp+BASILISK_AUCTION_DURATION ) + if ( minamount != 0 && maxamount >= minamount )//&& time(NULL) > list[0].timestamp+BASILISK_AUCTION_DURATION ) { *issueR = list[maxi]; for (i=0; i %.8f\n",maxi,list[maxi].requestid,list[maxi].quoteid,dstr(maxamount),dstr(minamount)); + printf(" automatch[%d] r.%u quoteid.%u triggered %.8f >= %.8f\n",maxi,list[maxi].requestid,list[maxi].quoteid,dstr(maxamount),dstr(minamount)); if ( minamount > 0 ) metric = (dstr(maxamount) / dstr(minamount)) - 1.; else metric = 1.; diff --git a/basilisk/jumblr.c b/basilisk/jumblr.c index 0710007c6..9618a9421 100755 --- a/basilisk/jumblr.c +++ b/basilisk/jumblr.c @@ -27,19 +27,19 @@ z_sendmany "fromaddress" [{"address":... ,"amount":..., "memo":""},...] ( minconf ) ( fee ) */ -#define JUMBLR_INCR 99.65 -#define JUMBLR_TXFEE 0.01 #define JUMBLR_ADDR "RGhxXpXSSBTBm9EvNsXnTQczthMCxHX91t" #define JUMBLR_BTCADDR "18RmTJe9qMech8siuhYfMtHo8RtcN1obC6" -#define JUMBLR_FEE 0.001 int32_t jumblr_addresstype(struct supernet_info *myinfo,struct iguana_info *coin,char *addr) { - if ( addr[0] == 'z' && addr[1] == 'c' && strlen(addr) >= 40 ) - return('z'); - else if ( strlen(addr) < 40 ) - return('t'); - else return(-1); + if ( strcmp(coin->symbol,"KMD") == 0 ) + { + if ( addr[0] == 'z' && addr[1] == 'c' && strlen(addr) >= 40 ) + return('z'); + else if ( strlen(addr) < 40 ) + return('t'); + else return(-1); + } else return('t'); } struct jumblr_item *jumblr_opidfind(struct supernet_info *myinfo,char *opid) @@ -170,10 +170,12 @@ char *jumblr_zgetbalance(struct supernet_info *myinfo,struct iguana_info *coin,c return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"z_getbalance",params)); } -char *jumblr_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *addr) +char *jumblr_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) { char params[1024]; - sprintf(params,"[1, 99999999, [\"%s\"]]",addr); + if ( coin->FULLNODE == 0 ) + return(dex_listunspent(myinfo,coin,0,0,coin->symbol,coinaddr)); + sprintf(params,"[1, 99999999, [\"%s\"]]",coinaddr); return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",params)); } @@ -193,10 +195,11 @@ int64_t jumblr_balance(struct supernet_info *myinfo,struct iguana_info *coin,cha char *retstr; double val; cJSON *retjson; int32_t i,n; int64_t balance = 0; if ( jumblr_addresstype(myinfo,coin,addr) == 't' ) { - if ( coin->FULLNODE < 0 && jumblr_ismine(myinfo,coin,addr) > 0 ) + if ( coin->FULLNODE < 0 && iguana_isnotarychain(coin->symbol) < 0 ) { if ( (retstr= jumblr_listunspent(myinfo,coin,addr)) != 0 ) { + printf("jumblr.[%s].(%s)\n",coin->symbol,retstr); if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( (n= cJSON_GetArraySize(retjson)) > 0 ) @@ -209,10 +212,11 @@ int64_t jumblr_balance(struct supernet_info *myinfo,struct iguana_info *coin,cha } else if ( (retstr= dex_getbalance(myinfo,coin,0,0,coin->symbol,addr)) != 0 ) { - //printf("retstr.(%s)\n",retstr); + //printf("DEX retstr.(%s)\n",retstr); if ( (retjson= cJSON_Parse(retstr)) != 0 ) { balance = jdouble(retjson,"balance") * SATOSHIDEN; + //printf("GOT BALANCE %s %.8f\n",coin->symbol,dstr(balance)); free_json(retjson); } free(retstr); @@ -289,8 +293,8 @@ void jumblr_opidupdate(struct supernet_info *myinfo,struct iguana_info *coin,str if ( strcmp(status,"success") == 0 ) { ptr->status = jumblr_itemset(ptr,item,status); - jumblr_privkey(myinfo,BTCaddr,KMDdeposit,JUMBLR_DEPOSITPREFIX); - jumblr_privkey(myinfo,BTCaddr,KMDjumblr,""); + jumblr_privkey(myinfo,BTCaddr,0,KMDdeposit,JUMBLR_DEPOSITPREFIX); + jumblr_privkey(myinfo,BTCaddr,0,KMDjumblr,""); if ( (jumblr_addresstype(myinfo,coin,ptr->src) == 't' && jumblr_addresstype(myinfo,coin,ptr->src) == 'z' && strcmp(ptr->src,KMDdeposit) != 0) || (jumblr_addresstype(myinfo,coin,ptr->src) == 'z' && jumblr_addresstype(myinfo,coin,ptr->src) == 't' && strcmp(ptr->dest,KMDjumblr) != 0) ) { printf("a non-jumblr t->z pruned\n"); @@ -364,79 +368,309 @@ void jumblr_opidsupdate(struct supernet_info *myinfo,struct iguana_info *coin) } } -bits256 jumblr_privkey(struct supernet_info *myinfo,char *BTCaddr,char *KMDaddr,char *prefix) +int64_t jumblr_DEXsplit(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *splittxidp,char *coinaddr,bits256 txid,int32_t vout,int64_t remaining,double bigprice,double middleprice,double smallprice,double fees[4],cJSON *privkeys,double esttxfee) +{ + int64_t values[4],outputs[64],value,total,estfee; int32_t i,n,success=0,completed,sendflag,numoutputs = 0; char *retstr; cJSON *retjson,*utxo,*item; + total = 0; + estfee = SATOSHIDEN * esttxfee; + memset(values,0,sizeof(values)); + memset(outputs,0,sizeof(outputs)); + if ( bigprice > SMALLVAL ) + values[0] = SATOSHIDEN * bigprice; + if ( middleprice > SMALLVAL ) + values[1] = SATOSHIDEN * middleprice; + if ( smallprice > SMALLVAL ) + values[2] = SATOSHIDEN * smallprice; + for (i=0; i<4; i++) + { + if ( fees[i] > SMALLVAL ) + values[3+i] = SATOSHIDEN * fees[i]; + } + for (i=0; i<7; i++) + { + if ( (value= values[i]) != 0 ) + { + n = 0; + while ( n < 10 && remaining > value && numoutputs < sizeof(outputs)/sizeof(*outputs) ) + { + outputs[numoutputs++] = value; + remaining -= value; + total += value; + printf("%.8f ",dstr(value)); + n++; + } + } + } + char str[65]; printf("numoutputs.%d total %.8f %s/v%d\n",numoutputs,dstr(total),bits256_str(str,txid),vout); + if ( numoutputs > 1 ) // no point to make just one + { + if ( (retstr= _dex_gettxout(myinfo,coin->symbol,txid,vout)) != 0 ) + { + item = cJSON_Parse(retstr); + jaddbits256(item,"txid",txid); + jaddnum(item,"vout",vout); + free(retstr); + if ( item != 0 ) + { + utxo = cJSON_CreateArray(); + jaddi(utxo,item); + sendflag = 0; + ///printf("jitem.(%s)\n",jprint(utxo,0)); + if ( (retstr= iguana_utxorawtx(myinfo,coin,0,coinaddr,coinaddr,outputs,numoutputs,0,&completed,sendflag,utxo,privkeys)) != 0 ) + { + if ( completed != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,"error") == 0 && jobj(retjson,"sent") != 0 ) + { + *splittxidp = jbits256(retjson,"sent"); + success = 1; + printf("DEXsplit success %.8f\n",dstr(total)); + } + free_json(retjson); + } + } + free(retstr); + } + free_json(utxo); + } + } + } + return(success * total); +} + +double jumblr_DEXutxosize(double *targetvolBp,double *targetvolMp,double *targetvolSp,int32_t isbob,double kmdprice) +{ + double fee,depositfactor = (isbob == 0) ? 1. : 1.2; + fee = JUMBLR_INCR * JUMBLR_FEE; + *targetvolBp = depositfactor * kmdprice * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE); + *targetvolMp = depositfactor * kmdprice * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE); + *targetvolSp = depositfactor * kmdprice * ((JUMBLR_INCR + 3*fee) + 3*JUMBLR_TXFEE); + return(depositfactor); +} + +int32_t jumblr_DEXutxoind(int32_t *shouldsplitp,double targetvolB,double targetvolM,double targetvolS,double amount,double margin,double dexfeeratio,double esttxfee) +{ + *shouldsplitp = 0; + if ( amount >= targetvolB ) + { + if ( amount > margin * (targetvolB + targetvolS) ) + *shouldsplitp = 1; + return(0); + } + else + { + if ( amount >= targetvolM ) + { + if ( amount > margin * (targetvolM + targetvolS) ) + *shouldsplitp = 1; + return(1); + } + else + { + if ( amount >= targetvolS ) + { + if ( amount > margin * targetvolS ) + *shouldsplitp = 1; + return(2); + } + else if ( amount >= targetvolB/dexfeeratio ) + { + if ( amount > margin * targetvolB/dexfeeratio ) + *shouldsplitp = 1; + return(3); + } + else if ( amount >= targetvolM/dexfeeratio ) + { + if ( amount > margin * targetvolM/dexfeeratio ) + *shouldsplitp = 1; + return(4); + } + else if ( amount >= targetvolS/dexfeeratio ) + { + if ( amount > margin * targetvolS/dexfeeratio ) + *shouldsplitp = 1; + return(5); + } + else if ( amount >= esttxfee ) + { + if ( amount > esttxfee*4 ) + *shouldsplitp = 1; + return(6); + } + else return(-1); + } + } +} + +int32_t jumblr_DEXutxoupdate(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *shouldsplitp,bits256 *splittxidp,char *coinaddr,bits256 privkey,bits256 txid,int32_t vout,uint64_t value,int32_t isbob,double kmdprice,double estfee) { - bits256 privkey,pubkey; uint8_t pubkey33[33]; char passphrase[sizeof(myinfo->jumblr_passphrase) + 64]; - sprintf(passphrase,"%s%s",prefix,myinfo->jumblr_passphrase); - conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); - bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey); - bitcoin_address(BTCaddr,0,pubkey33,33); - bitcoin_address(KMDaddr,60,pubkey33,33); - return(privkey); + double fees[4],targetvolB,amount,targetvolM,targetvolS,depositfactor,dexfeeratio,margin; int32_t ind = -1,i; cJSON *privkeys; char wifstr[128]; + *shouldsplitp = 0; + margin = 1.1; + depositfactor = (isbob == 0) ? 1. : 1.2; + dexfeeratio = 500.; + amount = dstr(value); + memset(splittxidp,0,sizeof(*splittxidp)); + depositfactor = jumblr_DEXutxosize(&targetvolB,&targetvolM,&targetvolS,isbob,kmdprice); + printf("depositfactor %.8f targetvols %.8f %.8f %.8f\n",depositfactor,targetvolB,targetvolM,targetvolS); + fees[0] = (margin * targetvolB) / dexfeeratio; + fees[1] = (margin * targetvolM) / dexfeeratio; + fees[2] = (margin * targetvolS) / dexfeeratio; + fees[3] = (strcmp("BTC",coin->symbol) == 0) ? 50000 : 10000; + for (i=0; i<4; i++) + if ( fees[i] < 10000 ) + fees[i] = 10000; + if ( (ind= jumblr_DEXutxoind(shouldsplitp,targetvolB,targetvolM,targetvolS,amount,margin,dexfeeratio,fees[3])) >= 0 ) + { + printf("shouldsplit.%d ind.%d\n",*shouldsplitp,ind); + if ( *shouldsplitp != 0 ) + { + privkeys = cJSON_CreateArray(); + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + jaddistr(privkeys,wifstr); + if ( jumblr_DEXsplit(myinfo,coin,splittxidp,coinaddr,txid,vout,value,margin * targetvolB,margin * targetvolM,margin * targetvolS,fees,privkeys,estfee) > 0 ) + ind = -1; + else *shouldsplitp = 0; + free_json(privkeys); + } + } // else printf("negative ind\n"); + return(ind); } -void jumblr_DEXcheck(struct supernet_info *myinfo,struct iguana_info *coinkmd,char *BTCaddr,char *KMDaddr,bits256 privkey) +/*struct DEXcoin_info + { + bits256 deposit_privkey,jumblr_privkey; + struct iguana_info *coin; + cJSON *utxos,*spentutxos,*bigutxos,*normalutxos,*smallutxos,*feeutxos,*otherutxos; + double btcprice,USD_average,DEXpending,maxbid,minask,avail,KMDavail; + uint32_t lasttime; + char CMCname[32],symbol[16],depositaddr[64],KMDdepositaddr[64],KMDjumblraddr[64],jumblraddr[64]; + };*/ + +int32_t jumblr_utxotxidpending(struct supernet_info *myinfo,bits256 *splittxidp,int32_t *indp,struct iguana_info *coin,bits256 txid,int32_t vout) { - static double kmdprice,pending; static uint32_t lasttime; - double btcavail=0,minbtc,avebid,aveask,highbid,lowask,CMC_average,USD_average,changes[3]; struct iguana_info *coinbtc; cJSON *vals; bits256 hash; char *retstr; - coinbtc = iguana_coinfind("BTC"); - if ( kmdprice == 0. || time(NULL) > lasttime+60 ) + int32_t i; + memset(splittxidp,0,sizeof(*splittxidp)); + for (i=0; iDEXinfo.numpending; i++) { - kmdprice = get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,"komodo","KMD","BTC",&USD_average); - lasttime = (uint32_t)time(NULL); - printf("KMD %.8f\n",kmdprice); + if ( coin->DEXinfo.pending[i].vout == vout && bits256_cmp(coin->DEXinfo.pending[i].txid,txid) == 0 ) + { + *indp = coin->DEXinfo.pending[i].ind; + *splittxidp = coin->DEXinfo.pending[i].splittxid; + // printf("jumblr_utxotxidpending found txid in slot.%d\n",i); + return(i); + } } - if ( kmdprice > SMALLVAL ) + // printf("jumblr_utxotxidpending cant find txid\n"); + return(-1); +} + +void jumblr_utxotxidpendingadd(struct supernet_info *myinfo,char *dest,struct iguana_info *coin,bits256 txid,int32_t vout,uint64_t value,bits256 splittxid,int32_t ind,double price,double estfee,int32_t shouldsplit) +{ + struct jumblr_pending pend; cJSON *vals,*retjson; bits256 hash; char *retstr; + memset(&pend,0,sizeof(pend)); + pend.splittxid = splittxid; + pend.txid = txid; + pend.vout = vout; + pend.ind = ind; + if ( 0 && myinfo->IAMLP == 0 && shouldsplit == 0 && ind < 3 ) { - minbtc = (kmdprice * 1.1) * (JUMBLR_INCR + 3*(JUMBLR_INCR * JUMBLR_FEE + JUMBLR_TXFEE)); - if ( coinbtc != 0 && (btcavail= dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))) > minbtc+pending ) + static uint32_t num; + if ( num == 0 && price > SMALLVAL ) { - printf("BTC deposits %.8f, min %.8f\n",btcavail,minbtc); + num++; vals = cJSON_CreateObject(); - jaddstr(vals,"source","BTC"); - //hash = curve25519(privkey,curve25519_basepoint9()); - jaddstr(vals,"dest","KMD"); - jaddnum(vals,"amount",btcavail*.3); - jaddnum(vals,"minprice",kmdprice*.95); + jaddstr(vals,"source",coin->symbol); + jaddstr(vals,"dest",dest); + jaddnum(vals,"amount",price * 100);//dstr(value) - estfee); + jaddnum(vals,"minprice",price); jaddnum(vals,"usejumblr",1); memset(hash.bytes,0,sizeof(hash)); - pending = btcavail; - if ( (retstr= InstantDEX_request(myinfo,coinbtc,0,0,hash,vals,"")) != 0 ) + if ( (retstr= InstantDEX_request(myinfo,coin,0,0,hash,vals,"")) != 0 ) { - printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr); + free_json(retjson); + } free(retstr); } - // curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"request\",\"vals\":{\"source\":\"KMD\",\"amount\":20,\"dest\":\"USD\",\"minprice\":0.08}}" - } //else printf("btcavail %.8f pending %.8f\n",btcavail,pending); - } else printf("null kmdprice %.8f\n",kmdprice); + free_json(vals); + } + } + coin->DEXinfo.pending = realloc(coin->DEXinfo.pending,sizeof(*coin->DEXinfo.pending) * (1 + coin->DEXinfo.numpending)); + coin->DEXinfo.pending[coin->DEXinfo.numpending++] = pend; +} + +void jumblr_utxoupdate(struct supernet_info *myinfo,char *dest,struct iguana_info *coin,double price,char *coinaddr,bits256 privkey,double estfee) +{ + char *retstr; cJSON *array,*item; int32_t shouldsplit,i,n,vout,ind; bits256 txid,splittxid; uint64_t value; + if ( (retstr= jumblr_listunspent(myinfo,coin,coinaddr)) != 0 ) + { + //printf("%s.(%s)\n",coin->symbol,retstr); + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; iIAMLP,price,estfee); + jumblr_utxotxidpendingadd(myinfo,dest,coin,txid,vout,value,splittxid,ind,price,estfee,shouldsplit); + } + else + { + // update status of utxo + } + } + } + free_json(array); + } + free(retstr); + } } void jumblr_iteration(struct supernet_info *myinfo,struct iguana_info *coin,int32_t selector,int32_t modval) { //static uint32_t lasttime; - char BTCaddr[64],KMDaddr[64],*zaddr,*retstr; bits256 privkey; uint64_t amount=0,total=0; double fee; struct jumblr_item *ptr,*tmp; uint8_t r; + char BTCaddr[64],KMDaddr[64],*zaddr,*retstr; int32_t iter,counter,chosen_one,n; bits256 privkey; uint64_t amount=0,total=0; double fee; struct jumblr_item *ptr,*tmp; uint8_t r,s; + if ( myinfo->IAMNOTARY != 0 ) + return; fee = JUMBLR_INCR * JUMBLR_FEE; OS_randombytes(&r,sizeof(r)); //r = 0; + // randomize size chosen and order of chunks if ( strcmp(coin->symbol,"KMD") == 0 && coin->FULLNODE < 0 ) { + s = (selector + (r>>1)) % 3; //printf("JUMBLR selector.%d modval.%d r.%d\n",selector,modval,r&7); - switch ( selector ) + switch ( s ) { case 0: // public -> z, need to importprivkey - jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); + jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,JUMBLR_DEPOSITPREFIX); if ( (total= jumblr_balance(myinfo,coin,KMDaddr)) >= (JUMBLR_INCR + 3*(fee+JUMBLR_TXFEE))*SATOSHIDEN ) { if ( (r & 1) == 0 ) { if ( (zaddr= jumblr_zgetnewaddress(myinfo,coin)) != 0 ) { + amount = 0; if ( total >= SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE) ) amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE); - else if ( total >= SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE) ) + if ( (r & 2) != 0 && total >= SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE) ) amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE); - else amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee) + 3*JUMBLR_TXFEE); - if ( (retstr= jumblr_sendt_to_z(myinfo,coin,KMDaddr,zaddr,dstr(amount))) != 0 ) + if ( (r & 4) != 0 ) + amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee) + 3*JUMBLR_TXFEE); + if ( amount > 0 && (retstr= jumblr_sendt_to_z(myinfo,coin,KMDaddr,zaddr,dstr(amount))) != 0 ) { printf("sendt_to_z.(%s)\n",retstr); free(retstr); @@ -448,43 +682,86 @@ void jumblr_iteration(struct supernet_info *myinfo,struct iguana_info *coin,int3 break; case 1: // z -> z jumblr_opidsupdate(myinfo,coin); - HASH_ITER(hh,myinfo->jumblrs,ptr,tmp) + chosen_one = -1; + for (iter=counter=0; iter<2; iter++) { - if ( jumblr_addresstype(myinfo,coin,ptr->src) == 't' && jumblr_addresstype(myinfo,coin,ptr->dest) == 'z' ) + counter = n = 0; + HASH_ITER(hh,myinfo->jumblrs,ptr,tmp) { - if ( (r & 1) == 0 && ptr->spent == 0 && (total= jumblr_balance(myinfo,coin,ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) + if ( jumblr_addresstype(myinfo,coin,ptr->src) == 't' && jumblr_addresstype(myinfo,coin,ptr->dest) == 'z' ) { - if ( (zaddr= jumblr_zgetnewaddress(myinfo,coin)) != 0 ) + if ( (r & 1) == 0 && ptr->spent == 0 && (total= jumblr_balance(myinfo,coin,ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) { - if ( (retstr= jumblr_sendz_to_z(myinfo,coin,ptr->dest,zaddr,dstr(total))) != 0 ) + if ( iter == 1 && counter == chosen_one ) { - printf("sendz_to_z.(%s)\n",retstr); - free(retstr); + if ( (zaddr= jumblr_zgetnewaddress(myinfo,coin)) != 0 ) + { + if ( (retstr= jumblr_sendz_to_z(myinfo,coin,ptr->dest,zaddr,dstr(total))) != 0 ) + { + printf("n.%d counter.%d chosen_one.%d sendz_to_z.(%s)\n",n,counter,chosen_one,retstr); + free(retstr); + } + ptr->spent = (uint32_t)time(NULL); + free(zaddr); + break; + } } - ptr->spent = (uint32_t)time(NULL); - free(zaddr); - break; + counter++; } } + n++; + } + if ( counter == 0 ) + break; + if ( iter == 0 ) + { + OS_randombytes((uint8_t *)&chosen_one,sizeof(chosen_one)); + if ( chosen_one < 0 ) + chosen_one = -chosen_one; + chosen_one %= counter; + printf("jumblr z->z chosen_one.%d of %d, from %d\n",chosen_one,counter,n); } } break; case 2: // z -> public - jumblr_opidsupdate(myinfo,coin); - HASH_ITER(hh,myinfo->jumblrs,ptr,tmp) + if ( myinfo->runsilent == 0 ) { - if ( jumblr_addresstype(myinfo,coin,ptr->src) == 'z' && jumblr_addresstype(myinfo,coin,ptr->dest) == 'z' ) + jumblr_opidsupdate(myinfo,coin); + chosen_one = -1; + for (iter=0; iter<2; iter++) { - if ( (r & 1) == 0 && ptr->spent == 0 && (total= jumblr_balance(myinfo,coin,ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) + counter = n = 0; + HASH_ITER(hh,myinfo->jumblrs,ptr,tmp) { - privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); - if ( (retstr= jumblr_sendz_to_t(myinfo,coin,ptr->dest,KMDaddr,dstr(total))) != 0 ) + if ( jumblr_addresstype(myinfo,coin,ptr->src) == 'z' && jumblr_addresstype(myinfo,coin,ptr->dest) == 'z' ) { - printf("sendz_to_t.(%s)\n",retstr); - free(retstr); + if ( (r & 1) == 0 && ptr->spent == 0 && (total= jumblr_balance(myinfo,coin,ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) + { + if ( iter == 1 && n == chosen_one ) + { + privkey = jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,""); + if ( (retstr= jumblr_sendz_to_t(myinfo,coin,ptr->dest,KMDaddr,dstr(total))) != 0 ) + { + printf("sendz_to_t.(%s)\n",retstr); + free(retstr); + } + ptr->spent = (uint32_t)time(NULL); + break; + } + counter++; + } } - ptr->spent = (uint32_t)time(NULL); + n++; + } + if ( counter == 0 ) break; + if ( iter == 0 ) + { + OS_randombytes((uint8_t *)&chosen_one,sizeof(chosen_one)); + if ( chosen_one < 0 ) + chosen_one = -chosen_one; + chosen_one %= counter; + printf("jumblr z->t chosen_one.%d of %d, from %d\n",chosen_one,counter,n); } } } diff --git a/basilisk/smartaddress.c b/basilisk/smartaddress.c index ff9707b0c..727a54709 100755 --- a/basilisk/smartaddress.c +++ b/basilisk/smartaddress.c @@ -15,21 +15,206 @@ // included from basilisk.c -int32_t smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *BTCaddr,char *KMDaddr) +// deposit address -> corresponding KMD address, if KMD deposit starts JUMBLR +// jumblr address is the destination of JUMBLR and JUMBLR BTC (would need tracking to map back to non-BTC) +// address is DEX'ed for + +// return value convention: -1 error, 0 partial match, >= 1 exact match + +int32_t smartaddress_type(char *typestr) +{ + char upper[64]; + if ( strcmp(typestr,"deposit") != 0 && strcmp(typestr,"jumblr") != 0 && strcmp(typestr,"dividend") != 0 && strcmp(typestr,"pangea") != 0 ) + { + upper[sizeof(upper)-1] = 0; + strncpy(upper,typestr,sizeof(upper)-1); + touppercase(upper); + if ( iguana_coinfind(upper) != 0 ) + return(0); + else return(-1); + } + return(1); +} + +bits256 jumblr_privkey(struct supernet_info *myinfo,char *coinaddr,uint8_t pubtype,char *KMDaddr,char *prefix) +{ + bits256 privkey,pubkey; uint8_t pubkey33[33]; char passphrase[sizeof(myinfo->jumblr_passphrase) + 64]; + sprintf(passphrase,"%s%s",prefix,myinfo->jumblr_passphrase); + if ( myinfo->jumblr_passphrase[0] == 0 ) + strcpy(myinfo->jumblr_passphrase,"password"); + conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey); + bitcoin_address(coinaddr,pubtype,pubkey33,33); + bitcoin_address(KMDaddr,60,pubkey33,33); + //printf("(%s) -> (%s %s)\n",passphrase,coinaddr,KMDaddr); + return(privkey); +} + +cJSON *smartaddress_extrajson(struct smartaddress *ap) +{ + cJSON *retjson = cJSON_CreateObject(); + if ( strcmp(ap->typestr,"dividend") == 0 ) + { + + } + return(retjson); +} + +cJSON *smartaddress_json(struct smartaddress *ap) +{ + char coinaddr[64],symbol[64]; uint8_t desttype,tmp,rmd160[20]; int32_t j,n; struct iguana_info *coin,*dest; cJSON *array,*item,*retjson; double amount; + retjson = cJSON_CreateObject(); + jaddstr(retjson,"type",ap->typestr); + strcpy(symbol,ap->typestr), touppercase(symbol); + if ( (dest= iguana_coinfind(symbol)) != 0 ) + desttype = dest->chain->pubtype; + else desttype = 60; + if ( (n= ap->numsymbols) > 0 ) + { + array = cJSON_CreateArray(); + for (j=0; jsymbols[j].symbol)) != 0 ) + { + bitcoin_address(coinaddr,coin->chain->pubtype,ap->pubkey33,33); + item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jaddstr(item,"address",coinaddr); + if ( (amount= ap->symbols[j].srcavail) != 0 ) + jaddnum(item,"sourceamount",amount); + if ( dest != 0 ) + { + bitcoin_addr2rmd160(&tmp,rmd160,coinaddr); + bitcoin_address(coinaddr,desttype,rmd160,20); + jaddstr(item,"dest",coinaddr); + if ( (amount= ap->symbols[j].destamount) != 0 ) + jaddnum(item,"destamount",amount); + if ( coin->DEXinfo.depositaddr[0] != 0 ) + { + jaddstr(item,"jumblr_deposit",coin->DEXinfo.depositaddr); + jaddnum(item,"deposit_avail",coin->DEXinfo.avail); + } + if ( coin->DEXinfo.jumblraddr[0] != 0 ) + { + jaddstr(item,"jumblr",coin->DEXinfo.jumblraddr); + jaddnum(item,"jumblr_avail",coin->DEXinfo.jumblravail); + } + if ( ap->symbols[j].maxbid != 0. ) + jaddnum(item,"maxbid",ap->symbols[j].maxbid); + if ( ap->symbols[j].minask != 0. ) + jaddnum(item,"minask",ap->symbols[j].minask); + } + jadd(item,"extra",smartaddress_extrajson(ap)); + jaddi(array,item); + } + } + jadd(retjson,"coins",array); + } + return(retjson); +} + +void smartaddress_symboladd(struct smartaddress *ap,char *symbol,double maxbid,double minask) +{ + char tmp[64]; struct smartaddress_symbol *sp; + strcpy(tmp,ap->typestr), touppercase(tmp); + if ( strcmp(tmp,symbol) != 0 ) + { + ap->symbols = realloc(ap->symbols,(ap->numsymbols+1) * sizeof(*ap->symbols)); + sp = &ap->symbols[ap->numsymbols++]; + memset(sp,0,sizeof(*sp)); + safecopy(sp->symbol,symbol,sizeof(sp->symbol)); + sp->maxbid = maxbid; + sp->minask = minask; + printf("symboladd.%d (%s) <- (%s %f %f)\n",ap->numsymbols,ap->typestr,symbol,maxbid,minask); + } +} + +struct smartaddress *smartaddressptr(struct smartaddress_symbol **ptrp,struct supernet_info *myinfo,char *_type,char *_symbol) +{ + char type[64],symbol[64]; int32_t i,j,n; struct smartaddress *ap; + if ( ptrp != 0 ) + *ptrp = 0; + strcpy(type,_type), tolowercase(type); + strcpy(symbol,_symbol), touppercase(symbol); + for (i=0; inumsmartaddrs; i++) + { + ap = &myinfo->smartaddrs[i]; + if ( strcmp(type,ap->typestr) == 0 ) + { + n = ap->numsymbols; + for (j=0; jsymbols[j].symbol,symbol) == 0 ) + { + if ( ptrp != 0 ) + *ptrp = &ap->symbols[j]; + return(ap); + } + } + } + } + return(0); +} + +void smartaddress_minmaxupdate(struct supernet_info *myinfo,char *_type,char *_symbol,double maxbid,double minask) { - struct smartaddress *ap; - int32_t i; + struct smartaddress *ap; struct smartaddress_symbol *sp; + if ( (ap= smartaddressptr(&sp,myinfo,_type,_symbol)) != 0 && sp != 0 ) + { + dxblend(&sp->maxbid,maxbid,0.5); + dxblend(&sp->minask,minask,0.5); + } +} + +void smartaddress_availupdate(struct supernet_info *myinfo,char *_type,char *_symbol,double srcavail,double destamount) +{ + struct smartaddress *ap; struct smartaddress_symbol *sp; + if ( (ap= smartaddressptr(&sp,myinfo,_type,_symbol)) != 0 && sp != 0 ) + { + if ( srcavail > SMALLVAL ) + sp->srcavail = srcavail; + if ( destamount > SMALLVAL ) + sp->destamount = destamount; + } +} + +int32_t _smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *type,char *symbol,double maxbid,double minask) +{ + char coinaddr[64]; uint8_t addrtype,rmd160[20]; struct smartaddress *ap; int32_t i,j,n; if ( myinfo->numsmartaddrs < sizeof(myinfo->smartaddrs)/sizeof(*myinfo->smartaddrs) ) { for (i=0; inumsmartaddrs; i++) - if ( bits256_cmp(myinfo->smartaddrs[i].privkey,privkey) == 0 ) - return(-1); - ap = &myinfo->smartaddrs[myinfo->numsmartaddrs++]; + { + ap = &myinfo->smartaddrs[i]; + if ( strcmp(type,ap->typestr) == 0 && bits256_cmp(ap->privkey,privkey) == 0 ) + { + n = ap->numsymbols; + for (j=0; jsymbols[j].symbol,symbol) == 0 ) + { + ap->symbols[j].maxbid = maxbid; + ap->symbols[j].minask = minask; + if ( maxbid > SMALLVAL && minask > SMALLVAL && smartaddress_type(type) == 0 ) + smartaddress_minmaxupdate(myinfo,symbol,type,1./minask,1./maxbid); + return(0); + } + } + smartaddress_symboladd(ap,symbol,maxbid,minask); + return(i+1); + } + } + ap = &myinfo->smartaddrs[myinfo->numsmartaddrs]; + if ( smartaddress_type(symbol) < 0 ) + return(-1); + strcpy(ap->typestr,type); + smartaddress_symboladd(ap,"KMD",0.,0.); + smartaddress_symboladd(ap,"BTC",0.,0.); ap->privkey = privkey; bitcoin_pubkey33(myinfo->ctx,ap->pubkey33,privkey); calc_rmd160_sha256(ap->rmd160,ap->pubkey33,33); ap->pubkey = curve25519(privkey,curve25519_basepoint9()); - char coinaddr[64]; uint8_t addrtype,rmd160[20]; + char str[65]; printf("pubkey.(%s) ",bits256_str(str,ap->pubkey)); bitcoin_address(coinaddr,0,ap->pubkey33,33); for (i=0; i<20; i++) printf("%02x",ap->rmd160[i]); @@ -37,54 +222,464 @@ int32_t smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *BTCa printf(", "); for (i=0; i<20; i++) printf("%02x",rmd160[i]); - printf (" <- rmd160 for %d %s vs %s\n",myinfo->numsmartaddrs,coinaddr,BTCaddr); - return(myinfo->numsmartaddrs); + printf (" <- rmd160 for %d %s\n",myinfo->numsmartaddrs,coinaddr); + return(++myinfo->numsmartaddrs + 1); } printf("too many smartaddresses %d vs %d\n",myinfo->numsmartaddrs,(int32_t)(sizeof(myinfo->smartaddrs)/sizeof(*myinfo->smartaddrs))); return(-1); } -int32_t smartaddress(struct supernet_info *myinfo,bits256 *privkeyp,char *coinaddr) +int32_t smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *type,char *symbol,double maxbid,double minask) +{ + int32_t retval; + portable_mutex_lock(&myinfo->smart_mutex); + retval = _smartaddress_add(myinfo,privkey,type,symbol,maxbid,minask); + portable_mutex_unlock(&myinfo->smart_mutex); + return(retval); +} + +int32_t smartaddress_symbolmatch(char *typestr,double *bidaskp,struct smartaddress *ap,char *symbol) +{ + int32_t j,n; + strcpy(typestr,ap->typestr); + if ( (n= ap->numsymbols) > 0 ) + { + for (j=0; jsymbols[j].symbol,symbol) == 0 ) + { + bidaskp[0] = ap->symbols[j].maxbid; + bidaskp[1] = ap->symbols[j].minask; + return(j); + } + } + } + return(-1); +} + +int32_t smartaddress(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,char *coinaddr) { - int32_t i; uint8_t addrtype,rmd160[20]; + int32_t i,j,retval = -1; uint8_t addrtype,rmd160[20]; struct smartaddress *ap; memset(privkeyp,0,sizeof(*privkeyp)); + memset(bidaskp,0,sizeof(*bidaskp) * 2); bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + portable_mutex_lock(&myinfo->smart_mutex); for (i=0; inumsmartaddrs; i++) if ( memcmp(myinfo->smartaddrs[i].rmd160,rmd160,20) == 0 ) { - *privkeyp = myinfo->smartaddrs[i].privkey; - printf("MATCHED %s\n",coinaddr); - return(i); + ap = &myinfo->smartaddrs[i]; + *privkeyp = ap->privkey; + if ( (j= smartaddress_symbolmatch(typestr,bidaskp,ap,symbol)) >= 0 ) + retval = 0; + else retval = (i+1); + break; } + portable_mutex_unlock(&myinfo->smart_mutex); for (i=0; i<20; i++) printf("%02x",rmd160[i]); printf(" <- rmd160 smartaddress cant find (%s) of %d\n",coinaddr,myinfo->numsmartaddrs); - return(-1); + return(retval); } -int32_t smartaddress_pubkey(struct supernet_info *myinfo,bits256 *privkeyp,bits256 pubkey) +int32_t smartaddress_pubkey(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,bits256 pubkey) { - int32_t i; + int32_t i,j,retval = -1; struct smartaddress *ap; memset(privkeyp,0,sizeof(*privkeyp)); + memset(bidaskp,0,sizeof(*bidaskp) * 2); + if ( bits256_cmp(myinfo->myaddr.persistent,pubkey) == 0 ) + { + *privkeyp = myinfo->persistent_priv; + return(myinfo->numsmartaddrs); + } + portable_mutex_lock(&myinfo->smart_mutex); for (i=0; inumsmartaddrs; i++) if ( bits256_cmp(myinfo->smartaddrs[i].pubkey,pubkey) == 0 ) { - *privkeyp = myinfo->smartaddrs[i].privkey; - return(i); + ap = &myinfo->smartaddrs[i]; + *privkeyp = ap->privkey; + if ( (j= smartaddress_symbolmatch(typestr,bidaskp,ap,symbol)) >= 0 ) + retval = 0; + else retval = (i+1); + break; } - return(-1); + portable_mutex_unlock(&myinfo->smart_mutex); + //char str[65]; if ( retval < 0 ) + // printf("smartaddress_pubkey no match for %s\n",bits256_str(str,pubkey)); + return(retval); } -int32_t smartaddress_pubkey33(struct supernet_info *myinfo,bits256 *privkeyp,uint8_t *pubkey33) +int32_t smartaddress_pubkey33(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,uint8_t *pubkey33) { - int32_t i; + int32_t i,j,retval = -1; struct smartaddress *ap; memset(privkeyp,0,sizeof(*privkeyp)); + memset(bidaskp,0,sizeof(*bidaskp) * 2); + portable_mutex_lock(&myinfo->smart_mutex); for (i=0; inumsmartaddrs; i++) if ( memcmp(myinfo->smartaddrs[i].pubkey33,pubkey33,33) == 0 ) { - *privkeyp = myinfo->smartaddrs[i].privkey; - return(i); + ap = &myinfo->smartaddrs[i]; + *privkeyp = ap->privkey; + if ( (j= smartaddress_symbolmatch(typestr,bidaskp,ap,symbol)) >= 0 ) + retval = 0; + else retval = (i+1); + break; } - return(0); + portable_mutex_unlock(&myinfo->smart_mutex); + return(retval); +} + +void smartaddress_CMCname(char *CMCname,char *symbol) +{ + if ( strcmp(symbol,"KMD") == 0 ) + strcpy(CMCname,"komodo"); + else if ( strcmp(symbol,"BTC") == 0 ) + strcpy(CMCname,"bitcoin"); +} + +void smartaddress_coinupdate(struct supernet_info *myinfo,char *symbol,double BTC2KMD,double KMDavail,double KMD2USD) +{ + int32_t r; double avebid,aveask,highbid,lowask,CMC_average,changes[3]; struct iguana_info *coin; struct DEXcoin_info *ptr; + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + ptr = &coin->DEXinfo; + ptr->coin = coin; + if ( coin->CMCname[0] == 0 ) + smartaddress_CMCname(coin->CMCname,symbol); + r = (((symbol[0]^symbol[1]^symbol[2])&0x7f) % 15) - 7; // 53 to 67 seconds + if ( time(NULL) > (ptr->lasttime + 60 + r) ) + { + if ( strcmp(symbol,ptr->symbol) != 0 ) + { + safecopy(ptr->symbol,symbol,sizeof(ptr->symbol)); + safecopy(ptr->CMCname,coin->CMCname,sizeof(ptr->CMCname)); + } + ptr->deposit_privkey = jumblr_privkey(myinfo,ptr->depositaddr,coin->chain->pubtype,ptr->KMDdepositaddr,JUMBLR_DEPOSITPREFIX); + ptr->jumblr_privkey = jumblr_privkey(myinfo,ptr->jumblraddr,coin->chain->pubtype,ptr->KMDjumblraddr,""); + ptr->avail = dstr(jumblr_balance(myinfo,coin,ptr->depositaddr)); + ptr->jumblravail = dstr(jumblr_balance(myinfo,ptr->coin,ptr->jumblraddr)); + if ( strcmp(symbol,"USD") == 0 ) + { + if ( KMD2USD > SMALLVAL ) + { + ptr->kmdprice = 1./ KMD2USD; + if ( (ptr->BTC2KMD= BTC2KMD) > SMALLVAL ) + ptr->btcprice = ptr->kmdprice * BTC2KMD; + } + printf("USD btcprice %.8f kmdprice %.8f\n",ptr->btcprice,ptr->kmdprice); + } + else + { + if ( strcmp(symbol,"BTC") == 0 ) + ptr->btcprice = 1.; + else if ( coin->CMCname[0] != 0 && (ptr->btcprice == 0. || (ptr->counter++ % 10) == 0) ) + ptr->btcprice = get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,coin->CMCname,symbol,"BTC",&ptr->USD_average); + if ( strcmp("KMD",symbol) == 0 ) + ptr->kmdprice = 1.; + else if ( (ptr->BTC2KMD= BTC2KMD) > SMALLVAL ) + ptr->kmdprice = ptr->btcprice / BTC2KMD; + } + ptr->lasttime = (uint32_t)time(NULL); + printf("%s avail %.8f KMDavail %.8f btcprice %.8f deposit.(%s %s) -> jumblr.(%s %s)\n",symbol,ptr->avail,KMDavail,ptr->btcprice,ptr->depositaddr,ptr->KMDdepositaddr,ptr->jumblraddr,ptr->KMDjumblraddr); + } + } // else printf("skip\n"); +} + +void smartaddress_dex(struct supernet_info *myinfo,char *type,int32_t selector,struct iguana_info *basecoin,char *coinaddr,double maxavail,struct iguana_info *relcoin,double maxbid,double minask,cJSON *extraobj,double maxvol) +{ + double minamount,minbtc,price,avail,vol,btc2kmd,basebtc,relbtc,baseusd,relusd; char *retstr; cJSON *vals; bits256 hash; struct smartaddress *ap; + basebtc = basecoin->DEXinfo.btcprice; + relbtc = relcoin->DEXinfo.btcprice; + baseusd = basecoin->DEXinfo.USD_average; + relusd = relcoin->DEXinfo.USD_average; + if ( (btc2kmd= basecoin->DEXinfo.BTC2KMD) < SMALLVAL && (btc2kmd= relcoin->DEXinfo.BTC2KMD) < SMALLVAL ) + return; + minamount = price = 0.; + if ( basebtc < SMALLVAL && relbtc < SMALLVAL ) + return; + if ( myinfo->DEXratio < .95 || myinfo->DEXratio > 1.01 ) + myinfo->DEXratio = 0.995; + if ( basebtc < SMALLVAL || relbtc < SMALLVAL ) + { + if ( (price= maxbid) > SMALLVAL ) + { + if ( basebtc < SMALLVAL ) + basebtc = price * relbtc, printf("calculated basebtc %.8f from (%.8f * %.8f)\n",basebtc,price,relbtc); + else if ( relbtc < SMALLVAL ) + relbtc = basebtc / price, printf("calculated relbtc %.8f from (%.8f / %.8f)\n",relbtc,basebtc,price); // price * relbtc == basebtc + } + } else price = myinfo->DEXratio * (basebtc / relbtc); + minbtc = btc2kmd * (JUMBLR_INCR + 3*(JUMBLR_INCR * JUMBLR_FEE + JUMBLR_TXFEE)); + if ( minamount == 0. && basebtc > SMALLVAL ) + minamount = (minbtc / basebtc); + printf("DEX %s/%s maxavail %.8f minbtc %.8f btcprice %.8f -> minamount %.8f price %.8f vs maxbid %.8f DEXratio %.5f DEXpending %.8f\n",basecoin->symbol,relcoin->symbol,maxavail,minbtc,basecoin->DEXinfo.btcprice,minamount,price,maxbid,myinfo->DEXratio,basecoin->DEXinfo.DEXpending); + if ( minamount > SMALLVAL && maxavail > minamount + basecoin->DEXinfo.DEXpending && (maxbid == 0. || price <= maxbid) ) + { + avail = (maxavail - basecoin->DEXinfo.DEXpending); + /*if ( avail >= (100. * minamount) ) + vol = (100. * minamount); + else if ( avail >= (10. * minamount) ) + vol = (10. * minamount); + else*/ if ( avail >= minamount ) + vol = minamount; + else vol = 0.; + if ( vol > 0. ) + { + vals = cJSON_CreateObject(); + jaddstr(vals,"source",basecoin->symbol); + jaddstr(vals,"dest",relcoin->symbol); + jaddnum(vals,"amount",vol); + jaddnum(vals,"minprice",price); + if ( (ap= smartaddressptr(0,myinfo,type,basecoin->symbol)) != 0 ) + jaddbits256(vals,"srchash",ap->pubkey); + if ( selector != 0 ) + { + jaddnum(vals,"usejumblr",selector); + jaddnum(vals,"DEXselector",selector); + } + memset(hash.bytes,0,sizeof(hash)); + basecoin->DEXinfo.DEXpending += vol; + if ( (retstr= InstantDEX_request(myinfo,basecoin,0,0,hash,vals,"")) != 0 ) + { + printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr); + free(retstr); + } + free_json(vals); + } else printf("avail %.8f < minamount %.8f\n",avail,minamount); + } //else printf("failed if check %d %d %d %d\n",minamount > SMALLVAL,maxavail > minamount + basecoin->DEXinfo.DEXpending,maxbid == 0,price <= maxbid); + /* + minbtc = (basecoin->DEXinfo.btcprice * 1.2) * (JUMBLR_INCR + 3*(JUMBLR_INCR * JUMBLR_FEE + JUMBLR_TXFEE)); + btcavail = dstr(jumblr_balance(myinfo,coinbtc,kmdcoin->DEXinfo.depositaddr)); + avail = (btcavail - coinbtc->DEXinfo.DEXpending); + printf("BTC.%d deposits %.8f, min %.8f avail %.8f pending %.8f\n",toKMD,btcavail,minbtc,avail,coinbtc->DEXinfo.DEXpending); + if ( toKMD == 0 && coinbtc != 0 && btcavail > (minbtc + coinbtc->DEXinfo.DEXpending) ) + { + if ( vol > 0. ) + { + vals = cJSON_CreateObject(); + jaddstr(vals,"source","BTC"); + jaddstr(vals,"dest","KMD"); + jaddnum(vals,"amount",vol); + jaddnum(vals,"minprice",0.985/kmdcoin->DEXinfo.btcprice); + jaddnum(vals,"usejumblr",1); + jaddnum(vals,"DEXselector",1); + memset(hash.bytes,0,sizeof(hash)); + coinbtc->DEXinfo.DEXpending += vol; + if ( (retstr= InstantDEX_request(myinfo,coinbtc,0,0,hash,vals,"")) != 0 ) + { + printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr); + free(retstr); + } + free_json(vals); + // curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"request\",\"vals\":{\"source\":\"KMD\",\"amount\":20,\"dest\":\"USD\",\"minprice\":0.08}}" + } + } //else printf("btcavail %.8f pending %.8f\n",btcavail,pending); + minkmd = 100.; + avail = (kmdcoin->DEXinfo.KMDavail - kmdcoin->DEXinfo.DEXpending); + printf("KMD.%d deposits %.8f, min %.8f, avail %.8f pending %.8f\n",toKMD,kmdcoin->DEXinfo.KMDavail,minkmd,avail,kmdcoin->DEXinfo.DEXpending); + if ( toKMD != 0 && coinbtc != 0 && kmdcoin->DEXinfo.KMDavail > (minkmd + kmdcoin->DEXinfo.DEXpending) ) + { + if ( avail > 100.*JUMBLR_INCR ) + vol = 100.*JUMBLR_INCR; + else if ( avail > 10.*JUMBLR_INCR ) + vol = 10.*JUMBLR_INCR; + else if ( avail >= JUMBLR_INCR ) + vol = JUMBLR_INCR; + else vol = 0.; + if ( vol > 0. ) + { + vals = cJSON_CreateObject(); + jaddstr(vals,"source","KMD"); + jaddstr(vals,"dest","BTC"); + jaddnum(vals,"amount",vol); + //jaddnum(vals,"destamount",JUMBLR_INCR*kmdcoin->DEXinfo.btcprice); + jaddnum(vals,"minprice",0.985 * kmdcoin->DEXinfo.btcprice); + jaddnum(vals,"usejumblr",2); + memset(hash.bytes,0,sizeof(hash)); + kmdcoin->DEXinfo.DEXpending += vol; + jaddnum(vals,"DEXselector",2); + if ( (retstr= InstantDEX_request(myinfo,coinbtc,0,0,hash,vals,"")) != 0 ) + { + printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr); + free(retstr); + } + free_json(vals); + } + } else printf("kmdavail %.8f pending %.8f\n",kmdcoin->DEXinfo.avail,kmdcoin->DEXinfo.DEXpending);*/ +} + +void smartaddress_depositjumblr(struct supernet_info *myinfo,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj) +{ + struct iguana_info *basecoin,*relcoin; + if ( (basecoin= iguana_coinfind(symbol)) != 0 && (relcoin= iguana_coinfind("KMD")) != 0 ) + { + if ( strcmp(coinaddr,basecoin->DEXinfo.depositaddr) == 0 ) + smartaddress_dex(myinfo,"deposit",1,basecoin,coinaddr,basecoin->DEXinfo.avail,relcoin,maxbid,minask,extraobj,0.); + else printf("smartaddress_jumblr.%s: mismatch deposit address (%s) vs (%s)\n",symbol,coinaddr,basecoin->DEXinfo.depositaddr); + } +} + +double smartaddress_jumblrcredit(struct supernet_info *myinfo,char *symbol) +{ + return(0.); // default to BTC conversion for now +} + +void smartaddress_jumblr(struct supernet_info *myinfo,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj) +{ + struct iguana_info *basecoin,*relcoin; double credits = 0.; + if ( strcmp("BTC",symbol) != 0 ) + { + if ( (credits= smartaddress_jumblrcredit(myinfo,symbol)) <= 0. ) + return; + } + if ( (basecoin= iguana_coinfind("KMD")) != 0 && (relcoin= iguana_coinfind(symbol)) != 0 ) + { + if ( strcmp(coinaddr,basecoin->DEXinfo.jumblraddr) == 0 ) + smartaddress_dex(myinfo,"jumblr",2,basecoin,coinaddr,basecoin->DEXinfo.jumblravail,relcoin,maxbid,minask,extraobj,credits); + else printf("smartaddress_jumblr.%s: mismatch jumblr address (%s) vs (%s)\n",symbol,coinaddr,basecoin->DEXinfo.jumblraddr); + } +} + +void smartaddress_dividend(struct supernet_info *myinfo,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj) +{ + // support list of weighted addresses, including snapshots +} + +void smartaddress_pangea(struct supernet_info *myinfo,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj) +{ + // table deposit +} + +void smartaddress_action(struct supernet_info *myinfo,int32_t selector,char *typestr,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj) +{ + char rel[64]; struct iguana_info *basecoin,*relcoin; double avail; + if ( strcmp(typestr,"deposit") == 0 && selector == 0 ) + smartaddress_depositjumblr(myinfo,symbol,coinaddr,maxbid,minask,extraobj); + else if ( strcmp(typestr,"jumblr") == 0 && selector == 0 ) + smartaddress_jumblr(myinfo,symbol,coinaddr,maxbid,minask,extraobj); + else if ( strcmp(typestr,"dividend") == 0 && selector == 0 ) + smartaddress_dividend(myinfo,symbol,coinaddr,maxbid,minask,extraobj); + else if ( strcmp(typestr,"pangea") == 0 && selector == 0 ) + smartaddress_pangea(myinfo,symbol,coinaddr,maxbid,minask,extraobj); + else + { + safecopy(rel,typestr,sizeof(rel)); + touppercase(rel); + if ( (relcoin= iguana_coinfind(rel)) != 0 && (basecoin= iguana_coinfind(symbol)) != 0 ) + { + if ( myinfo->numswaps == 0 )//|| (basecoin->FULLNODE < 0 && relcoin->FULLNODE < 0) ) + { + if ( (avail= dstr(jumblr_balance(myinfo,basecoin,coinaddr))) > SMALLVAL ) + { + smartaddress_availupdate(myinfo,typestr,symbol,avail,SMALLVAL*0.99); + smartaddress_dex(myinfo,typestr,0,basecoin,coinaddr,avail,relcoin,maxbid,minask,extraobj,0.); + } + } + } + } +} + +void smartaddress_update(struct supernet_info *myinfo,int32_t selector) +{ + double maxbid,minask; uint8_t addrtype,rmd160[20]; char *smartstr,*typestr,*symbol,*address,coinaddr[64]; cJSON *smartarray,*extraobj,*item,*array,*coinitem; int32_t iter,i,n,j,m; struct iguana_info *kmdcoin,*coinbtc = 0; + //printf("smartaddress_update numswaps.%d notary.%d IAMLP.%d %p %p %f\n",myinfo->numswaps,myinfo->IAMNOTARY,myinfo->IAMLP,kmdcoin,coinbtc,kmdcoin->DEXinfo.btcprice); + if ( myinfo->IAMNOTARY != 0 || myinfo->IAMLP != 0 || myinfo->secret[0] == 0 ) + return; + kmdcoin = iguana_coinfind("KMD"); + coinbtc = iguana_coinfind("BTC"); + if ( kmdcoin == 0 || coinbtc == 0 ) + return; + smartaddress_coinupdate(myinfo,"KMD",0.,0.,0.); // must be first + if ( kmdcoin->DEXinfo.btcprice > SMALLVAL ) + { + if ( (smartstr= InstantDEX_smartaddresses(myinfo,0,0,0)) != 0 ) + { + if ( (smartarray= cJSON_Parse(smartstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(smartarray)) > 0 ) + { + for (iter=0; iter<2; iter++) + { + for (i=0; iDEXinfo.btcprice,kmdcoin->DEXinfo.avail,kmdcoin->DEXinfo.USD_average); + else + { + printf("Action.%s (%s)\n",typestr,jprint(coinitem,0)); + if ( (address= jstr(coinitem,"address")) != 0 ) + { + if ( strcmp(typestr,"jumblr") == 0 ) + { + bitcoin_addr2rmd160(&addrtype,rmd160,address); + bitcoin_address(coinaddr,kmdcoin->chain->pubtype,rmd160,20); + } else strcpy(coinaddr,address); + maxbid = jdouble(coinitem,"maxbid"); + minask = jdouble(coinitem,"minask"); + extraobj = jobj(coinitem,"extra"); + smartaddress_action(myinfo,selector,typestr,symbol,coinaddr,maxbid,minask,extraobj); + } + } + } + } + } + } + } + free_json(smartarray); + } + free(smartstr); + } + } +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" +#include "../includes/iguana_apideclares2.h" + +ZERO_ARGS(InstantDEX,smartaddresses) +{ + int32_t i; cJSON *retjson = cJSON_CreateArray(); + portable_mutex_lock(&myinfo->smart_mutex); + for (i=0; inumsmartaddrs; i++) + jaddi(retjson,smartaddress_json(&myinfo->smartaddrs[i])); + portable_mutex_unlock(&myinfo->smart_mutex); + return(jprint(retjson,1)); +} + +TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,smartaddress,type,symbol,maxbid,minask) +{ + char prefix[64],coinaddr[64],KMDaddr[64],typestr[64]; double bidask[2]; uint8_t pubkey33[33]; bits256 privkey; + if ( smartaddress_type(type) < 0 ) + return(clonestr("{\"error\":\"non-supported smartaddress type\"}")); + if ( iguana_coinfind(symbol) == 0 ) + return(clonestr("{\"error\":\"non-supported smartaddress symbol\"}")); + if ( strcmp(type,"deposit") == 0 || strcmp(type,"jumblr") == 0 ) + { + if ( smartaddress_pubkey(myinfo,typestr,bidask,&privkey,symbol,strcmp(type,"deposit") == 0 ? myinfo->jumblr_depositkey : myinfo->jumblr_pubkey) < 0 ) + return(clonestr("{\"error\":\"unexpected missing smartaddress deposit/jumblr\"}")); + } + else + { + strcpy(prefix,type); + tolowercase(prefix); + if ( strcmp(prefix,"btc") == 0 || strcmp(prefix,"kmd") == 0 ) + return(clonestr("{\"success\":\"no need add BTC or KMD to smartaddress\"}")); + strcat(prefix," "); + privkey = jumblr_privkey(myinfo,coinaddr,0,KMDaddr,prefix); + } + if ( (coin= iguana_coinfind(symbol)) == 0 ) + return(clonestr("{\"error\":\"non-supported smartaddress symbol\"}")); + bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey); + bitcoin_address(coinaddr,coin->chain->pubtype,pubkey33,33); + smartaddress_add(myinfo,privkey,type,symbol,maxbid,minask); + return(InstantDEX_smartaddresses(myinfo,0,0,0)); } +#include "../includes/iguana_apiundefs.h" diff --git a/basilisk/tradebots_liquidity.c b/basilisk/tradebots_liquidity.c index 7e21127aa..b044accd4 100755 --- a/basilisk/tradebots_liquidity.c +++ b/basilisk/tradebots_liquidity.c @@ -932,7 +932,7 @@ void _default_liquidity_command(struct supernet_info *myinfo,char *base,bits256 li.ask = jdouble(vals,"ask"); if ( (li.minvol= jdouble(vals,"minvol")) <= 0. ) li.minvol = (strcmp("BTC",base) == 0) ? 0.0001 : 0.001; - if ( strcmp(li.base,"KMD") == 0 && strcmp(li.rel,"BTC") == 0 && li.minvol > 100. ) + if ( strcmp(li.base,"KMD") == 0 && strcmp(li.rel,"BTC") == 0 && li.minvol >= 100. ) li.minvol = 100.; if ( (li.maxvol= jdouble(vals,"maxvol")) < li.minvol ) li.maxvol = li.minvol; @@ -984,17 +984,28 @@ void _default_liquidity_command(struct supernet_info *myinfo,char *base,bits256 } else tradebot_monitor(myinfo,0,0,0,li.exchange,li.base,li.rel,0.); } myinfo->linfos[i] = li; - printf("Set linfo[%d] %s (%s/%s) profitmargin %.6f bid %.8f ask %.8f minvol %.6f maxvol %.6f ref %.8f <- (%s)\n",i,li.exchange,li.base,li.rel,li.profit,li.bid,li.ask,li.minvol,li.maxvol,li.refprice,jprint(vals,0)); + //printf("Set linfo[%d] %s (%s/%s) profitmargin %.6f bid %.8f ask %.8f minvol %.6f maxvol %.6f ref %.8f <- (%s)\n",i,li.exchange,li.base,li.rel,li.profit,li.bid,li.ask,li.minvol,li.maxvol,li.refprice,jprint(vals,0)); return; } } printf("ERROR: too many linfos %d\n",i); } -int32_t _default_volume_ok(struct supernet_info *myinfo,struct liquidity_info *li,int32_t dir,double volume) +int32_t _default_volume_ok(struct supernet_info *myinfo,struct liquidity_info *li,int32_t dir,double volume,double price) { - printf("minvol %f maxvol %f vs volume %f\n",li->minvol,li->maxvol,volume); - if ( (li->minvol == 0 || volume >= li->minvol) && (li->maxvol == 0 || volume <= li->maxvol) ) + double minvol,maxvol; + if ( dir < 0 ) + { + minvol = li->minvol; + maxvol = li->maxvol; + } + else + { + minvol = price * li->minvol; + maxvol = price * li->maxvol; + } + printf("dir.%d minvol %f maxvol %f vs (%f %f) volume %f price %.8f\n",dir,li->minvol,li->maxvol,minvol,maxvol,volume,price); + if ( (minvol == 0. || volume >= minvol) && (maxvol == 0. || volume <= maxvol) ) return(0); else return(-1); } @@ -1018,7 +1029,7 @@ double _default_liquidity_active(struct supernet_info *myinfo,double *refpricep, printf("continue %s %s/%s [%d] dir.%d vs %s %s/%s\n",exchange,base,rel,i,dir,refli.exchange,refli.base,refli.rel); continue; } - if ( _default_volume_ok(myinfo,&refli,dir,destvolume) == 0 ) + if ( _default_volume_ok(myinfo,&refli,dir,destvolume,dir > 0 ? refli.bid : refli.ask) == 0 ) { if ( refli.profit != 0. ) *refpricep = refli.refprice; @@ -1131,7 +1142,24 @@ void _default_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_s void tradebot_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob) { - printf("balancing trade\n"); + if ( swap->bobcoin != 0 && swap->alicecoin != 0 ) + { + if ( iambob != 0 ) + { + if ( strcmp(swap->I.req.src,swap->bobcoin->symbol) == 0 ) + swap->bobcoin->DEXinfo.DEXpending -= swap->I.req.srcamount; + else if ( strcmp(swap->I.req.dest,swap->bobcoin->symbol) == 0 ) + swap->bobcoin->DEXinfo.DEXpending -= swap->I.req.destamount; + } + else + { + if ( strcmp(swap->I.req.src,swap->alicecoin->symbol) == 0 ) + swap->alicecoin->DEXinfo.DEXpending -= swap->I.req.srcamount; + else if ( strcmp(swap->I.req.dest,swap->alicecoin->symbol) == 0 ) + swap->alicecoin->DEXinfo.DEXpending -= swap->I.req.destamount; + } + } + printf(">>>>>>>>>>>>>>>>>> balancing trade done by marketmaker\n"); return; if ( swap->balancingtrade == 0 ) _default_swap_balancingtrade(myinfo,swap,iambob); diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 040436d1a..84ba44794 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -18,7 +18,7 @@ // iguana_OS has functions that invoke system calls. Whenever possible stdio and similar functions are use and most functions are fully portable and in this file. For things that require OS specific, the call is routed to iguana_OS_portable_* Usually, all but one OS can be handled with the same code, so iguana_OS_portable.c has most of this shared logic and an #ifdef iguana_OS_nonportable.c #ifdef __APPLE__ -#define LIQUIDITY_PROVIDER 1 +//#define LIQUIDITY_PROVIDER 1 #endif #ifdef NATIVE_WINDOWS @@ -129,7 +129,8 @@ int32_t hseek(HUFF *hp,int32_t offset,int32_t mode); #define portable_mutex_unlock pthread_mutex_unlock #define OS_thread_create pthread_create -#define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0) +#define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0,0) +#define issue_curlt(cmdstr,timeout) bitcoind_RPC(0,"curl",cmdstr,0,0,0,timeout) struct allocitem { uint32_t allocsize,type; } PACKED; struct queueitem { struct queueitem *next,*prev; uint32_t allocsize,type; } PACKED; @@ -197,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); @@ -347,7 +350,7 @@ char *hmac_tiger_str(char *dest,char *key,int32_t key_size,char *message); char *hmac_whirlpool_str(char *dest,char *key,int32_t key_size,char *message); int nn_base64_encode(const uint8_t *in,size_t in_len,char *out,size_t out_len); int nn_base64_decode(const char *in,size_t in_len,uint8_t *out,size_t out_len); - +void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen); void sha256_sha256(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void rmd160ofsha256(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_md5str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); @@ -358,6 +361,8 @@ void calc_base64_encodestr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_base64_decodestr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_hexstr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_unhexstr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); +int32_t safecopy(char *dest,char *src,long len); +double dxblend(double *destp,double val,double decay); uint64_t calc_ipbits(char *ip_port); void expand_ipbits(char *ipaddr,uint64_t ipbits); @@ -384,6 +389,7 @@ int32_t iguana_rwvarint(int32_t rwflag,uint8_t *serialized,uint64_t *varint64p); int32_t iguana_rwvarint32(int32_t rwflag,uint8_t *serialized,uint32_t *int32p); int32_t iguana_rwvarstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp); int32_t iguana_rwmem(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); +#define bits256_nonz(a) (((a).ulongs[0] | (a).ulongs[1] | (a).ulongs[2] | (a).ulongs[3]) != 0) bits256 bits256_ave(bits256 a,bits256 b); bits256 bits256_doublesha256(char *hashstr,uint8_t *data,int32_t datalen); diff --git a/crypto777/OS_time.c b/crypto777/OS_time.c index e930424f6..03489f03e 100755 --- a/crypto777/OS_time.c +++ b/crypto777/OS_time.c @@ -578,8 +578,8 @@ int32_t OS_conv_unixtime(struct tai *tp,int32_t *secondsp,time_t timestamp) // g int32_t conv_date(int32_t *secondsp,char *date) { - char origdate[64],tmpdate[64]; int32_t year,month,day,hour,min,sec,len; - strcpy(origdate,date), strcpy(tmpdate,date), tmpdate[8 + 2] = 0; + char origdate[512],tmpdate[512]; int32_t year,month,day,hour,min,sec,len; + safecopy(origdate,date,sizeof(origdate)), safecopy(tmpdate,date,sizeof(tmpdate)), tmpdate[8 + 2] = 0; year = atoi(tmpdate), month = atoi(tmpdate+5), day = atoi(tmpdate+8); *secondsp = 0; if ( (len= (int32_t)strlen(date)) <= 10 ) @@ -591,8 +591,8 @@ int32_t conv_date(int32_t *secondsp,char *date) if ( hour >= 0 && hour < 24 && min >= 0 && min < 60 && sec >= 0 && sec < 60 ) *secondsp = (3600*hour + 60*min + sec); else printf("ERROR: seconds.%d %d %d %d, len.%d\n",*secondsp,hour,min,sec,len); - } - //printf("(%s) -> Y.%d M.%d D.%d %d:%d:%d\n",date,year,month,day,hour,min,sec); + //printf("(%s) -> Y.%d M.%d D.%d %d:%d:%d\n",date,year,month,day,hour,min,sec); + } //else printf("short len.(%s) from (%s)\n",date,origdate); sprintf(origdate,"%d-%02d-%02d",year,month,day); //2015-07-25T22:34:31Z if ( strcmp(tmpdate,origdate) != 0 ) { diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index e0d7fca85..fd27643d3 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -17,13 +17,8 @@ #define LIQUIDITY_PROVIDER 1 #if LIQUIDITY_PROVIDER -#ifdef _WIN32 -#include -#include -#else #include #include -#endif // return data from the server #define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) @@ -62,7 +57,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * //printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 ) { - if ( strcmp(command,"signrawtransaction") != 0 ) + if ( strcmp(command,"signrawtransaction") != 0 && strcmp(command,"getrawtransaction") != 0 ) printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); return(rpcstr); } @@ -90,7 +85,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * } else if ( (error->type&0xff) != cJSON_NULL || (result->type&0xff) != cJSON_NULL ) { - if ( strcmp(command,"signrawtransaction") != 0 && strcmp(command,"sendrawtransaction") != 0 ) + if ( strcmp(command,"getrawtransaction") != 0 && strcmp(command,"signrawtransaction") != 0 && strcmp(command,"sendrawtransaction") != 0 ) printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC (%s) error.%s\n",debugstr,command,rpcstr); retstr = rpcstr; rpcstr = 0; @@ -120,7 +115,7 @@ char *Jay_NXTrequest(char *command,char *params) return(retstr); } -char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params) +char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout) { static int didinit,count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY; struct curl_slist *headers = NULL; struct return_string s; CURLcode res; CURL *curl_handle; @@ -142,7 +137,7 @@ char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char * if ( url[0] == 0 ) strcpy(url,"http://127.0.0.1:7776"); if ( specialcase != 0 && (0) ) - printf("<<<<<<<<<<< bitcoind_RPC: debug.(%s) url.(%s) command.(%s) params.(%s)\n",debugstr,url,command,params); + printf("<<<<<<<<<<< bitcoind_RPC: userpass.(%s) url.(%s) command.(%s) params.(%s)\n",userpass,url,command,params); try_again: if ( retstrp != 0 ) *retstrp = 0; @@ -158,7 +153,8 @@ try_again: curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS, 1L); // no progress callback - //curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT, 60L); + if ( timeout > 0 ) + curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT, timeout); // causes problems with iguana timeouts if ( strncmp(url,"https",5) == 0 ) { curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0); @@ -206,9 +202,9 @@ try_again: if ( res != CURLE_OK ) { numretries++; - if ( specialcase != 0 ) + if ( specialcase != 0 || timeout != 0 ) { - printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res); + //printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res); free(s.ptr); return(0); } diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 13cc6567e..8bce48b19 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -546,7 +546,7 @@ static char *print_object(cJSON *item,int32_t depth,int32_t fmt) /* Get Array size/item / object item. */ int32_t cJSON_GetArraySize(cJSON *array) {cJSON *c; if ( array == 0 ) return(0); c=array->child;int32_t i=0;while(c)i++,c=c->next;return i;} cJSON *cJSON_GetArrayItem(cJSON *array,int32_t item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} -cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} +cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) { if ( object == 0 ) return(0); cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} /* Utility for array list handling. */ static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} @@ -858,7 +858,7 @@ bits256 get_API_bits256(cJSON *obj) } return(hash); } -bits256 jbits256(cJSON *json,char *field) { if ( field == 0 ) return(get_API_bits256(json)); return(get_API_bits256(cJSON_GetObjectItem(json,field))); } +bits256 jbits256(cJSON *json,char *field) { if ( field == 0 ) return(get_API_bits256(json)); return(get_API_bits256(json != 0 ? cJSON_GetObjectItem(json,field) : 0)); } bits256 jbits256i(cJSON *json,int32_t i) { return(get_API_bits256(cJSON_GetArrayItem(json,i))); } void jaddbits256(cJSON *json,char *field,bits256 hash) { char str[65]; bits256_str(str,hash), jaddstr(json,field,str); } void jaddibits256(cJSON *json,bits256 hash) { char str[65]; bits256_str(str,hash), jaddistr(json,str); } @@ -896,10 +896,14 @@ int32_t jnum(cJSON *obj,char *field) void ensure_jsonitem(cJSON *json,char *field,char *value) { - cJSON *obj = cJSON_GetObjectItem(json,field); - if ( obj == 0 ) - cJSON_AddItemToObject(json,field,cJSON_CreateString(value)); - else cJSON_ReplaceItemInObject(json,field,cJSON_CreateString(value)); + cJSON *obj; + if ( json != 0 ) + { + obj = cJSON_GetObjectItem(json,field); + if ( obj == 0 ) + cJSON_AddItemToObject(json,field,cJSON_CreateString(value)); + else cJSON_ReplaceItemInObject(json,field,cJSON_CreateString(value)); + } } int32_t in_jsonarray(cJSON *array,char *value) diff --git a/crypto777/hmac/sha224.c b/crypto777/hmac/sha224.c index 78a0bfb84..683440d70 100755 --- a/crypto777/hmac/sha224.c +++ b/crypto777/hmac/sha224.c @@ -26,7 +26,7 @@ const struct ltc_hash_descriptor sha224_desc = 9, &sha224_init, - &sha256_process, + &sha256i_process, &sha224_done, &sha224_test, NULL @@ -69,7 +69,7 @@ int sha224_done(hash_state * md, unsigned char *out) LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); - err = sha256_done(md, buf); + err = sha256i_done(md, buf); XMEMCPY(out, buf, 28); #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); diff --git a/crypto777/hmac/sha256.c b/crypto777/hmac/sha256.c index 29dceaa2e..e3b6a27b9 100755 --- a/crypto777/hmac/sha256.c +++ b/crypto777/hmac/sha256.c @@ -17,24 +17,6 @@ //#ifdef LTC_SHA256 -const struct ltc_hash_descriptor sha256_desc = -{ - "sha256", - 0, - 32, - 64, - - /* OID */ - { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, - 9, - - &sha256_init, - &sha256_process, - &sha256_done, - &sha256_test, - NULL -}; - #ifdef LTC_SMALL_CODE /* the K array */ static const ulong32 K[64] = { @@ -203,7 +185,7 @@ static int sha256_compress(hash_state * md, unsigned char *buf) @param md The hash state you wish to initialize @return CRYPT_OK if successful */ -int sha256_init(hash_state * md) +int sha256i_init(hash_state * md) { LTC_ARGCHK(md != NULL); @@ -227,7 +209,7 @@ int sha256_init(hash_state * md) @param inlen The length of the data (octets) @return CRYPT_OK if successful */ -HASH_PROCESS(sha256_process, sha256_compress, sha256, 64) +HASH_PROCESS(sha256i_process, sha256_compress, sha256, 64) /** Terminate the hash to get the digest @@ -235,7 +217,7 @@ HASH_PROCESS(sha256_process, sha256_compress, sha256, 64) @param out [out] The destination of the hash (32 bytes) @return CRYPT_OK if successful */ -int sha256_done(hash_state * md, unsigned char *out) +int sha256i_done(hash_state * md, unsigned char *out) { int i; @@ -287,9 +269,9 @@ int sha256_done(hash_state * md, unsigned char *out) void calc_sha256(char hashstr[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len) { hash_state md; - sha256_init(&md); - sha256_process(&md,src,len); - sha256_done(&md,hash); + sha256i_init(&md); + sha256i_process(&md,src,len); + sha256i_done(&md,hash); if ( hashstr != 0 ) { int32_t init_hexbytes_noT(char *hexbytes,uint8_t *message,long len); @@ -300,11 +282,11 @@ void calc_sha256(char hashstr[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t void calc_sha256cat(uint8_t hash[256 >> 3],uint8_t *src,int32_t len,uint8_t *src2,int32_t len2) { hash_state md; - sha256_init(&md); - sha256_process(&md,src,len); + sha256i_init(&md); + sha256i_process(&md,src,len); if ( src2 != 0 ) - sha256_process(&md,src2,len2); - sha256_done(&md,hash); + sha256i_process(&md,src2,len2); + sha256i_done(&md,hash); } void update_sha256(uint8_t hash[256 >> 3],struct sha256_state *state,uint8_t *src,int32_t len) @@ -312,14 +294,14 @@ void update_sha256(uint8_t hash[256 >> 3],struct sha256_state *state,uint8_t *sr hash_state md; memset(&md,0,sizeof(md)); if ( src == 0 ) - sha256_init(&md); + sha256i_init(&md); else { md.sha256 = *state; - sha256_process(&md,src,len); + sha256i_process(&md,src,len); } *state = md.sha256; - sha256_done(&md,hash); + sha256i_done(&md,hash); } /*void calc_OP_HASH160(char hexstr[41],uint8_t hash160[20],char *pubkey) @@ -334,9 +316,9 @@ void update_sha256(uint8_t hash[256 >> 3],struct sha256_state *state,uint8_t *sr return; } decode_hex(buf,len,pubkey); - sha256_init(&md); - sha256_process(&md,buf,len); - sha256_done(&md,sha256); + sha256i_init(&md); + sha256i_process(&md,buf,len); + sha256i_done(&md,sha256); rmd160_init(&md); rmd160_process(&md,sha256,256 >> 3); @@ -389,9 +371,9 @@ int sha256_test(void) char *str; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { - sha256_init(&md); - sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); - sha256_done(&md, tmp); + sha256i_init(&md); + sha256i_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha256i_done(&md, tmp); if (XMEMCMP(tmp, tests[i].hash, 32) != 0) { for (j=0; j<32; j++) printf("%02x",tmp[j]); @@ -400,16 +382,16 @@ int sha256_test(void) strcpy(str,(char*)tests[i].msg); reverse_hexstr(str); printf("reversed.(%s)\n",str); - sha256_init(&md); - sha256_process(&md, (unsigned char*)str, (unsigned long)strlen(str)); - sha256_done(&md, tmp); + sha256i_init(&md); + sha256i_process(&md, (unsigned char*)str, (unsigned long)strlen(str)); + sha256i_done(&md, tmp); for (j=0; j<32; j++) printf("%02x",tmp[j]); printf(" <- sha256(%s)\n",str); decode_hex(buf,(int)strlen(tests[i].msg),tests[i].msg); - sha256_init(&md); - sha256_process(&md, (unsigned char*)buf, (unsigned long)strlen(tests[i].msg)/2); - sha256_done(&md, tmp); + sha256i_init(&md); + sha256i_process(&md, (unsigned char*)buf, (unsigned long)strlen(tests[i].msg)/2); + sha256i_done(&md, tmp); for (j=0; j<32; j++) printf("%02x",tmp[j]); printf(" <- sha256(binary %s)\n",tests[i].msg); @@ -436,6 +418,24 @@ int sha256_test(void) #undef Maj +const struct ltc_hash_descriptor sha256_desc = +{ + "sha256", + 0, + 32, + 64, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, + 9, + + &sha256i_init, + &sha256i_process, + &sha256i_done, + &sha256_test, + NULL +}; + /* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha256.c,v $ */ /* $Revision: 1.11 $ */ diff --git a/crypto777/hmac/tomcrypt_hash.h b/crypto777/hmac/tomcrypt_hash.h index b596c6a37..de5977437 100755 --- a/crypto777/hmac/tomcrypt_hash.h +++ b/crypto777/hmac/tomcrypt_hash.h @@ -228,9 +228,9 @@ extern const struct ltc_hash_descriptor sha384_desc; #endif #ifdef LTC_SHA256 -int sha256_init(hash_state * md); -int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int sha256_done(hash_state * md, unsigned char *hash); +int sha256i_init(hash_state * md); +int sha256i_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha256i_done(hash_state * md, unsigned char *hash); int sha256_test(void); extern const struct ltc_hash_descriptor sha256_desc; @@ -239,7 +239,7 @@ extern const struct ltc_hash_descriptor sha256_desc; #error LTC_SHA256 is required for LTC_SHA224 #endif int sha224_init(hash_state * md); -#define sha224_process sha256_process +#define sha224_process sha256i_process int sha224_done(hash_state * md, unsigned char *hash); int sha224_test(void); extern const struct ltc_hash_descriptor sha224_desc; 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_OS.c b/crypto777/iguana_OS.c index 8bd55e0d1..504905ee1 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -422,6 +422,7 @@ void *iguana_meminit(struct OS_memspace *mem,char *name,void *ptr,int64_t totals mem->totalsize = totalsize; } mem->threadsafe = threadsafe; + mem->alignflag = 4; iguana_memreset(mem); if ( mem->totalsize == 0 ) printf("meminit.%s ILLEGAL STATE null size\n",mem->name), getchar(); diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index 80988fa5f..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)]; @@ -1279,7 +1274,7 @@ double get_theoretical(double *avebidp,double *aveaskp,double *highbidp,double * weighted = weighted_orderbook(avebidp,aveaskp,highbidp,lowaskp,bittrex_orderbook(base,rel,25),1./(*CMC_averagep)); if ( *CMC_averagep > SMALLVAL && weighted > SMALLVAL ) theoretical = calc_theoretical(weighted,*CMC_averagep,changes); - if ( counter++ == 0 ) + if ( (0) && counter++ < 100 ) printf("HBLA.[%.8f %.8f] AVE.[%.8f %.8f] (%s) CMC %f %f %f %f\n",*highbidp,*lowaskp,*avebidp,*aveaskp,jprint(item,0),*CMC_averagep,changes[0],changes[1],changes[2]); free_json(cmcjson); } diff --git a/crypto777/m_LP_win_cross b/crypto777/m_LP_win_cross new file mode 100755 index 000000000..483f14aa5 --- /dev/null +++ b/crypto777/m_LP_win_cross @@ -0,0 +1,4 @@ +git pull +rm *.o +i686-w64-mingw32-gcc -DWIN32 -static-libgcc -c -DLIQUIDITY_PROVIDER=1 -O2 *.c jpeg/*.c jpeg/unix/*.c -DPTW32_STATIC_LIB -lm -DCURL_STATICLIB -L../win_lib/lib/ -I../win_lib/include/ -L../win_lib/ -lcurl +rm -f ../agents/libcrypto777.a; ar rc ../agents/libcrypto777.a *.o diff --git a/crypto777/nanosrc/aio/worker_posix.c b/crypto777/nanosrc/aio/worker_posix.c index a2662d078..070a87a86 100755 --- a/crypto777/nanosrc/aio/worker_posix.c +++ b/crypto777/nanosrc/aio/worker_posix.c @@ -103,7 +103,7 @@ int nn_worker_init(struct nn_worker *self) { int32_t rc; PNACL_message("nn_worker_init %p\n",self); - sleep(1); + //sleep(1); rc = nn_efd_init(&self->efd); PNACL_message("efd init: rc.%d\n",rc); if ( rc < 0 ) diff --git a/crypto777/nanosrc/core/global.c b/crypto777/nanosrc/core/global.c index 51ab91709..e8f750f88 100755 --- a/crypto777/nanosrc/core/global.c +++ b/crypto777/nanosrc/core/global.c @@ -240,7 +240,7 @@ PNACL_message("list init\n"); // Initialise other parts of the global state. nn_list_init(&SELF.transports); nn_list_init(&SELF.socktypes); - sleep(1); + //sleep(1); PNACL_message("transports init\n"); // Plug in individual transports. //nn_global_add_transport(nn_ipc); @@ -248,36 +248,36 @@ PNACL_message("transports init\n"); //nn_global_add_transport(nn_inproc); //nn_global_add_transport(nn_ws); //nn_global_add_transport(nn_tcpmux); - sleep(1); + //sleep(1); PNACL_message("socktypes init\n"); // Plug in individual socktypes nn_global_add_socktype(nn_pair_socktype); - sleep(1); + //sleep(1); PNACL_message("nn_xpair_socktype init\n"); nn_global_add_socktype(nn_xpair_socktype); PNACL_message("did nn_xpair_socktype init\n"); - //nn_global_add_socktype(nn_rep_socktype); - //nn_global_add_socktype(nn_req_socktype); - //nn_global_add_socktype(nn_xrep_socktype); - //nn_global_add_socktype(nn_xreq_socktype); - //nn_global_add_socktype(nn_respondent_socktype); - //nn_global_add_socktype(nn_surveyor_socktype); - //nn_global_add_socktype(nn_xrespondent_socktype); - //nn_global_add_socktype(nn_xsurveyor_socktype); - //nn_global_add_socktype(nn_pub_socktype); - //nn_global_add_socktype(nn_sub_socktype); - //nn_global_add_socktype(nn_xpub_socktype); - //nn_global_add_socktype(nn_xsub_socktype); - //nn_global_add_socktype(nn_push_socktype); - //nn_global_add_socktype(nn_xpush_socktype); - //nn_global_add_socktype(nn_pull_socktype); - //nn_global_add_socktype(nn_xpull_socktype); - //nn_global_add_socktype(nn_bus_socktype); - //nn_global_add_socktype(nn_xbus_socktype); - sleep(1); + nn_global_add_socktype(nn_rep_socktype); + nn_global_add_socktype(nn_req_socktype); + nn_global_add_socktype(nn_xrep_socktype); + nn_global_add_socktype(nn_xreq_socktype); + nn_global_add_socktype(nn_respondent_socktype); + nn_global_add_socktype(nn_surveyor_socktype); + nn_global_add_socktype(nn_xrespondent_socktype); + nn_global_add_socktype(nn_xsurveyor_socktype); + nn_global_add_socktype(nn_pub_socktype); + nn_global_add_socktype(nn_sub_socktype); + nn_global_add_socktype(nn_xpub_socktype); + nn_global_add_socktype(nn_xsub_socktype); + nn_global_add_socktype(nn_push_socktype); + nn_global_add_socktype(nn_xpush_socktype); + nn_global_add_socktype(nn_pull_socktype); + nn_global_add_socktype(nn_xpull_socktype); + nn_global_add_socktype(nn_bus_socktype); + nn_global_add_socktype(nn_xbus_socktype); + //sleep(1); PNACL_message("do pool init\n"); nn_pool_init(&SELF.pool); // Start the worker threads - sleep(1); + //sleep(1); PNACL_message("do FSM init\n"); nn_fsm_init_root(&SELF.fsm,nn_global_handler,nn_global_shutdown,&SELF.ctx); // Start FSM SELF.state = NN_GLOBAL_STATE_IDLE; diff --git a/crypto777/nanosrc/utils/efd_pipe.c b/crypto777/nanosrc/utils/efd_pipe.c index ddce06119..4df5fd3b3 100755 --- a/crypto777/nanosrc/utils/efd_pipe.c +++ b/crypto777/nanosrc/utils/efd_pipe.c @@ -34,14 +34,14 @@ int nn_efd_init(struct nn_efd *self) { int rc,flags,p[2]; PNACL_message("inside efd_init: pipe\n"); - sleep(1); + //sleep(1); #if defined NN_HAVE_PIPE2 rc = pipe2(p, O_NONBLOCK | O_CLOEXEC); #else rc = pipe(p); #endif PNACL_message("rc efd_init: %d\n",rc); - sleep(1); + //sleep(1); if (rc != 0 && (errno == EMFILE || errno == ENFILE)) return -EMFILE; errno_assert (rc == 0); diff --git a/crypto777/scrypt.c b/crypto777/scrypt.c index fa482eaf8..1b156a286 100755 --- a/crypto777/scrypt.c +++ b/crypto777/scrypt.c @@ -69,7 +69,7 @@ static const uint32_t sha256_k[64] = { 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; -static inline void sha256_init(uint32_t *state) +static inline void scrypt_sha256_init(uint32_t *state) { memcpy(state, sha256_h, 32); } @@ -102,7 +102,7 @@ W[i] + sha256_k[i]) #define swab32(x) ((((x) << 24) & 0xff000000u) | (((x) << 8) & 0x00ff0000u) | (((x) >> 8) & 0x0000ff00u) | (((x) >> 24) & 0x000000ffu)) -static inline void sha256_transform(uint32_t *state, const uint32_t *block, int swap) +static inline void scrypt_sha256_transform(uint32_t *state, const uint32_t *block, int swap) { uint32_t W[64]; uint32_t S[8]; @@ -203,29 +203,29 @@ static inline void HMAC_SHA256_80_init(const uint32_t *key,uint32_t *tstate, uin /* tstate is assumed to contain the midstate of key */ memcpy(pad, key + 16, 16); memcpy(pad + 4, keypad, 48); - sha256_transform(tstate, pad, 0); + scrypt_sha256_transform(tstate, pad, 0); memcpy(ihash, tstate, 32); - sha256_init(ostate); + scrypt_sha256_init(ostate); for (i = 0; i < 8; i++) pad[i] = ihash[i] ^ 0x5c5c5c5c; for (; i < 16; i++) pad[i] = 0x5c5c5c5c; - sha256_transform(ostate, pad, 0); + scrypt_sha256_transform(ostate, pad, 0); - sha256_init(tstate); + scrypt_sha256_init(tstate); for (i = 0; i < 8; i++) pad[i] = ihash[i] ^ 0x36363636; for (; i < 16; i++) pad[i] = 0x36363636; - sha256_transform(tstate, pad, 0); + scrypt_sha256_transform(tstate, pad, 0); } static inline void PBKDF2_SHA256_80_128(const uint32_t *tstate,const uint32_t *ostate, const uint32_t *salt, uint32_t *output) { uint32_t istate[8], ostate2[8],ibuf[16], obuf[16]; int i, j; memcpy(istate, tstate, 32); - sha256_transform(istate, salt, 0); + scrypt_sha256_transform(istate, salt, 0); memcpy(ibuf, salt + 16, 16); memcpy(ibuf + 5, innerpad, 44); memcpy(obuf + 8, outerpad, 32); @@ -233,9 +233,9 @@ static inline void PBKDF2_SHA256_80_128(const uint32_t *tstate,const uint32_t *o { memcpy(obuf, istate, 32); ibuf[4] = i + 1; - sha256_transform(obuf, ibuf, 0); + scrypt_sha256_transform(obuf, ibuf, 0); memcpy(ostate2, ostate, 32); - sha256_transform(ostate2, obuf, 0); + scrypt_sha256_transform(ostate2, obuf, 0); for (j = 0; j < 8; j++) output[8 * i + j] = swab32(ostate2[j]); } @@ -244,12 +244,12 @@ static inline void PBKDF2_SHA256_80_128(const uint32_t *tstate,const uint32_t *o static inline void PBKDF2_SHA256_128_32(uint32_t *tstate, uint32_t *ostate,const uint32_t *salt, uint32_t *output) { uint32_t buf[16]; int i; - sha256_transform(tstate, salt, 1); - sha256_transform(tstate, salt + 16, 1); - sha256_transform(tstate, finalblk, 0); + scrypt_sha256_transform(tstate, salt, 1); + scrypt_sha256_transform(tstate, salt + 16, 1); + scrypt_sha256_transform(tstate, finalblk, 0); memcpy(buf, tstate, 32); memcpy(buf + 8, outerpad, 32); - sha256_transform(ostate, buf, 0); + scrypt_sha256_transform(ostate, buf, 0); for (i = 0; i < 8; i++) output[i] = swab32(ostate[i]); } @@ -363,11 +363,11 @@ void calc_scrypthash(uint32_t *hash,void *data) uint8_t *scratchbuf; uint32_t midstate[8]; memset(midstate,0,sizeof(midstate)); memset(hash,0,32); - sha256_init(midstate); - sha256_transform(midstate,(void *)data,0); + scrypt_sha256_init(midstate); + scrypt_sha256_transform(midstate,(void *)data,0); scratchbuf = malloc(1024 * 128 + 64); scrypt_1024_1_1_256((void *)data,hash,midstate,scratchbuf,1024); free(scratchbuf); } //010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c -//010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c00 \ No newline at end of file +//010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c00 diff --git a/iguana.vcxproj b/iguana.vcxproj index e7a0d7a57..fbdc95c13 100644 --- a/iguana.vcxproj +++ b/iguana.vcxproj @@ -73,16 +73,22 @@ true + $(ProjectDir)\includes;$(ProjectDir)\includes\curl;$(IncludePath) + $(ProjectDir)\OSlibs\win;$(LibraryPath) true + $(SolutionDir)/includes;$(SolutionDir)/includes/curl;$(IncludePath) false + $(ProjectDir)\includes;$(ProjectDir)\includes\curl;$(IncludePath) + $(ProjectDir)\OSlibs\win;$(LibraryPath) false false + $(ProjectDir)\includes;$(ProjectDir)\includes\curl;$(IncludePath) @@ -97,7 +103,7 @@ Console true - Ws2_32.lib;pthreadVC2.lib;nanomsg.lib;%(AdditionalDependencies) + Ws2_32.lib;pthreadVC2.lib;nanomsg.lib;libcurl.lib;%(AdditionalDependencies) .\iguana;.\OSlibs\win;%(AdditionalLibraryDirectories) @@ -114,7 +120,7 @@ Console true .\OSlibs\win\x64;%(AdditionalLibraryDirectories) - pthread_lib.lib;Ws2_32.lib;nanomsg.lib;%(AdditionalDependencies) + pthread_lib.lib;Ws2_32.lib;nanomsg.lib;libcurl.lib;%(AdditionalDependencies) @@ -133,7 +139,7 @@ true true true - Ws2_32.lib;pthreadVC2.lib;nanomsg.lib;%(AdditionalDependencies) + Ws2_32.lib;pthreadVC2.lib;nanomsg.lib;libcurl.lib;%(AdditionalDependencies) .\OSlibs\win\release;%(AdditionalLibraryDirectories) @@ -154,7 +160,7 @@ true true true - Ws2_32.lib;Advapi32.lib;$(SolutionDir)OSlibs\win\x64\pthread_lib.lib;nanomsg.lib;%(AdditionalDependencies) + Ws2_32.lib;Advapi32.lib;$(SolutionDir)OSlibs\win\x64\pthread_lib.lib;libcurl.lib;nanomsg.lib;%(AdditionalDependencies) .\OSlibs\win\x64\release;%(AdditionalLibraryDirectories) diff --git a/iguana/coins/basilisk/coqui b/iguana/coins/basilisk/coqui new file mode 100755 index 000000000..55730d486 --- /dev/null +++ b/iguana/coins/basilisk/coqui @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"COQUI.conf\",\"path\":\"${HOME#"/"}/.komodo/COQUI\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"COQUI\",\"name\":\"COQUI\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"dd5ce076\",\"p2p\":14275,\"rpc\":14276,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/mesh b/iguana/coins/basilisk/mesh index 81904b6d7..a8cf1b219 100755 --- a/iguana/coins/basilisk/mesh +++ b/iguana/coins/basilisk/mesh @@ -1 +1 @@ -curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"MESH.conf\",\"path\":\"${HOME#"/"}/.komodo/MESH\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MESH\",\"name\":\"MESH\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"c28227c2\",\"p2p\":11940,\"rpc\":11941,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"MESH.conf\",\"path\":\"${HOME#"/"}/.komodo/MESH\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MESH\",\"name\":\"MESH\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"4d6bbfb6\",\"p2p\":8399,\"rpc\":8400,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/basilisk/wireless b/iguana/coins/basilisk/wireless deleted file mode 100755 index f1a56bef5..000000000 --- a/iguana/coins/basilisk/wireless +++ /dev/null @@ -1 +0,0 @@ -curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"WIRELESS.conf\",\"path\":\"${HOME#"/"}/.komodo/WIRELESS\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"WIRELESS\",\"name\":\"WIRELESS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"62071ed3\",\"p2p\":11666,\"rpc\":11667,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/basilisk/wlc b/iguana/coins/basilisk/wlc new file mode 100755 index 000000000..8c10b2475 --- /dev/null +++ b/iguana/coins/basilisk/wlc @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"WLC.conf\",\"path\":\"${HOME#"/"}/.komodo/WLC\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"WLC\",\"name\":\"WLC\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7ec1c253\",\"p2p\":12166,\"rpc\":12167,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/btc_osx b/iguana/coins/btc_osx new file mode 100755 index 000000000..d7dfce062 --- /dev/null +++ b/iguana/coins/btc_osx @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"bitcoin.conf\",\"path\":\"/${HOME#"/"}/Library/Application\ Support/Bitcoin\",\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":64,\"endpend\":64,\"services\":0,\"maxpeers\":512,\"RELAY\":-1,\"VALIDATE\":0,\"portp2p\":8333,\"minconfirms\":1}" + diff --git a/iguana/coins/coqui_7776 b/iguana/coins/coqui_7776 new file mode 100755 index 000000000..6079fd06e --- /dev/null +++ b/iguana/coins/coqui_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"COQUI.conf\",\"path\":\"${HOME#"/"}/.komodo/COQUI\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"COQUI\",\"name\":\"COQUI\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fa05f107\",\"p2p\":14275,\"rpc\":14276,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/genltc b/iguana/coins/genltc index df691b5d6..ea034ed80 100755 --- a/iguana/coins/genltc +++ b/iguana/coins/genltc @@ -1,4 +1,4 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":68,\"endpend\":68,\"services\":129,\"maxpeers\":256,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9332,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":68,\"endpend\":68,\"services\":129,\"maxpeers\":256,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9332,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" diff --git a/iguana/coins/jumblr b/iguana/coins/jumblr new file mode 100755 index 000000000..5b52ce9a6 --- /dev/null +++ b/iguana/coins/jumblr @@ -0,0 +1,4 @@ +~/komodo/src/komodod -ac_name=JUMBLR -ac_supply=999999 -addnode=78.47.196.146 & + +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"JUMBLR.conf\",\"path\":\"${HOME#"/"}/.komodo/JUMBLR\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"JUMBLR\",\"name\":\"JUMBLR\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7223759e\",\"p2p\":15105,\"rpc\":15106,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/jumblr_osx b/iguana/coins/jumblr_osx new file mode 100755 index 000000000..dd50b1842 --- /dev/null +++ b/iguana/coins/jumblr_osx @@ -0,0 +1,3 @@ +/Applications/komodoOSX.app/Contents/komodod -ac_name=JUMBLR -ac_supply=999999 -addnode=78.47.196.146 & +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"JUMBLR.conf\",\"path\":\"/${HOME#"/"}/Library/Application\ Support/Komodo/JUMBLR\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"JUMBLR\",\"name\":\"JUMBLR\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7223759e\",\"p2p\":15105,\"rpc\":15106,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/kmd_osx b/iguana/coins/kmd_osx new file mode 100755 index 000000000..2374af8a7 --- /dev/null +++ b/iguana/coins/kmd_osx @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"komodo.conf\",\"path\":\"/${HOME#"/"}/Library/Application\ Support/Komodo\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":0,\"maxpeers\":32,\"newcoin\":\"KMD\",\"name\":\"Komodo\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"f9eee48d\",\"p2p\":7770,\"rpc\":7771,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0}" + diff --git a/iguana/coins/ltc_7776 b/iguana/coins/ltc_7776 new file mode 100755 index 000000000..d6b5e4e11 --- /dev/null +++ b/iguana/coins/ltc_7776 @@ -0,0 +1,4 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"litecoin.conf\",\"path\":\"${HOME#"/"}/.litecoin\",\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":68,\"endpend\":68,\"services\":129,\"maxpeers\":256,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9332,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" + diff --git a/iguana/coins/mesh_7776 b/iguana/coins/mesh_7776 index 214335788..bcccf8d8d 100755 --- a/iguana/coins/mesh_7776 +++ b/iguana/coins/mesh_7776 @@ -1 +1 @@ -curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MESH.conf\",\"path\":\"${HOME#"/"}/.komodo/MESH\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MESH\",\"name\":\"MESH\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"c28227c2\",\"p2p\":11940,\"rpc\":11941,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MESH.conf\",\"path\":\"${HOME#"/"}/.komodo/MESH\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MESH\",\"name\":\"MESH\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"4d6bbfb6\",\"p2p\":9454,\"rpc\":9455,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/revs b/iguana/coins/revs new file mode 100755 index 000000000..23f4948b2 --- /dev/null +++ b/iguana/coins/revs @@ -0,0 +1,3 @@ +~/komodo/src/komodod -ac_name=REVS -ac_supply=1300000 -addnode=78.47.196.146 & +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"REVS.conf\",\"path\":\"${HOME#"/"}/.komodo/REVS\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"REVS\",\"name\":\"REVS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"905c3498\",\"p2p\":10195,\"rpc\":10196,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/revs_osx b/iguana/coins/revs_osx new file mode 100755 index 000000000..c98b4fabb --- /dev/null +++ b/iguana/coins/revs_osx @@ -0,0 +1,3 @@ +/Applications/komodoOSX.app/Contents/komodod -ac_name=REVS -ac_supply=1300000 -addnode=78.47.196.146 & +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"REVS.conf\",\"path\":\"/${HOME#"/"}/Library/Application\ Support/Komodo/REVS\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"REVS\",\"name\":\"REVS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"905c3498\",\"p2p\":10195,\"rpc\":10196,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/wireless_7776 b/iguana/coins/wireless_7776 deleted file mode 100755 index 420a3508c..000000000 --- a/iguana/coins/wireless_7776 +++ /dev/null @@ -1 +0,0 @@ -curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"WIRELESS.conf\",\"path\":\"${HOME#"/"}/.komodo/WIRELESS\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"WIRELESS\",\"name\":\"WIRELESS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"62071ed3\",\"p2p\":11666,\"rpc\":11667,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/wlc_7776 b/iguana/coins/wlc_7776 new file mode 100755 index 000000000..b43b7f793 --- /dev/null +++ b/iguana/coins/wlc_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"WLC.conf\",\"path\":\"${HOME#"/"}/.komodo/WLC\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"WLC\",\"name\":\"WLC\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7ec1c253\",\"p2p\":12166,\"rpc\":12167,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/dPoW.h b/iguana/dPoW.h index b773104c8..47e9f1642 100755 --- a/iguana/dPoW.h +++ b/iguana/dPoW.h @@ -137,7 +137,7 @@ struct dpow_info int32_t lastheight,maxblocks,SRCHEIGHT,SHORTFLAG,ratifying; struct pax_transaction *PAX; portable_mutex_t paxmutex,dexmutex; - uint32_t ipbits[64],numipbits; + uint32_t ipbits[128],numipbits; struct dpow_block **blocks; }; uint64_t dpow_notarybestk(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp); diff --git a/iguana/dexscripts/.marker b/iguana/dexscripts/.marker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/dpow/dpow_network.c b/iguana/dpow/dpow_network.c index cadc11faa..9899b9cac 100755 --- a/iguana/dpow/dpow_network.c +++ b/iguana/dpow/dpow_network.c @@ -88,6 +88,9 @@ void dex_init(struct supernet_info *myinfo) break; } mask |= (1 << j); +#ifdef NOTARY_TESTMODE + seeds[j] = NOTARY_TESTMODE; +#endif printf("seed.[%d] <- %s\n",i,seeds[j]); strcpy(myinfo->dexseed_ipaddrs[i],seeds[j]); myinfo->dexipbits[i] = (uint32_t)calc_ipbits(myinfo->dexseed_ipaddrs[i]); @@ -140,23 +143,34 @@ int32_t signed_nn_send(struct supernet_info *myinfo,void *ctx,bits256 privkey,in return(-1); } -int32_t signed_nn_recv(void **freeptrp,void *ctx,uint8_t notaries[64][33],int32_t n,int32_t sock,void *packetp) +int32_t signed_nn_recv(void **freeptrp,struct supernet_info *myinfo,uint8_t notaries[64][33],int32_t n,int32_t sock,void *packetp) { - int32_t i,recvbytes; uint8_t pubkey33[33],pubkey0[33]; bits256 packethash; struct signed_nnpacket *sigpacket=0; + int32_t i=0,recvbytes; uint8_t pubkey33[33],pubkey0[33]; bits256 packethash; struct signed_nnpacket *sigpacket=0; *(void **)packetp = 0; *freeptrp = 0; - if ( (recvbytes= nn_recv(sock,&sigpacket,NN_MSG,0)) > 0 ) + /*for (i=0; i<100; i++) cant do this!! slows down notary servers, big latency + { + struct nn_pollfd pfd; + pfd.fd = myinfo->reqsock; + pfd.events = NN_POLLIN; + if ( nn_poll(&pfd,1,100) > 0 ) + break; + usleep(1000); + } + if ( i == 100 ) + recvbytes = 0; + else*/ if ( (recvbytes= nn_recv(sock,&sigpacket,NN_MSG,0)) > 0 ) { //for (i=0; ipacketlen == recvbytes-sizeof(*sigpacket)); + //printf(" <- [%d] RECV.%d crc.%08x cmp.%d\n",i,recvbytes,calc_crc32(0,(void *)sigpacket,recvbytes),sigpacket->packetlen == recvbytes-sizeof(*sigpacket)); } if ( sigpacket != 0 && recvbytes > sizeof(*sigpacket) && sigpacket->packetlen == recvbytes-sizeof(*sigpacket) ) { vcalc_sha256(0,packethash.bytes,(void *)&sigpacket->nonce,(int32_t)(sigpacket->packetlen+sizeof(sigpacket->nonce)+sizeof(sigpacket->packetlen))); if ( bits256_cmp(packethash,sigpacket->packethash) == 0 && sigpacket->packethash.bytes[0] == 0 ) { - if ( bitcoin_recoververify(ctx,"nnrecv",sigpacket->sig64,sigpacket->packethash,pubkey33,33) == 0 ) + if ( bitcoin_recoververify(myinfo->ctx,"nnrecv",sigpacket->sig64,sigpacket->packethash,pubkey33,33) == 0 ) { char *notary0 = "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828"; // expand to official notaries @@ -376,7 +390,7 @@ void dex_packet(struct supernet_info *myinfo,struct dex_nanomsghdr *dexp,int32_t char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32_t keylen,uint8_t *data,int32_t datalen) { - struct dex_nanomsghdr *dexp; cJSON *retjson; char ipaddr[64],str[128]; int32_t timeout,i,n,size,recvbytes,sentbytes = 0,reqsock,subsock; uint32_t *retptr,ipbits; void *freeptr; char *retstr = 0; + struct dex_nanomsghdr *dexp; cJSON *retjson; char ipaddr[64],str[128]; int32_t prio,timeout,i,n,size,recvbytes,sentbytes = 0,reqsock,subsock; uint32_t *retptr,ipbits; void *freeptr; char *retstr = 0; portable_mutex_lock(&myinfo->dexmutex); subsock = myinfo->subsock; reqsock = myinfo->reqsock; @@ -386,15 +400,15 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32 { timeout = 1000; nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); - //timeout = 1500; - //nn_setsockopt(reqsock,NN_TCP,NN_RECONNECT_IVL,&timeout,sizeof(timeout)); - timeout = 3000; + timeout = 1000; + nn_setsockopt(reqsock,NN_TCP,NN_RECONNECT_IVL,&timeout,sizeof(timeout)); + timeout = 10000; nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - //prio = 1; - //nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_SNDPRIO,&prio,sizeof(prio)); - //nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVPRIO,&prio,sizeof(prio)); for (i=0; idexseed_ipaddrs)/sizeof(*myinfo->dexseed_ipaddrs); i++) { + prio = (i/2) + 1; + //nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_SNDPRIO,&prio,sizeof(prio)); + //nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVPRIO,&prio,sizeof(prio)); if ( nn_connect(reqsock,nanomsg_tcpname(0,str,myinfo->dexseed_ipaddrs[i],REP_SOCK)) < 0 ) { nn_close(reqsock); @@ -402,9 +416,6 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32 break; } } - //prio = 8; - //nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_SNDPRIO,&prio,sizeof(prio)); - //nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVPRIO,&prio,sizeof(prio)); } if ( reqsock >= 0 ) { @@ -421,14 +432,14 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32 } if ( reqsock >= 0 && subsock >= 0 ) { - timeout = 100; + timeout = 1; nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); printf("CLIENT sockets req.%d sub.%d\n",reqsock,subsock); //timeout = 5000; //nn_setsockopt(reqsock,NN_TCP,NN_RECONNECT_IVL,&timeout,sizeof(timeout)); - timeout = 10000; - nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + //timeout = 10000; + //nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); } } } @@ -467,14 +478,14 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32 if ( nn_poll(&pfd,1,100) > 0 ) { sentbytes = nn_send(myinfo->reqsock,dexp,size,0); - //printf(" sent.%d:%d datalen.%d crc.%08x\n",sentbytes,size,datalen,calc_crc32(0,(void *)dexp,size)); + //printf(" [%d] sent.%d:%d datalen.%d crc.%08x\n",i,sentbytes,size,datalen,calc_crc32(0,(void *)dexp,size)); break; } usleep(1000); } //for (i=0; ictx,myinfo->notaries,myinfo->numnotaries,myinfo->reqsock,&retptr)) >= 0 ) + if ( (recvbytes= signed_nn_recv(&freeptr,myinfo,myinfo->notaries,myinfo->numnotaries,myinfo->reqsock,&retptr)) >= 0 ) { //printf("req returned.[%d]\n",recvbytes); portable_mutex_lock(&myinfo->dexmutex); @@ -515,7 +526,7 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32 printf("%d: subscribe connect (%s)\n",myinfo->numdexipbits,str); } } -#ifndef __APPLE__ +#ifndef NOTARY_TESTMODE if ( (rand() % 100) < 40 ) { nanomsg_tcpname(0,str,ipaddr,REP_SOCK); @@ -550,7 +561,7 @@ void dex_channelsend(struct supernet_info *myinfo,bits256 srchash,bits256 destha void dpow_randipbits(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *retjson) { - int32_t m; uint32_t ipbits; char *coinstr; + int32_t m; uint32_t ipbits; char *coinstr; cJSON *infojson; if ( is_cJSON_Array(retjson) == 0 ) { if ( (m= myinfo->numdpowipbits) > 0 ) @@ -561,6 +572,11 @@ void dpow_randipbits(struct supernet_info *myinfo,struct iguana_info *coin,cJSON } if ( (coinstr= jstr(retjson,"coin")) == 0 ) jaddstr(retjson,"coin",coin->symbol); + if ( (infojson= dpow_getinfo(myinfo,coin)) != 0 ) + { + jaddnum(retjson,"notaryheight",juint(infojson,"blocks")); + free_json(infojson); + } } } @@ -798,7 +814,13 @@ char *dex_response(int32_t *broadcastflagp,struct supernet_info *myinfo,struct d } //printf("DEX NOTARIES -> (%s)\n",retstr); } - } else printf("(%s) not active\n",dexreq.name); + } + else + { + static uint32_t counter; + if ( counter++ < 10 ) + printf("request came in from GUI for (%s) that is not active\n",dexreq.name); + } if ( retstr == 0 ) return(clonestr("{\"error\":\"null return\"}")); } @@ -813,7 +835,7 @@ char *dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *data,int32 { if ( (retstrs[j]= _dex_reqsend(myinfo,handler,0,0,data,datalen)) != 0 ) { - //printf("j.%d of max.%d M.%d (%s)\n",j,max,M,retstrs[j]); +//printf("j.%d of max.%d M.%d (%s)\n",j,max,M,retstrs[j]); if ( strncmp(retstrs[j],"{\"error\":\"null return\"}",strlen("{\"error\":\"null return\"}")) != 0 && strncmp(retstrs[j],"[]",strlen("[]")) != 0 && strcmp("0",retstrs[j]) != 0 ) { if ( ++j == M ) @@ -1082,11 +1104,13 @@ char *_dex_getbestblockhash(struct supernet_info *myinfo,char *symbol) char *_dex_sendrawtransaction(struct supernet_info *myinfo,char *symbol,char *signedtx) { - struct dex_request dexreq; + struct dex_request dexreq; char *retstr; memset(&dexreq,0,sizeof(dexreq)); safecopy(dexreq.name,symbol,sizeof(dexreq.name)); dexreq.func = 'S'; - return(_dex_sendrequeststr(myinfo,&dexreq,signedtx,0,3,"*")); + retstr = _dex_sendrequeststr(myinfo,&dexreq,signedtx,0,1,"*"); + //printf("RET.(%s)\n",retstr); + return(retstr); } char *_dex_importaddress(struct supernet_info *myinfo,char *symbol,char *address) @@ -1154,14 +1178,17 @@ char *_dex_listunspentarg(struct supernet_info *myinfo,char *symbol,char *addres dexreq.func = arg; if ( (retstr= _dex_sendrequeststr(myinfo,&dexreq,address,0,1,"")) != 0 ) { - //printf("UNSPENTS.(%s)\n",retstr); + //printf("_dex_listunspentarg: %s UNSPENTS.(%s)\n",symbol,retstr); } return(_dex_arrayreturn(retstr)); } char *_dex_listunspent(struct supernet_info *myinfo,char *symbol,char *address) { - return(_dex_listunspentarg(myinfo,symbol,address,'u')); // 'U' old variant + char *retstr; + retstr = _dex_listunspentarg(myinfo,symbol,address,'u'); // 'U' old variant + //printf("_dex_listunspent.(%s)\n",retstr); + return(retstr); } char *_dex_listunspent2(struct supernet_info *myinfo,char *symbol,char *address) @@ -1255,9 +1282,9 @@ int32_t dex_packetcheck(struct supernet_info *myinfo,struct dex_nanomsghdr *dexp int32_t dex_subsock_poll(struct supernet_info *myinfo) { int32_t size= -1; struct dex_nanomsghdr *dexp; void *freeptr; - return(0); + //return(0); //fprintf(stderr,"subsock.%d\n",myinfo->subsock); - if ( myinfo->subsock >= 0 && (size= signed_nn_recv(&freeptr,myinfo->ctx,myinfo->notaries,myinfo->numnotaries,myinfo->subsock,&dexp)) >= 0 ) + if ( myinfo->subsock >= 0 && (size= signed_nn_recv(&freeptr,myinfo,myinfo->notaries,myinfo->numnotaries,myinfo->subsock,&dexp)) >= 0 ) { if ( dexp != 0 ) { @@ -1296,7 +1323,7 @@ struct dpow_nanomsghdr { bits256 srchash,desthash; struct dpow_nanoutxo ratify,notarize; - uint32_t channel,height,size,datalen,crc32,myipbits,numipbits,ipbits[64]; + uint32_t channel,height,size,datalen,crc32,myipbits,numipbits,ipbits[128]; char symbol[16]; uint8_t senderind,version0,version1,packet[]; } PACKED; @@ -2004,10 +2031,10 @@ void dpow_send(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_blo printf("%d NANOSEND.%d ht.%d channel.%08x (%d) pax.%08x datalen.%d (%d %llx) (%d %llx) recv.%llx\n",i,sentbytes,np->height,np->channel,size,np->notarize.paxwdcrc,datalen,(int8_t)np->notarize.bestk,(long long)np->notarize.bestmask,bp->notaries[bp->myind].bestk,(long long)bp->notaries[bp->myind].bestmask,(long long)bp->recvmask); } -void dpow_ipbitsadd(struct supernet_info *myinfo,struct dpow_info *dp,uint32_t *ipbits,int32_t numipbits,int32_t fromid,uint32_t senderipbits) +void dpow_ipbitsadd(struct supernet_info *myinfo,struct dpow_info *dp,uint32_t *ipbits,int32_t numipbits,int32_t maxipbits,int32_t fromid,uint32_t senderipbits) { int32_t i,j,matched,missing,n; char ipaddr[64]; - if ( numipbits >= 64 ) + if ( numipbits >= maxipbits ) { static int32_t counter; if ( counter++ < 100 ) @@ -2063,10 +2090,10 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) for (iter=0; iter<100; iter++) { freeptr = 0; - if ( (flags & 1) == 0 && (size= signed_nn_recv(&freeptr,myinfo->ctx,myinfo->notaries,myinfo->numnotaries,myinfo->dpowsock,&np)) > 0 ) + if ( (flags & 1) == 0 && (size= signed_nn_recv(&freeptr,myinfo,myinfo->notaries,myinfo->numnotaries,myinfo->dpowsock,&np)) > 0 ) { num++; - if ( size > 0 ) + if ( size >= sizeof(*np) ) { //fprintf(stderr,"%d ",size); if ( np->version0 == (DPOW_VERSION & 0xff) && np->version1 == ((DPOW_VERSION >> 8) & 0xff) ) @@ -2090,7 +2117,7 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) printf("received nnpacket for (%s)\n",np->symbol); else { - dpow_ipbitsadd(myinfo,dp,np->ipbits,np->numipbits,np->senderind,np->myipbits); + dpow_ipbitsadd(myinfo,dp,np->ipbits,np->numipbits,sizeof(np->ipbits)/sizeof(*np->ipbits),np->senderind,np->myipbits); if ( (bp= dpow_heightfind(myinfo,dp,np->height)) != 0 && bp->state != 0xffffffff && bp->myind >= 0 ) { //char str[65]; printf("%s RECV ht.%d ch.%08x (%d) crc32.%08x:%08x datalen.%d:%d firstz.%d i.%d senderind.%d myind.%d\n",bits256_str(str,np->srchash),np->height,np->channel,size,np->crc32,crc32,np->datalen,(int32_t)(size - sizeof(*np)),firstz,i,np->senderind,bp->myind); @@ -2117,7 +2144,7 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) if ( myinfo->dexsock >= 0 ) // from servers { freeptr = 0; - if ( (flags & 2) == 0 && (size= signed_nn_recv(&freeptr,myinfo->ctx,myinfo->notaries,myinfo->numnotaries,myinfo->dexsock,&dexp)) > 0 ) + if ( (flags & 2) == 0 && (size= signed_nn_recv(&freeptr,myinfo,myinfo->notaries,myinfo->numnotaries,myinfo->dexsock,&dexp)) > 0 ) { //fprintf(stderr,"%d ",size); n++; @@ -2157,11 +2184,11 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) { r = myinfo->dpowipbits[rand() % m]; signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->repsock,&r,sizeof(r)); - //printf("REP.%08x <- rand ip m.%d %x\n",dexp->crc32,m,r); + printf("REP.%08x <- rand ip m.%d %x\n",dexp->crc32,m,r); } else printf("illegal state without dpowipbits?\n"); if ( dex_packetcheck(myinfo,dexp,size) == 0 ) { - signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->dexsock,dexp,size); + //signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->dexsock,dexp,size); //signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->pubsock,dexp,size); //printf("REP.%08x -> dexbus and pub, t.%d lag.%d\n",dexp->crc32,dexp->timestamp,(int32_t)(time(NULL)-dexp->timestamp)); dex_packet(myinfo,dexp,size); @@ -2183,7 +2210,7 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) } else break; } portable_mutex_unlock(&myinfo->dpowmutex); - return(num); + return(num+n+num2); } #else diff --git a/iguana/dpow/dpow_prices.c b/iguana/dpow/dpow_prices.c index 3a8257bb7..d83da8dd1 100755 --- a/iguana/dpow/dpow_prices.c +++ b/iguana/dpow/dpow_prices.c @@ -1275,25 +1275,33 @@ int32_t PAX_ecbparse(char *date,double *prices,char *url,int32_t basenum) printf("(%s)\n",jsonstr); if ( (json= cJSON_Parse(jsonstr)) != 0 ) { - copy_cJSON(&tmp,jobj(json,"date")), safecopy(date,tmp.buf,64); - if ( (basestr= jstr(json,"base")) != 0 && strcmp(basestr,CURRENCIES[basenum]) == 0 && (ratesobj= jobj(json,"rates")) != 0 && (item= ratesobj->child) != 0 ) + if ( jobj(json,"error") != 0 || jobj(json,"date") == 0 ) { - while ( item != 0 ) + printf("Got error from fixer.io (%s)\n",jsonstr); + sleep(10); + } + else + { + copy_cJSON(&tmp,jobj(json,"date")), safecopy(date,tmp.buf,64); + if ( (basestr= jstr(json,"base")) != 0 && strcmp(basestr,CURRENCIES[basenum]) == 0 && (ratesobj= jobj(json,"rates")) != 0 && (item= ratesobj->child) != 0 ) { - if ( (relstr= get_cJSON_fieldname(item)) != 0 && (relnum= PAX_basenum(relstr)) >= 0 ) + while ( item != 0 ) { - i = basenum*MAX_CURRENCIES + relnum; - prices[i] = item->valuedouble; - //if ( basenum == JPYNUM ) - // prices[i] *= 100.; - // else if ( relnum == JPYNUM ) - // prices[i] /= 100.; - count++; - if ( Debuglevel > 2 ) - printf("(%02d:%02d %f) ",basenum,relnum,prices[i]); - sprintf(name,"%s%s",CURRENCIES[basenum],CURRENCIES[relnum]); - } else printf("cant find.(%s)\n",relstr);//, getchar(); - item = item->next; + if ( (relstr= get_cJSON_fieldname(item)) != 0 && (relnum= PAX_basenum(relstr)) >= 0 ) + { + i = basenum*MAX_CURRENCIES + relnum; + prices[i] = item->valuedouble; + //if ( basenum == JPYNUM ) + // prices[i] *= 100.; + // else if ( relnum == JPYNUM ) + // prices[i] /= 100.; + count++; + if ( Debuglevel > 2 ) + printf("(%02d:%02d %f) ",basenum,relnum,prices[i]); + sprintf(name,"%s%s",CURRENCIES[basenum],CURRENCIES[relnum]); + } else printf("cant find.(%s)\n",relstr);//, getchar(); + item = item->next; + } } } free_json(json); @@ -1322,12 +1330,13 @@ int32_t PAX_ecbprices(char *date,double *prices,int32_t year,int32_t month,int32 { for (basenum=0; basenum= MAX_CURRENCIES ) break; if ( iter == 0 ) { sprintf(url,"%s%s",baseurl,CURRENCIES[basenum]); count += PAX_ecbparse(basenum == 0 ? date : tmpdate,prices,url,basenum); + usleep(100000); if ( (basenum != 0 && strcmp(tmpdate,date) != 0) || (checkdate[0] != 0 && strcmp(checkdate,date) != 0) ) { //printf("date mismatch (%s) != (%s) or checkdate.(%s)\n",tmpdate,date,checkdate); @@ -1338,7 +1347,7 @@ int32_t PAX_ecbprices(char *date,double *prices,int32_t year,int32_t month,int32 { for (nonz=i=0; i= MAX_CURRENCIES ) break; if ( prices[MAX_CURRENCIES*basenum + i] != 0. ) nonz++; @@ -1358,6 +1367,7 @@ int32_t ecb_matrix(double basevals[MAX_CURRENCIES],double matrix[MAX_CURRENCIES] FILE *fp=0; double price,bid,ask; int32_t n=0,datenum,relid,baseid,year=0,seconds,month=0,day=0,loaded = 0; char name[16],fname[64],_date[64]; if ( date == 0 ) date = _date, memset(_date,0,sizeof(_date)); + //printf("ecb_matrix(%s)\n",date); sprintf(fname,"%s/ECB/%s",GLOBAL_DBDIR,date), OS_compatible_path(fname); if ( date[0] != 0 && (fp= fopen(fname,"rb")) != 0 ) { @@ -1365,7 +1375,7 @@ int32_t ecb_matrix(double basevals[MAX_CURRENCIES],double matrix[MAX_CURRENCIES] loaded = 1; else printf("fread error\n"); fclose(fp); - } //else printf("ecb_matrix.(%s) load error fp.%p\n",fname,fp); + } else printf("ecb_matrix.(%s) load error fp.%p\n",fname,fp); datenum = conv_date(&seconds,date); year = datenum / 10000, month = (datenum / 100) % 100, day = (datenum % 100); if ( loaded == 0 ) @@ -1428,7 +1438,7 @@ void PAX_update(struct PAX_data *dp,double *btcusdp,double *kmdbtcp) *kmdbtcp = 0; bitcoinave = 0;//url_json("https://api.bitcoinaverage.com/ticker/USD/"); //bitcoincharts = url_json("http://api.bitcoincharts.com/v1/weighted_prices.json"); - blockchaininfo = 0;//url_json("https://blockchain.info/ticker"); + blockchaininfo = url_json("https://blockchain.info/ticker"); coindesk = 0;//url_json("http://api.coindesk.com/v1/bpi/historical/close.json"); sprintf(url,"https://poloniex.com/public?command=returnChartData¤cyPair=BTC_KMD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-3600*24)); sprintf(url2,"https://poloniex.com/public?command=returnChartData¤cyPair=BTC_BTCD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-3600*24)); @@ -1531,7 +1541,7 @@ void PAX_update(struct PAX_data *dp,double *btcusdp,double *kmdbtcp) if ( (item= jobj(blockchaininfo,"USD")) != 0 && item != 0 && (price= jdouble(item,"15m")) > SMALLVAL ) { dpow_price("blockchain.info","BTCUSD",price,price); - //printf("blockchaininfo %f %f\n",btcusd,price); + printf("blockchaininfo %f %f\n",btcusd,price); dxblend(&btcusd,price,0.5); } free_json(blockchaininfo); @@ -1779,13 +1789,20 @@ double PAX_val(uint32_t pval,int32_t baseid) void PAX_genecbsplines(struct PAX_data *dp) { + static portable_mutex_t mutex; static int32_t initflag; int32_t i,j,datenum,seconds,numsamples; double prices[128][MAX_SPLINES],splineval,diff; uint32_t pvals[MAX_CURRENCIES],utc32[MAX_SPLINES],timestamp; struct tai t; + if ( initflag == 0 ) + { + portable_mutex_init(&mutex); + initflag = 1; + } + portable_mutex_lock(&mutex); for (i=numsamples=0; i<28; i++) { datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)-(28-i+1)*24*3600); expand_datenum(dp->edate,datenum); timestamp = OS_conv_datenum(datenum,12,0,0); - //printf("i.%d datenum.%d %s t%u\n",i,datenum,dp->edate,timestamp); + printf("i.%d datenum.%d %s t%u\n",i,datenum,dp->edate,timestamp); if ( (datenum= ecb_matrix(dp->basevals,dp->ecbmatrix,dp->edate)) > 0 ) { utc32[numsamples] = timestamp; @@ -1812,15 +1829,19 @@ void PAX_genecbsplines(struct PAX_data *dp) //printf("%s splineval %f vs %f %f %f\n",CURRENCIES[j],prices[j][numsamples-1],prices[j][numsamples],prices[j][numsamples+1],prices[j][numsamples+2]); PAX_genspline(&dp->splines[j],j,CURRENCIES[j],utc32,prices[j],numsamples+3,prices[j]); } + portable_mutex_unlock(&mutex); } +#define BTCFACTOR_TIMESTAMP 1503746319 +#define BTCFACTOR_HEIGHT 466266 + int32_t PAX_idle(struct supernet_info *myinfo)//struct PAX_data *argdp,int32_t idlegap) { - static double lastupdate,lastdayupdate; static int32_t didinit; static char *userhome; int32_t idlegap = 10; + static double lastupdate,lastdayupdate; static uint32_t didinit; static char *userhome; int32_t idlegap = 10; FILE *fp; long filesize; char fname[512]; double splineval; uint32_t pvals[128],timestamp; int32_t i,datenum,seconds,c; struct tai t; struct PAX_data *dp; uint8_t data[512]; if ( Currencymasks[0] == 0 ) return(0); - if ( didinit == 0 ) + if ( time(NULL) > didinit+12*3600 ) { if ( (userhome= OS_filestr(&filesize,"userhome.txt")) == 0 ) userhome = "root"; @@ -1831,15 +1852,15 @@ int32_t PAX_idle(struct supernet_info *myinfo)//struct PAX_data *argdp,int32_t i userhome[strlen(userhome)-1] = 0; } } - myinfo->PAXDATA = calloc(1,sizeof(*dp)); - didinit = 1; + if ( myinfo->PAXDATA == 0 ) + myinfo->PAXDATA = calloc(1,sizeof(*dp)); dp = myinfo->PAXDATA; PAX_genecbsplines(dp); printf("generated splines\n"); - datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)); + didinit = (uint32_t)time(NULL); + datenum = OS_conv_unixtime(&t,&seconds,didinit); expand_datenum(dp->edate,datenum); } - dp = myinfo->PAXDATA; /*if ( 0 && time(NULL) > dp->lastupdate+10 ) { @@ -1886,8 +1907,9 @@ int32_t PAX_idle(struct supernet_info *myinfo)//struct PAX_data *argdp,int32_t i PAX_emitprices(pvals,dp); } timestamp = (uint32_t)time(NULL); - int32_t dispflag = ((rand() % 64) == 0); - if ( dp->kmdbtc == 0 || dispflag != 0 ) + int32_t dispflag = ((rand() % 6) == 0); + //printf("PAX_IDLE.%d %.8f %.8f\n",dispflag,dp->kmdbtc,dp->btcusd); + if ( dp->kmdbtc == 0 || dp->btcusd == 0 || dispflag != 0 ) { PAX_update(dp,&dp->btcusd,&dp->kmdbtc); for (i=0; ikmdbtc * 1000); - pvals[4] = PAX_val32(dp->btcusd * .001); + double btcfactor; + //if ( time(NULL) > BTCFACTOR_TIMESTAMP ) + btcfactor = .00001; + //else btcfactor = .001; + pvals[4] = PAX_val32(dp->btcusd * btcfactor); pvals[5] = PAX_val32(dp->CNYUSD); - if ( dispflag != 0 ) - printf("KMD %.8f BTC %f CNY %f (%f)\n",dp->kmdbtc,dp->btcusd,dp->CNYUSD,1./dp->CNYUSD); sprintf(fname,"/%s/.komodo/komodofeed",userhome); if ( (fp= fopen(fname,"wb")) != 0 ) { @@ -1921,7 +1945,7 @@ int32_t PAX_idle(struct supernet_info *myinfo)//struct PAX_data *argdp,int32_t i { for (i=0; i<6; i++) printf("%u ",pvals[i]); - printf("pvals -> %s\n",fname); + printf("KMD %.8f BTC %f CNY %f (%f) btcusd pval.%u\n",dp->kmdbtc,dp->btcusd,dp->CNYUSD,1./dp->CNYUSD,pvals[4]); } } } diff --git a/iguana/dpow/dpow_rpc.c b/iguana/dpow/dpow_rpc.c index f8ffded08..0e294f4d9 100755 --- a/iguana/dpow/dpow_rpc.c +++ b/iguana/dpow/dpow_rpc.c @@ -13,7 +13,7 @@ * * ******************************************************************************/ -#define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0) +#define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0,0) cJSON *dpow_getinfo(struct supernet_info *myinfo,struct iguana_info *coin) { @@ -569,7 +569,7 @@ char *dpow_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *c jaddistr(array,signedtx); paramstr = jprint(array,1); retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"sendrawtransaction",paramstr); - //printf(">>>>>>>>>>> %s sendrawtransaction.(%s) -> %s\n",coin->symbol,paramstr,retstr); + printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr); free(paramstr); return(retstr); } @@ -772,7 +772,7 @@ int32_t dpow_vini_ismine(struct supernet_info *myinfo,struct dpow_info *dp,cJSON int32_t dpow_haveutxo(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr) { - int32_t i,j,n,vout,haveutxo = 0; uint32_t r; bits256 txid; cJSON *unspents,*item; uint64_t satoshis; char *str,*address; uint8_t script[35]; + int32_t vout,haveutxo = 0; uint32_t i,j,n,r; bits256 txid; cJSON *unspents,*item; uint64_t satoshis; char *str,*address; uint8_t script[35]; memset(txidp,0,sizeof(*txidp)); *voutp = -1; if ( (unspents= dpow_listunspent(myinfo,coin,coinaddr)) != 0 ) @@ -788,13 +788,15 @@ int32_t dpow_haveutxo(struct supernet_info *myinfo,struct iguana_info *coin,bits "confirmations" : 4282, "spendable" : true },*/ - r = 0; - memcpy(&r,coin->symbol,3); - r = calc_crc32(0,(void *)&r,sizeof(r)); + //r = 0; + //memcpy(&r,coin->symbol,3); + //r = calc_crc32(0,(void *)&r,sizeof(r)); + OS_randombytes((uint8_t *)&r,sizeof(r)); for (j=0; jdestcoin->symbol,"BTC") != 0) && (n= dpow_paxpending(extras,&paxwdcrc)) > 0 ) + if ( 0 && (src_or_dest == 0 || strcmp(bp->destcoin->symbol,"BTC") != 0) && (n= dpow_paxpending(extras,&paxwdcrc)) > 0 ) { for (i=0; iprice = price; + ptr->volume = volume; + ptr->height = height; + ptr->hour = hour; + ptr->dir = dir; + ptr->seconds = seconds; +} + +void stats_pairupdate(int32_t dir,struct DEXstats_datenuminfo *date,char *symbol,char *dest,int32_t datenum,int32_t hour,int32_t seconds,int32_t height,double volume,double price) +{ + int32_t i; struct DEXstats_pairinfo *pair = 0; + if ( date->datenum != datenum || seconds < 0 || seconds >= 3600 || hour < 0 || hour >= 24 ) + { + printf("date->datenum %d != %d? hour.%d seconds.%d\n",date->datenum,datenum,hour,seconds); + return; + } + //printf("%d numpairs.%d %p %p\n",date->datenum,date->numpairs,date,date->pairs); + for (i=0; inumpairs; i++) + if ( strcmp(dest,date->pairs[i].dest) == 0 ) + { + pair = &date->pairs[i]; + break; + } + if ( date->pairs == 0 || i == date->numpairs ) + { + date->pairs = realloc(date->pairs,sizeof(*date->pairs) * (date->numpairs + 1)); + pair = &date->pairs[date->numpairs++]; + memset(pair,0,sizeof(*pair)); + strcpy(pair->dest,dest); + printf("%d new pair.%d (%s) -> dest.(%s)\n",date->datenum,date->numpairs,symbol,dest); + } + pair->prices = realloc(pair->prices,sizeof(*pair->prices) * (pair->numprices+1)); + stats_pricepoint(dir,&pair->prices[pair->numprices++],hour,seconds,height,volume,price); + //printf("(%s/%s).%d numprices.%d h.%d s.%-4d %.8f %.6f\n",symbol,dest,date->datenum,pair->numprices,hour,seconds,price,volume); +} + +void stats_datenumupdate(int32_t dir,struct DEXstats_priceinfo *pp,int32_t datenum,int32_t hour,int32_t seconds,int32_t height,double volume,char *dest,double price) +{ + int32_t offset,i,n; struct DEXstats_datenuminfo *date; + if ( (offset= datenum - pp->firstdatenum) < 0 ) + { + printf("illegal datenum.%d for %s when 1st.%d\n",datenum,pp->symbol,pp->firstdatenum); + return; + } + if ( offset == 0 || offset > pp->numdates ) + { + pp->dates = realloc(pp->dates,sizeof(*pp->dates) * (offset+1)); + n = (offset - pp->numdates); + printf("allocate %s.[%d to %d]\n",pp->symbol,pp->numdates,pp->numdates+n); + for (i=0; i<=n; i++) + { + date = &pp->dates[pp->numdates + i]; + if ( date->datenum != pp->firstdatenum + pp->numdates + i ) + { + memset(date,0,sizeof(*date)); + date->datenum = pp->firstdatenum + pp->numdates + i; + } + } + pp->numdates = offset; + } + stats_pairupdate(dir,&pp->dates[offset],pp->symbol,dest,datenum,hour,seconds,height,volume,price); +} + +struct DEXstats_priceinfo *stats_priceinfo(char *symbol,int32_t datenum) +{ + int32_t i; struct DEXstats_priceinfo *pp = 0; + if ( Num_priceinfos >= sizeof(Prices)/sizeof(*Prices) ) + return(0); + for (i=0; isymbol,symbol); + pp->firstdatenum = datenum; + } + return(pp); +} + +void stats_LPpubkeyupdate(char *LPpubkey,uint32_t timestamp) +{ + printf("LP.(%s) t.%u\n",LPpubkey,timestamp); +} + +void stats_priceupdate(int32_t datenum,int32_t hour,int32_t seconds,uint32_t timestamp,int32_t height,char *key,char *LPpubkey,cJSON *tradejson) +{ + int32_t dir = 0; uint64_t srcamount,destamount; char *source,*dest; double price; struct DEXstats_priceinfo *pp; + if ( LPpubkey != 0 ) + stats_LPpubkeyupdate(LPpubkey,timestamp); + if ( tradejson != 0 ) + { + source = jstr(jitem(tradejson,0),0); + srcamount = SATOSHIDEN * jdouble(jitem(tradejson,1),0); + dest = jstr(jitem(tradejson,2),0); + destamount = SATOSHIDEN * jdouble(jitem(tradejson,3),0); + if ( srcamount != 0 && destamount != 0 ) + { + price = (double)destamount / srcamount; + if ( key != 0 ) + { + dir = 1; + if ( (pp= stats_priceinfo(source,datenum)) != 0 ) + stats_datenumupdate(-1,pp,datenum,hour,seconds,height,dstr(srcamount),dest,price); + if ( (pp= stats_priceinfo(dest,datenum)) != 0 ) + stats_datenumupdate(1,pp,datenum,hour,seconds,height,dstr(destamount),source,1. / price); + } + else if ( (pp= stats_priceinfo(source,datenum)) != 0 ) + stats_datenumupdate(0,pp,datenum,hour,seconds,height,dstr(srcamount),dest,price); + } else price = 0.; + if ( dir != 0 ) + printf("dir.%-2d %d.%02d.%04d ht.%-4d %s (%s %12.8f) -> (%s %12.8f) %16.8f %16.8f\n",dir,datenum,hour,seconds,height,key!=0?key:"",source,dstr(srcamount),dest,dstr(destamount),price,1./price); + } +} + +double _pairaved(double valA,double valB) +{ + if ( valA != 0. && valB != 0. ) + return((valA + valB) / 2.); + else if ( valA != 0. ) return(valA); + else return(valB); +} + +double calc_loganswer(double pastlogprice,double futurelogprice) +{ + if ( fabs(pastlogprice) < .0000001 || fabs(futurelogprice) < .0000001 ) + return(0); + return(10000. * (exp(futurelogprice - pastlogprice)-1.)); +} + +double _pairdiff(register double valA,register double valB) +{ + if ( valA != 0. && valB != 0. ) + return((valA - valB)); + else return(0.); +} + +double balanced_ave(double buf[],int32_t i,int32_t width) +{ + register int32_t nonz,j; register double sum,price; + nonz = 0; + sum = 0.0; + for (j=-width; j<=width; j++) + { + price = buf[i + j]; + if ( price != 0.0 ) + { + sum += price; + nonz++; + } + } + if ( nonz != 0 ) + sum /= nonz; + return(sum); +} + +void buf_trioave(double dest[],double src[],int32_t n) +{ + register int32_t i,j,width = 3; + for (i=0; i<128; i++) + src[i] = 0; + //for (i=n-width-1; i>width; i--) + // dest[i] = balanced_ave(src,i,width); + //for (i=width; i>0; i--) + // dest[i] = balanced_ave(src,i,i); + for (i=1; i>16)&0x0ff) + (float)((color>>8)&0x0ff) + (float)((color>>0)&0x0ff))/0x300); +} + +int32_t pixel_ratios(uint32_t red,uint32_t green,uint32_t blue) +{ + float max; + /*if ( red > green ) + max = red; + else + max = green; + if ( blue > max ) + max = blue;*/ + max = (red + green + blue); + if ( max == 0. ) + return(0); + if ( max > 0xff ) + { + red = (uint32_t)(((float)red / max) * 0xff); + green = (uint32_t)(((float)green / max) * 0xff); + blue = (uint32_t)(((float)blue / max) * 0xff); + } + + if ( red > 0xff ) + red = 0xff; + if ( green > 0xff ) + green = 0xff; + if ( blue > 0xff ) + blue = 0xff; + return((red << 16) | (green << 8) | blue); +} + +int32_t conv_yval_to_y(register float yval,register int32_t height) +{ + register int32_t y; + height = (height>>1) - 2; + y = (int32_t)-yval; + if ( y > height ) + y = height; + else if ( y < -height ) + y = -height; + + y += height; + if ( y < 0 ) + y = 0; + height <<= 1; + if ( y >= height-1 ) + y = height-1; + return(y); +} + +uint32_t scale_color(uint32_t color,float strength) +{ + int32_t red,green,blue; + if ( strength < 0. ) + strength = -strength; + red = (color>>16) & 0xff; + green = (color>>8) & 0xff; + blue = color & 0xff; + + red = (int32_t)((float)red * (strength/100.f)); + green = (int32_t)((float)green * (strength/100.f)); + blue = (int32_t)((float)blue * (strength/100.f)); + if ( red > 0xff ) + red = 0xff; + if ( green > 0xff ) + green = 0xff; + if ( blue > 0xff ) + blue = 0xff; + return((red<<16) | (green<<8) | blue); +} + +uint32_t pixel_blend(uint32_t pixel,uint32_t color)//,int32_t groupsize) +{ + int32_t red,green,blue,sum,n,n2,groupsize = 1; + float red2,green2,blue2,sum2; + if ( color == 0 ) + return(pixel); + if ( pixel == 0 ) + { + return((1<<24) | scale_color(color,100.f/(float)groupsize)); + } + n = (pixel>>24) & 0xff; + if ( n == 0 ) + n = 1; + pixel &= 0xffffff; + red = (pixel>>16) & 0xff; + green = (pixel>>8) & 0xff; + blue = pixel & 0xff; + sum = red + green + blue; + + n2 = (color>>24) & 0xff; + if ( n2 == 0 ) + n2 = 1; + red2 = ((float)((color>>16) & 0xff)) / groupsize; + green2 = ((float)((color>>8) & 0xff)) / groupsize; + blue2 = ((float)(color & 0xff)) / groupsize; + sum2 = (red2 + green2 + blue2); + + //printf("gs %d (%d x %d,%d,%d: %d) + (%d x %.1f,%.1f,%.1f: %.1f) = ",groupsize,n,red,green,blue,sum,n2,red2,green2,blue2,sum2); + red = (uint32_t)(((((((float)red / (float) sum) * n) + (((float)red2 / (float) sum2) * n2)) / (n+n2)) * ((sum+sum2)/2))); + green = (uint32_t)(((((((float)green / (float) sum) * n) + (((float)green2 / (float) sum2) * n2)) / (n+n2)) * ((sum+sum2)/2))); + blue = (uint32_t)(((((((float)blue / (float) sum) * n) + (((float)blue2 / (float) sum2) * n2)) / (n+n2)) * ((sum+sum2)/2))); + + n += n2; + if ( n > 0xff ) + n = 0xff; + ///printf("%x (%d,%d,%d) ",color,red,green,blue); + color = (n<<24) | pixel_ratios(red,green,blue);//pixel_overflow(&red,&green,&blue); + + //printf("%x (%d,%d,%d)\n",color,(color>>16)&0xff,(color>>8)&0xff,color&0xff); + return(color); +} + +void init_forex_colors(uint32_t *forex_colors) +{ + int32_t i; + forex_colors[0] = 0x00ff00; + forex_colors[1] = 0x0033ff; + forex_colors[2] = 0xff0000; + forex_colors[3] = 0x00ffff; + forex_colors[4] = 0xffff00; + forex_colors[5] = 0xff00ff; + forex_colors[6] = 0xffffff; + forex_colors[7] = 0xff8800; + forex_colors[8] = 0xff88ff; + for (i=9; i<16; i++) + forex_colors[i] = pixel_blend(forex_colors[i-8],0xffffff); +} + +int32_t is_primary_color(register uint32_t color) +{ + static uint32_t forex_colors[16]; + register int32_t i; + if ( forex_colors[0] == 0 ) + init_forex_colors(forex_colors); + for (i=0; i<8; i++) + if ( color == forex_colors[i] ) + return(1); + return(0); +} + +void disp_yval(register int32_t color,register float yval,register uint32_t *bitmap,register int32_t x,register int32_t rowwidth,register int32_t height) +{ + register int32_t y; + if ( forex_colors[0] == 0 ) + init_forex_colors(forex_colors); + x += LEFTMARGIN; + if ( x < 0 || x >= rowwidth ) + return; + //y = conv_yval_to_y(yval,height/Display_scale) * Display_scale; + y = conv_yval_to_y(yval * Display_scale,height); + if ( 1 && is_primary_color(color) != 0 ) + { + bitmap[y*rowwidth + x] = color; + //printf("(%d, %d) <- %x, ",x,y,color); + return; + } + //if ( pixelwt(color) > pixelwt(bitmap[y*rowwidth + x]) ) + bitmap[y*rowwidth + x] = pixel_blend(bitmap[y*rowwidth + x],color); + return; + //if ( is_primary_color(color) != 0 || (is_primary_color(bitmap[y*rowwidth+x]) == 0 && pixelwt(color) > pixelwt(bitmap[y*rowwidth + x])) ) + // bitmap[y*rowwidth + x] = color; +} + +void disp_yvalsum(register int32_t color,register float yval,register uint32_t *bitmap,register int32_t x,register int32_t rowwidth,register int32_t height) +{ + int32_t y,red,green,blue,dispcolor; + x += LEFTMARGIN; + if ( x < 0 || x >= rowwidth ) + return; + y = conv_yval_to_y(yval * Display_scale,height); + red = (color>>16) & 0xff; + green = (color>>8) & 0xff; + blue = color & 0xff; + dispcolor = bitmap[y*rowwidth + x]; + red += (dispcolor>>16) & 0xff; + green += (dispcolor>>8) & 0xff; + blue += dispcolor & 0xff; + bitmap[y*rowwidth + x] = pixel_ratios(red,green,blue); +} + +void disp_dot(register float radius,register int32_t color,register float yval,register uint32_t *bitmap,register int32_t x,register int32_t rowwidth,register int32_t height) +{ + register float i,j,sq,val; + if ( radius > 1 ) + { + sq = radius * radius; + for (i=-radius; i<=radius; i++) + { + for (j=-radius; j<=radius; j++) + { + val = ((j*j + i*i) / sq); + if ( val <= 1. ) + { + val = 1. - val; + disp_yval(scale_color(color,(100 * val * val * val * val)),yval+j,bitmap,x+i,rowwidth,height); + } + } + } + } + else disp_yval(color,yval,bitmap,x,rowwidth,height); +} + +void horizline(int32_t calclogflag,int32_t rowwidth,int32_t height,uint32_t *bitmap,double rawprice,double ave) +{ + int32_t x; + double yval; + if ( calclogflag != 0 ) + yval = _calc_pricey(log(rawprice),log(ave)); + else yval = _calc_pricey(rawprice,ave); + for (x=0; x %f) ",val,yval); + if ( fabs(yval) > .0000000001 ) + { + aveabs += fabs(yval); + nonz++; + if ( color != 0 ) + disp_yval(color,yval,bitmap,x,rowwidth,height); + } + } else yval = 0.; + output[x] = yval; + } + if ( nonz != 0 ) + aveabs /= nonz; + return(aveabs); + // + //printf("ave %f rowwidth.%d\n",ave,rowwidth); +} + +double stats_splineval(struct stats_spline *spline,uint32_t timestamp,int32_t lookahead) +{ + int32_t i,gap,ind = (spline->num - 1); + if ( timestamp >= spline->utc32[ind] ) + { + gap = (timestamp - spline->utc32[ind]); + if ( gap < lookahead ) + return(_extrapolate_spline64(spline->spline64[ind],gap)); + else return(0.); + } + else if ( timestamp <= spline->utc32[0] ) + { + gap = (spline->utc32[0] - timestamp); + if ( gap < lookahead ) + return(_extrapolate_spline64(spline->spline64[0],gap)); + else return(0.); + } + for (i=0; inum-1; i++) + { + ind = (i + spline->lasti) % (spline->num - 1); + if ( timestamp >= spline->utc32[ind] && timestamp < spline->utc32[ind+1] ) + { + spline->lasti = ind; + return(_extrapolate_spline64(spline->spline64[ind],timestamp - spline->utc32[ind])); + } + } + return(0.); +} + +double stats_calcspline(struct stats_spline *spline,double *outputs,double *slopes,int32_t dispwidth,uint32_t *utc32,double *splinevals,int32_t num) +{ + static double errsums[3]; static int errcount; + double c[MAX_SPLINES],f[MAX_SPLINES],dd[MAX_SPLINES],dl[MAX_SPLINES],du[MAX_SPLINES],gaps[MAX_SPLINES]; + int32_t n,i,lasti,x,numsplines,nonz; double vx,vy,vw,vz,gap,sum,xval,yval,abssum,lastval,lastxval,yval64,yval32,yval3; uint32_t gap32; + sum = lastxval = n = lasti = nonz = 0; + for (i=0; i 0 ) + { + if ( (gaps[n-1]= utc32[i] - lastxval) < 0 ) + { + printf("illegal gap %f to t%d\n",lastxval,utc32[i]); + return(0); + } + } + spline->utc32[n] = lastxval = utc32[i]; + n++; + } + } + if ( (numsplines= n) < 4 ) + return(0); + for (i=0; i=0; i--) + c[i] -= c[i+1] * du[i]; + //tridiagonal(n-2, dl, dd, du, c); + + for (i=n-3; i>=0; i--) + c[i+1] = c[i]; + c[0] = (1.0 + (double)gaps[0] / gaps[1]) * c[1] - ((double)gaps[0] / gaps[1] * c[2]); + c[n-1] = (1.0 + (double)gaps[n-2] / gaps[n-3] ) * c[n-2] - ((double)gaps[n-2] / gaps[n-3] * c[n-3]); + //printf("c[n-1] %f, n-2 %f, n-3 %f\n",c[n-1],c[n-2],c[n-3]); + abssum = nonz = lastval = 0; + outputs[spline->firstx] = f[0]; + spline->num = numsplines; + for (i=0; iutc32[i],(vx),vy*1000*1000,vz*1000*1000*1000*1000,vw*1000*1000*1000*1000*1000*1000,gap,conv_unixtime(&tmp,spline->utc32[i])); + spline->dSplines[i][0] = vx, spline->dSplines[i][1] = vy, spline->dSplines[i][2] = vz, spline->dSplines[i][3] = vw; + spline->spline64[i][0] = dto64(vx), spline->spline64[i][1] = dto64(vy*1000*1000), spline->spline64[i][2] = dto64(vz*1000*1000*1000*1000), spline->spline64[i][3] = dto64(vw*1000*1000*1000*1000*1000*1000); + spline->spline32[i][0] = dto32(vx), spline->spline32[i][1] = dto32(vy*1000*1000), spline->spline32[i][2] = dto32(vz*1000*1000*1000*1000), spline->spline32[i][3] = dto32(vw*1000*1000*1000*1000*1000*1000); + gap32 = gap = spline->dispincr; + xval = spline->utc32[i] + gap; + lastval = vx; + while ( i < n-1 ) + { + x = spline->firstx + ((xval - spline->utc32[0]) / spline->dispincr); + if ( x > dispwidth-1 ) x = dispwidth-1; + if ( x < 0 ) x = 0; + if ( (i < n-2 && gap > gaps[i] + spline->dispincr) ) + break; + if ( i == n-2 && xval > spline->utc32[n-1] + MAX_LOOKAHEAD*spline->dispincr ) + { + //printf("x.%d dispwidth.%d xval %f > utc[n-1] %f + %f\n",x,dispwidth,xval,utc[n-1],MAX_LOOKAHEAD*incr); + break; + } + if ( x >= 0 ) + { + yval = _extrapolate_Spline(spline->dSplines[i],gap); + yval64 = _extrapolate_spline64(spline->spline64[i],gap32); + if ( (yval3 = stats_splineval(spline,gap32 + spline->utc32[i],MAX_LOOKAHEAD*spline->dispincr)) != 0 ) + { + yval32 = _extrapolate_spline32(spline->spline32[i],gap32); + errsums[0] += fabs(yval - yval64), errsums[1] += fabs(yval - yval32), errsums[2] += fabs(yval - yval3), errcount++; + if ( fabs(yval - yval3) > SMALLVAL ) + printf("(%.10f vs %.10f %.10f %.10f [%.16f %.16f %.16f]) ",yval,yval64,yval32,yval3, errsums[0]/errcount,errsums[1]/errcount,errsums[2]/errcount); + } + if ( yval > 5000. ) yval = 5000.; + else if ( yval < -5000. ) yval = -5000.; + if ( isnan(yval) == 0 ) + { + outputs[x] = yval; + spline->lastval = outputs[x], spline->lastutc = xval; + if ( 1 && fabs(lastval) > SMALLVAL ) + { + if ( lastval != 0 && outputs[x] != 0 ) + { + if ( slopes != 0 ) + slopes[x] = (outputs[x] - lastval), abssum += fabs(slopes[x]); + nonz++; + } + } + } + //else outputs[x] = 0.; + //printf("x.%-4d %d %f %f %f i%-4d: gap %9.6f %9.6f last %9.6f slope %9.6f | %9.1f [%9.1f %9.6f %9.6f %9.6f %9.6f]\n",x,firstx,xval,utc[0],incr,i,gap,yval,lastval,slopes[x],xval,utc[i+1],dSplines[i][0],dSplines[i][1]*1000*1000,dSplines[i][2]*1000*1000*1000*1000,dSplines[i][3]*1000*1000*1000*1000*1000*1000); + } + gap32 += spline->dispincr, gap += spline->dispincr, xval += spline->dispincr; + } + //double pred = (i>0) ? _extrapolate_Spline(dSplines[i-1],gaps[i-1]) : 0.; + //printf("%2d: w%8.1f [gap %f -> %9.6f | %9.6f %9.6f %9.6f %9.6f %9.6f]\n",i,weekinds[i],gap,pred,f[i],dSplines[i].x,1000000*dSplines[i].y,1000000*1000000*dSplines[i].z,1000000*1000000*1000*dSplines[i].w); + } + if ( nonz != 0 ) + abssum /= nonz; + spline->aveslopeabs = abssum; + return(lastval); +} + +int32_t stats_genspline(double output[2048],double slopes[2048],struct stats_spline *spline,int32_t splineid,char *name,uint32_t *utc32,double *splinevals,int32_t numsplines,double *refvals) +{ + int32_t i; double origvals[MAX_SPLINES]; + if ( numsplines > MAX_SPLINES ) + { + printf("numsplines.%d > MAX_SPLINES.%d\n",numsplines,MAX_SPLINES); + return(-1); + } + memset(spline,0,sizeof(*spline)), memset(output,0,sizeof(*output)*2048), memset(slopes,0,sizeof(*slopes)*2048); + spline->dispincr = 3600, spline->basenum = splineid, strcpy(spline->name,name); + memcpy(origvals,splinevals,sizeof(*splinevals) * MAX_SPLINES); + spline->lastval = stats_calcspline(spline,output,slopes,2048,utc32,splinevals,numsplines); + if ( refvals != 0 ) + { + for (i=0; inum; i++) + { + if ( i < spline->num ) + { + if ( 0 && refvals[i] != 0 && output[i * 24] != refvals[i] ) + printf("{%.8f != %.8f}.%d ",output[i * 24],refvals[i],i); + spline->pricevals[i] = output[i * 24]; + } + } + } + //printf("spline.%s num.%d\n",name,spline->num); + return(spline->num); +} + +void output_line(int32_t calclogflag,double ave,double *buf,int32_t n,int32_t color,uint32_t *bitmap,int32_t rowwidth,int32_t height) +{ + double src[1024],dest[1024]; int32_t i; + memset(src,0,sizeof(src)); + memset(dest,0,sizeof(dest)); + if ( (1) ) + { + for (i=0; i<1024; i++) + src[1023-i] = dest[1023-i] = buf[i]; + smooth1024(dest,src,3); + for (i=0; i<1024; i++) + src[1023-i] = dest[i]; + } + else + { + for (i=0; i<1024; i++) + src[i] = buf[i]; + } + _output_line(calclogflag,ave,buf,src,1024,color,bitmap,rowwidth,height); +} + +void stats_updatedisp(struct DEXstats_disp *disp,double price,double volume) +{ + if ( price > SMALLVAL && volume > SMALLVAL ) + { + disp->pricesum += (price * volume); + disp->volumesum += volume; + } +} + +void stats_dispprices(struct DEXstats_disp *prices,int32_t leftdatenum,int32_t numdates,struct DEXstats_datenuminfo *date,char *dest,int32_t current_daysecond) +{ + int32_t i,j,offset,datenum = date->datenum; struct DEXstats_pairinfo *pair; struct DEXstats_pricepoint *ptr; uint32_t timestamp,lefttimestamp,righttimestamp; + offset = datenum - leftdatenum; + lefttimestamp = OS_conv_datenum(leftdatenum,0,0,0); + righttimestamp = OS_conv_datenum(leftdatenum+numdates,0,0,0); + //printf("search dest.%s datenum.%d vs leftdatenum.%d numdates.%d offset.%d numpairs.%d\n",dest,datenum,leftdatenum,numdates,offset,date->numpairs); + for (i=0; inumpairs; i++) + { + if ( strcmp(dest,date->pairs[i].dest) == 0 ) + { + pair = &date->pairs[i]; + //printf("found dest.(%s) numprices.%d\n",dest,pair->numprices); + for (j=0; jnumprices; j++) + { + ptr = &pair->prices[j]; + timestamp = OS_conv_datenum(date->datenum,ptr->hour,ptr->seconds/60,ptr->seconds%60); + timestamp += (24*3600 - current_daysecond); + offset = (timestamp - lefttimestamp) / (24*3600); + if ( offset >= 0 && offset < numdates ) + { + //printf("found dest.(%s) numprices.%d offset.%d (%.8f %.6f)\n",dest,pair->numprices,offset,ptr->price,ptr->volume); + stats_updatedisp(&prices[offset],ptr->price,ptr->volume); + } + } + break; + } + } +} + +#include "../../crypto777/jpeg/jinclude.h" +#include "../../crypto777/jpeg/jpeglib.h" +#include "../../crypto777/jpeg/jerror.h" + +void gen_jpegfile(char *fname,int32_t quality,uint8_t *bitmap,int32_t width,int32_t height) +{ + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + FILE * outfile; /* target file */ + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + int row_stride; /* physical row width in image buffer */ + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + if ( (outfile= fopen(fname,"wb")) == NULL) + { + fprintf(stderr, "can't open %s\n", fname); + return; + } + jpeg_stdio_dest(&cinfo, outfile); + cinfo.image_width = width; /* image width and height, in pixels */ + cinfo.image_height = height; + cinfo.input_components = 3; /* # of color components per pixel */ + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); + jpeg_start_compress(&cinfo, TRUE); + row_stride = width * 3; /* JSAMPLEs per row in image_buffer */ + while (cinfo.next_scanline < cinfo.image_height) + { + row_pointer[0] = &bitmap[cinfo.next_scanline * row_stride]; + (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + jpeg_finish_compress(&cinfo); + fclose(outfile); + jpeg_destroy_compress(&cinfo); +} + +char *stats_prices(char *symbol,char *dest,struct DEXstats_disp *prices,int32_t leftdatenum,int32_t numdates) +{ + int32_t i,j,n; struct DEXstats_priceinfo *pp; uint32_t *utc32,tmp,timestamp,lefttimestamp,righttimestamp; double *splinevals,total; char fname[1024]; cJSON *retjson,*array,*item; + timestamp = (uint32_t)time(NULL); + if ( Num_priceinfos >= sizeof(Prices)/sizeof(*Prices) ) + return(0); + lefttimestamp = OS_conv_datenum(leftdatenum-1,0,0,0); + righttimestamp = OS_conv_datenum(leftdatenum+numdates,0,0,0); + for (i=0; inumdates; j++) + { + timestamp = OS_conv_datenum(pp->firstdatenum+j,0,0,0); + if ( timestamp < lefttimestamp ) // can speed up by calculating offset 0 + { + //printf("skip (%s) datenums %d %d %d\n",symbol,datenum,pp->firstdatenum,pp->firstdatenum+pp->numdates); + continue; + } + stats_dispprices(prices,leftdatenum,numdates,&pp->dates[j],dest,timestamp % (3600*24)); + } + break; + } + tmp = OS_conv_datenum(leftdatenum,0,0,0); + utc32 = calloc(sizeof(*utc32),numdates); + splinevals = calloc(sizeof(*splinevals),numdates); + for (total=i=n=0; i 3 ) + { + double output[2048],slopes[2048],sum = 0.; struct stats_spline spline; int32_t splineid = 0; + memset(&spline,0,sizeof(spline)); + stats_genspline(output,slopes,&spline,splineid,"spline",utc32,splinevals,n,0); + array = cJSON_CreateArray(); + for (i=0; i> 8) & 0xff; + blue = (val >> 16) & 0xff; + *tmpptr++ = red; + *tmpptr++ = green; + *tmpptr++ = blue; + } + sprintf(fname,"%s/bitmaps/%s_%s.jpg",STATS_DESTDIR,symbol,dest), OS_portable_path(fname); + gen_jpegfile(fname,100,bytemap,numdates*24,height); + free(bitmap), free(bytemap); + jaddstr(retjson,"bitmap",fname); + jadd(retjson,"hourly",array); + jaddnum(retjson,"average",sum); + } + free(utc32); + free(splinevals); + return(jprint(retjson,1)); +} + +#ifndef FROM_MARKETMAKER +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 ) + return(clonestr("{\"error\":\"need method in request\"}")); + if ( (agent= jstr(argjson,"agent")) == 0 ) + agent = "stats"; + if ( strcmp(method,"bitmap") == 0 ) + { + if ( (endtimestamp= juint(argjson,"endtimestamp")) == 0 ) + endtimestamp = (uint32_t)time(NULL); + if ( (source= jstr(argjson,"source")) == 0 ) + source = "KMD"; + if ( (dest= jstr(argjson,"dest")) == 0 ) + dest = "USD"; + if ( (numdates= jint(argjson,"numdates")) <= 0 || numdates > 1024/24 ) + numdates = 1024/24; + leftdatenum = OS_conv_unixtime(&T,&seconds,endtimestamp - numdates*24*3600); + printf("(%s/%s) endtimestamp.%u: leftdatenum.%d\n",source,dest,endtimestamp,leftdatenum); + memset(prices,0,sizeof(prices)); + if ( (retstr= stats_prices(source,dest,prices,leftdatenum,numdates+1)) != 0 ) + return(retstr); + } + return(clonestr(jprint(argjson,0))); +} +#endif + +#endif /* DEXstats_h */ diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c new file mode 100644 index 000000000..ba6a5b63f --- /dev/null +++ b/iguana/exchanges/LP_bitcoin.c @@ -0,0 +1,3627 @@ + +/****************************************************************************** + * 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_bitcoin.c +// marketmaker +// + +union iguana_stacknum { int32_t val; int64_t val64; uint8_t rmd160[20]; bits256 hash2; uint8_t pubkey[33]; uint8_t sig[74]; }; +struct iguana_stackdata { uint8_t *data; uint16_t size; union iguana_stacknum U; }; + +char *bitcoin_base58encode(char *coinaddr,uint8_t *data,int32_t datalen); +int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr); + +#define IGUANA_MAXSCRIPTSIZE 10001 +#define IGUANA_SEQUENCEID_FINAL 0xfffffffe + +#define IGUANA_SCRIPT_NULL 0 +#define IGUANA_SCRIPT_76AC 1 +#define IGUANA_SCRIPT_76A988AC 2 +#define IGUANA_SCRIPT_P2SH 3 +#define IGUANA_SCRIPT_OPRETURN 4 +#define IGUANA_SCRIPT_3of3 5 +#define IGUANA_SCRIPT_2of3 6 +#define IGUANA_SCRIPT_1of3 7 +#define IGUANA_SCRIPT_2of2 8 +#define IGUANA_SCRIPT_1of2 9 +#define IGUANA_SCRIPT_MSIG 10 +#define IGUANA_SCRIPT_DATA 11 +#define IGUANA_SCRIPT_AC 12 +#define IGUANA_SCRIPT_1of1 13 +#define IGUANA_SCRIPT_STRANGE 15 + +#define MAX_SCRIPT_ELEMENT_SIZE 520 +#define MAX_OPS_PER_SCRIPT 201 // Maximum number of non-push operations per script +#define MAX_PUBKEYS_PER_MULTISIG 20 // Maximum number of public keys per multisig + +#define IGUANA_MAXSTACKITEMS ((int32_t)(IGUANA_MAXSCRIPTSIZE / sizeof(uint32_t))) +#define IGUANA_MAXSTACKDEPTH 128 +struct iguana_interpreter +{ + int32_t active,ifdepth,elsedepth,codeseparator,stackdepth,altstackdepth,maxstackdepth; + int8_t lastpath[IGUANA_MAXSTACKDEPTH]; + cJSON *logarray; + struct iguana_stackdata stack[]; +}; +static struct bitcoin_opcode { UT_hash_handle hh; uint8_t opcode,flags,stackitems; int8_t extralen; } *OPTABLE; static char *OPCODES[0x100]; static int32_t OPCODELENS[0x100]; + +#define SIGHASH_ALL 1 +#define SIGHASH_NONE 2 +#define SIGHASH_SINGLE 3 +#define SIGHASH_ANYONECANPAY 0x80 + +#define SCRIPT_OP_NOP 0x00 +#define SCRIPT_OP_TRUE 0x51 +#define SCRIPT_OP_2 0x52 +#define SCRIPT_OP_3 0x53 +#define SCRIPT_OP_4 0x54 +#define SCRIPT_OP_IF 0x63 +#define SCRIPT_OP_ELSE 0x67 +#define SCRIPT_OP_RETURN 0x6a +#define SCRIPT_OP_DUP 0x76 +#define SCRIPT_OP_ENDIF 0x68 +#define SCRIPT_OP_DROP 0x75 +#define SCRIPT_OP_EQUALVERIFY 0x88 +#define SCRIPT_OP_SHA256 0xa8 +#define SCRIPT_OP_HASH160 0xa9 + +#define SCRIPT_OP_EQUAL 0x87 +#define SCRIPT_OP_CHECKSIG 0xac +#define SCRIPT_OP_CHECKMULTISIG 0xae +#define SCRIPT_OP_CHECKSEQUENCEVERIFY 0xb2 +#define SCRIPT_OP_CHECKLOCKTIMEVERIFY 0xb1 +#define IGUANA_OP_0 0x00 +#define IGUANA_OP_PUSHDATA1 0x4c +#define IGUANA_OP_PUSHDATA2 0x4d +#define IGUANA_OP_PUSHDATA4 0x4e +#define IGUANA_OP_1NEGATE 0x4f +#define IGUANA_OP_1 0x51 +#define IGUANA_OP_16 0x60 +#define IGUANA_OP_NOP 0x61 +#define IGUANA_OP_IF 0x63 +#define IGUANA_OP_NOTIF 0x64 +#define IGUANA_OP_ELSE 0x67 +#define IGUANA_OP_ENDIF 0x68 +#define IGUANA_OP_VERIFY 0x69 +#define IGUANA_OP_RETURN 0x6a + +#define IGUANA_OP_TOALTSTACK 0x6b +#define IGUANA_OP_FROMALTSTACK 0x6c +#define IGUANA_OP_2DROP 0x6d +#define IGUANA_OP_2DUP 0x6e +#define IGUANA_OP_3DUP 0x6f +#define IGUANA_OP_2OVER 0x70 +#define IGUANA_OP_2ROT 0x71 +#define IGUANA_OP_2SWAP 0x72 +#define IGUANA_OP_IFDUP 0x73 +#define IGUANA_OP_DEPTH 0x74 +#define IGUANA_OP_DROP 0x75 +#define IGUANA_OP_DUP 0x76 +#define IGUANA_OP_NIP 0x77 +#define IGUANA_OP_OVER 0x78 +#define IGUANA_OP_PICK 0x79 +#define IGUANA_OP_ROLL 0x7a +#define IGUANA_OP_ROT 0x7b +#define IGUANA_OP_SWAP 0x7c +#define IGUANA_OP_TUCK 0x7d + +#define IGUANA_OP_EQUAL 0x87 +#define IGUANA_OP_EQUALVERIFY 0x88 + +#define IGUANA_OP_1ADD 0x8b +#define IGUANA_OP_1SUB 0x8c +#define IGUANA_OP_NEGATE 0x8f +#define IGUANA_OP_ABS 0x90 +#define IGUANA_OP_NOT 0x91 +#define IGUANA_OP_0NOTEQUAL 0x92 +#define IGUANA_OP_ADD 0x93 +#define IGUANA_OP_SUB 0x94 + +#define IGUANA_OP_BOOLAND 0x9a +#define IGUANA_OP_BOOLOR 0x9b +#define IGUANA_OP_NUMEQUAL 0x9c +#define IGUANA_OP_NUMEQUALVERIFY 0x9d +#define IGUANA_OP_NUMNOTEQUAL 0x9e +#define IGUANA_OP_LESSTHAN 0x9f +#define IGUANA_OP_GREATERTHAN 0xa0 +#define IGUANA_OP_LESSTHANOREQUAL 0xa1 +#define IGUANA_OP_GREATERTHANOREQUAL 0xa2 +#define IGUANA_OP_MIN 0xa3 +#define IGUANA_OP_MAX 0xa4 +#define IGUANA_OP_WITHIN 0xa5 + +#define IGUANA_OP_RIPEMD160 0xa6 +#define IGUANA_OP_SHA1 0xa7 +#define IGUANA_OP_SHA256 0xa8 +#define IGUANA_OP_HASH160 0xa9 +#define IGUANA_OP_HASH256 0xaa +#define IGUANA_OP_CODESEPARATOR 0xab +#define IGUANA_OP_CHECKSIG 0xac +#define IGUANA_OP_CHECKSIGVERIFY 0xad +#define IGUANA_OP_CHECKMULTISIG 0xae +#define IGUANA_OP_CHECKMULTISIGVERIFY 0xaf + +#define IGUANA_OP_NOP1 0xb0 +#define IGUANA_OP_CHECKLOCKTIMEVERIFY 0xb1 +#define IGUANA_OP_CHECKSEQUENCEVERIFY 0xb2 +#define IGUANA_OP_NOP10 0xb9 + +#define IGUANA_OP_COMBINEPUBKEYS 0xc0 +#define IGUANA_OP_CHECKSCHNORR 0xc1 +#define IGUANA_OP_CHECKSCHNORRVERIFY 0xc2 + +// https://github.com/TierNolan/bips/blob/cpkv/bip-cprkv.mediawiki +#define IGUANA_OP_CHECKPRIVATEKEY 0xc3 +#define IGUANA_OP_CHECKPRIVATEKEYVERIFY 0xc4 + +#define IGUANA_NOPFLAG 1 +#define IGUANA_ALWAYSILLEGAL 2 +#define IGUANA_EXECUTIONILLEGAL 4 +#define IGUANA_POSTVERIFY 8 +#define IGUANA_CRYPTOFLAG 16 +#define IGUANA_MATHFLAG 32 +#define IGUANA_CONTROLFLAG 64 +#define IGUANA_STACKFLAG 128 + +enum opcodetype +{ + // push value + OP_0 = 0x00, + OP_FALSE = OP_0, + OP_PUSHDATA1 = 0x4c, + OP_PUSHDATA2 = 0x4d, + OP_PUSHDATA4 = 0x4e, + OP_1NEGATE = 0x4f, + OP_RESERVED = 0x50, + OP_1 = 0x51, + OP_TRUE=OP_1, + OP_2 = 0x52, + OP_3 = 0x53, + OP_4 = 0x54, + OP_5 = 0x55, + OP_6 = 0x56, + OP_7 = 0x57, + OP_8 = 0x58, + OP_9 = 0x59, + OP_10 = 0x5a, + OP_11 = 0x5b, + OP_12 = 0x5c, + OP_13 = 0x5d, + OP_14 = 0x5e, + OP_15 = 0x5f, + OP_16 = 0x60, + + // control + OP_NOP = 0x61, + OP_VER = 0x62, + OP_IF = 0x63, + OP_NOTIF = 0x64, + OP_VERIF = 0x65, + OP_VERNOTIF = 0x66, + OP_ELSE = 0x67, + OP_ENDIF = 0x68, + OP_VERIFY = 0x69, + OP_RETURN = 0x6a, + + // stack ops + OP_TOALTSTACK = 0x6b, + OP_FROMALTSTACK = 0x6c, + OP_2DROP = 0x6d, + OP_2DUP = 0x6e, + OP_3DUP = 0x6f, + OP_2OVER = 0x70, + OP_2ROT = 0x71, + OP_2SWAP = 0x72, + OP_IFDUP = 0x73, + OP_DEPTH = 0x74, + OP_DROP = 0x75, + OP_DUP = 0x76, + OP_NIP = 0x77, + OP_OVER = 0x78, + OP_PICK = 0x79, + OP_ROLL = 0x7a, + OP_ROT = 0x7b, + OP_SWAP = 0x7c, + OP_TUCK = 0x7d, + + // splice ops + OP_CAT = 0x7e, + OP_SUBSTR = 0x7f, + OP_LEFT = 0x80, + OP_RIGHT = 0x81, + OP_SIZE = 0x82, + + // bit logic + OP_INVERT = 0x83, + OP_AND = 0x84, + OP_OR = 0x85, + OP_XOR = 0x86, + OP_EQUAL = 0x87, + OP_EQUALVERIFY = 0x88, + OP_RESERVED1 = 0x89, + OP_RESERVED2 = 0x8a, + + // numeric + OP_1ADD = 0x8b, + OP_1SUB = 0x8c, + OP_2MUL = 0x8d, + OP_2DIV = 0x8e, + OP_NEGATE = 0x8f, + OP_ABS = 0x90, + OP_NOT = 0x91, + OP_0NOTEQUAL = 0x92, + + OP_ADD = 0x93, + OP_SUB = 0x94, + OP_MUL = 0x95, + OP_DIV = 0x96, + OP_MOD = 0x97, + OP_LSHIFT = 0x98, + OP_RSHIFT = 0x99, + + OP_BOOLAND = 0x9a, + OP_BOOLOR = 0x9b, + OP_NUMEQUAL = 0x9c, + OP_NUMEQUALVERIFY = 0x9d, + OP_NUMNOTEQUAL = 0x9e, + OP_LESSTHAN = 0x9f, + OP_GREATERTHAN = 0xa0, + OP_LESSTHANOREQUAL = 0xa1, + OP_GREATERTHANOREQUAL = 0xa2, + OP_MIN = 0xa3, + OP_MAX = 0xa4, + + OP_WITHIN = 0xa5, + + // crypto + OP_RIPEMD160 = 0xa6, + OP_SHA1 = 0xa7, + OP_SHA256 = 0xa8, + OP_HASH160 = 0xa9, + OP_HASH256 = 0xaa, + OP_CODESEPARATOR = 0xab, + OP_CHECKSIG = 0xac, + OP_CHECKSIGVERIFY = 0xad, + OP_CHECKMULTISIG = 0xae, + OP_CHECKMULTISIGVERIFY = 0xaf, + + // expansion + OP_NOP1 = 0xb0, + OP_CHECKLOCKTIMEVERIFY = 0xb1, + OP_CHECKSEQUENCEVERIFY = 0xb2, + OP_NOP4 = 0xb3, + OP_NOP5 = 0xb4, + OP_NOP6 = 0xb5, + OP_NOP7 = 0xb6, + OP_NOP8 = 0xb7, + OP_NOP9 = 0xb8, + OP_NOP10 = 0xb9, + + OP_COMBINEPUBKEYS = 0xc0, + OP_CHECKSCHNORR = 0xc1, + OP_CHECKSCHNORRVERIFY = 0xc2, + OP_CHECKPRIVATEKEY = 0xc3, + OP_CHECKPRIVATEKEYVERIFY = 0xc4, + + // template matching params + //OP_SMALLINTEGER = 0xfa, + //OP_PUBKEYS = 0xfb, + //OP_PUBKEYHASH = 0xfd, + //OP_PUBKEY = 0xfe, + + OP_INVALIDOPCODE = 0xff, +}; + +struct { bits256 privkey; uint8_t rmd160[20]; } LP_privkeys[100]; int32_t LP_numprivkeys; + +bits256 LP_privkeyfind(uint8_t rmd160[20]) +{ + int32_t i; static bits256 zero; + for (i=0; i no privkey\n"); + return(zero); +} + +int32_t LP_privkeyadd(bits256 privkey,uint8_t rmd160[20]) +{ + bits256 tmpkey; + tmpkey = LP_privkeyfind(rmd160); + if ( bits256_nonz(tmpkey) != 0 ) + return(-bits256_cmp(privkey,tmpkey)); + LP_privkeys[LP_numprivkeys].privkey = privkey; + memcpy(LP_privkeys[LP_numprivkeys].rmd160,rmd160,20); + //int32_t i; for (i=0; i<20; i++) + // printf("%02x",rmd160[i]); + //char str[65]; printf(" -> add privkey.(%s)\n",bits256_str(str,privkey)); + LP_numprivkeys++; + return(LP_numprivkeys); +} + +int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp) +{ + int32_t i; uint64_t x; + if ( rwflag == 0 ) + { + x = 0; + for (i=len-1; i>=0; i--) + { + x <<= 8; + x |= serialized[i]; + } + switch ( len ) + { + case 1: *(uint8_t *)endianedp = (uint8_t)x; break; + case 2: *(uint16_t *)endianedp = (uint16_t)x; break; + case 4: *(uint32_t *)endianedp = (uint32_t)x; break; + case 8: *(uint64_t *)endianedp = (uint64_t)x; break; + } + } + else + { + x = 0; + switch ( len ) + { + case 1: x = *(uint8_t *)endianedp; break; + case 2: x = *(uint16_t *)endianedp; break; + case 4: x = *(uint32_t *)endianedp; break; + case 8: x = *(uint64_t *)endianedp; break; + } + for (i=0; i>= 8) + serialized[i] = (uint8_t)(x & 0xff); + } + return(len); +} + +int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp) +{ + int32_t i; + if ( rwflag == 0 ) + { + for (i=0; i> 8) & 0xff; + } + return(serialized); +} + +uint8_t *iguana_varint32(int32_t rwflag,uint8_t *serialized,uint16_t *varint16p) +{ + serialized = iguana_varint16(rwflag,serialized,varint16p); + serialized = iguana_varint16(rwflag,serialized,&varint16p[1]); + return(serialized); +} + +uint8_t *iguana_varint64(int32_t rwflag,uint8_t *serialized,uint32_t *varint32p) +{ + serialized = iguana_varint32(rwflag,serialized,(uint16_t *)varint32p); + serialized = iguana_varint32(rwflag,serialized,(uint16_t *)&varint32p[1]); + return(serialized); +} + +int32_t iguana_rwvarint(int32_t rwflag,uint8_t *serialized,uint64_t *varint64p) +{ + uint64_t n; int32_t vlen = 1; + if ( rwflag == 0 ) + { + *varint64p = 0; + if ( (n= *serialized++) >= 0xfd ) + { + if ( n == 0xfd ) + { + n = 0; + iguana_varint16(rwflag,serialized,(uint16_t *)&n); + vlen += 2; + } + else if ( n == 0xfe ) + { + n = 0; + iguana_varint32(rwflag,serialized,(uint16_t *)&n); + vlen += 4; + } + else if ( n == 0xff ) + { + n = 0; + iguana_varint64(rwflag,serialized,(uint32_t *)&n); + vlen += 8; + } + } + *varint64p = n; + } + else + { + n = *varint64p; + if ( n < 0xfd ) + *serialized++ = (uint8_t)n; + else if ( n <= 0xffff ) + { + *serialized++ = 0xfd; + iguana_varint16(rwflag,serialized,(uint16_t *)varint64p); + vlen += 2; + } + else if ( n <= 0xffffffff ) + { + *serialized++ = 0xfe; + iguana_varint32(rwflag,serialized,(uint16_t *)varint64p); + vlen += 4; + } + else + { + *serialized++ = 0xff; + iguana_varint64(rwflag,serialized,(uint32_t *)varint64p); + vlen += 8; + } + } + return(vlen); +} + +int32_t iguana_rwvarint32(int32_t rwflag,uint8_t *serialized,uint32_t *int32p) +{ + int32_t len; uint64_t x = 0; + if ( rwflag != 0 ) + x = *int32p; + len = iguana_rwvarint(rwflag,serialized,&x); + if ( rwflag == 0 ) + *int32p = (int32_t)x; + return(len); +} + +int32_t iguana_rwvarstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp) +{ + int32_t vlen; uint64_t n; + if ( rwflag == 0 ) + { + vlen = iguana_rwvarint(rwflag,serialized,&n); + memcpy(endianedp,&serialized[vlen],n); + ((uint8_t *)endianedp)[n] = 0; + } + else + { + n = strlen(endianedp); + if ( n > maxlen ) + n = maxlen; + vlen = iguana_rwvarint(rwflag,serialized,&n); + memcpy(&serialized[vlen],endianedp,n); + } + return((int32_t)(n + vlen)); +} + +int32_t iguana_rwmem(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp) +{ + if ( rwflag == 0 ) + memcpy(endianedp,serialized,len); + else memcpy(serialized,endianedp,len); + return(len); +} + +const char *get_opname(uint8_t *stackitemsp,uint8_t *flagsp,int32_t *extralenp,enum opcodetype opcode) +{ + *extralenp = 0; + switch ( opcode ) + { + // push value + case OP_0 : return "0"; + case OP_PUSHDATA1 : *extralenp = 1; return "OP_PUSHDATA1"; + case OP_PUSHDATA2 : *extralenp = 2; return "OP_PUSHDATA2"; + case OP_PUSHDATA4 : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_PUSHDATA4"; + case OP_1NEGATE : return "-1"; + case OP_RESERVED : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_RESERVED"; + case OP_1 : return "1"; + case OP_2 : return "2"; + case OP_3 : return "3"; + case OP_4 : return "4"; + case OP_5 : return "5"; + case OP_6 : return "6"; + case OP_7 : return "7"; + case OP_8 : return "8"; + case OP_9 : return "9"; + case OP_10 : return "10"; + case OP_11 : return "11"; + case OP_12 : return "12"; + case OP_13 : return "13"; + case OP_14 : return "14"; + case OP_15 : return "15"; + case OP_16 : return "16"; + + // control + case OP_NOP : *flagsp = IGUANA_NOPFLAG; return "OP_NOP"; + case OP_VER : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_VER"; + case OP_IF : *flagsp = IGUANA_CONTROLFLAG; *stackitemsp = 1; return "OP_IF"; + case OP_NOTIF : *flagsp = IGUANA_CONTROLFLAG; *stackitemsp = 1; return "OP_NOTIF"; + case OP_VERIF : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_VERIF"; + case OP_VERNOTIF : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_VERNOTIF"; + case OP_ELSE : *flagsp = IGUANA_CONTROLFLAG; return "OP_ELSE"; + case OP_ENDIF : *flagsp = IGUANA_CONTROLFLAG; return "OP_ENDIF"; + case OP_VERIFY : *flagsp = IGUANA_POSTVERIFY; return "OP_VERIFY"; + case OP_RETURN : *flagsp = IGUANA_CONTROLFLAG; return "OP_RETURN"; + + // stack ops + case OP_TOALTSTACK : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_TOALTSTACK"; + case OP_FROMALTSTACK : *flagsp = IGUANA_STACKFLAG; return "OP_FROMALTSTACK"; + case OP_2DROP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_2DROP"; + case OP_2DUP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_2DUP"; + case OP_3DUP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 3; return "OP_3DUP"; + case OP_2OVER : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 4; return "OP_2OVER"; + case OP_2ROT : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 6; return "OP_2ROT"; + case OP_2SWAP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 4; return "OP_2SWAP"; + case OP_IFDUP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_IFDUP"; + case OP_DEPTH : *flagsp = IGUANA_STACKFLAG; return "OP_DEPTH"; + case OP_DROP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_DROP"; + case OP_DUP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_DUP"; + case OP_NIP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_NIP"; + case OP_OVER : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_OVER"; + case OP_PICK : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_PICK"; + case OP_ROLL : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_ROLL"; + case OP_ROT : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 3; return "OP_ROT"; + case OP_SWAP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_SWAP"; + case OP_TUCK : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_TUCK"; + + // splice ops + case OP_CAT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_CAT"; + case OP_SUBSTR : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_SUBSTR"; + case OP_LEFT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_LEFT"; + case OP_RIGHT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_RIGHT"; + case OP_SIZE : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_SIZE"; + + // bit logic + case OP_INVERT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_INVERT"; + case OP_AND : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_AND"; + case OP_OR : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_OR"; + case OP_XOR : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_XOR"; + case OP_EQUAL : *stackitemsp = 2; return "OP_EQUAL"; + case OP_EQUALVERIFY : *stackitemsp = 2; *flagsp = IGUANA_POSTVERIFY; return "OP_EQUALVERIFY"; + case OP_RESERVED1 : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_RESERVED1"; + case OP_RESERVED2 : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_RESERVED2"; + + // numeric + case OP_1ADD : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_1ADD"; + case OP_1SUB : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_1SUB"; + case OP_2MUL : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_2MUL"; + case OP_2DIV : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_2DIV"; + case OP_NEGATE : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_NEGATE"; + case OP_ABS : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_ABS"; + case OP_NOT : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_NOT"; + case OP_0NOTEQUAL : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_0NOTEQUAL"; + case OP_ADD : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_ADD"; + case OP_SUB : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_SUB"; + case OP_MUL : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_MUL"; + case OP_DIV : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_DIV"; + case OP_MOD : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_MOD"; + case OP_LSHIFT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_LSHIFT"; + case OP_RSHIFT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_RSHIFT"; + case OP_BOOLAND : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_BOOLAND"; + case OP_BOOLOR : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_BOOLOR"; + case OP_NUMEQUAL : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_NUMEQUAL"; + case OP_NUMEQUALVERIFY: *flagsp = IGUANA_MATHFLAG | IGUANA_POSTVERIFY; *stackitemsp = 2; return "OP_NUMEQUALVERIFY"; + case OP_NUMNOTEQUAL : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_NUMNOTEQUAL"; + case OP_LESSTHAN : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_LESSTHAN"; + case OP_GREATERTHAN : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_GREATERTHAN"; + case OP_LESSTHANOREQUAL: *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_LESSTHANOREQUAL"; + case OP_GREATERTHANOREQUAL: *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_GREATERTHANOREQUAL"; + case OP_MIN : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_MIN"; + case OP_MAX : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_MAX"; + case OP_WITHIN : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 3; return "OP_WITHIN"; + + // crypto + case OP_RIPEMD160 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_RIPEMD160"; + case OP_SHA1 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_SHA1"; + case OP_SHA256 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_SHA256"; + case OP_HASH160 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_HASH160"; + case OP_HASH256 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_HASH256"; + case OP_CODESEPARATOR: return "OP_CODESEPARATOR"; + case OP_CHECKSIG : *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKSIG"; + case OP_CHECKSIGVERIFY: *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKSIGVERIFY"; + case OP_CHECKMULTISIG: *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKMULTISIG"; + case OP_CHECKMULTISIGVERIFY: *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKMULTISIGVERIFY"; + case OP_COMBINEPUBKEYS: *flagsp = IGUANA_CRYPTOFLAG; return "OP_COMBINEPUBKEYS"; + case OP_CHECKSCHNORR: *stackitemsp = 3; *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKSCHNORR"; + case OP_CHECKSCHNORRVERIFY: *stackitemsp = 3; *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKSCHNORRVERIFY"; + case OP_CHECKPRIVATEKEY: *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKPRIVATEKEY"; + case OP_CHECKPRIVATEKEYVERIFY: *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKPRIVATEKEYVERIFY"; + + // expanson + case OP_NOP1 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP1"; + case OP_CHECKLOCKTIMEVERIFY: *stackitemsp = 1; return "OP_CHECKLOCKTIMEVERIFY"; + case OP_CHECKSEQUENCEVERIFY: *stackitemsp = 1; return "OP_CHECKSEQUENCEVERIFY"; + case OP_NOP4 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP4"; + case OP_NOP5 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP5"; + case OP_NOP6 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP6"; + case OP_NOP7 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP7"; + case OP_NOP8 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP8"; + case OP_NOP9 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP9"; + case OP_NOP10 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP10"; + + case OP_INVALIDOPCODE: return "OP_INVALIDOPCODE"; + default: return "OP_UNKNOWN"; + } +} + +void iguana_optableinit() +{ + int32_t i,extralen; uint8_t stackitems,flags; char *opname; struct bitcoin_opcode *op; + if ( OPTABLE == 0 ) + { + for (i=0; i<0x100; i++) + OPCODES[i] = "OP_UNKNOWN"; + for (i=0; i<0x100; i++) + { + extralen = stackitems = flags = 0; + opname = (char *)get_opname(&stackitems,&flags,&extralen,i); + if ( strcmp("OP_UNKNOWN",opname) != 0 ) + { + op = calloc(1,sizeof(*op)); + HASH_ADD_KEYPTR(hh,OPTABLE,opname,strlen(opname),op); + //printf("{%-16s %02x} ",opname,i); + op->opcode = i; + op->flags = flags; + op->stackitems = stackitems; + op->extralen = extralen; + OPCODES[i] = (char *)op->hh.key; + OPCODELENS[i] = (int32_t)strlen(OPCODES[i]); + } + } + //printf("bitcoin opcodes\n"); + } +} + +int32_t bitcoin_pubkeylen(const uint8_t *pubkey) +{ + if ( pubkey[0] == 2 || pubkey[0] == 3 ) + return(33); + else if ( pubkey[0] == 4 ) + return(65); + else + { + //printf("illegal pubkey.[%02x] %llx\n",pubkey[0],*(long long *)pubkey); + return(-1); + } +} + +int32_t iguana_expandscript(char *asmstr,int32_t maxlen,uint8_t *script,int32_t scriptlen) +{ + int32_t len,n,j,i = 0; uint8_t opcode; uint32_t val,extraflag; + iguana_optableinit(); + asmstr[0] = len = 0; + while ( i < scriptlen ) + { + val = extraflag = 0; + opcode = script[i++]; + if ( opcode > 0 && opcode < 76 ) + { + for (j=0; j= IGUANA_OP_1 && opcode <= IGUANA_OP_16 ) + { + sprintf(&asmstr[len],"%d",opcode - IGUANA_OP_1 + 1); + len += strlen(&asmstr[len]); + } + else if ( opcode == IGUANA_OP_0 ) + { + strcpy(&asmstr[len],"OP_FALSE"); + len += 8; + } + else if ( opcode == IGUANA_OP_1NEGATE ) + { + asmstr[len++] = '-'; + asmstr[len++] = '1'; + } + else + { + //printf("dest.%p <- %p %02x\n",&asmstr[len],OPCODES[opcode],opcode); + strcpy(&asmstr[len],OPCODES[opcode]); + len += OPCODELENS[opcode]; + } + if ( i < scriptlen ) + asmstr[len++] = ' '; + if ( opcode == IGUANA_OP_PUSHDATA1 ) + { + n = script[i++]; + for (j=0; jstack[--stacks->stackdepth]; + memset(&stacks->stack[stacks->stackdepth],0,sizeof(Snum)); + return(Snum); +} + +static int32_t iguana_altpush(struct iguana_interpreter *stacks,struct iguana_stackdata Snum) +{ + stacks->stack[2*IGUANA_MAXSTACKITEMS - ++stacks->altstackdepth] = Snum; + return(stacks->altstackdepth); +} + +static struct iguana_stackdata iguana_altpop(struct iguana_interpreter *stacks) +{ + struct iguana_stackdata Snum,*ptr; + ptr = &stacks->stack[2*IGUANA_MAXSTACKITEMS - --stacks->altstackdepth]; + Snum = *ptr; + memset(ptr,0,sizeof(Snum)); + return(Snum); +} + +static struct iguana_stackdata iguana_clone(struct iguana_stackdata Snum) +{ + struct iguana_stackdata clone; + clone = Snum; + if ( Snum.data != 0 ) + { + clone.data = malloc(Snum.size); + memcpy(clone.data,Snum.data,Snum.size); + } + return(clone); +} + +static int32_t iguana_isnonz(struct iguana_stackdata Snum) +{ + uint8_t *buf; int32_t i; + if ( Snum.size == sizeof(int32_t) ) + return(Snum.U.val != 0); + else if ( Snum.size == sizeof(int64_t) ) + return(Snum.U.val64 != 0); + else if ( Snum.size == 20 ) + buf = Snum.U.rmd160; + else if ( Snum.size == sizeof(bits256) ) + buf = Snum.U.hash2.bytes; + else if ( Snum.size == 33 ) + buf = Snum.U.pubkey; + else if ( Snum.size < 74 ) + buf = Snum.U.sig; + else buf = Snum.data; + for (i=0; ilastpath[stacks->ifdepth] < 0 ) + return(0); + //printf("PUSH.(%lld %p %d)\n",(long long)num64,numbuf,numlen); + if ( stacks->maxstackdepth > 0 ) + { + if ( numbuf != 0 ) + { + int32_t i; for (i=0; istackdepth < stacks->maxstackdepth ) + { + if ( stacks->logarray != 0 ) + item = cJSON_CreateObject(); + memset(&Snum,0,sizeof(Snum)); + if ( numbuf != 0 ) + { + if ( numlen <= sizeof(int32_t) ) + { + iguana_rwnum(1,(void *)&num,numlen,numbuf); + numlen = sizeof(num); + Snum.U.val = num; + } + else if ( numlen <= sizeof(int64_t) ) + { + iguana_rwnum(1,(void *)&num64,numlen,numbuf); + numlen = sizeof(num64); + Snum.U.val64 = num64; + } + else if ( numlen == 20 ) + memcpy(Snum.U.rmd160,numbuf,20); + else if ( numlen == sizeof(bits256) ) + iguana_rwbignum(1,Snum.U.hash2.bytes,sizeof(Snum.U.hash2),numbuf); + else if ( numlen == 33 ) + memcpy(Snum.U.pubkey,numbuf,numlen); + else if ( numlen < 74 ) + memcpy(Snum.U.sig,numbuf,numlen); + else + { + Snum.data = malloc(numlen); + memcpy(Snum.data,numbuf,numlen); + if ( item != 0 ) + jaddnum(item,"push",numlen); + } + Snum.size = numlen; + if ( item != 0 ) + { + init_hexbytes_noT(tmpstr,numbuf,numlen); + jaddstr(item,"push",tmpstr); + } + } + else if ( num64 <= 0xffffffff ) // what about negative numbers? + { + Snum.U.val = num, Snum.size = sizeof(num); + if ( item != 0 ) + jaddnum(item,"push",Snum.U.val); + } + else + { + Snum.U.val64 = num64, Snum.size = sizeof(num64); + if ( item != 0 ) + jaddnum(item,"push",Snum.U.val64); + } + if ( item != 0 ) + { + jaddnum(item,"depth",stacks->stackdepth); + if ( stacks->logarray != 0 ) + jaddi(stacks->logarray,item); + } + stacks->stack[stacks->stackdepth++] = Snum; + } else return(-1); + } else stacks->stackdepth++; + return(0); +} + +int32_t iguana_databuf(uint8_t *databuf,struct iguana_stackdata Snum) +{ + if ( Snum.size == 4 ) + memcpy(databuf,&Snum.U.val,4); + else if ( Snum.size == 8 ) + memcpy(databuf,&Snum.U.val64,8); + else if ( Snum.size == 20 ) + memcpy(databuf,&Snum.U.rmd160,20); + else if ( Snum.size == 32 ) + memcpy(databuf,&Snum.U.hash2.bytes,32); + else if ( Snum.size == 33 ) + memcpy(databuf,&Snum.U.pubkey,33); + else if ( Snum.size < 74 ) + memcpy(databuf,&Snum.U.sig,Snum.size); + else memcpy(databuf,&Snum.data,Snum.size); + return(Snum.size); +} + +static int32_t iguana_cmp(struct iguana_stackdata *a,struct iguana_stackdata *b) +{ + if ( a->size == b->size ) + { + if ( a->size == 4 ) + return(a->U.val != b->U.val); + else if ( a->size == 8 ) + return(a->U.val64 != b->U.val64); + else if ( a->size == 20 ) + return(memcmp(a->U.rmd160,b->U.rmd160,sizeof(a->U.rmd160))); + else if ( a->size == 32 ) + return(memcmp(a->U.hash2.bytes,b->U.hash2.bytes,sizeof(a->U.hash2))); + else if ( a->size == 33 ) + return(memcmp(a->U.pubkey,b->U.pubkey,33)); + else if ( a->size < 74 ) + return(memcmp(a->U.sig,b->U.sig,a->size)); + else return(memcmp(a->data,b->data,sizeof(a->size))); + } + return(-1); +} + +static int32_t iguana_dataparse(struct iguana_interpreter *stacks,uint8_t *script,int32_t k,char *str,int32_t *lenp) +{ + int32_t n,c,len; char tmp[4]; + *lenp = 0; + c = str[0]; + n = is_hexstr(str,0); + if ( n > 0 ) + { + if ( (n & 1) != 0 ) + len = (n+1) >> 1; + else len = n >> 1; + if ( len > 0 && len < 76 ) + { + if ( len == 1 ) + { + if ( n == 1 ) + { + tmp[0] = '0'; + tmp[1] = c; + tmp[2] = 0; + decode_hex(&script[k],1,tmp), (*lenp) = 1; + iguana_pushdata(stacks,script[k],0,0); + if ( script[k] != 0 ) + script[k++] += (IGUANA_OP_1 - 1); + return(k); + } + else if ( n == 2 && c == '1' && str[1] == '0' && is_delim(str[2]) != 0 ) + { + script[k++] = (IGUANA_OP_1 - 1) + 0x10, (*lenp) = 2; + iguana_pushdata(stacks,0x10,0,0); + return(k); + } + else if ( n == 2 && c == '8' && is_delim(str[2]) != 0 ) + { + if ( str[1] == '1' ) + { + script[k++] = IGUANA_OP_1NEGATE, (*lenp) = 2; + iguana_pushdata(stacks,-1,0,0); + return(k); + } + else if ( str[1] == '0' ) + { + script[k++] = IGUANA_OP_0, (*lenp) = 2; + iguana_pushdata(stacks,0,0,0); + return(k); + } + } + } + if ( len != 0 ) + script[k++] = len; + } + else if ( len <= 0xff ) + { + script[k++] = IGUANA_OP_PUSHDATA1; + script[k++] = len; + } + else if ( len <= 0xffff ) + { + if ( len <= MAX_SCRIPT_ELEMENT_SIZE ) + { + script[k++] = IGUANA_OP_PUSHDATA2; + script[k++] = (len & 0xff); + script[k++] = ((len >> 8) & 0xff); + } + else + { + printf("len.%d > MAX_SCRIPT_ELEMENT_SIZE.%d, offset.%d\n",len,MAX_SCRIPT_ELEMENT_SIZE,k); + return(-1); + } + } + else + { + printf("len.%d > MAX_SCRIPT_ELEMENT_SIZE.%d, offset.%d\n",len,MAX_SCRIPT_ELEMENT_SIZE,k); + return(-1); + } + if ( len != 0 ) + { + uint8_t *numstart; int32_t numlen; + numstart = &script[k], numlen = len; + if ( (n & 1) != 0 ) + { + tmp[0] = '0'; + tmp[1] = c; + tmp[2] = 0; + decode_hex(&script[k++],1,tmp), *lenp = 1; + len--; + } + if ( len != 0 ) + { + decode_hex(&script[k],len,str), (*lenp) += (len << 1); + k += len; + } + iguana_pushdata(stacks,0,numstart,numlen); + } + return(k); + } + return(0); +} + +void iguana_stack(struct iguana_interpreter *stacks,struct iguana_stackdata *args,int32_t num,char *pushstr,char *clonestr) +{ + int32_t i,c; + while ( (c= *pushstr++) != 0 ) + stacks->stack[stacks->stackdepth++] = args[c - '0']; + while ( (c= *clonestr++) != 0 ) + stacks->stack[stacks->stackdepth++] = iguana_clone(args[c - '0']); + if ( num > 0 ) + { + for (i=0; i 0 && siglen > 0 && siglen < 74 ) + { + if ( (retval= (bitcoin_verify(ctx,sig,siglen-1,sigtxid,pubkey,plen) == 0)) == 0 ) + { + } + if ( (0) ) + { + int32_t i; char str[65]; + for (i=0; i 0 && privlen == 32 ) + { + bitcoin_pubkey33(ctx,checkpub,*(bits256 *)privkey); + return(memcmp(checkpub,pubkey,33) == 0); + } + return(0); +} + +int32_t iguana_checkschnorrsig(void *ctx,int64_t M,struct iguana_stackdata pubkeyarg,struct iguana_stackdata sigarg,bits256 sigtxid) +{ + /*uint8_t combined_pub[MAX_SCRIPT_ELEMENT_SIZE],sig[MAX_SCRIPT_ELEMENT_SIZE]; int32_t plen,siglen; + plen = iguana_databuf(combined_pub,pubkeyarg); + siglen = iguana_databuf(sig,sigarg); + if ( bitcoin_pubkeylen(combined_pub) == 33 && siglen == 64 ) + return(bitcoin_schnorr_verify(ctx,sig,sigtxid,combined_pub,33) == 0);*/ + return(0); +} + +int32_t iguana_checkmultisig(void *ctx,struct iguana_interpreter *stacks,int32_t M,int32_t N,bits256 txhash2) +{ + int32_t i,j=0,len,n,m,valid=0,numsigners = 0,siglens[MAX_PUBKEYS_PER_MULTISIG]; uint8_t pubkeys[MAX_PUBKEYS_PER_MULTISIG][MAX_SCRIPT_ELEMENT_SIZE],sigs[MAX_PUBKEYS_PER_MULTISIG][MAX_SCRIPT_ELEMENT_SIZE]; + if ( M <= N && N <= MAX_PUBKEYS_PER_MULTISIG ) + { + if ( stacks->stackdepth <= 0 ) + return(0); + n = (int32_t)iguana_num(iguana_pop(stacks)); + if ( n != N ) + { + printf("iguana_checkmultisig n.%d != N.%d\n",n,N); + return(0); + } + //printf("n.%d stackdepth.%d\n",n,stacks->stackdepth); + for (i=0; istackdepth <= 0 ) + return(0); + len = iguana_databuf(pubkeys[i],iguana_pop(stacks)); + if ( len == bitcoin_pubkeylen(pubkeys[i]) ) + { + numsigners++; + //for (j=0; j<33; j++) + // printf("%02x",pubkeys[i][j]); + //printf(" <- pubkey.[%d]\n",i); + } + else + { + printf("nonpubkey on stack\n"); + return(0); + memcpy(sigs[0],pubkeys[i],len); + siglens[0] = len; + break; + } + } + if ( stacks->stackdepth <= 0 ) + return(0); + m = (int32_t)iguana_num(iguana_pop(stacks)); + //printf("m.%d stackdepth.%d\n",m,stacks->stackdepth); + + if ( m != M ) + { + printf("iguana_checkmultisig m.%d != M.%d\n",m,M); + return(0); + } + for (i=0; istackdepth <= 0 ) + return(0); + siglens[i] = iguana_databuf(sigs[i],iguana_pop(stacks)); + if ( siglens[i] <= 0 || siglens[i] > 74 ) + break; + //for (j=0; jstackdepth,bits256_str(str,txhash2)); + if ( stacks->stackdepth > 0 ) + iguana_pop(stacks); // for backward compatibility + j = numsigners-1; + for (i=numsigners-1; i>=0; i--) + { + for (; j>=0; j--) + { + if ( bitcoin_verify(ctx,sigs[i],siglens[i]-1,txhash2,pubkeys[j],bitcoin_pubkeylen(pubkeys[j])) == 0 ) + { + if ( ++valid >= M ) + return(1); + j--; + break; + } + } + } + } + } + printf("checkmultisig: valid.%d j.%d M.%d N.%d numsigners.%d\n",valid,j,M,N,numsigners); + return(0); +} + +#define LOCKTIME_THRESHOLD 500000000 +int32_t iguana_checklocktimeverify(void *ctx,int64_t tx_lockval,uint32_t nSequence,struct iguana_stackdata Snum) +{ + int64_t nLockTime = iguana_num(Snum); + if ( nLockTime < 0 || tx_lockval < 0 ) + { + printf("CLTV.0 nLockTime.%lld tx_lockval.%lld\n",(long long)nLockTime,(long long)tx_lockval); + return(-1); + } + else if ( ((tx_lockval < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || + (tx_lockval >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD)) == 0 ) + { + printf("CLTV.1 nLockTime.%lld tx_lockval.%lld\n",(long long)nLockTime,(long long)tx_lockval); + return(-1); + } + else if ( nLockTime > tx_lockval ) + { + printf("CLTV.2 nLockTime.%lld tx_lockval.%lld\n",(long long)nLockTime,(long long)tx_lockval); + return(-1); + } + return(0); +} + +int32_t iguana_checksequenceverify(void *ctx,int64_t nLockTime,uint32_t nSequence,struct iguana_stackdata Snum) +{ + return(0); +} + +cJSON *iguana_spendasm(uint8_t *spendscript,int32_t spendlen) +{ + char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; cJSON *spendasm = cJSON_CreateObject(); + iguana_expandscript(asmstr,sizeof(asmstr),spendscript,spendlen); + //int32_t i; for (i=0; i (%s)\n",asmstr); + jaddstr(spendasm,"interpreter",asmstr); + return(spendasm); +} + +int32_t bitcoin_assembler(void *ctx,cJSON *logarray,uint8_t script[IGUANA_MAXSCRIPTSIZE],cJSON *interpreter,int32_t interpret,int64_t nLockTime,struct vin_info *V) +{ + struct bitcoin_opcode *op; cJSON *array = 0; struct iguana_interpreter STACKS,*stacks = &STACKS; + struct iguana_stackdata args[MAX_PUBKEYS_PER_MULTISIG]; + uint8_t databuf[MAX_SCRIPT_ELEMENT_SIZE]; char *asmstr,*str,*hexstr; cJSON *item; + int32_t c,numops,dlen,plen,numvars,numused,numargs=0,i,j,k,n=0,len,datalen,errs=0; int64_t val; + iguana_optableinit(); + if ( (asmstr= jstr(interpreter,"interpreter")) == 0 || asmstr[0] == 0 ) + return(0); + if ( (numvars= juint(interpreter,"numvars")) > 0 ) + { + if ( (array= jarray(&n,interpreter,"args")) == 0 || (interpret != 0 && n != numvars) ) + return(-2); + } + str = asmstr; + if ( interpret != 0 ) + { + stacks = calloc(1,sizeof(*stacks) + sizeof(*stacks->stack)*2*IGUANA_MAXSTACKITEMS); + stacks->maxstackdepth = IGUANA_MAXSTACKITEMS; + if ( (stacks->logarray= logarray) != 0 ) + item = cJSON_CreateObject(); + else item = 0; + if ( V->M == 0 && V->N == 0 ) + V->N = V->M = 1; + for (i=0; iN; i++) + { + if ( V->signers[i].siglen != 0 ) + { + iguana_pushdata(stacks,0,V->signers[i].sig,V->signers[i].siglen); + if ( bitcoin_pubkeylen(V->signers[i].pubkey) <= 0 ) + { + printf("missing pubkey.[%d]\n",i); + free(stacks); + return(-1); + } + //printf("pushdata siglen.%d depth.%d\n",V->signers[i].siglen,stacks->stackdepth); + } + } + for (i=0; iN; i++) + { + if ( V->signers[i].siglen != 0 ) + { + plen = bitcoin_pubkeylen(V->signers[i].pubkey); + if ( V->suppress_pubkeys == 0 && (V->spendscript[0] != plen || V->spendscript[V->spendlen - 1] != IGUANA_OP_CHECKSIG || bitcoin_pubkeylen(&V->spendscript[1]) <= 0) ) + { + iguana_pushdata(stacks,0,V->signers[i].pubkey,plen); + //printf(">>>>>>>>> suppress.%d pushdata [%02x %02x] plen.%d depth.%d\n",V->suppress_pubkeys,V->signers[i].pubkey[0],V->signers[i].pubkey[1],plen,stacks->stackdepth); + } // else printf("<<<<<<<<<< skip pubkey push %d script[0].%d spendlen.%d depth.%d\n",plen,V->spendscript[0],V->spendlen,stacks->stackdepth); + } + } + if ( V->userdatalen != 0 ) + { + len = 0; + while ( len < V->userdatalen ) + { + dlen = V->userdata[len++]; + if ( dlen > 0 && dlen < 76 ) + iguana_pushdata(stacks,0,&V->userdata[len],dlen), len += dlen; + else if ( dlen >= IGUANA_OP_1 && dlen <= IGUANA_OP_16 ) + { + dlen -= (IGUANA_OP_1 - 1); + iguana_pushdata(stacks,dlen,0,0); + } + else if ( dlen == IGUANA_OP_PUSHDATA1 ) + { + iguana_pushdata(stacks,V->userdata[len++],0,0); + } + else if ( dlen == IGUANA_OP_PUSHDATA2 ) + { + iguana_pushdata(stacks,V->userdata[len] + ((int32_t)V->userdata[len+1]<<8),0,0); + len += 2; + } + else if ( dlen == IGUANA_OP_0 ) + iguana_pushdata(stacks,0,0,0); + else if ( dlen == IGUANA_OP_1NEGATE ) + iguana_pushdata(stacks,-1,0,0); + else + { + printf("invalid data opcode %02x\n",dlen); + free(stacks); + return(-1); + } + //printf("user data stackdepth.%d dlen.%d\n",stacks->stackdepth,dlen); + } + if ( len != V->userdatalen ) + { + printf("mismatched userdatalen %d vs %d\n",len,V->userdatalen); + free(stacks); + return(-1); + } + } + if ( item != 0 && stacks->logarray != 0 ) + { + jaddstr(item,"spendasm",asmstr); + jaddi(stacks->logarray,item); + } + if ( V->extras != 0 ) + { + if ( (n= cJSON_GetArraySize(V->extras)) > 0 ) + { + for (i=0; iextras,i),0)) != 0 && (len= is_hexstr(hexstr,0)) > 0 ) + { + len >>= 1; + decode_hex(databuf,len,hexstr); + iguana_pushdata(stacks,0,databuf,len); + } + } + } + } + } else memset(stacks,0,sizeof(*stacks)); + stacks->lastpath[0] = 1; + k = numops = numused = 0; + script[k] = 0; + while ( (c= *str++) != 0 ) + { + if ( is_delim(c) != 0 ) + { + //if ( c == 0 ) + // break; + continue; + } + if ( c == '/' && *str == '/' ) // support // + break; + else if ( c == '-' && *str == '1' && is_delim(str[1]) != 0 ) + { + script[k++] = IGUANA_OP_1NEGATE, str += 3; // OP_1NEGATE; + iguana_pushdata(stacks,-1,0,0); + continue; + } + else if ( c == '%' && *str == 's' ) + { + str++; + if ( numused < numvars && (hexstr= jstr(jitem(array,numused++),0)) != 0 ) + { + if ( (n= iguana_dataparse(stacks,script,k,str,&len)) > 0 ) + { + k += n; + continue; + } + } + printf("dataparse error.%d, numused.%d >= numvars.%d\n",n,numused,numvars); + errs++; + break; + } + else + { + str--; + if ( (n= iguana_dataparse(stacks,script,k,str,&len)) > 0 ) + { + k = n; + str += len; + continue; + } + else if ( n < 0 ) + { + printf("dataparse negative n.%d\n",n); + errs++; + break; + } + } + for (j=0; j<32; j++) + if ( is_delim(str[j]) != 0 ) + break; + if ( j == 32 ) + { + printf("too long opcode.%s at offset.%ld\n",str,(long)str-(long)asmstr); + errs++; + break; + } + HASH_FIND(hh,OPTABLE,str,j,op); + printf("{%s}\n",str); + str += j; + if ( op != 0 ) + { + if ( numargs > 0 ) + { + for (i=0; iopcode; + if ( (op->flags & IGUANA_CONTROLFLAG) != 0 ) + { + //printf("control opcode depth.%d\n",stacks->stackdepth); + switch ( op->opcode ) + { + case IGUANA_OP_IF: case IGUANA_OP_NOTIF: + if ( stacks->ifdepth >= IGUANA_MAXSTACKDEPTH ) + { + printf("ifdepth.%d >= MAXSTACKDEPTH.%d\n",stacks->ifdepth,IGUANA_MAXSTACKDEPTH); + errs++; + } + else + { + if ( stacks->stackdepth <= 0 ) + { + printf("if invalid stackdepth %d\n",stacks->stackdepth); + errs++; + } + else + { + args[0] = iguana_pop(stacks); + if ( iguana_isnonz(args[0]) == (op->opcode == IGUANA_OP_IF) ) + { + val = 1; + //printf("OP_IF enabled depth.%d\n",stacks->stackdepth); + } + else + { + val = -1; + //printf("OP_IF disabled depth.%d\n",stacks->stackdepth); + } + stacks->lastpath[++stacks->ifdepth] = val; + } + } + break; + case IGUANA_OP_ELSE: + /*if ( stacks->stackdepth <= 0 ) + { + printf("else invalid stackdepth %d\n",stacks->stackdepth); + errs++; + } + else*/ + { + if ( stacks->ifdepth <= stacks->elsedepth ) + { + printf("unhandled opcode.%02x stacks->ifdepth %d <= %d stacks->elsedepth\n",op->opcode,stacks->ifdepth,stacks->elsedepth); + errs++; + } + stacks->lastpath[stacks->ifdepth] *= -1; + //printf("OP_ELSE status.%d depth.%d\n",stacks->lastpath[stacks->ifdepth],stacks->stackdepth); + } + break; + case IGUANA_OP_ENDIF: + if ( stacks->ifdepth <= 0 ) + { + printf("endif without if offset.%ld\n",(long)str-(long)asmstr); + errs++; + } + stacks->ifdepth--; + //printf("OP_ENDIF status.%d depth.%d\n",stacks->lastpath[stacks->ifdepth],stacks->stackdepth); + break; + case IGUANA_OP_VERIFY: + break; + case IGUANA_OP_RETURN: + iguana_pushdata(stacks,0,0,0); + errs++; + break; + } + if ( errs != 0 ) + break; + continue; + } + if ( stacks->lastpath[stacks->ifdepth] != 0 ) + { + if ( stacks->lastpath[stacks->ifdepth] < 0 ) + { + //printf("SKIP opcode.%02x depth.%d\n",op->opcode,stacks->stackdepth); + if ( stacks->logarray ) + jaddistr(stacks->logarray,"skip"); + continue; + } + //printf("conditional opcode.%02x stackdepth.%d\n",op->opcode,stacks->stackdepth); + } + if ( op->opcode <= IGUANA_OP_16 || ++numops <= MAX_OPS_PER_SCRIPT ) + { + if ( (op->flags & IGUANA_ALWAYSILLEGAL) != 0 ) + { + printf("disabled opcode.%s at offset.%ld\n",str,(long)str-(long)asmstr); + errs++; + break; + } + else if ( op->extralen > 0 ) + { + if ( is_delim(*str) != 0 ) + str++; + if ( is_hexstr(str,0) != (op->extralen<<1) ) + { + printf("expected extralen.%d of hex, got.(%s) at offset.%ld\n",op->extralen,str,(long)str-(long)asmstr); + errs++; + break; + } + decode_hex(&script[k],op->extralen,str), str += (op->extralen << 1); + if ( op->extralen == 1 ) + iguana_pushdata(stacks,script[k],0,0); + else if ( op->extralen == 2 ) + iguana_pushdata(stacks,script[k] + ((uint32_t)script[k]<<8),0,0); + k += op->extralen; + continue; + } + if ( interpret == 0 || V == 0 ) + continue; + if ( (op->flags & IGUANA_NOPFLAG) != 0 ) + continue; + if ( (numargs= op->stackitems) > 0 ) + { + if ( stacks->stackdepth < op->stackitems ) + { + //printf("stackdepth.%d needed.%d (%s) at offset.%ld\n",stacks->stackdepth,op->stackitems,str,(long)str-(long)asmstr); + errs++; + break; + } + for (i=0; iopcode,numargs,stacks->stackdepth); + if ( stacks->logarray != 0 ) + { + char tmpstr[1096]; + item = cJSON_CreateObject(); + array = cJSON_CreateArray(); + for (i=0; ihh.key,array); + jaddi(stacks->logarray,item); + } + if ( (op->flags & IGUANA_EXECUTIONILLEGAL) != 0 ) + { + printf("opcode not allowed to run.%s at %ld\n",(char *)op->hh.key,(long)str-(long)asmstr); + errs++; + break; + } + else if ( op->opcode == IGUANA_OP_EQUALVERIFY || op->opcode == IGUANA_OP_EQUAL ) + { + if ( iguana_cmp(&args[0],&args[1]) == 0 ) + iguana_pushdata(stacks,1,0,0); + else + { + iguana_pushdata(stacks,0,0,0); + for (i=0; iopcode,args[0].size,args[1].size); + } + } + else if ( (op->flags & IGUANA_CRYPTOFLAG) != 0 ) + { + uint8_t rmd160[20],revdatabuf[MAX_SCRIPT_ELEMENT_SIZE]; bits256 hash; + datalen = iguana_databuf(databuf,args[0]); + for (i=0; iopcode ) + { + case IGUANA_OP_RIPEMD160: + calc_rmd160(0,rmd160,databuf,datalen); + iguana_pushdata(stacks,0,rmd160,sizeof(rmd160)); + break; + case IGUANA_OP_SHA1: + calc_sha1(0,rmd160,databuf,datalen); + iguana_pushdata(stacks,0,rmd160,sizeof(rmd160)); + break; + case IGUANA_OP_HASH160: + /*if ( datalen == 32 ) + { + revcalc_rmd160_sha256(rmd160,*(bits256 *)databuf); + printf("SPECIAL CASE REVERSE\n"); + } else + for (i=0; i<32; i++) + printf("%02x",databuf[i]); + printf(" <- databuf\n"); + for (i=0; i<32; i++) + printf("%02x",revdatabuf[i]); + printf(" <- revdatabuf\n"); + calc_rmd160_sha256(rmd160,revdatabuf,datalen); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- rmd160 revdatabuf\n"); + revcalc_rmd160_sha256(rmd160,*(bits256 *)databuf); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- rmd160 special\n"); + calc_rmd160_sha256(rmd160,databuf,datalen); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- rmd160 databuf\n");*/ + if ( datalen == 32 ) + calc_rmd160_sha256(rmd160,revdatabuf,datalen); + else calc_rmd160_sha256(rmd160,databuf,datalen); + iguana_pushdata(stacks,0,rmd160,sizeof(rmd160)); + break; + case IGUANA_OP_SHA256: + vcalc_sha256(0,hash.bytes,databuf,datalen); + for (i=0; i sha256 %s\n",bits256_str(str,hash)); + iguana_pushdata(stacks,0,hash.bytes,sizeof(hash)); + break; + case IGUANA_OP_HASH256: + hash = bits256_doublesha256(0,databuf,datalen); + iguana_pushdata(stacks,0,hash.bytes,sizeof(hash)); + break; + case IGUANA_OP_CHECKSIG: case IGUANA_OP_CHECKSIGVERIFY: + iguana_pushdata(stacks,iguana_checksig(ctx,args[1],args[0],V->sigtxid),0,0); + break; + case IGUANA_OP_CHECKMULTISIG: case IGUANA_OP_CHECKMULTISIGVERIFY: + iguana_pushdata(stacks,iguana_checkmultisig(ctx,stacks,V->M,V->N,V->sigtxid),0,0); + break; + case IGUANA_OP_CHECKSCHNORR: case IGUANA_OP_CHECKSCHNORRVERIFY: + iguana_pushdata(stacks,iguana_checkschnorrsig(ctx,iguana_num(args[2]),args[1],args[0],V->sigtxid),0,0); + break; + case IGUANA_OP_CHECKPRIVATEKEY: case IGUANA_OP_CHECKPRIVATEKEYVERIFY: + iguana_pushdata(stacks,iguana_checkprivatekey(ctx,args[1],args[0]),0,0); + break; + } + } + else if ( op->opcode == IGUANA_OP_CHECKLOCKTIMEVERIFY ) // former OP_NOP2 + { + if ( V->ignore_cltverr == 0 && iguana_checklocktimeverify(ctx,nLockTime,V->sequence,args[0]) < 0 ) + { + iguana_stack(stacks,args,1,"0",""); + errs++; + break; + } + iguana_stack(stacks,args,1,"0",""); + continue; + } + else if ( op->opcode == IGUANA_OP_CHECKSEQUENCEVERIFY ) // former OP_NOP3 + { + if ( iguana_checksequenceverify(ctx,nLockTime,V->sequence,args[0]) < 0 ) + { + iguana_stack(stacks,args,1,"0",""); + errs++; + break; + } + iguana_stack(stacks,args,1,"0",""); + continue; + } + else if ( (op->flags & IGUANA_STACKFLAG) != 0 ) + { + val = 0; + if ( op->opcode == IGUANA_OP_PICK || op->opcode == IGUANA_OP_ROLL ) + { + if ( interpret != 0 && stacks->stackdepth < (val= iguana_num(args[0])) ) + { + printf("stack not deep enough %d < %lld\n",stacks->stackdepth,(long long)iguana_num(args[0])); + errs++; + break; + } + if ( op->opcode == IGUANA_OP_PICK ) + { + stacks->stack[stacks->stackdepth] = iguana_clone(stacks->stack[stacks->stackdepth - 1 - val]); + stacks->stackdepth++; + } + else + { + args[1] = stacks->stack[stacks->stackdepth - 1 - val]; + for (i=(int32_t)(stacks->stackdepth-1-val); istackdepth-1; i++) + stacks->stack[i] = stacks->stack[i+1]; + stacks->stack[stacks->stackdepth - 1] = args[1]; + } + } + else + { + switch ( op->opcode ) + { + case IGUANA_OP_TOALTSTACK: + if ( stacks->altstackdepth < stacks->maxstackdepth ) + { + iguana_altpush(stacks,args[0]); + memset(&args[0],0,sizeof(args[0])); + } + else + { + printf("altstack overflow %d vs %d\n",stacks->altstackdepth,stacks->maxstackdepth); + errs++; + } + break; + case IGUANA_OP_FROMALTSTACK: + stacks->stack[stacks->stackdepth++] = iguana_altpop(stacks); + break; + case IGUANA_OP_DEPTH: iguana_pushdata(stacks,stacks->stackdepth,0,0); break; + case IGUANA_OP_DROP: case IGUANA_OP_2DROP: break; + case IGUANA_OP_3DUP: iguana_stack(stacks,args,3,"012","012"); break; + case IGUANA_OP_2OVER: iguana_stack(stacks,args,4,"0123","01"); break; + case IGUANA_OP_2ROT: iguana_stack(stacks,args,6,"234501",""); break; + case IGUANA_OP_2SWAP: iguana_stack(stacks,args,4,"2301",""); break; + case IGUANA_OP_IFDUP: + if ( iguana_isnonz(args[0]) != 0 ) + iguana_stack(stacks,args,0,"","0"); + iguana_stack(stacks,args,1,"0",""); + break; + case IGUANA_OP_DUP: iguana_stack(stacks,args,1,"0","0"); break; + case IGUANA_OP_2DUP: iguana_stack(stacks,args,2,"01","01"); break; + case IGUANA_OP_NIP: + if ( args[0].data != 0 ) + free(args[0].data); + iguana_stack(stacks,args,2,"1",""); + break; + case IGUANA_OP_OVER: iguana_stack(stacks,args,2,"01","0"); break; + case IGUANA_OP_ROT: iguana_stack(stacks,args,3,"120",""); break; + case IGUANA_OP_SWAP: iguana_stack(stacks,args,2,"10",""); break; + case IGUANA_OP_TUCK: iguana_stack(stacks,args,2,"10","1"); break; + } + } + } + else if ( (op->flags & IGUANA_MATHFLAG) != 0 ) + { + int64_t numA=0,numB=0,numC=0; + for (i=0; istackitems; i++) + { + if ( args[i].size != sizeof(int32_t) ) + break; + if ( i == 0 ) + numA = iguana_num(args[i]); + else if ( i == 1 ) + numB = iguana_num(args[i]); + else if ( i == 2 ) + numC = iguana_num(args[i]); + } + if ( i != op->stackitems ) + { + printf("math script non-int32_t arg[%d] of %d\n",i,op->stackitems); + errs++; + break; + } + switch ( op->opcode ) + { + case IGUANA_OP_1ADD: iguana_pushdata(stacks,numA + 1,0,0); break; + case IGUANA_OP_1SUB: iguana_pushdata(stacks,numA - 1,0,0); break; + case IGUANA_OP_NEGATE: iguana_pushdata(stacks,-numA,0,0); break; + case IGUANA_OP_ABS: iguana_pushdata(stacks,numA<0?-numA:numA,0,0); break; + case IGUANA_OP_NOT: iguana_pushdata(stacks,numA == 0,0,0); break; + case IGUANA_OP_0NOTEQUAL: iguana_pushdata(stacks,numA != 0,0,0); break; + case IGUANA_OP_ADD: iguana_pushdata(stacks,numA + numB,0,0); break; + case IGUANA_OP_SUB: iguana_pushdata(stacks,numA - numB,0,0); break; + case IGUANA_OP_BOOLAND:iguana_pushdata(stacks,numA != 0 && numB != 0,0,0); break; + case IGUANA_OP_BOOLOR: iguana_pushdata(stacks,numA != 0 || numB != 0,0,0); break; + case IGUANA_OP_NUMEQUAL: case IGUANA_OP_NUMEQUALVERIFY: + iguana_pushdata(stacks,numA == numB,0,0); break; + case IGUANA_OP_NUMNOTEQUAL:iguana_pushdata(stacks,numA != numB,0,0); break; + case IGUANA_OP_LESSTHAN: iguana_pushdata(stacks,numA < numB,0,0); break; + case IGUANA_OP_GREATERTHAN:iguana_pushdata(stacks,numA > numB,0,0); break; + case IGUANA_OP_LESSTHANOREQUAL:iguana_pushdata(stacks,numA <= numB,0,0); break; + case IGUANA_OP_GREATERTHANOREQUAL:iguana_pushdata(stacks,numA >= numB,0,0); break; + case IGUANA_OP_MIN: iguana_pushdata(stacks,numA <= numB ? numA : numB,0,0); break; + case IGUANA_OP_MAX: iguana_pushdata(stacks,numA >= numB ? numA : numB,0,0); break; + case IGUANA_OP_WITHIN: iguana_pushdata(stacks,numB <= numA && numA < numC,0,0); break; + } + } + else if ( op->opcode == IGUANA_OP_CODESEPARATOR ) + { + if ( stacks != 0 ) + stacks->codeseparator = k; + continue; + } + else + { + printf("unhandled opcode.%02x (%s)\n",op->opcode,str); + errs++; + break; + } + if ( (op->flags & IGUANA_POSTVERIFY) != 0 ) + { + if ( stacks->stackdepth < 1 ) + { + printf("empty stack at offset.%ld\n",(long)str - (long)asmstr); + errs++; + break; + } + if ( iguana_isnonz(stacks->stack[stacks->stackdepth-1]) == 0 ) + break; + iguana_pop(stacks); + } + } + else + { + printf("too many ops opcode.%s at offset.%ld\n",str,(long)str - (long)asmstr); + errs++; + break; + } + } + else + { + printf("unknown opcode.%s at offset.%ld\n",str,(long)str - (long)asmstr); + errs++; + break; + } + } + if ( stacks != &STACKS ) + { + if ( jobj(interpreter,"result") != 0 ) + jdelete(interpreter,"result"); + if ( stacks->stackdepth <= 0 ) + { + errs++; + printf("empty stack error\n"); + jaddstr(interpreter,"error","empty stack"); + jadd(interpreter,"result",jfalse()); + } + else if ( iguana_isnonz(stacks->stack[--stacks->stackdepth]) != 0 ) + { + //printf("Evaluate true, depth.%d errs.%d k.%d\n",stacks->stackdepth,errs,k); + if ( errs == 0 ) + jadd(interpreter,"result",jtrue()); + else jadd(interpreter,"result",jfalse()); + } + else + { + jadd(interpreter,"result",jfalse()); + printf("Evaluate FALSE, depth.%d errs.%d [0] size.%d val.%d\n",stacks->stackdepth,errs,stacks->stack[0].size,stacks->stack[0].U.val); + errs++; + if ( stacks->logarray != 0 ) + printf("LOG.(%s)\n\n",jprint(stacks->logarray,0)); + } + if ( numargs > 0 ) + { + for (i=0; i OP_EQUALVERIFY OP_CHECKSIG +int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) +{ + script[n++] = SCRIPT_OP_DUP; + script[n++] = SCRIPT_OP_HASH160; + script[n++] = 0x14; memcpy(&script[n],rmd160,0x14); n += 0x14; + script[n++] = SCRIPT_OP_EQUALVERIFY; + script[n++] = SCRIPT_OP_CHECKSIG; + return(n); +} + +int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime) +{ + script[n++] = 4; + script[n++] = locktime & 0xff, locktime >>= 8; + script[n++] = locktime & 0xff, locktime >>= 8; + script[n++] = locktime & 0xff, locktime >>= 8; + script[n++] = locktime & 0xff; + script[n++] = SCRIPT_OP_CHECKLOCKTIMEVERIFY; + script[n++] = SCRIPT_OP_DROP; + return(n); +} + +int32_t bitcoin_timelockspend(uint8_t *script,int32_t n,uint8_t rmd160[20],uint32_t timestamp) +{ + n = bitcoin_checklocktimeverify(script,n,timestamp); + n = bitcoin_standardspend(script,n,rmd160); + return(n); +} + +int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp) +{ + int32_t i,plen; + script[n++] = 0x50 + vp->M; + for (i=0; iN; i++) + { + if ( (plen= bitcoin_pubkeylen(vp->signers[i].pubkey)) < 0 ) + return(-1); + script[n++] = plen; + memcpy(&script[n],vp->signers[i].pubkey,plen); + n += plen; + } + script[n++] = 0x50 + vp->N; + script[n++] = SCRIPT_OP_CHECKMULTISIG; + calc_rmd160_sha256(p2sh_rmd160,script,n); + return(n); +} + +int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,const int32_t p2shlen) +{ + if ( p2shlen >= 0xfd ) + { + script[n++] = 0x4d; + script[n++] = (p2shlen & 0xff); + script[n++] = ((p2shlen >> 8) & 0xff); + } + else if ( p2shlen > 76 ) + { + script[n++] = 0x4c; + script[n++] = p2shlen; + } else script[n++] = p2shlen; + memcpy(&script[n],p2shscript,p2shlen), n += p2shlen; + return(n); +} + +char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params) +{ + return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,4)); +} + +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; + offset = 1 + (taddr != 0); + memset(rmd160,0,20); + *addrtypep = 0; + buf = _buf; + if ( (len= bitcoin_base58decode(buf,coinaddr)) >= 4 ) + { + // validate with trailing hash, then remove hash + hash = bits256_doublesha256(0,buf,20+offset); + *addrtypep = (taddr == 0) ? *buf : buf[1]; + memcpy(rmd160,buf+offset,20); + if ( (buf[20+offset]&0xff) == hash.bytes[31] && (buf[21+offset]&0xff) == hash.bytes[30] &&(buf[22+offset]&0xff) == hash.bytes[29] && (buf[23+offset]&0xff) == hash.bytes[28] ) + { + //printf("coinaddr.(%s) valid checksum addrtype.%02x\n",coinaddr,*addrtypep); + return(20); + } + else + { + int32_t i; + if ( len > 20 ) + { + hash = bits256_doublesha256(0,buf,len); + } + for (i=0; i "); + hash = bits256_doublesha256(0,data,(int32_t)data_len+offset); + //for (i=0; i<32; i++) + // printf("%02x",hash.bytes[i]); + //printf(" checkhash\n"); + for (i=0; i<4; i++) + data[data_len+i+offset] = hash.bytes[31-i]; + return(data_len + 4 + offset); +} + +int32_t bitcoin_wif2priv(uint8_t wiftaddr,uint8_t *addrtypep,bits256 *privkeyp,char *wifstr) +{ + 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 ) + { + // validate with trailing hash, then remove hash + if ( len < 38 ) + len = 38; + hash = bits256_doublesha256(0,buf,len - 4); + *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)); + } + } + return((int32_t)strlen(wifstr)); +} + +int32_t bitcoin_priv2wiflong(uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype) +{ + 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(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)); + } + } + return((int32_t)strlen(wifstr)); +} + +bits256 LP_privkey(char *coinaddr,uint8_t taddr) +{ + bits256 privkey; uint8_t addrtype,rmd160[20]; + bitcoin_addr2rmd160(taddr,&addrtype,rmd160,coinaddr); + privkey = LP_privkeyfind(rmd160); + return(privkey); +} + +bits256 LP_pubkey(bits256 privkey) +{ + bits256 pubkey; + pubkey = curve25519(privkey,curve25519_basepoint9()); + return(pubkey); +} + +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(wiftaddr,&addrtype,&V->signers[ind].privkey,wifstr); + if ( addrtype != pubtype ) + return(clonestr("{\"error\":\"invalid wifA\"}")); + else return(0); +} + +uint8_t iguana_addrtype(uint8_t pubtype,uint8_t p2shtype,uint8_t script_type) +{ + if ( script_type == IGUANA_SCRIPT_76A988AC || script_type == IGUANA_SCRIPT_AC || script_type == IGUANA_SCRIPT_76AC ) + return(pubtype); + else + { + //printf("P2SH type.%d\n",script_type); + return(p2shtype); + } +} + +int32_t iguana_scriptgen(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi) +{ + uint8_t addrtype; char rmd160str[41],pubkeystr[256]; int32_t plen,i,m,n,flag = 0,scriptlen = 0; + m = n = 0; + if ( asmstr != 0 ) + asmstr[0] = 0; + addrtype = iguana_addrtype(pubtype,p2shtype,type); + if ( type == IGUANA_SCRIPT_76A988AC || type == IGUANA_SCRIPT_AC || type == IGUANA_SCRIPT_76AC || type == IGUANA_SCRIPT_P2SH ) + { + init_hexbytes_noT(rmd160str,rmd160,20); + bitcoin_address(coinaddr,taddr,addrtype,rmd160,20); + } + switch ( type ) + { + case IGUANA_SCRIPT_NULL: + if ( asmstr != 0 ) + strcpy(asmstr,txi == 0 ? "coinbase " : "PoSbase "); + flag++; + coinaddr[0] = 0; + break; + case IGUANA_SCRIPT_76AC: + case IGUANA_SCRIPT_AC: + if ( (plen= bitcoin_pubkeylen(vp->signers[0].pubkey)) < 0 ) + return(0); + init_hexbytes_noT(pubkeystr,(uint8_t *)vp->signers[0].pubkey,plen); + if ( asmstr != 0 ) + { + if ( type == IGUANA_SCRIPT_76AC ) + strcpy(asmstr,"OP_DUP "); + sprintf(asmstr + strlen(asmstr),"%s OP_CHECKSIG // %s",pubkeystr,coinaddr); + } + if ( type == IGUANA_SCRIPT_76AC ) + script[scriptlen++] = 0x76; + scriptlen = bitcoin_pubkeyspend(script,scriptlen,(uint8_t *)vp->signers[0].pubkey); + //printf("[%02x] type.%d scriptlen.%d\n",vp->signers[0].pubkey[0],type,scriptlen); + break; + case IGUANA_SCRIPT_76A988AC: + if ( asmstr != 0 ) + sprintf(asmstr,"OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG // %s",rmd160str,coinaddr); + scriptlen = bitcoin_standardspend(script,0,rmd160); + break; + case IGUANA_SCRIPT_P2SH: + if ( asmstr != 0 ) + sprintf(asmstr,"OP_HASH160 %s OP_EQUAL // %s",rmd160str,coinaddr); + scriptlen = bitcoin_p2shspend(script,0,rmd160); + break; + case IGUANA_SCRIPT_OPRETURN: + if ( asmstr != 0 ) + strcpy(asmstr,"OP_RETURN "); + bitcoin_address(coinaddr,taddr,addrtype,(uint8_t *)&vp->spendscript[0],vp->spendlen); + flag++; + break; + case IGUANA_SCRIPT_3of3: m = 3, n = 3; break; + case IGUANA_SCRIPT_2of3: m = 2, n = 3; break; + case IGUANA_SCRIPT_1of3: m = 1, n = 3; break; + case IGUANA_SCRIPT_2of2: m = 2, n = 2; break; + case IGUANA_SCRIPT_1of2: m = 1, n = 2; break; + case IGUANA_SCRIPT_1of1: m = 1, n = 1; break; + case IGUANA_SCRIPT_MSIG: m = vp->M, n = vp->N; break; + case IGUANA_SCRIPT_DATA: + if ( asmstr != 0 ) + strcpy(asmstr,"DATA ONLY"); + bitcoin_address(coinaddr,taddr,addrtype,(uint8_t *)&vp->spendscript[0],vp->spendlen); + flag++; + break; + case IGUANA_SCRIPT_STRANGE: + if ( asmstr != 0 ) + strcpy(asmstr,"STRANGE SCRIPT "); + bitcoin_address(coinaddr,taddr,addrtype,(uint8_t *)&vp->spendscript[0],vp->spendlen); + flag++; + break; + default: break;//printf("unexpected script type.%d\n",type); break; + } + if ( n > 0 ) + { + scriptlen = bitcoin_MofNspendscript(rmd160,script,0,vp); + bitcoin_address(coinaddr,taddr,p2shtype,script,scriptlen); + if ( asmstr != 0 ) + { + sprintf(asmstr,"%d ",m); + for (i=0; isigners[i].pubkey)) > 0 ) + { + init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->signers[i].pubkey,plen); + if ( asmstr != 0 ) + strcat(asmstr," "); + } + else if ( asmstr != 0 ) + strcat(asmstr,"NOPUBKEY "); + sprintf(asmstr + strlen(asmstr),"%d // M.%d of N.%d [",n,m,n); + for (i=0; isigners[i].coinaddr,ispendlen > 0 ) + init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->spendscript,vp->spendlen); + *Mp = m, *nump = n; + return(scriptlen); +} + +int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype) +{ + int32_t j,n,siglen,plen; uint8_t *p2shscript; + j = n = 0; + *userdatap = 0; + *userdatalenp = *pubkeysizep = *sigsizep = 0; + *hashtypep = SIGHASH_ALL; + while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen < len && j < 16 ) + { + vp->signers[j].siglen = siglen; + memcpy(vp->signers[j].sig,&scriptsig[n+1],siglen); + if ( j == 0 ) + *hashtypep = vp->signers[j].sig[siglen-1]; + else if ( vp->signers[j].sig[siglen-1] != *hashtypep ) + { + //printf("SIGHASH.%d mismatch %d vs %d\n",j,vp->signers[j].sig[siglen-1],*hashtypep); + break; + } + (*sigsizep) += siglen; + //printf("sigsize %d [%02x]\n",*sigsizep,vp->signers[j].sig[siglen-1]); + n += (siglen + 1); + j++; + if ( spendtype == 0 && j > 1 ) + spendtype = IGUANA_SCRIPT_MSIG; + } + vp->numsigs = j; + vp->type = spendtype; + if ( j == 0 ) + { + //*userdatalenp = len; + vp->spendlen = len; + return(vp->spendlen); + } + j = 0; + while ( ((plen= scriptsig[n]) == 33 || plen == 65) && j < 16 && plen+n <= len ) + { + memcpy(vp->signers[j].pubkey,&scriptsig[n+1],plen); + calc_rmd160_sha256(vp->signers[j].rmd160,vp->signers[j].pubkey,plen); + if ( j == 0 ) + memcpy(vp->rmd160,vp->signers[j].rmd160,20); + n += (plen + 1); + (*pubkeysizep) += plen; + j++; + } + vp->numpubkeys = j; + *userdatap = &scriptsig[n]; + if ( len > n ) + *userdatalenp = (len - n); + p2shscript = 0; + while ( n < len ) + { + if ( n+2 < len && (scriptsig[n] == 0x4c || scriptsig[n] == 0x4d) ) + { + if ( scriptsig[n] == 0x4c ) + vp->p2shlen = scriptsig[n+1], n += 2; + else vp->p2shlen = ((uint32_t)scriptsig[n+1] + ((uint32_t)scriptsig[n+2] << 8)), n += 3; + //printf("p2sh opcode.%02x %02x %02x scriptlen.%d\n",scriptsig[n],scriptsig[n+1],scriptsig[n+2],vp->p2shlen); + if ( vp->p2shlen < IGUANA_MAXSCRIPTSIZE && n+vp->p2shlen <= len ) + { + p2shscript = &scriptsig[n]; + memcpy(vp->p2shscript,&scriptsig[n],vp->p2shlen); + n += vp->p2shlen; + vp->type = IGUANA_SCRIPT_P2SH; + } else vp->p2shlen = 0; + } + } + if ( *userdatap == p2shscript ) + *userdatap = 0; + /*if ( len == 0 ) + { + // txid.(eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2).v1 + decode_hex(vp->rmd160,20,"010966776006953d5567439e5e39f86a0d273bee");//3564a74f9ddb4372301c49154605573d7d1a88fe"); + vp->type = IGUANA_SCRIPT_76A988AC; + }*/ + vp->spendlen = iguana_scriptgen(taddr,pubtype,p2shtype,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,0,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout); + //printf("type.%d asmstr.(%s) spendlen.%d\n",vp->type,asmstr,vp->spendlen); + return(vp->spendlen); +} + +int32_t _iguana_calcrmd160(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,struct vin_info *vp) +{ + static uint8_t zero_rmd160[20]; + char hexstr[8192]; uint8_t *script,type; int32_t i,n,m,plen; + if ( vp->N == 0 ) + vp->N = 1; + if ( vp->M == 0 ) + vp->M = 1; + type = IGUANA_SCRIPT_STRANGE; + init_hexbytes_noT(hexstr,vp->spendscript,vp->spendlen); + //char str[65]; printf("script.(%s).%d in %s len.%d plen.%d spendlen.%d cmp.%d\n",hexstr,vp->spendlen,bits256_str(str,vp->vin.prev_hash),vp->spendlen,bitcoin_pubkeylen(&vp->spendscript[1]),vp->spendlen,vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG); + if ( vp->spendlen == 0 ) + { + if ( zero_rmd160[0] == 0 ) + { + calc_rmd160_sha256(zero_rmd160,vp->spendscript,vp->spendlen); + //vcalc_sha256(0,sha256,vp->spendscript,vp->spendlen); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + //calc_rmd160(0,zero_rmd160,sha256,sizeof(sha256)); // b472a266d0bd89c13706a4132ccfb16f7c3b9fcb + init_hexbytes_noT(hexstr,zero_rmd160,20); + } + memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); + return(IGUANA_SCRIPT_NULL); + } + else if ( vp->spendscript[0] == SCRIPT_OP_RETURN ) + type = IGUANA_SCRIPT_OPRETURN; + else if ( vp->spendscript[0] == SCRIPT_OP_DUP && vp->spendscript[1] == SCRIPT_OP_HASH160 && vp->spendscript[2] == 20 && vp->spendscript[vp->spendscript[2]+3] == SCRIPT_OP_EQUALVERIFY && vp->spendscript[vp->spendscript[2]+4] == SCRIPT_OP_CHECKSIG ) + { + //printf("IGUANA_SCRIPT_76A988AC plen.%d vs %d vp->spendlen\n",vp->spendscript[2]+4,vp->spendlen); + // 76a9145f69cb73016264270dae9f65c51f60d0e4d6fd4488ac + memcpy(vp->rmd160,&vp->spendscript[3],20); + if ( (plen= vp->spendscript[2]+5) != vp->spendlen ) + { + return(IGUANA_SCRIPT_STRANGE); + /*while ( plen < vp->spendlen ) + if ( vp->spendscript[plen++] != 0x61 ) // nop + return(IGUANA_SCRIPT_STRANGE);*/ + } + return(IGUANA_SCRIPT_76A988AC); + } + // 21035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055eac + else if ( vp->spendscript[0] == SCRIPT_OP_DUP && (plen= bitcoin_pubkeylen(&vp->spendscript[2])) > 0 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG && vp->spendscript[0] == plen && vp->spendlen == plen+3 ) + { + memcpy(vp->signers[0].pubkey,&vp->spendscript[2],plen); + calc_rmd160_sha256(vp->rmd160,vp->signers[0].pubkey,plen); + //printf("found IGUANA_SCRIPT_76AC\n"); + return(IGUANA_SCRIPT_76AC); + } + else if ( (plen= bitcoin_pubkeylen(&vp->spendscript[1])) > 0 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG && vp->spendscript[0] == plen && vp->spendlen == plen+2 ) + { + memcpy(vp->signers[0].pubkey,&vp->spendscript[1],plen); + calc_rmd160_sha256(vp->rmd160,vp->signers[0].pubkey,plen); + //printf("found IGUANA_SCRIPT_AC\n"); + return(IGUANA_SCRIPT_AC); + } + else if ( vp->spendscript[0] == SCRIPT_OP_HASH160 && vp->spendscript[1] == 0x14 && vp->spendlen == 23 && vp->spendscript[22] == SCRIPT_OP_EQUAL ) + { + memcpy(vp->rmd160,vp->spendscript+2,20); + return(IGUANA_SCRIPT_P2SH); + } + else if ( vp->spendlen > 34 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKMULTISIG && (n= vp->spendscript[vp->spendlen-2]) >= 0x51 && n <= 0x60 && (m= vp->spendscript[0]) >= 0x51 && m <= n ) // m of n multisig + { + m -= 0x50, n -= 0x50; + script = vp->spendscript+1; + for (i=0; isigners[i].pubkey,script,plen); + calc_rmd160_sha256(vp->signers[i].rmd160,vp->signers[i].pubkey,plen); + bitcoin_address(vp->signers[i].coinaddr,taddr,pubtype,vp->signers[i].pubkey,plen); + } + if ( (int32_t)((long)script - (long)vp->spendscript) == vp->spendlen-2 ) + { + vp->N = n; + vp->M = m; + //printf("M.%d N.%d\n",m,n); + } + calc_rmd160_sha256(vp->rmd160,vp->spendscript,vp->spendlen); + if ( n == 3 ) + { + if ( m == 3 ) + return(IGUANA_SCRIPT_3of3); + else if ( m == 2 ) + return(IGUANA_SCRIPT_2of3); + else if ( m == 1 ) + return(IGUANA_SCRIPT_1of3); + } + else if ( n == 2 ) + { + if ( m == 2 ) + return(IGUANA_SCRIPT_2of2); + else if ( m == 1 ) + return(IGUANA_SCRIPT_1of2); + } + else if ( m == 1 && n == 1 ) + return(IGUANA_SCRIPT_1of1); + //printf("strange msig M.%d of N.%d\n",m,n); + return(IGUANA_SCRIPT_MSIG); + } + else if ( vp->spendlen == vp->spendscript[0]+1 ) + { + //printf("just data.%d\n",vp->spendlen); + memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); + return(IGUANA_SCRIPT_DATA); + } + if ( type != IGUANA_SCRIPT_OPRETURN && type != IGUANA_SCRIPT_DATA ) + { + if ( vp->spendlen > 0 && vp->spendlen < sizeof(hexstr)/2-1 ) + { + static FILE *fp; + init_hexbytes_noT(hexstr,vp->spendscript,vp->spendlen); + //char str[65]; printf("unparsed script.(%s).%d in %s len.%d\n",hexstr,vp->spendlen,bits256_str(str,vp->vin.prev_hash),vp->spendlen); + if ( 1 && fp == 0 ) + fp = fopen("unparsed.txt","w"); + if ( fp != 0 ) + fprintf(fp,"%s\n",hexstr), fflush(fp); + } else sprintf(hexstr,"pkscript overflowed %ld\n",(long)sizeof(hexstr)); + } + calc_rmd160_sha256(vp->rmd160,vp->spendscript,vp->spendlen); + return(type); +} + +int32_t iguana_calcrmd160(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,char *asmstr,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence) +{ + int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; + memset(vp,0,sizeof(*vp)); + vp->vin.prev_hash = debugtxid, vp->vin.prev_vout = vout; + vp->spendlen = pk_scriptlen; + vp->vin.sequence = sequence; + memcpy(vp->spendscript,pk_script,pk_scriptlen); + if ( (vp->type= _iguana_calcrmd160(taddr,pubtype,p2shtype,vp)) >= 0 ) + { + scriptlen = iguana_scriptgen(taddr,pubtype,p2shtype,&vp->M,&vp->N,vp->coinaddr,script,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vout); + if ( vp->M == 0 && vp->N == 0 ) + { + vp->M = vp->N = 1; + strcpy(vp->signers[0].coinaddr,vp->coinaddr); + memcpy(vp->signers[0].rmd160,vp->rmd160,20); + } + if ( scriptlen != pk_scriptlen || (scriptlen != 0 && memcmp(script,pk_script,scriptlen) != 0) ) + { + if ( vp->type != IGUANA_SCRIPT_OPRETURN && vp->type != IGUANA_SCRIPT_DATA && vp->type != IGUANA_SCRIPT_STRANGE ) + { + int32_t i; + printf("\n--------------------\n"); + for (i=0; itype,scriptlen,pk_scriptlen); + } + } + } + return(vp->type); +} + +cJSON *bitcoin_txscript(char *asmstr,char **vardata,int32_t numvars) +{ + int32_t i; cJSON *scriptjson,*array; + scriptjson = cJSON_CreateObject(); + jaddstr(scriptjson,"asm",asmstr); + jaddnum(scriptjson,"numvars",numvars); + if ( numvars > 0 ) + { + array = cJSON_CreateArray(); + for (i=0; i= 0 ) + { + if ( (n= V.N) == 0 ) + n = 1; + for (i=0; i 0 ) + init_hexbytes_noT(pubkeystr,V.signers[i].pubkey,plen); + else pubkeystr[0] = 0; + jaddistr(pubkeys,pubkeystr); + } + } + return(pubkeys); +} + +void iguana_addscript(cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname) +{ + char *scriptstr,scriptbuf[8192+256]; int32_t maxlen; cJSON *scriptobj; + if ( scriptlen < 0 || scriptlen > IGUANA_MAXSCRIPTSIZE || scriptlen > sizeof(scriptbuf) ) + return; + scriptstr = scriptbuf, maxlen = sizeof(scriptbuf); + init_hexbytes_noT(scriptstr,script,scriptlen); + //if ( strcmp(fieldname,"userdata") == 0 ) + // printf("SCRIPT_USERDATA.(%s)\n",scriptstr); + if ( strcmp(fieldname,"coinbase") == 0 ) + jaddstr(dest,"coinbase",scriptstr); + else + { + scriptobj = cJSON_CreateObject(); + jaddstr(scriptobj,"hex",scriptstr); + iguana_expandscript(scriptstr,maxlen,script,scriptlen); + if ( scriptstr[0] != 0 ) + jaddstr(scriptobj,"asm",scriptstr); + if ( scriptstr != scriptbuf ) + free(scriptstr); + jadd(dest,fieldname,scriptobj); + } +} + +cJSON *iguana_pubkeysjson(uint8_t *pubkeyptrs[],int32_t numpubkeys) +{ + int32_t i,plen; char pubkeystr[256]; cJSON *pubkeysjson = cJSON_CreateArray(); + for (i=0; i 0 ) + init_hexbytes_noT(pubkeystr,pubkeyptrs[i],plen); + else pubkeystr[0] = 0; + jaddistr(pubkeysjson,pubkeystr); + } + return(pubkeysjson); +} + +cJSON *bitcoin_txinput(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys,uint8_t *sig,int32_t siglen) +{ + cJSON *item,*vins; char p2shscriptstr[IGUANA_MAXSCRIPTSIZE*2+1]; uint8_t *script,len=0; + vins = jduplicate(jobj(txobj,"vin")); + jdelete(txobj,"vin"); + item = cJSON_CreateObject(); + if ( sig != 0 && siglen > 0 ) + iguana_addscript(item,sig,siglen,"scriptSig"); + if ( spendscript != 0 && spendscript > 0 ) + { + iguana_addscript(item,spendscript,spendlen,"scriptPubKey"); + script = spendscript, len = spendlen; + } + else if ( redeemscript != 0 && p2shlen > 0 ) + { + init_hexbytes_noT(p2shscriptstr,redeemscript,p2shlen); + jaddstr(item,"redeemScript",p2shscriptstr); + script = redeemscript, len = p2shlen; + } else script = 0; + if ( script != 0 && numpubkeys == 0 ) + jadd(item,"pubkeys",iguana_scriptpubkeys(taddr,pubtype,p2shtype,script,len,txid,vout,sequenceid)); + else if ( pubkeys != 0 && numpubkeys > 0 ) + jadd(item,"pubkeys",iguana_pubkeysjson(pubkeys,numpubkeys)); + jaddbits256(item,"txid",txid); + jaddnum(item,"vout",vout); + jaddnum(item,"sequence",sequenceid); + jaddi(vins,item); + jadd(txobj,"vin",vins); + //printf("addvin -> (%s)\n",jprint(txobj,0)); + return(txobj); +} + +cJSON *bitcoin_txcreate(char *symbol,int32_t isPoS,int64_t locktime,uint32_t txversion,uint32_t timestamp) +{ + cJSON *json = cJSON_CreateObject(); + jaddnum(json,"version",txversion); + if ( locktime == 0 && strcmp(symbol,"KMD") == 0 ) + locktime = (uint32_t)time(NULL); + jaddnum(json,"locktime",locktime); + if ( isPoS != 0 ) + jaddnum(json,"timestamp",timestamp == 0 ? time(NULL) : timestamp); + jadd(json,"vin",cJSON_CreateArray()); + jadd(json,"vout",cJSON_CreateArray()); + return(json); +} + +cJSON *bitcoin_txoutput(cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis) +{ + char *hexstr; cJSON *item,*skey,*vouts = jduplicate(jobj(txobj,"vout")); + jdelete(txobj,"vout"); + item = cJSON_CreateObject(); + jadd64bits(item,"satoshis",satoshis); + skey = cJSON_CreateObject(); + hexstr = malloc(len*2 + 1); + init_hexbytes_noT(hexstr,paymentscript,len); + jaddstr(skey,"hex",hexstr); + //printf("addoutput.(%s %s)\n",hexstr,jprint(skey,0)); + free(hexstr); + jadd(item,"scriptPubKey",skey); + jaddi(vouts,item); + jadd(txobj,"vout",vouts); + return(txobj); +} + +int32_t bitcoin_txaddspend(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,cJSON *txobj,char *destaddress,uint64_t satoshis) +{ + uint8_t outputscript[128],addrtype,rmd160[20]; int32_t scriptlen; + if ( bitcoin_validaddress(taddr,pubtype,p2shtype,destaddress) == 0 && satoshis != 0 ) + { + bitcoin_addr2rmd160(taddr,&addrtype,rmd160,destaddress); + scriptlen = bitcoin_standardspend(outputscript,0,rmd160); + bitcoin_txoutput(txobj,outputscript,scriptlen,satoshis); + return(0); + } else return(-1); +} + +int32_t iguana_vinparse(int32_t rwflag,uint8_t *serialized,struct iguana_msgvin *msg) +{ + int32_t p2shlen,len = 0; uint32_t tmp; + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->prev_hash),msg->prev_hash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->prev_vout),&msg->prev_vout); + //char str[65]; printf("prev_hash.(%s) v%d\n",bits256_str(str,msg->prev_hash),msg->prev_vout); + if ( rwflag == 1 ) + { + tmp = msg->scriptlen + msg->userdatalen + msg->p2shlen; + if ( msg->p2shlen != 0 ) + { + if ( msg->p2shlen < 76 ) + tmp++; + else if ( msg->p2shlen < 0x100 ) + tmp += 2; + else tmp += 3; + } + } + len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); + if ( rwflag == 0 ) + { + /*if ( msg->p2shlen != 0 ) + { + if ( msg->p2shlen < 76 ) + tmp++; + else if ( msg->p2shlen < 0x100 ) + tmp += 2; + else tmp += 3; + }*/ + msg->scriptlen = tmp; + } + if ( msg->scriptlen > IGUANA_MAXSCRIPTSIZE ) + { + printf("iguana_vinparse illegal scriptlen.%d\n",msg->scriptlen); + return(-1); + } + //printf("len.%d scriptlen.%d user.%d p2sh.%d\n",len,msg->scriptlen,msg->userdatalen,msg->p2shlen); + if ( rwflag == 0 ) + { + msg->vinscript = &serialized[len]; + len += msg->scriptlen; + } + else + { + if ( msg->vinscript != 0 && msg->scriptlen > 0 ) + memcpy(&serialized[len],msg->vinscript,msg->scriptlen), len += msg->scriptlen; // pubkeys here + if ( msg->userdatalen > 0 && msg->userdata != 0 ) + { + //printf("userdata.%d scriptlen.%d\n",msg->userdatalen,msg->scriptlen); + memcpy(&serialized[len],msg->userdata,msg->userdatalen); + len += msg->userdatalen; + } + if ( (p2shlen= msg->p2shlen) > 0 && msg->redeemscript != 0 ) + { + if ( p2shlen < 76 ) + serialized[len++] = p2shlen; + else if ( p2shlen <= 0xff ) + { + serialized[len++] = 0x4c; + serialized[len++] = p2shlen; + } + else if ( p2shlen <= 0xffff ) + { + serialized[len++] = 0x4d; + serialized[len++] = (p2shlen & 0xff); + serialized[len++] = ((p2shlen >> 8) & 0xff); + } else return(-1); + memcpy(&serialized[len],msg->redeemscript,p2shlen), len += p2shlen; + if ( (0) ) + { + int32_t j; + for (j=0; jredeemscript[j]); + printf(" p2shlen.%d %x\n",p2shlen,p2shlen); + } + } + } + //printf("sequence starts.%d %08x\n",len,*(int32_t *)&serialized[len]); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence); + if ( (0) ) + { + int32_t i; char str[65]; + for (i=0; isequence,bits256_str(str,msg->prev_hash),msg->prev_vout,msg->vinscript,msg->scriptlen,rwflag); + } + return(len); +} + +int32_t iguana_voutparse(int32_t rwflag,uint8_t *serialized,struct iguana_msgvout *msg) +{ + int32_t len = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->value),&msg->value); + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->pk_scriptlen); + if ( msg->pk_scriptlen > IGUANA_MAXSCRIPTSIZE ) + { + printf("iguana_voutparse illegal scriptlen.%d\n",msg->pk_scriptlen); + return(-1); + } + if ( rwflag == 0 ) + msg->pk_script = &serialized[len]; + else if ( msg->pk_scriptlen > 0 ) + { + memcpy(&serialized[len],msg->pk_script,msg->pk_scriptlen); + if ( (0) ) + { + int32_t i; + for (i=0; ipk_scriptlen; i++) + printf("%02x",msg->pk_script[i]); + printf(" [%p] scriptlen.%d rwflag.%d %.8f\n",msg->pk_script,msg->pk_scriptlen,rwflag,dstr(msg->value)); + } + } // else serialized[len++] = 0; + len += msg->pk_scriptlen; + return(len); +} + +cJSON *iguana_vinjson(struct iguana_msgvin *vin,bits256 sigtxid) +{ + char str[65]; int32_t vout; cJSON *json = cJSON_CreateObject(); + vout = vin->prev_vout; + jaddnum(json,"sequence",vin->sequence); + if ( vout < 0 && bits256_nonz(vin->prev_hash) == 0 ) + iguana_addscript(json,vin->vinscript,vin->scriptlen,"coinbase"); + else + { + jaddstr(json,"txid",bits256_str(str,vin->prev_hash)); + jaddnum(json,"vout",vout); + if ( bits256_nonz(sigtxid) != 0 ) + jaddbits256(json,"sigtxid",sigtxid); + if ( vin->scriptlen > 0 && vin->vinscript != 0 ) // sigs + iguana_addscript(json,vin->vinscript,vin->scriptlen,"scriptSig"); + if ( vin->userdatalen > 0 && vin->userdata != 0 ) + iguana_addscript(json,vin->userdata,vin->userdatalen,"userdata"); + if ( vin->p2shlen > 0 && vin->redeemscript != 0 ) + iguana_addscript(json,vin->redeemscript,vin->p2shlen,"redeemScript"); + if ( vin->spendlen > 0 && vin->spendscript != 0 ) + iguana_addscript(json,vin->spendscript,vin->spendlen,"scriptPubKey"); + } + return(json); +} + +int32_t iguana_parsehexstr(uint8_t **destp,uint16_t *lenp,uint8_t *dest2,int32_t *len2p,uint8_t *serialized,char *hexstr) +{ + int32_t n; + n = (int32_t)strlen(hexstr) >> 1; + //printf("addhex.(%s) %d\n",hexstr,n); + if ( serialized == 0 ) + { + if ( (serialized= *destp) == 0 ) + printf("iguana_parsehexstr null serialized and destp\n"); + } + if ( serialized != 0 ) + { + decode_hex(serialized,n,hexstr); + *destp = serialized; + *lenp = n; + if ( dest2 != 0 && len2p != 0 ) + { + *len2p = n; + memcpy(dest2,serialized,n); + } + } + return(n); +} + +int32_t iguana_scriptnum(uint8_t opcode) +{ + if ( opcode == 0x00 ) + return(0); + else if ( opcode >= 0x51 && opcode < 0x60 ) + return(opcode - 0x50); + else return(-1); +} + +int32_t iguana_parsevinobj(uint8_t *serialized,int32_t maxsize,struct iguana_msgvin *vin,cJSON *vinobj,struct vin_info *V) +{ + //struct iguana_outpoint outpt; struct iguana_waddress *waddr; struct iguana_waccount *wacct; + uint8_t lastbyte; uint32_t tmp=0; int32_t i,n,starti,suppress_pubkeys,siglen,plen,m,endi,rwflag=1,len = 0; char *userdata=0,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0; + //printf("PARSEVIN.(%s) vin.%p\n",jprint(vinobj,0),vin); + if ( V == 0 ) + memset(vin,0,sizeof(*vin)); + vin->prev_vout = -1; + suppress_pubkeys = juint(vinobj,"suppress"); + if ( jobj(vinobj,"sequence") != 0 ) + vin->sequence = juint(vinobj,"sequence"); + else vin->sequence = 0xffffffff; + if ( (hexstr= jstr(vinobj,"coinbase")) == 0 ) + { + vin->prev_hash = jbits256(vinobj,"txid"); + //char str[65]; printf("vin->prev_hash.(%s)\n",bits256_str(str,vin->prev_hash)); + vin->prev_vout = jint(vinobj,"vout"); + if ( (scriptjson= jobj(vinobj,"scriptSig")) != 0 ) + hexstr = jstr(scriptjson,"hex"); + if ( ((spendstr= jstr(vinobj,"scriptPub")) == 0 && (spendstr= jstr(vinobj,"scriptPubKey")) == 0) || is_hexstr(spendstr,(int32_t)strlen(spendstr)) <= 0 ) + { + if ( (obj= jobj(vinobj,"scriptPub")) != 0 || (obj= jobj(vinobj,"scriptPubKey")) != 0 ) + { + spendstr = jstr(obj,"hex"); + if ( spendstr[0] != 0 ) + { + lastbyte = _decode_hex(&spendstr[strlen(spendstr)-2]); + //if ( lastbyte == SCRIPT_OP_CHECKMULTISIG ) + // need_op0 = 1; + if ( V != 0 ) + { + V->spendlen = (int32_t)strlen(spendstr) >> 1; + decode_hex(V->spendscript,V->spendlen,spendstr); + } + } + } + } + if ( (redeemstr= jstr(vinobj,"redeemScript")) == 0 || is_hexstr(redeemstr,(int32_t)strlen(redeemstr)) <= 0 ) + { + if ( (obj= jobj(vinobj,"redeemScript")) != 0 ) + { + redeemstr = jstr(obj,"hex"); + lastbyte = _decode_hex(&redeemstr[strlen(redeemstr)-2]); + //if ( lastbyte == SCRIPT_OP_CHECKMULTISIG ) + // need_op0 = 1; + } + } + if ( (userdata= jstr(vinobj,"userdata")) == 0 || is_hexstr(userdata,(int32_t)strlen(userdata)) <= 0 ) + { + if ( (obj= jobj(vinobj,"userdata")) != 0 ) + userdata = jstr(obj,"hex"); + } + } + //char str[65]; printf("rw.%d prevhash.(%s)\n",rwflag,bits256_str(str,vin->prev_hash)); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(vin->prev_hash),vin->prev_hash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(vin->prev_vout),&vin->prev_vout); + if ( V != 0 ) + { + V->suppress_pubkeys = suppress_pubkeys; + if ( vin->vinscript == 0 && V->spendlen == 0 ) + { + /*if ( iguana_RTunspentindfind(coin,&outpt,V->coinaddr,spendscript,&spendlen,&V->amount,&V->height,vin->prev_hash,vin->prev_vout,coin->bundlescount-1,0) == 0 ) + { + V->unspentind = outpt.unspentind; + if ( V->coinaddr[0] != 0 && (waddr= iguana_waddresssearch(&wacct,V->coinaddr)) != 0 ) + { + plen = bitcoin_pubkeylen(waddr->pubkey); + for (z=0; zsigners[0].pubkey[z] = waddr->pubkey[z]; + } + //printf("V %.8f (%s) spendscript.[%d]\n",dstr(V->amount),V->coinaddr,V->spendlen); + } + if ( spendlen != 0 && V->spendlen == 0 ) + { + V->spendlen = spendlen; + memcpy(V->spendscript,spendscript,spendlen); + }*/ + } + } + tmp = IGUANA_MAXSCRIPTSIZE; + starti = len; + len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); + endi = len; + //printf("rwflag.%d len.%d tmp.%d\n",rwflag,len,tmp); + //if ( need_op0 != 0 ) + // serialized[len++] = 0; // hack for bug for bug backward compatibility + if ( hexstr != 0 ) + { + n = (int32_t)strlen(hexstr) >> 1; + //printf("add.(%s) offset.%d\n",hexstr,len); + vin->vinscript = &serialized[len]; + decode_hex(&serialized[len],n,hexstr); + vin->scriptlen = n;// + need_op0; + if ( V != 0 ) + { + i = m = 0; + while ( m < n ) + { + siglen = serialized[len + m++]; + //if ( i == 0 && m == 1 && siglen == 0 ) // multisig backward compatible + // continue; + if ( serialized[len + m + siglen - 1] == SIGHASH_ALL ) + memcpy(V->signers[i++].sig,&serialized[len + m],siglen); + if ( (0) ) + { + int32_t j; + for (j=0; jvinscript != 0 ) + { + /*if ( vin->vinscript == 0 ) + { + vin->vinscript = serialized; + vin->vinscript[0] = 0; + vin->scriptlen = 1; + }*/ + for (i=0; i> 1) > 0 ) + { + if ( V != 0 ) + { + memcpy(V->signers[i].pubkey,&vin->vinscript[vin->scriptlen],plen); + if ( V->spendlen == 35 && V->spendscript[0] == 33 && V->spendscript[34] == 0xac ) + suppress_pubkeys = 1; + } + if ( suppress_pubkeys == 0 ) + { + printf("addpub.(%s)\n",pubkeystr); + vin->vinscript[vin->scriptlen++] = plen; + decode_hex(&vin->vinscript[vin->scriptlen],plen,pubkeystr); + vin->scriptlen += plen; + serialized[len++] = plen; + memcpy(&serialized[len],&vin->vinscript[vin->scriptlen],plen), len += plen; + } + } + } + } + //printf("userdata len.%d: ",len); + if ( userdata != 0 ) + { + n = iguana_parsehexstr(&vin->userdata,&vin->userdatalen,V!=0?V->userdata:0,V!=0?&V->userdatalen:0,&serialized[len],userdata); + //printf("parsed userdata.%d\n",n); + len += n; + } + //printf("redeemlen.%d: ",len); + if ( redeemstr != 0 ) + { + n = (int32_t)strlen(redeemstr) >> 1; + if ( n < 76 ) + serialized[len++] = n; + else if ( n <= 0xff ) + { + serialized[len++] = 0x4c; + serialized[len++] = n; + } + else + { + serialized[len++] = 0x4d; + serialized[len++] = n & 0xff; + serialized[len++] = (n >> 8) & 0xff; + } + n = iguana_parsehexstr(&vin->redeemscript,&vin->p2shlen,V!=0?V->p2shscript:0,V!=0?&V->p2shlen:0,&serialized[len],redeemstr); + len += n; + if ( vin->redeemscript[vin->p2shlen-1] == SCRIPT_OP_CHECKMULTISIG ) + { + V->M = iguana_scriptnum(vin->redeemscript[0]); + V->N = iguana_scriptnum(vin->redeemscript[vin->p2shlen-2]); + } + } + tmp = (len - endi); + if ( tmp < 0xfd ) + { + serialized[starti] = tmp; + for (i=starti+1; i> 8) & 0xff); + } + //printf("len.%d tmp.%d output sequence.[%d] <- %x\n",len,tmp,len,vin->sequence); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(vin->sequence),&vin->sequence); + if ( spendstr != 0 ) + { + if ( V != 0 ) + { + if ( V->spendlen == 0 ) + { + V->spendlen = (int32_t)strlen(spendstr) >> 1; + decode_hex(V->spendscript,V->spendlen,spendstr); + } + if ( vin->spendscript == 0 ) + vin->spendscript = V->spendscript; + } + if ( vin->spendlen == 0 && vin->spendscript != 0 ) + { + vin->spendlen = (int32_t)strlen(spendstr) >> 1; + decode_hex(vin->spendscript,vin->spendlen,spendstr); + } + //printf("serialized.%p len.%d\n",serialized,len); + //n = iguana_parsehexstr(&vin->spendscript,&vin->spendlen,V!=0?V->spendscript:0,V!=0?&V->spendlen:0,&serialized[len],spendstr); + //len += n; + } + return(len); +} + +int32_t iguana_parsevoutobj(uint8_t *serialized,int32_t maxsize,struct iguana_msgvout *vout,cJSON *voutobj) +{ + int32_t n,len = 0,rwflag = 1; cJSON *skey; char *hexstr; + memset(vout,0,sizeof(*vout)); + if ( jobj(voutobj,"satoshis") != 0 ) + vout->value = j64bits(voutobj,"satoshis"); + else vout->value = jdouble(voutobj,"value") * SATOSHIDEN; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(vout->value),&vout->value); + if ( (skey= jobj(voutobj,"scriptPubKey")) != 0 ) + { + if ( (hexstr= jstr(skey,"hex")) != 0 ) + { + n = (int32_t)strlen(hexstr) >> 1; + vout->pk_scriptlen = n; + len += iguana_rwvarint32(rwflag,&serialized[len],&vout->pk_scriptlen); + decode_hex(&serialized[len],n,hexstr); + vout->pk_script = &serialized[len]; + len += n; + } // else serialized[len++] = 0; + } //else serialized[len++] = 0; + return(len); +} + +cJSON *iguana_voutjson(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,struct iguana_msgvout *vout,int32_t txi,bits256 txid) +{ + // 035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055e OP_CHECKSIG + char scriptstr[IGUANA_MAXSCRIPTSIZE+1],asmstr[2*IGUANA_MAXSCRIPTSIZE+1]; int32_t i,m,n,scriptlen,asmtype; struct vin_info *vp; + uint8_t space[8192]; cJSON *addrs,*skey,*json = cJSON_CreateObject(); + vp = calloc(1,sizeof(*vp)); + jadd64bits(json,"satoshis",vout->value); + jaddnum(json,"value",dstr(vout->value)); + jaddnum(json,"n",txi); + //"scriptPubKey":{"asm":"OP_DUP OP_HASH160 5f69cb73016264270dae9f65c51f60d0e4d6fd44 OP_EQUALVERIFY OP_CHECKSIG","reqSigs":1,"type":"pubkeyhash","addresses":["RHyh1V9syARTf2pyxibz7v27D5paBeWza5"]} + if ( vout->pk_script != 0 && vout->pk_scriptlen*2+1 < sizeof(scriptstr) ) + { + memset(vp,0,sizeof(*vp)); + if ( (asmtype= iguana_calcrmd160(taddr,pubtype,p2shtype,asmstr,vp,vout->pk_script,vout->pk_scriptlen,txid,txi,0xffffffff)) >= 0 ) + { + skey = cJSON_CreateObject(); + scriptlen = iguana_scriptgen(taddr,pubtype,p2shtype,&m,&n,vp->coinaddr,space,asmstr,vp->rmd160,asmtype,vp,txi); + if ( asmstr[0] != 0 ) + jaddstr(skey,"asm",asmstr); + addrs = cJSON_CreateArray(); + if ( vp->N == 1 ) + { + if ( asmtype == 2 ) + { + jaddnum(skey,"reqSigs",1); + jaddstr(skey,"type","pubkeyhash"); + } + if ( vp->coinaddr[0] != 0 ) + jaddistr(addrs,vp->coinaddr); + } + else + { + jaddnum(skey,"reqSigs",vp->M); + for (i=0; iN; i++) + { + //btc_convrmd160(coinaddr,coin->chain->pubtype,V.signers[i].pubkey); + jaddistr(addrs,vp->signers[i].coinaddr); + } + } + jadd(skey,"addresses",addrs); + init_hexbytes_noT(scriptstr,vout->pk_script,vout->pk_scriptlen); + if ( scriptstr[0] != 0 ) + jaddstr(skey,"hex",scriptstr); + jadd(json,"scriptPubKey",skey); + } + } + return(json); +} + +void iguana_vinobjset(struct iguana_msgvin *vin,cJSON *item,uint8_t *spendscript,int32_t maxsize) +{ + char *redeemstr,*hexstr=0; cJSON *sobj; + if ( (redeemstr= jstr(item,"redeemScript")) != 0 && is_hexstr(redeemstr,0) > 0 ) + { + vin->p2shlen = (int32_t)strlen(redeemstr) >> 1; + vin->spendlen = vin->p2shlen; + vin->redeemscript = calloc(1,vin->p2shlen); + decode_hex(vin->redeemscript,vin->p2shlen,redeemstr); + hexstr = redeemstr; + //printf("VINOBJSET.(%s)\n",redeemstr); + } + else if ( (sobj= jobj(item,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && is_hexstr(hexstr,0) > 0 && (vin->spendlen == 0 || vin->spendscript == 0) ) + { + vin->spendlen = (int32_t)strlen(hexstr) >> 1; + } + if ( hexstr != 0 && vin->spendlen != 0 ) + { + if ( vin->spendlen < maxsize ) + { + if ( vin->spendscript == 0 ) + vin->spendscript = spendscript; + decode_hex(vin->spendscript,vin->spendlen,hexstr); + } + } +} + +int32_t iguana_vinarray_check(cJSON *vinarray,bits256 txid,int32_t vout) +{ + bits256 array_txid; cJSON *item; int32_t array_vout,i,n = cJSON_GetArraySize(vinarray); + for (i=0; ivins,dest.tx_in * sizeof(*dest.vins)); + memcpy(dest.vouts,msgtx->vouts,dest.tx_out * sizeof(*dest.vouts)); + memset(sigtxid.bytes,0,sizeof(sigtxid)); + if ( hashtype != SIGHASH_ALL ) + { + printf("currently only SIGHASH_ALL supported, not %d\n",hashtype); + return(sigtxid); + } + for (i=0; i 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 && + { +#ifdef BTC2_VERSION + if ( height >= BTC2_HARDFORK_HEIGHT ) + hashtype |= (0x777 << 20); +#endif + len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype); + revsigtxid = bits256_doublesha256(0,serialized,len); + for (i=0; iversion),&msg->version); + if ( json != 0 ) + { + jaddnum(json,"version",msg->version); + vinarray = cJSON_CreateArray(); + voutarray = cJSON_CreateArray(); + if ( rwflag == 0 ) + sigser = calloc(1,maxsize*2); + //printf("json.%p array.%p sigser.%p\n",json,vinarray,sigser); + } + //printf("version.%d\n",msg->version); + if ( isPoS != 0 ) + { + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); + //char str[65]; printf("version.%d timestamp.%08x %u %s\n",msg->version,msg->timestamp,msg->timestamp,utc_str(str,msg->timestamp)); + if ( json != 0 ) + jaddnum(json,"timestamp",msg->timestamp); + } + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); + if ( rwflag == 0 ) + { + if ( msg->vins == 0 ) + { + if ( sizeof(struct iguana_msgvin)*msg->tx_in > extralen ) + { + printf("(size.%d * tx_in.%d) > extralen.%d\n",(int32_t)sizeof(struct iguana_msgvin),msg->tx_in,extralen); + return(-1); + } + msg->vins = (struct iguana_msgvin *)extraspace; + extraused += (sizeof(struct iguana_msgvin) * msg->tx_in); + } else printf("unexpected non-null msg->vins.%p\n",msg->vins); + memset(msg->vins,0,sizeof(struct iguana_msgvin) * msg->tx_in); + } + for (i=0; itx_in; i++) + { + //printf("vin.%d starts offset.%d\n",i,len); + if ( vins != 0 && jitem(vins,i) != 0 ) + iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript)); + if ( (n= iguana_vinparse(rwflag,&serialized[len],&msg->vins[i])) < 0 ) + return(-1); + //printf("serialized vin.[%02x %02x %02x]\n",serialized[len],serialized[len+1],serialized[len+2]); + if ( msg->vins[i].spendscript == spendscript ) + msg->vins[i].spendscript = 0; + //printf("vin.%d n.%d len.%d\n",i,n,len); + len += n; + if ( len > maxsize ) + { + printf("invalid tx_in.%d len.%d vs maxsize.%d\n",msg->tx_in,len,maxsize); + return(-1); + } + } + //for (i=-3; i<7; i++) + // printf("%02x",serialized[len+i]); + //printf(" prev 3 bytes before tx_out rw.%d\n",rwflag); + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out); + if ( rwflag == 0 ) + { + if ( msg->vouts == 0 ) + { + if ( (extraused & 0xf) != 0 ) + extraused += 0xf - (extraused & 0xf); + if ( extraused + sizeof(struct iguana_msgvout)*msg->tx_out > extralen ) + { + printf("extraused.%d + tx_out.%d > extralen.%d\n",extraused,msg->tx_out,extralen); + return(-1); + } + msg->vouts = (struct iguana_msgvout *)&extraspace[extraused]; + extraused += (sizeof(struct iguana_msgvout) * msg->tx_out); + } else printf("unexpected non-null msg->vouts %p\n",msg->vouts); + memset(msg->vouts,0,sizeof(struct iguana_msgvout) * msg->tx_out); + } + for (i=0; itx_out; i++) + { + //printf("rwflag.%d vout.%d starts %d\n",rwflag,i,len); + if ( (n= iguana_voutparse(rwflag,&serialized[len],&msg->vouts[i])) < 0 ) + return(-1); + len += n; + if ( len > maxsize ) + { + printf("invalidC tx_out.%d of %d len.%d vs maxsize.%d n.%d\n",i,msg->tx_out,len,maxsize,n); + return(-1); + } + if ( voutarray != 0 ) + jaddi(voutarray,iguana_voutjson(taddr,pubtype,p2shtype,&msg->vouts[i],i,*txidp)); + } + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); + //printf("lock_time.%08x len.%d\n",msg->lock_time,len); + /*if ( strcmp(coin->symbol,"VPN") == 0 ) + { + uint16_t ddosflag = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ddosflag),&ddosflag); + for (i=0; serialized[len]!=0&&lentx_in; i++) + { + memset(sigtxid.bytes,0,sizeof(sigtxid)); + if ( vins != 0 && jitem(vins,i) != 0 ) + { + iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript)); + sigtxid = bitcoin_sigtxid(taddr,pubtype,p2shtype,isPoS,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,SIGHASH_ALL,vpnstr,suppress_pubkeys); + //printf("after vini.%d vinscript.%p spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].vinscript,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0)); + if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 ) + jaddi(vinarray,iguana_vinjson(&msg->vins[i],sigtxid)); + if ( msg->vins[i].spendscript == spendscript ) + msg->vins[i].spendscript = 0; + } else if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 ) + jaddi(vinarray,iguana_vinjson(&msg->vins[i],sigtxid)); + } + free(sigser); + jadd(json,"vin",vinarray); + msg->tx_in = cJSON_GetArraySize(vinarray); + jaddnum(json,"numvins",msg->tx_in); + } + if ( voutarray != 0 ) + { + jadd(json,"vout",voutarray); + jaddnum(json,"numvouts",msg->tx_out); + } + *txidp = bits256_doublesha256(txidstr,txstart,len); + if ( json != 0 ) + { + jaddnum(json,"locktime",msg->lock_time); + jaddnum(json,"size",len); + jaddbits256(json,"txid",*txidp); + //printf("TX.(%s) %p\n",jprint(json,0),json); + } + msg->allocsize = len; + return(len); +} + +bits256 iguana_parsetxobj(uint8_t isPoS,int32_t *txstartp,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj,struct vin_info *V) +{ + int32_t i,n,numvins,numvouts,len = 0,rwflag=1; cJSON *array=0; bits256 txid; char vpnstr[64]; + memset(&txid,0,sizeof(txid)); + memset(msg,0,sizeof(*msg)); + *txstartp = 0; + if ( txobj == 0 ) + return(txid); + vpnstr[0] = 0; + if ( (msg->version= juint(txobj,"version")) == 0 ) + msg->version = 1; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); + if ( isPoS != 0 ) + { + if ( (msg->timestamp= juint(txobj,"timestamp")) == 0 ) + msg->timestamp = (uint32_t)time(NULL); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); + } + if ( (array= jarray(&numvins,txobj,"vin")) != 0 ) + { + msg->tx_in = numvins; + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); + if ( len + sizeof(struct iguana_msgvin)*msg->tx_in > maxsize ) + return(txid); + maxsize -= (sizeof(struct iguana_msgvin) * msg->tx_in); + msg->vins = (struct iguana_msgvin *)&serialized[maxsize]; + memset(msg->vins,0,sizeof(struct iguana_msgvin) * msg->tx_in); + if ( msg->tx_in > 0 && msg->tx_in*sizeof(struct iguana_msgvin) < maxsize ) + { + for (i=0; itx_in; i++) + { + n = iguana_parsevinobj(&serialized[len],maxsize,&msg->vins[i],jitem(array,i),V!=0?&V[i]:0); + //for (j=0; j<8; j++) + // printf("%02x",serialized[len+j]); + //char str[65]; printf(" <- vinobj.%d starts offset.%d %s\n",i,len,bits256_str(str,msg->vins[i].prev_hash)); + len += n; + } + } + } + if ( (array= jarray(&numvouts,txobj,"vout")) != 0 ) + { + msg->tx_out = numvouts; + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out); + if ( len + sizeof(struct iguana_msgvout)*msg->tx_out > maxsize ) + return(txid); + maxsize -= (sizeof(struct iguana_msgvout) * msg->tx_out); + msg->vouts = (struct iguana_msgvout *)&serialized[maxsize]; + memset(msg->vouts,0,sizeof(struct iguana_msgvout) * msg->tx_out); + if ( msg->tx_out > 0 && msg->tx_out*sizeof(struct iguana_msgvout) < maxsize ) + { + for (i=0; itx_out; i++) + { + //printf("parsetxobj parsevout.%d starts %d\n",i,len); + len += iguana_parsevoutobj(&serialized[len],maxsize,&msg->vouts[i],jitem(array,i)); + } + } + } + msg->lock_time = jint(txobj,"locktime"); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); + //msg->txid = jbits256(txobj,"txid"); + *txstartp = 0; + msg->allocsize = len; + msg->txid = txid = bits256_doublesha256(0,serialized,len); + return(txid); +} + +char *iguana_rawtxbytes(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,cJSON *json,struct iguana_msgtx *msgtx,int32_t suppress_pubkeys) +{ + int32_t n; char *txbytes = 0,vpnstr[64]; uint8_t *serialized; + serialized = malloc(IGUANA_MAXPACKETSIZE); + vpnstr[0] = 0; + //char str[65]; printf("%d of %d: %s\n",i,msg.txn_count,bits256_str(str,tx.txid)); + if ( (n= iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&msgtx->txid,vpnstr,0,0,0,suppress_pubkeys)) > 0 ) + { + txbytes = malloc(n*2+1); + init_hexbytes_noT(txbytes,serialized,n); + } + free(serialized); + return(txbytes); +} + +char *bitcoin_json2hex(uint8_t isPoS,bits256 *txidp,cJSON *txjson,struct vin_info *V) +{ + int32_t txstart; uint8_t *serialized; struct iguana_msgtx msgtx; char *txbytes = 0; + if ( txjson == 0 ) + { + memset(txidp,0,sizeof(*txidp)); + return(0); + } + serialized = malloc(IGUANA_MAXPACKETSIZE*1.5); + *txidp = iguana_parsetxobj(isPoS,&txstart,serialized,IGUANA_MAXPACKETSIZE*1.5,&msgtx,txjson,V); + if ( msgtx.allocsize > 0 ) + { + txbytes = malloc(msgtx.allocsize*2 + 1); + init_hexbytes_noT(txbytes,&serialized[txstart],msgtx.allocsize); + } else printf("bitcoin_txtest: zero msgtx allocsize.(%s)\n",jprint(txjson,0)); + free(serialized); + return(txbytes); +} + +cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys) +{ + int32_t n; char vpnstr[64]; struct iguana_msgtx M; cJSON *txobj; + if ( serialized == 0 ) + return(0); + txobj = cJSON_CreateObject(); + if ( msgtx == 0 ) + msgtx = &M; + memset(msgtx,0,sizeof(M)); + vpnstr[0] = 0; + memset(txidp,0,sizeof(*txidp)); + if ( (n= iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,0,txobj,serialized,len,msgtx,txidp,vpnstr,extraspace,extralen,vins,suppress_pubkeys)) <= 0 ) + { + printf("errortxobj.(%s)\n",jprint(txobj,0)); + free_json(txobj); + txobj = cJSON_CreateObject(); + jaddstr(txobj,"error","couldnt decode transaction"); + } + //printf("msgtx.(%s)\n",jprint(txobj,0)); + if ( n != len ) + { + int32_t i; + for (i=0; i<=len; i++) + printf("%02x",serialized[i]); + printf(" data2json n.%d vs len.%d\n",n,len); + } + return(txobj); +} + +cJSON *bitcoin_hex2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extraspace,int32_t extralen,uint8_t *origserialized,cJSON *vins,int32_t suppress_pubkeys) +{ + int32_t len; uint8_t *serialized; cJSON *txobj; + if ( txbytes == 0 ) + return(0); + len = (int32_t)strlen(txbytes) >> 1; + if ( (serialized= origserialized) == 0 ) + serialized = calloc(1,len+4096); + decode_hex(serialized,len,txbytes); + txobj = bitcoin_data2json(taddr,pubtype,p2shtype,isPoS,height,txidp,msgtx,extraspace,extralen,serialized,len,vins,suppress_pubkeys); + if ( serialized != origserialized ) + free(serialized); + return(txobj); +} diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c new file mode 100644 index 000000000..a5fd82434 --- /dev/null +++ b/iguana/exchanges/LP_coins.c @@ -0,0 +1,381 @@ + +/****************************************************************************** + * 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_coins.c +// marketmaker +// + +char *portstrs[][3] = { { "BTC", "8332" }, { "KMD", "7771" } }; + +uint16_t LP_rpcport(char *symbol) +{ + int32_t i; + for (i=0; isymbol); + 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"); + if ( coin->isPoS != 0 ) + jaddstr(item,"type","PoS"); + jaddstr(item,"smartaddress",coin->smartaddr); + jaddstr(item,"rpc",coin->serverport); + jaddnum(item,"pubtype",coin->pubtype); + jaddnum(item,"p2shtype",coin->p2shtype); + jaddnum(item,"wiftype",coin->wiftype); + jaddnum(item,"txfee",coin->txfee); + return(item); +} + +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,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; + portable_mutex_lock(&LP_coinmutex); + HASH_FIND(hh,LP_coins,symbol,strlen(symbol),coin); + portable_mutex_unlock(&LP_coinmutex); + return(coin); +} + +struct iguana_info *LP_coinadd(struct iguana_info *cdata) +{ + struct iguana_info *coin = calloc(1,sizeof(*coin)); + //printf("%s: (%s) (%s)\n",symbol,cdata.serverport,cdata.userpass); + *coin = *cdata; + portable_mutex_init(&coin->txmutex); + portable_mutex_lock(&LP_coinmutex); + HASH_ADD_KEYPTR(hh,LP_coins,coin->symbol,strlen(coin->symbol),coin); + portable_mutex_unlock(&LP_coinmutex); + 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 wiftaddr,uint8_t taddr,uint16_t busport,char *confpath) +{ + char *name2; + memset(coin,0,sizeof(*coin)); + safecopy(coin->symbol,symbol,sizeof(coin->symbol)); + 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->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; + 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) +{ + struct iguana_info *coin; + if ( base != 0 && (coin= LP_coinsearch(base)) != 0 && coin->inactive != 0 ) + return(1); + else if ( rel != 0 && (coin= LP_coinsearch(rel)) != 0 && coin->inactive != 0 ) + return(1); + else return(0); +} + +struct iguana_info *LP_coinfind(char *symbol) +{ + 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 = LP_MIN_TXFEE; + estimatedrate = 20; + pubtype = 60; + p2shtype = 85; + wiftype = 188; + assetname = ""; + if ( strcmp(symbol,"BTC") == 0 ) + { + txfee = 0; + estimatedrate = 300; + pubtype = 0; + p2shtype = 5; + wiftype = 128; + name = "bitcoin"; + } + else if ( strcmp(symbol,"KMD") == 0 ) + name = "komodo"; + else return(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 ) + { + coin->inactive = isinactive * (uint32_t)time(NULL); + 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); + } + } + return(coin); +} + +// "coins":[{"coin":"", "rpcport":pppp}, {"coin":"LTC", "name":"litecoin", "rpcport":9332, "pubtype":48, "p2shtype":5, "wiftype":176, "txfee":100000 }] +// {"coin":"HUSH", "name":"hush", "rpcport":8822, "taddr":28, "pubtype":184, "p2shtype":189, "wiftype":128, "txfee":10000 } + +struct iguana_info *LP_coincreate(cJSON *item) +{ + struct iguana_info cdata,*coin=0; int32_t isPoS,longestchain = 1; uint16_t port; uint64_t txfee; double estimatedrate; uint8_t pubtype,p2shtype,wiftype; char *name=0,*symbol,*assetname=0; + 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"); + txfee = j64bits(item,"txfee"); + if ( (estimatedrate= jdouble(item,"estimatedrate")) == 0. ) + estimatedrate = 20; + 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,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 ) + { + if ( jobj(item,"active") != 0 ) + coin->inactive = !jint(item,"active"); + else + { + if ( IAMLP == 0 || assetname != name ) + coin->inactive = (uint32_t)time(NULL); + else coin->inactive = 0; + } + } else coin->inactive = 0; + } + if ( coin != 0 && coin->inactive != 0 ) + printf("LPnode.%d %s inactive.%u %p vs %p\n",IAMLP,coin->symbol,coin->inactive,assetname,name); + return(0); +} + diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c new file mode 100644 index 000000000..ad0a07be4 --- /dev/null +++ b/iguana/exchanges/LP_commands.c @@ -0,0 +1,431 @@ + +/****************************************************************************** + * 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_commands.c +// 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,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 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 ) + { + flag = 1; + if ( (pushport= juint(argjson,"push")) == 0 ) + pushport = argport + 1; + if ( (subport= juint(argjson,"sub")) == 0 ) + subport = argport + 2; + if ( (peer= LP_peerfind((uint32_t)calc_ipbits(ipaddr),argport)) != 0 ) + { + if ( 0 && (otherpeers= jint(argjson,"numpeers")) > peer->numpeers ) + peer->numpeers = otherpeers; + if ( 0 && (othernumutxos= jint(argjson,"numutxos")) > peer->numutxos ) + { + 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,jint(argjson,"numpeers"),jint(argjson,"numutxos"),juint(argjson,"session")); + } + } + if ( (method= jstr(argjson,"method")) == 0 ) + { + if ( flag == 0 || jobj(argjson,"result") != 0 ) + printf("stats_JSON no method: (%s) (%s:%u)\n",jprint(argjson,0),ipaddr,argport); + return(0); + } + /*if ( strcmp(method,"hello") == 0 ) + { + //printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport); + return(0); + } + else*/ if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 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,"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, 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\ +secretaddresses(passphrase, num=10, pubtype=60, taddr=0)\n\ +snapshot(coin, height)\n\ +snapshot_balance(coin, height, addresses[])\n\ +dividends(coin, height, )\n\ +\"}")); + + base = jstr(argjson,"base"); + rel = jstr(argjson,"rel"); + if ( USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 ) + { + if ( USERPASS_COUNTER == 0 ) + { + USERPASS_COUNTER = 1; + retjson = cJSON_CreateObject(); + jaddstr(retjson,"userpass",USERPASS); + 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()); + } + else if ( strcmp(method,"secretaddresses") == 0 ) + { + uint8_t taddr,pubtype; + pubtype = (jobj(argjson,"pubtype") == 0) ? 60 : juint(argjson,"pubtype"); + taddr = (jobj(argjson,"taddr") == 0) ? 0 : juint(argjson,"taddr"); + return(LP_secretaddresses(ctx,jstr(argjson,"passphrase"),juint(argjson,"num"),taddr,pubtype)); + } + if ( base != 0 && rel != 0 ) + { + double price,bid,ask; + 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(&changed,base,rel,price) < 0 ) + return(clonestr("{\"error\":\"couldnt set price\"}")); + //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 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"base",base); + jaddstr(retjson,"rel",rel); + jaddnum(retjson,"bid",bid); + jaddnum(retjson,"ask",ask); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"no price set\"}")); + } + else if ( strcmp(method,"ordermatch") == 0 ) + { + if ( price > SMALLVAL ) + 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 ) + { + struct LP_quoteinfo Q; + if ( price > SMALLVAL || jobj(argjson,"quote") != 0 ) + { + LP_quoteparse(&Q,jobj(argjson,"quote")); + 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 ) + { + 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\"}")); + } + } + else if ( rel != 0 && strcmp(method,"bestfit") == 0 ) + { + double relvolume; + if ( (relvolume= jdouble(argjson,"relvolume")) > SMALLVAL ) + return(LP_bestfit(rel,relvolume)); + else return(clonestr("{\"error\":\"no relvolume set\"}")); + } + else if ( (coin= jstr(argjson,"coin")) != 0 ) + { + if ( strcmp(method,"enable") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + ptr->inactive = 0; + 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(0),1)); + } + else if ( strcmp(method,"snapshot") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + return(jprint(LP_snapshot(ptr,juint(argjson,"height")),1)); + else return(clonestr("{\"error\":\"cant find coind\"}")); + } + else if ( strcmp(method,"dividends") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + return(LP_dividends(ptr,juint(argjson,"height"),argjson)); + else return(clonestr("{\"error\":\"cant find coind\"}")); + } + else if ( strcmp(method,"snapshot_balance") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + return(LP_snapshot_balance(ptr,juint(argjson,"height"),argjson)); + else return(clonestr("{\"error\":\"cant find coind\"}")); + } + if ( LP_isdisabled(coin,0) != 0 ) + return(clonestr("{\"error\":\"coin is disabled\"}")); + if ( strcmp(method,"inventory") == 0 ) + { + struct iguana_info *ptr; + if ( (ptr= LP_coinfind(coin)) != 0 ) + { + //privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,ptr,"",USERPASS_WIFSTR); + //LP_utxopurge(0); + 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); + jaddnum(retjson,"timestamp",time(NULL)); + jadd(retjson,"alice",LP_inventory(coin,0)); + jadd(retjson,"bob",LP_inventory(coin,1)); + 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; + if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) + return(basilisk_swapentry(requestid,quoteid)); + else return(basilisk_swaplist()); + } + else if ( strcmp(method,"myprices") == 0 ) + return(LP_myprices()); + else if ( strcmp(method,"trust") == 0 ) + return(LP_pubkey_trustset(jbits256(argjson,"pubkey"),jint(argjson,"trust"))); + } + 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 ( 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); + else if ( strcmp(method,"connected") == 0 ) + retstr = LP_connectedalice(argjson); + else if ( strcmp(method,"checktxid") == 0 ) + retstr = LP_spentcheck(argjson); + else if ( strcmp(method,"getcoins") == 0 ) + 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,"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(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); + else if ( strcmp(method,"forward") == 0 ) + return(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); + else if ( strcmp(method,"keepalive") == 0 ) + 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,"utxo") == 0 ) + { + if ( LP_utxoaddjson(1,LP_mypubsock,argjson) != 0 ) + 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 ) + { + 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,"psock") == 0 ) + { + if ( myipaddr == 0 || myipaddr[0] == 0 || strcmp(myipaddr,"127.0.0.1") == 0 ) + { + if ( LP_mypeer != 0 ) + myipaddr = LP_mypeer->ipaddr; + else printf("LP_psock dont have actual ipaddr?\n"); + } + 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,"psock") == 0 ) + { + //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); + } + return(0); +} diff --git a/iguana/exchanges/LP_forwarding.c b/iguana/exchanges/LP_forwarding.c new file mode 100644 index 000000000..749cf2f2e --- /dev/null +++ b/iguana/exchanges/LP_forwarding.c @@ -0,0 +1,351 @@ + +/****************************************************************************** + * 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_forwarding.c +// 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; + bits256 pubkey; + char pushaddr[64]; + int32_t pushsock; + uint32_t lasttime,hello; +} *LP_forwardinfos; +#define LP_KEEPALIVE (3600 * 24) + +struct LP_forwardinfo *LP_forwardfind(bits256 pubkey) +{ + struct LP_forwardinfo *ptr=0; + portable_mutex_lock(&LP_forwardmutex); + HASH_FIND(hh,LP_forwardinfos,&pubkey,sizeof(pubkey),ptr); + portable_mutex_unlock(&LP_forwardmutex); + if ( ptr != 0 && ptr->lasttime > time(NULL)-LP_KEEPALIVE ) + return(ptr); + else return(0); +} + +char *LP_lookup(bits256 pubkey) +{ + if ( bits256_nonz(pubkey) == 0 ) + return(clonestr("{\"result\":\"illegal pubkey\"}")); + if ( LP_forwardfind(pubkey) != 0 ) + return(clonestr("{\"result\":\"success\",\"forwarding\":1}")); + else return(clonestr("{\"result\":\"notfound\"}")); +} + +int32_t LP_hello(struct LP_forwardinfo *ptr) +{ + int32_t i,n=10; char msg[512]; struct nn_pollfd pfd; + if ( bits256_cmp(ptr->pubkey,LP_mypubkey) != 0 ) + { + pfd.fd = ptr->pushsock; + pfd.events = NN_POLLOUT; + for (i=0; i 0 ) + { + sprintf(msg,"{\"method\":\"hello\",\"from\":\"%s\"}",LP_mypeer != 0 ? LP_mypeer->ipaddr : ""); + //printf("HELLO sent.%d bytes to %s on i.%d\n",LP_send(ptr->pushsock,msg,0),ptr->pushaddr,i); + ptr->hello = (uint32_t)time(NULL); + return(i); + } + } + //printf("%d iterations on nn_poll and %s pushsock still not ready\n",i,ptr->pushaddr); + return(-1); + } + return(0); +} + +int32_t LP_hellos() +{ + struct LP_forwardinfo *ptr,*tmp; int32_t nonz = 0; + HASH_ITER(hh,LP_forwardinfos,ptr,tmp) + { + if ( ptr->hello == 0 && LP_hello(ptr) >= 0 ) + nonz++; + } + return(nonz); +} + +int32_t LP_pushsock_create(struct LP_forwardinfo *ptr,char *pushaddr) +{ + int32_t pushsock,timeout; + if ( (pushsock= nn_socket(AF_SP,LP_COMMAND_SENDSOCK)) < 0 ) + { + printf("LP_pushsock_create couldnt allocate socket for %s\n",pushaddr); + return(-1); + } + else if ( nn_connect(pushsock,pushaddr) < 0 ) + { + nn_close(pushsock); + printf("LP_pushsock_create couldnt connect to %s\n",pushaddr); + return(-1); + } + timeout = 1; + nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + if ( ptr != 0 ) + LP_hello(ptr); + return(pushsock); +} + +char *LP_register(bits256 pubkey,char *ipaddr,uint16_t port) +{ + struct LP_forwardinfo *ptr=0; int32_t pushsock; char pushaddr[64]; + if ( ipaddr == 0 || ipaddr[0] == 0 || is_ipaddr(ipaddr) == 0 || bits256_nonz(pubkey) == 0 ) + return(clonestr("{\"result\":\"illegal ipaddr or null pubkey\"}")); + nanomsg_transportname(0,pushaddr,ipaddr,port); + //char str[65]; printf("register.(%s) %s\n",pushaddr,bits256_str(str,pubkey)); + if ( (ptr= LP_forwardfind(pubkey)) != 0 ) + { + ptr->lasttime = (uint32_t)time(NULL); + if ( ptr->pushsock >= 0 ) + { + if ( strcmp(pushaddr,ptr->pushaddr) != 0 ) + { + nn_close(ptr->pushsock); + if ( LP_psockmark(ptr->pushaddr) < 0 ) + { + //printf("cant mark (%s)\n",ptr->pushaddr); + } + char str[65]; printf("%u recreate pushsock for %s <- %s %s\n",(uint32_t)time(NULL),ptr->pushaddr,pushaddr,bits256_str(str,pubkey)); + strcpy(ptr->pushaddr,pushaddr); + if ( (ptr->pushsock= LP_pushsock_create(ptr,pushaddr)) < 0 ) + return(clonestr("{\"result\":\"success\",\"status\":\"couldnt recreate pushsock\",\"registered\":0}")); + } //else printf("no need to create identical endpoint\n"); + } + return(clonestr("{\"result\":\"success\",\"status\":\"already registered\",\"registered\":1}")); + } + else if ( (pushsock= LP_pushsock_create(0,pushaddr)) < 0 ) + return(clonestr("{\"result\":\"success\",\"status\":\"couldnt create pushsock\"}")); + else + { + ptr = calloc(1,sizeof(*ptr)); + ptr->pubkey = pubkey; + strcpy(ptr->pushaddr,pushaddr); + ptr->pushsock = pushsock; + ptr->lasttime = (uint32_t)time(NULL); + portable_mutex_lock(&LP_forwardmutex); + HASH_ADD_KEYPTR(hh,LP_forwardinfos,&ptr->pubkey,sizeof(ptr->pubkey),ptr); + portable_mutex_unlock(&LP_forwardmutex); + //char str[65]; printf("registered (%s) -> (%s) pushsock.%d\n",bits256_str(str,pubkey),pushaddr,ptr->pushsock); + LP_hello(ptr); + return(LP_lookup(pubkey)); + } +} + +int32_t LP_forwarding_register(bits256 pubkey,char *publicaddr,uint16_t publicport,int32_t max) +{ + char *argstr,ipaddr[64]; cJSON *argjson; struct LP_peerinfo *peer,*tmp; int32_t j,n=0,arglen; + if ( publicaddr == 0 || publicaddr[0] == 0 || bits256_nonz(pubkey) == 0 ) + { + char str[65]; printf("LP_forwarding_register illegal publicaddr.(%s):%u or null pubkey (%s)\n",publicaddr,publicport,bits256_str(str,pubkey)); + return(0); + } + for (j=0; publicaddr[j]!=0; j++) + if ( publicaddr[j] >= '0' && publicaddr[j] <= '9' ) + break; + parse_ipaddr(ipaddr,publicaddr+j); + argjson = cJSON_CreateObject(); + jaddstr(argjson,"agent","stats"); + jaddstr(argjson,"method","register"); + jaddbits256(argjson,"client",pubkey); + jaddstr(argjson,"pushaddr",ipaddr); + jaddnum(argjson,"pushport",publicport); + argstr = jprint(argjson,1); + arglen = (int32_t)strlen(argstr) + 1; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( strcmp(LP_myipaddr,peer->ipaddr) == 0 ) + continue; + if ( peer->pushsock >= 0 ) + { + if ( LP_send(peer->pushsock,argstr,arglen,0) != arglen ) + { + 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); + } + free(argstr); + return(n); +} + +char *LP_registerall(int32_t numnodes) +{ + int32_t i,maxnodes,n=0; cJSON *retjson; + if ( numnodes < sizeof(default_LPnodes)/sizeof(*default_LPnodes) ) + numnodes = (int32_t)(sizeof(default_LPnodes)/sizeof(*default_LPnodes)); + if ( (maxnodes= LP_numpeers()) < numnodes ) + numnodes = maxnodes; + for (i=0; i= numnodes ) + break; + retjson = cJSON_CreateObject(); + if ( i == numnodes ) + jaddstr(retjson,"error","not enough nodes"); + jaddnum(retjson,"numnodes",numnodes); + jaddnum(retjson,"registered",n); + jaddnum(retjson,"iters",i); + return(jprint(retjson,1)); +} + +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; + if ( hexstr == 0 || hexstr[0] == 0 ) + return(clonestr("{\"result\":\"nohex\"}")); + datalen = (int32_t)strlen(hexstr) >> 1; + data = malloc(datalen); + decode_hex(data,datalen,hexstr); + if ( (argjson= cJSON_Parse((char *)data)) != 0 ) + reqjson = LP_dereference(argjson,"forward"); + if ( bits256_nonz(pubkey) == 0 || bits256_cmp(pubkey,LP_mypubkey) == 0 ) + { + 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:""); + if ( pubsock >= 0 ) + { + msg = jprint(reqjson,0); + LP_send(pubsock,msg,(int32_t)strlen(msg)+1,0); + } + } else printf("LP_forwardhex couldnt parse (%s)\n",(char *)data); + } + else if ( (ptr= LP_forwardfind(pubkey)) != 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 >= 0 ) + { + jaddstr(retjson,"result","success"); + 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 + { + jaddstr(retjson,"error","send error"); + jaddnum(retjson,"sentbytes",sentbytes); + jaddnum(retjson,"datalen",datalen); + jaddnum(retjson,"hello",ptr->hello); + retstr = jprint(retjson,1); + } + } + else + { + char str[65]; printf("couldnt find %s to forward to\n",bits256_str(str,pubkey)); + if ( pubsock >= 0 ) + { + msg = jprint(reqjson,0); + LP_send(pubsock,msg,(int32_t)strlen(msg)+1,1); + } + retstr = clonestr("{\"result\":\"notfound\"}"); + } + free(data); + if ( reqjson != 0 ) + free_json(reqjson); + if ( argjson != 0 ) + free_json(argjson); + return(retstr); +} + +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 *reqjson,*argjson; + if ( jsonstr == 0 || jsonstr[0] == 0 ) + return(-1); + len = (int32_t)strlen(jsonstr) + 1; + if ( bits256_nonz(pubkey) != 0 ) + { + if ( bits256_cmp(pubkey,LP_mypubkey) == 0 ) + { + printf("GOT FORWARDED.(%s)\n",myipaddr); + if ( (argjson= cJSON_Parse(jsonstr)) != 0 ) + { + if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,0,0)) != 0 ) + free(retstr); + free_json(argjson); + } + if ( freeflag != 0 ) + free(jsonstr); + return(1); + } + 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,freeflag) == len ) + return(1); + } + } + hexstr = malloc(len*2 + 1); + init_hexbytes_noT(hexstr,(uint8_t *)jsonstr,len); + if ( freeflag != 0 ) + free(jsonstr); + reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","forwardhex"); + jaddstr(reqjson,"hex",hexstr); + free(hexstr); + msg = jprint(reqjson,1); + mlen = (int32_t)strlen(msg) + 1; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + //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 ) + free(msg); + if ( n == 0 ) + return(-1); + else return(n-1); +} + + +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 new file mode 100644 index 000000000..e630c13ea --- /dev/null +++ b/iguana/exchanges/LP_include.h @@ -0,0 +1,289 @@ + +/****************************************************************************** + * 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_include.h +// marketmaker +// + +#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 100 +#define MAX_PSOCK_PORT 60000 +#define MIN_PSOCK_PORT 10000 +#define LP_MEMPOOL_TIMEINCR 10 +#define LP_GETINFO_INCR 30 +#define LP_ORDERBOOK_DURATION 3600 + +#define LP_HTTP_TIMEOUT 2 // 1 is too small due to edge cases of time(NULL) +#define LP_MAXPEER_ERRORS 3 +#define LP_MINPEER_GOOD 20 +#define LP_PEERGOOD_ERRORDECAY 0.9 + +#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)) + +#define INSTANTDEX_DECKSIZE 1000 +#define INSTANTDEX_LOCKTIME (3600*2 + 300*2) +#define INSTANTDEX_INSURANCEDIV 777 +#define INSTANTDEX_PUBKEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06" +#define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f" +#define JUMBLR_RMD160 "5177f8b427e5f47342a4b8ab5dac770815d4389e" +#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" +#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" +#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" + +//#define BASILISK_DISABLEWAITTX +//#define BASILISK_DISABLESENDTX + +#define LP_PROPAGATION_SLACK 100 // txid ordering is not enforced, so getting extra recent txid +#define LP_RESERVETIME 60 +#define LP_AVETXSIZE 256 +#define LP_CACHEDURATION 60 +#define BASILISK_DEFAULT_NUMCONFIRMS 1 +#define DEX_SLEEP 3 +#define BASILISK_KEYSIZE ((int32_t)(2*sizeof(bits256)+sizeof(uint32_t)*2)) + +extern char GLOBAL_DBDIR[],USERPASS[],USERPASS_WIFSTR[]; +extern int32_t IAMLP,USERPASS_COUNTER; + +struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; }; + +struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; }; + +struct iguana_msgtx +{ + uint32_t version,tx_in,tx_out,lock_time; + struct iguana_msgvin *vins; + struct iguana_msgvout *vouts; + bits256 txid; + int32_t allocsize,timestamp,numinputs,numoutputs; + int64_t inputsum,outputsum,txfee; + uint8_t *serialized; +}; + +struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; + +struct vin_info +{ + struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid; + int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,hashtype,userdatalen,suppress_pubkeys,ignore_cltverr; + uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65]; + uint8_t rmd160[20],spendscript[10000],p2shscript[10000],userdata[10000]; +}; + +struct basilisk_swapmessage +{ + bits256 srchash,desthash; + uint32_t crc32,msgbits,quoteid,datalen; + uint8_t *data; +}; + +struct basilisk_swap; + +struct basilisk_rawtxinfo +{ + char destaddr[64],coinstr[16]; + bits256 txid,signedtxid,actualtxid; + uint64_t amount,change,inputsum; + int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys; + uint32_t locktime,crcs[2]; + uint8_t addrtype,pubkey33[33],rmd160[20]; +}; + +struct basilisk_request +{ + uint32_t requestid,timestamp,quoteid,quotetime; // 0 to 15 + uint64_t srcamount,unused; // 16 to 31 + bits256 srchash; // 32 to 63 + bits256 desthash; + char src[8],dest[8]; + uint64_t destamount; + int32_t optionhours,DEXselector; +}; + +struct basilisk_rawtx +{ + char name[32]; + struct iguana_msgtx msgtx; + struct basilisk_rawtxinfo I; + struct iguana_info *coin; + char vinstr[8192],p2shaddr[64]; + cJSON *vins; + bits256 utxotxid; int32_t utxovout; + uint8_t txbytes[16384],spendscript[512],redeemscript[1024],extraspace[4096],pubkey33[33]; +}; + +struct basilisk_swapinfo +{ + struct basilisk_request req; + char bobstr[64],alicestr[64]; + 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,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]; + int32_t choosei,otherchoosei,cutverified,otherverifiedcut,numpubs,havestate,otherhavestate,pad2; + uint8_t secretAm[20],secretBn[20]; + uint8_t secretAm256[32],secretBn256[32]; + uint8_t userdata_aliceclaim[256],userdata_aliceclaimlen; + uint8_t userdata_alicereclaim[256],userdata_alicereclaimlen; + uint8_t userdata_alicespend[256],userdata_alicespendlen; + uint8_t userdata_bobspend[256],userdata_bobspendlen; + uint8_t userdata_bobreclaim[256],userdata_bobreclaimlen; + uint8_t userdata_bobrefund[256],userdata_bobrefundlen; +}; + +struct LP_outpoint { bits256 spendtxid; uint64_t value,interest; int32_t spendvini,spendheight; char coinaddr[40]; }; + +struct LP_transaction +{ + UT_hash_handle hh; + bits256 txid; int32_t height,numvouts,numvins; uint32_t timestamp; + struct LP_outpoint outpoints[]; +}; + +struct LP_address +{ + UT_hash_handle hh; + int64_t balance; + char coinaddr[40]; +}; + +struct iguana_info +{ + UT_hash_handle hh; + portable_mutex_t txmutex; struct LP_transaction *transactions; struct LP_address *addresses; + 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 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; }; + +struct LP_utxoinfo +{ + UT_hash_handle hh,hh2; + bits256 pubkey; + struct _LP_utxoinfo payment,deposit,fee; + struct LP_utxostats T; + struct LP_utxoswap S; + //struct LP_utxonetwork N; + int32_t iambob,iamlp; + uint8_t key[sizeof(bits256) + sizeof(int32_t)]; + uint8_t key2[sizeof(bits256) + sizeof(int32_t)]; + char coin[16],coinaddr[64],spendscript[256],gui[16]; +}; + +struct LP_peerinfo +{ + UT_hash_handle hh; + uint64_t ip_port; + uint32_t ipbits,errortime,errors,numpeers,numutxos,lasttime,connected,lastutxos,lastpeers,diduquery,good,sessionid; + int32_t pushsock,subsock; + uint16_t port; + char ipaddr[64]; +}; + +struct LP_quoteinfo +{ + struct basilisk_request R; + bits256 srchash,desthash,txid,txid2,desttxid,feetxid,privkey; + uint64_t satoshis,txfee,destsatoshis,desttxfee; + uint32_t timestamp,quotetime; int32_t vout,vout2,destvout,feevout,pair; + char srccoin[16],coinaddr[64],destcoin[16],destaddr[64]; +}; + +struct LP_endpoint { int32_t pair; char ipaddr[64]; uint16_t port; }; + +struct basilisk_swap +{ + void *ctx; struct iguana_info bobcoin,alicecoin; struct LP_utxoinfo *utxo; + struct LP_endpoint N; + void (*balancingtrade)(struct basilisk_swap *swap,int32_t iambob); + int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; uint32_t lasttime,aborted; + FILE *fp; + bits256 persistent_privkey,persistent_pubkey; + struct basilisk_swapinfo I; + struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim; + bits256 privkeys[INSTANTDEX_DECKSIZE]; + struct basilisk_swapmessage *messages; int32_t nummessages,sentflag; + char Bdeposit[64],Bpayment[64]; + uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; + uint8_t persistent_pubkey33[33],changermd160[20],pad[15],verifybuf[65536]; + +}; + +void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx); +uint32_t basilisk_requestid(struct basilisk_request *rp); +uint32_t basilisk_quoteid(struct basilisk_request *rp); +struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp); +char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params); +uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend); +//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,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); +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); +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 new file mode 100644 index 000000000..fffcf4d93 --- /dev/null +++ b/iguana/exchanges/LP_nativeDEX.c @@ -0,0 +1,696 @@ + +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ +//alice only coins GAME UNO BTM ANC: GAME BTCD PPC RDD XZC POT EAC FTC BASH SPR WDC UNO XPM XCN BELA CHC DIME MEC NAUT MED AUR MAX DGC RIC EB3 DOT BTM GEO ANC CANN ICASH WBB SRC PTC ADZ TIPS EQT START EFL FST FJC NYC GCN + +// +// LP_nativeDEX.c +// marketmaker +// +// new features: +// bittrex balancing +// detect port conflicts on enable +// stats +// 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,LP_messagemutex,LP_portfoliomutex; +int32_t LP_canbind; + +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" }; +char USERPASS[65],USERPASS_WIFSTR[64],LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" }; +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; +uint16_t LP_fixed_pairport,LP_publicport; +int32_t LP_mybussock = -1; +int32_t LP_mypubsock = -1; +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_mypub25519,LP_mypriv25519; + +// stubs + +void tradebot_swap_balancingtrade(struct basilisk_swap *swap,int32_t iambob) +{ + +} + +void tradebot_pendingadd(cJSON *tradejson,char *base,double basevolume,char *rel,double relvolume) +{ + // add to trades +} + +char *LP_getdatadir() +{ + return(USERHOME); +} + +char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_t skip) +{ + return(0); +} + +#include "LP_secp.c" +#include "LP_bitcoin.c" +#include "LP_coins.c" +#include "LP_rpc.c" +#include "LP_prices.c" +#include "LP_scan.c" +#include "LP_transaction.c" +#include "LP_remember.c" +#include "LP_swap.c" +#include "LP_peers.c" +#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) +{ + char *retstr=0; + if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 ) + return(0); + if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 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); + } + } + return(retstr); +} + +char *LP_decrypt(uint8_t *ptr,int32_t *recvlenp) +{ + 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) ) + { + if ( (jsonstr= (char *)_SuperNET_decipher(nonce,cipher,decoded,cipherlen,GENESIS_PUBKEY,LP_mypriv25519)) != 0 ) + { + recvlen = (cipherlen - crypto_box_ZEROBYTES); + if ( strlen(jsonstr)+1 != recvlen ) + { + printf("unexpected len %d vs recvlen.%d\n",(int32_t)strlen(jsonstr)+1,recvlen); + jsonstr = 0; + } else printf("decrypted (%s)\n",jsonstr); + } + } 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 ) + { + 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 ) + { + 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 ) + { + method2 = jstr(argjson,"method2"); + if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"encrypted") == 0 ||(method2 != 0 && strcmp(method2,"encrypted") == 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); + } + if ( jsonstr != 0 && argjson != 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); + } + } + } //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); +} + +void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo) +{ + 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 ) + { + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + utxo->T.lastspentcheck = now; + if ( LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) == 0 ) + { + printf("txid.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,dstr(utxo->payment.value)); + LP_spentnotify(utxo,0); + } + else if ( LP_txvalue(0,utxo->coin,u.txid,u.vout) == 0 ) + { + printf("txid2.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,u.txid),u.vout,dstr(u.value)); + LP_spentnotify(utxo,1); + } + } +} + +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,int32_t interval,int32_t maxentries) +{ + int32_t lastn,n = -1; + if ( peer->lastutxos < now-interval ) + { + //lastn = peer->numutxos - mypeer->numutxos + LP_PROPAGATION_SLACK; + //if ( lastn < LP_PROPAGATION_SLACK * 2 ) + lastn = LP_PROPAGATION_SLACK * 2; + if ( mypeer == 0 || strcmp(peer->ipaddr,mypeer->ipaddr) != 0 ) + { + 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,maxentries); + } + } //else printf("LP_peer_utxosquery skip.(%s) %u\n",peer->ipaddr,peer->lastutxos); + return(n); +} + +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,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"; + if ( mypeer == 0 ) + 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--; + 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); + peer->lastpeers = now; + //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); + 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,60,100); + } + LP_peer_pricesquery(peer->ipaddr,peer->port); + peer->diduquery = now; + } + if ( peer->numutxos > mostutxos ) + { + mostutxos = peer->numutxos; + mostpeer = peer; + } + } + //printf("numutxos vs mine.%d\n",LP_mypeer != 0 ? LP_mypeer->numutxos : -1); + if ( LP_mypeer != 0 && mostpeer != 0 && ((LP_mypeer->numutxos < mostutxos && time(NULL) > lastresync+10) || time(NULL) > lastresync+60) ) + { + //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); + } + HASH_ITER(hh,LP_utxoinfos[1],utxo,utmp) + { + 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); + } + } + } + HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht + { + cJSON *obj; int32_t height; bits256 zero; + //printf("%s ref.%d scan.%d to %d, longest.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); + if ( coin->inactive != 0 ) + continue; + memset(zero.bytes,0,sizeof(zero)); + if ( time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR ) + { + if ( (obj= LP_getinfo(coin->symbol)) != 0 ) + { + if ( (height= jint(obj,"blocks")) > coin->longestchain ) + { + coin->longestchain = height; + if ( coin->firstrefht != 0 ) + printf(">>>>>>>>>> set %s longestchain %d (ref.%d [%d, %d])\n",coin->symbol,height,coin->firstrefht,coin->firstscanht,coin->lastscanht); + } else LP_mempoolscan(coin->symbol,zero); + free_json(obj); + } else printf("error getting info.%s\n",coin->symbol); + coin->lastgetinfo = (uint32_t)time(NULL); + } + if ( coin->firstrefht == 0 ) + continue; + else if ( coin->firstscanht == 0 ) + coin->lastscanht = coin->firstscanht = coin->firstrefht; + else if ( coin->firstrefht < coin->firstscanht ) + { + printf("detected %s firstrefht.%d < firstscanht.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht); + coin->lastscanht = coin->firstscanht = coin->firstrefht; + } + if ( coin->lastscanht == coin->longestchain+1 ) + continue; + else if ( coin->lastscanht > coin->longestchain+1 ) + { + printf("detected chain rewind lastscanht.%d vs longestchain.%d, first.%d ref.%d\n",coin->lastscanht,coin->longestchain,coin->firstscanht,coin->firstrefht); + LP_undospends(coin,coin->longestchain-1); + LP_mempoolscan(coin->symbol,zero); + coin->lastscanht = coin->longestchain - 1; + if ( coin->firstscanht < coin->lastscanht ) + 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); + if ( LP_blockinit(coin,coin->lastscanht) < 0 ) + { + printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht); + continue; + } + coin->lastscanht++; + break; + } + if ( (counter % 6000) == 60 ) + { + if ( (retstr= basilisk_swapentry(0,0)) != 0 ) + { + //printf("SWAPS.(%s)\n",retstr); + free(retstr); + } + } + counter++; + return(nonz); +} + +void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins,char *passphrase) +{ + int32_t i,n; cJSON *item; + for (i=0; i 0 ) + { + for (i=0; i 25 ) + // continue; + LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,mypeer->ipaddr,myport); + } + } else LP_peersquery(mypeer,pubsock,seednode,myport,mypeer->ipaddr,myport); + } + else + { + if ( myipaddr == 0 ) + { + printf("couldnt get myipaddr\n"); + exit(-1); + } + if ( seednode == 0 || seednode[0] == 0 ) + { + OS_randombytes((void *)&r,sizeof(r)); + for (j=0; j>>>>>>>>>> set LP_canbind.%d\n",LP_canbind); + } + if ( LP_canbind > 1000 && LP_canbind < 65536 ) + LP_fixed_pairport = LP_canbind; + if ( LP_canbind != 0 ) + LP_canbind = 1; + srand((int32_t)n); + if ( userhome != 0 && userhome[0] != 0 ) + { + safecopy(USERHOME,userhome,sizeof(USERHOME)); +#ifdef __APPLE__ + strcat(USERHOME,"/Library/Application Support"); +#endif + } + portable_mutex_init(&LP_peermutex); + portable_mutex_init(&LP_utxomutex); + portable_mutex_init(&LP_UTXOmutex); + portable_mutex_init(&LP_commandmutex); + portable_mutex_init(&LP_swaplistmutex); + portable_mutex_init(&LP_cachemutex); + portable_mutex_init(&LP_networkmutex); + portable_mutex_init(&LP_forwardmutex); + portable_mutex_init(&LP_psockmutex); + portable_mutex_init(&LP_coinmutex); + portable_mutex_init(&LP_pubkeymutex); + portable_mutex_init(&LP_messagemutex); + portable_mutex_init(&LP_portfoliomutex); + LP_sessionid = (uint32_t)time(NULL); + printf("getting myipaddr sessionid.%u\n",LP_sessionid); + + #ifdef _WIN32 + if ( system("curl.exe -s4 checkip.amazonaws.com > ~\Temp") == 0 ) + { + if ( (myipaddr= OS_filestr(&filesize,"~\Temp")) != 0 && myipaddr[0] != 0 ) + { + n = strlen(myipaddr); + if ( myipaddr[n-1] == '\n' ) + myipaddr[--n] = 0; + strcpy(LP_myipaddr,myipaddr); + } else printf("error getting myipaddr\n"); + } else printf("error issuing curl\n"); + #else + if ( system("curl -s4 checkip.amazonaws.com > /tmp/myipaddr") == 0 ) + { + if ( (myipaddr= OS_filestr(&filesize,"/tmp/myipaddr")) != 0 && myipaddr[0] != 0 ) + { + n = strlen(myipaddr); + if ( myipaddr[n-1] == '\n' ) + myipaddr[--n] = 0; + strcpy(LP_myipaddr,myipaddr); + } else printf("error getting myipaddr\n"); + } else printf("error issuing curl\n"); + #endif + if ( IAMLP != 0 ) + { + pubsock = -1; + nanomsg_transportname(0,subaddr,myipaddr,mypubport); + nanomsg_transportname(1,bindaddr,myipaddr,mypubport); + if ( (pubsock= nn_socket(AF_SP,NN_PUB)) >= 0 ) + { + if ( nn_bind(pubsock,bindaddr) >= 0 ) + { + timeout = 10; + nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + } + else + { + printf("error binding to (%s).%d\n",subaddr,pubsock); + if ( pubsock >= 0 ) + nn_close(pubsock), pubsock = -1; + } + } else printf("error getting pubsock %d\n",pubsock); + printf(">>>>>>>>> myipaddr.%s (%s) pullsock.%d\n",myipaddr,subaddr,pubsock); + LP_mypubsock = pubsock; + } + 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_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 ) + { + printf("error launching LP_psockloop for (%s)\n",myipaddr); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",myport); + exit(-1); + } + 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,myport,passphrase) == 0 ) + usleep(1000000 / MAINLOOP_PERSEC); + } +} diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c new file mode 100644 index 000000000..aadc2f485 --- /dev/null +++ b/iguana/exchanges/LP_network.c @@ -0,0 +1,720 @@ + +/****************************************************************************** + * 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_network.c +// marketmaker +// + +struct psock +{ + uint32_t lasttime,lastping,errors; + int32_t publicsock,sendsock,ispaired; + uint16_t publicport,sendport; + char sendaddr[128],publicaddr[128]; +} *PSOCKS; + +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); // ws is worse + return(str); +} + +int32_t _LP_send(int32_t sock,void *msg,int32_t sendlen,int32_t freeflag) +{ + int32_t sentbytes; + if ( sock < 0 ) + { + printf("LP_send.(%s) to illegal socket\n",(char *)msg); + if ( freeflag != 0 ) + free(msg); + return(-1); + } + 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 ) + { + 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); + } + } + 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; + buf = malloc(datalen + sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2); + for (i=0; i<32; i++) + buf[offset++] = swap->I.myhash.bytes[i]; + for (i=0; i<32; i++) + buf[offset++] = swap->I.otherhash.bytes[i]; + offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); + offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits); + if ( datalen > 0 ) + memcpy(&buf[offset],data,datalen), offset += datalen; + if ( (sentbytes= nn_send(pairsock,buf,offset,0)) != offset ) + { + printf("sentbytes.%d vs offset.%d\n",sentbytes,offset); + if ( sentbytes < 0 ) + { + } + } + //printf("sent %d bytes\n",sentbytes); + //else printf("send.[%d] %x offset.%d datalen.%d [%llx]\n",sentbytes,msgbits,offset,datalen,*(long long *)data); + free(buf); + return(nextbits); +} + +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,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); + if ( buf != 0 && ptr != 0 && sendsock >= 0 ) + { + if ( size > 0 ) + { + 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 ) + nn_freemsg(buf); + buf = 0; + size = 0; + ptr = 0; + sendsock = -1; + } + } + } + else if ( Numpsocks > 0 ) + { + if ( pfds == 0 ) + pfds = calloc(MAX_PSOCK_PORT,sizeof(*pfds)); + portable_mutex_lock(&LP_psockmutex); + memset(pfds,0,sizeof(*pfds) * ((Numpsocks*2 <= MAX_PSOCK_PORT) ? Numpsocks*2 : MAX_PSOCK_PORT)); + for (iter=0; iter<2; iter++) + { + for (i=n=0; ipublicsock; + pfds[n].events = POLLIN; + } + else + { + if ( pfds[n].fd != ptr->publicsock ) + { + printf("unexpected fd.%d mismatched publicsock.%d\n",pfds[n].fd,ptr->publicsock); + break; + } + else if ( (pfds[n].revents & POLLIN) != 0 ) + { + printf("publicsock.%d %s has pollin\n",ptr->publicsock,ptr->publicaddr); + if ( (size= nn_recv(ptr->publicsock,&buf,NN_MSG,0)) > 0 ) + { + ptr->lasttime = now; + sendsock = ptr->sendsock; + break; + } + } + } + n++; + if ( iter == 0 ) + { + pfds[n].fd = ptr->sendsock; + pfds[n].events = POLLIN; + } + else + { + if ( pfds[n].fd != ptr->sendsock ) + { + printf("unexpected fd.%d mismatched sendsock.%d\n",pfds[n].fd,ptr->sendsock); + break; + } + else if ( (pfds[n].revents & POLLIN) != 0 ) + { + if ( (size= nn_recv(ptr->sendsock,&buf,NN_MSG,0)) > 0 ) + { + //printf("%s paired has pollin (%s)\n",ptr->sendaddr,(char *)buf); + ptr->lasttime = now; + if ( ptr->ispaired != 0 ) + { + sendsock = ptr->publicsock; + break; + } + else + { + nn_freemsg(buf); + buf = 0; + size = 0; + } + } + } + } + n++; + } + if ( iter == 0 ) + { + if ( (retval= nn_poll(pfds,n,1)) <= 0 ) + { + if ( retval != 0 ) + printf("nn_poll retval.%d\n",retval); + break; + } else printf("num pfds.%d retval.%d\n",n,retval); + } + } + //free(pfds); + //printf("sendsock.%d Numpsocks.%d\n",sendsock,Numpsocks); + if ( sendsock < 0 ) + { + for (i=nonz=0; i ptr->lasttime+PSOCK_KEEPALIVE ) + { + printf("PSOCKS[%d] of %d (%u %u) lag.%d IDLETIMEOUT\n",i,Numpsocks,ptr->publicport,ptr->sendport,now - ptr->lasttime); + if ( ptr->publicsock >= 0 ) + nn_close(ptr->publicsock); + if ( ptr->sendsock >= 0 ) + nn_close(ptr->sendsock); + //portable_mutex_lock(&LP_psockmutex); + if ( Numpsocks > 1 ) + { + PSOCKS[i] = PSOCKS[--Numpsocks]; + memset(&PSOCKS[Numpsocks],0,sizeof(*ptr)); + } else Numpsocks = 0; + //portable_mutex_unlock(&LP_psockmutex); + break; + } + else if ( now > ptr->lastping+PSOCK_KEEPALIVE/2 && ptr->errors < 3 ) + { + ptr->lastping = now; + 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; + } + } + } + if ( nonz == 0 && i == Numpsocks ) + usleep(100000); + } + portable_mutex_unlock(&LP_psockmutex); + } else usleep(100000); + } +} + +void LP_psockadd(int32_t ispaired,int32_t publicsock,uint16_t recvport,int32_t sendsock,uint16_t sendport,char *subaddr,char *publicaddr) +{ + struct psock *ptr; + portable_mutex_lock(&LP_psockmutex); + PSOCKS = realloc(PSOCKS,sizeof(*PSOCKS) * (Numpsocks + 1)); + ptr = &PSOCKS[Numpsocks++]; + ptr->ispaired = ispaired; + ptr->publicsock = publicsock; + ptr->publicport = recvport; + ptr->sendsock = sendsock; + ptr->sendport = sendport; + safecopy(ptr->sendaddr,subaddr,sizeof(ptr->sendaddr)); + safecopy(ptr->publicaddr,publicaddr,sizeof(ptr->publicaddr)); + ptr->lasttime = (uint32_t)time(NULL); + portable_mutex_unlock(&LP_psockmutex); +} + +int32_t LP_psockmark(char *publicaddr) +{ + int32_t i,retval = -1; struct psock *ptr; + portable_mutex_lock(&LP_psockmutex); + for (i=0; ipublicaddr) == 0 ) + { + printf("mark PSOCKS[%d] %s for deletion\n",i,publicaddr); + ptr->lasttime = 0; + retval = i; + break; + } + } + portable_mutex_unlock(&LP_psockmutex); + return(retval); +} + +char *LP_psock(char *myipaddr,int32_t ispaired) +{ + 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++; + for (i=0; i= 0 && (pubsock= nn_socket(AF_SP,ispaired!=0?NN_PAIR:NN_PAIR)) >= 0 ) + { + if ( nn_bind(pullsock,pushaddr) >= 0 && nn_bind(pubsock,subaddr) >= 0 ) + { + timeout = 1; + nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + 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)); + } + //if ( ispaired != 0 ) + { + nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + } + nanomsg_transportname(0,pushaddr,myipaddr,publicport); + nanomsg_transportname(0,subaddr,myipaddr,subport); + LP_psockadd(ispaired,pullsock,publicport,pubsock,subport,subaddr,pushaddr); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"LPipaddr",myipaddr); + jaddstr(retjson,"connectaddr",subaddr); + jaddnum(retjson,"connectport",subport); + jaddnum(retjson,"ispaired",ispaired); + jaddstr(retjson,"publicaddr",pushaddr); + jaddnum(retjson,"publicport",publicport); + printf("i.%d publicaddr.(%s) for subaddr.(%s), pullsock.%d pubsock.%d\n",i,pushaddr,subaddr,pullsock,pubsock); + break; + } else printf("bind error on %s or %s\n",pushaddr,subaddr); + if ( pullsock >= 0 ) + nn_close(pullsock); + if ( pubsock >= 0 ) + nn_close(pubsock); + } + } + if ( Psockport > MAX_PSOCK_PORT ) + Psockport = MIN_PSOCK_PORT; + if ( i == maxiters ) + jaddstr(retjson,"error","cant find psock ports"); + return(jprint(retjson,1)); +} + +/* + LP_pushaddr_get makes transparent the fact that most nodes cannot bind()! + + The idea is to create an LP node NN_PAIR sock that the LP node binds to and client node connects to. Additionally, the LP node creates an NN_PULL that other nodes can NN_PUSH to and returns this address in pushaddr/retval for the client node to register with. The desired result is that other than the initial LP node, all the other nodes do a normal NN_PUSH, requiring no change to the NN_PUSH/NN_PULL logic. Of course, the initial LP node needs to autoforward all packets from the public NN_PULL to the NN_PUB + + similar to LP_pushaddr_get, create an NN_PAIR for DEX atomic data, can be assumed to have a max lifetime of 2*INSTANTDEX_LOCKTIME + + 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); +} + +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 ) + { + 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); + } + 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(publicport); +} + +int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char *myipaddr,uint16_t mypullport,int32_t ispaired) +{ + int32_t nntype,pullsock,timeout; char bindaddr[128],connectaddr[128]; + *mypullportp = mypullport; + if ( ispaired == 0 ) + { + if ( LP_canbind != 0 ) + nntype = LP_COMMAND_RECVSOCK; + else nntype = NN_PAIR;//NN_SUB; + } else nntype = NN_PAIR; + if ( LP_canbind != 0 ) + { + nanomsg_transportname(0,publicaddr,myipaddr,mypullport); + nanomsg_transportname(1,bindaddr,myipaddr,mypullport); + } + 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 ) + break; + sleep(10); + printf("try to get publicaddr again\n"); + } + } + while ( 1 ) + { + if ( (pullsock= nn_socket(AF_SP,nntype)) >= 0 ) + { + if ( LP_canbind == 0 ) + { + if ( nn_connect(pullsock,connectaddr) < 0 ) + { + printf("bind to %s error for %s: %s\n",connectaddr,publicaddr,nn_strerror(nn_errno())); + exit(-1); + } else printf("nntype.%d NN_PAIR.%d connect to %s connectsock.%d\n",nntype,NN_PAIR,connectaddr,pullsock); + } + else + { + if ( nn_bind(pullsock,bindaddr) < 0 ) + { + printf("bind to %s error for %s: %s\n",bindaddr,publicaddr,nn_strerror(nn_errno())); + exit(-1); + } + } + timeout = 1; + nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + 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); + break; + if ( pullsock >= 0 ) + nn_close(pullsock); + } + return(pullsock); +} diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c new file mode 100644 index 000000000..3e3edf622 --- /dev/null +++ b/iguana/exchanges/LP_ordermatch.c @@ -0,0 +1,814 @@ + +/****************************************************************************** + * 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_ordermatch.c +// 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) +{ + struct basilisk_request R; + memset(rp,0,sizeof(*rp)); + rp->srchash = srchash; + rp->srcamount = srcsatoshis; + rp->timestamp = timestamp; + rp->DEXselector = DEXselector; + safecopy(rp->src,src,sizeof(rp->src)); + safecopy(rp->dest,dest,sizeof(rp->dest)); + R = *rp; + rp->requestid = basilisk_requestid(rp); + rp->quotetime = quotetime; + rp->desthash = desthash; + rp->destamount = destsatoshis; + rp->quoteid = basilisk_quoteid(rp); + printf("r.%u %u, q.%u %u: %s %.8f -> %s %.8f\n",rp->timestamp,rp->requestid,rp->quotetime,rp->quoteid,rp->src,dstr(rp->srcamount),rp->dest,dstr(rp->destamount)); + return(rp); +} + +cJSON *LP_quotejson(struct LP_quoteinfo *qp) +{ + double price; cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"base",qp->srccoin); + jaddstr(retjson,"rel",qp->destcoin); + if ( qp->coinaddr[0] != 0 ) + jaddstr(retjson,"address",qp->coinaddr); + if ( qp->timestamp != 0 ) + jaddnum(retjson,"timestamp",qp->timestamp); + if ( bits256_nonz(qp->txid) != 0 ) + { + jaddbits256(retjson,"txid",qp->txid); + jaddnum(retjson,"vout",qp->vout); + } + if ( bits256_nonz(qp->srchash) != 0 ) + jaddbits256(retjson,"srchash",qp->srchash); + if ( qp->txfee != 0 ) + jadd64bits(retjson,"txfee",qp->txfee); + if ( qp->quotetime != 0 ) + jaddnum(retjson,"quotetime",qp->quotetime); + if ( qp->satoshis != 0 ) + jadd64bits(retjson,"satoshis",qp->satoshis); + if ( bits256_nonz(qp->desthash) != 0 ) + jaddbits256(retjson,"desthash",qp->desthash); + if ( bits256_nonz(qp->txid2) != 0 ) + { + jaddbits256(retjson,"txid2",qp->txid2); + jaddnum(retjson,"vout2",qp->vout2); + } + if ( bits256_nonz(qp->desttxid) != 0 ) + { + if ( qp->destaddr[0] != 0 ) + jaddstr(retjson,"destaddr",qp->destaddr); + jaddbits256(retjson,"desttxid",qp->desttxid); + jaddnum(retjson,"destvout",qp->destvout); + } + if ( bits256_nonz(qp->feetxid) != 0 ) + { + jaddbits256(retjson,"feetxid",qp->feetxid); + jaddnum(retjson,"feevout",qp->feevout); + } + if ( qp->desttxfee != 0 ) + jadd64bits(retjson,"desttxfee",qp->desttxfee); + if ( qp->destsatoshis != 0 ) + { + jadd64bits(retjson,"destsatoshis",qp->destsatoshis); + if ( qp->satoshis != 0 ) + { + price = (double)qp->destsatoshis / qp->satoshis; + jaddnum(retjson,"price",price); + } + } + return(retjson); +} + +int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson) +{ + safecopy(qp->srccoin,jstr(argjson,"base"),sizeof(qp->srccoin)); + safecopy(qp->coinaddr,jstr(argjson,"address"),sizeof(qp->coinaddr)); + safecopy(qp->destcoin,jstr(argjson,"rel"),sizeof(qp->destcoin)); + safecopy(qp->destaddr,jstr(argjson,"destaddr"),sizeof(qp->destaddr)); + qp->timestamp = juint(argjson,"timestamp"); + qp->quotetime = juint(argjson,"quotetime"); + qp->txid = jbits256(argjson,"txid"); + qp->txid2 = jbits256(argjson,"txid2"); + qp->vout = jint(argjson,"vout"); + qp->vout2 = jint(argjson,"vout2"); + qp->feevout = jint(argjson,"feevout"); + qp->srchash = jbits256(argjson,"srchash"); + qp->desttxid = jbits256(argjson,"desttxid"); + qp->feetxid = jbits256(argjson,"feetxid"); + qp->destvout = jint(argjson,"destvout"); + qp->desthash = jbits256(argjson,"desthash"); + qp->satoshis = j64bits(argjson,"satoshis"); + qp->destsatoshis = j64bits(argjson,"destsatoshis"); + qp->txfee = j64bits(argjson,"txfee"); + qp->desttxfee = j64bits(argjson,"desttxfee"); + return(0); +} + +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)); + 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))); + return(-1); + } + qp->txid = utxo->payment.txid; + qp->vout = utxo->payment.vout; + qp->txid2 = utxo->deposit.txid; + qp->vout2 = utxo->deposit.vout; + if ( qp->desttxfee >= qp->destsatoshis ) + { + printf("quoteinit desttxfee %.8f < %.8f destsatoshis\n",dstr(qp->desttxfee),dstr(qp->destsatoshis)); + return(-2); + } + safecopy(qp->srccoin,utxo->coin,sizeof(qp->srccoin)); + safecopy(qp->coinaddr,utxo->coinaddr,sizeof(qp->coinaddr)); + qp->srchash = utxo->pubkey; + return(0); +} + +int32_t LP_quotedestinfo(struct LP_quoteinfo *qp,bits256 desttxid,int32_t destvout,bits256 feetxid,int32_t feevout,bits256 desthash,char *destaddr) +{ + qp->desttxid = desttxid; + qp->destvout = destvout; + qp->desthash = desthash; + qp->feetxid = feetxid; + qp->feevout = feevout; + safecopy(qp->destaddr,destaddr,sizeof(qp->destaddr)); + return(0); +} + +char *LP_quotereceived(cJSON *argjson) +{ + struct LP_cacheinfo *ptr; double price; struct LP_quoteinfo Q; + LP_quoteparse(&Q,argjson); + price = (double)Q.destsatoshis / Q.satoshis; + if ( (ptr= LP_cacheadd(Q.srccoin,Q.destcoin,Q.txid,Q.vout,price,&Q)) != 0 ) + { + ptr->Q = Q; + printf(">>>>>>>>>> received quote %s/%s %.8f\n",Q.srccoin,Q.destcoin,price); + return(clonestr("{\"result\":\"updated\"}")); + } else return(clonestr("{\"error\":\"nullptr\"}")); +} + +char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price) +{ + bits256 zero; char *msg; cJSON *reqjson = cJSON_CreateObject(); + memset(zero.bytes,0,sizeof(zero)); + jaddbits256(reqjson,"pubkey",LP_mypub25519); + jaddstr(reqjson,"base",base); + jaddstr(reqjson,"rel",rel); + jaddnum(reqjson,"price",price); + jaddstr(reqjson,"method","postprice"); + msg = jprint(reqjson,1); + LP_broadcast_message(pubsock,base,rel,zero,msg); + return(clonestr("{\"result\":\"success\"}")); +} + +char *LP_postedprice(cJSON *argjson) +{ + bits256 pubkey; double price; char *base,*rel; + //printf("PRICE POSTED.(%s)\n",jprint(argjson,0)); + if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && (price= jdouble(argjson,"price")) > SMALLVAL ) + { + pubkey = jbits256(argjson,"pubkey"); + if ( bits256_nonz(pubkey) != 0 ) + { + LP_pricefeedupdate(pubkey,base,rel,price); + return(clonestr("{\"result\":\"success\"}")); + } + } + return(clonestr("{\"error\":\"missing fields in posted price\"}")); +} + +int32_t LP_quote_checkmempool(struct LP_quoteinfo *qp) +{ + int32_t selector,spendvini; bits256 spendtxid; + if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,qp->srccoin,qp->txid,qp->vout,qp->txid2,qp->vout2)) >= 0 ) + { + char str[65]; printf("LP_tradecommand selector.%d in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); + return(-1); + } + if ( (selector= LP_mempool_vinscan(&spendtxid,&spendvini,qp->destcoin,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) >= 0 ) + { + char str[65]; printf("LP_tradecommand dest selector.%d in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); + return(-1); + } + return(0); +} + +double LP_quote_validate(struct LP_utxoinfo **autxop,struct LP_utxoinfo **butxop,struct LP_quoteinfo *qp,int32_t iambob) +{ + 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 ) + { + printf("bob not eligible\n"); + return(-2); + } + if ( LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 ) + { + char str[65]; printf("alice not eligible (%.8f %.8f) %s/v%d\n",dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->feetxid),qp->feevout); + return(-3); + } + if ( LP_quote_checkmempool(qp) < 0 ) + return(-4); + if ( (*butxop= LP_utxofind(1,qp->txid,qp->vout)) == 0 ) + return(-5); + if ( bits256_cmp((*butxop)->deposit.txid,qp->txid2) != 0 || (*butxop)->deposit.vout != qp->vout2 ) + return(-6); + if ( strcmp((*butxop)->coinaddr,qp->coinaddr) != 0 ) + return(-7); + if ( iambob == 0 ) + { + if ( (*autxop= LP_utxofind(0,qp->desttxid,qp->destvout)) == 0 ) + return(-8); + if ( bits256_cmp((*autxop)->fee.txid,qp->feetxid) != 0 || (*autxop)->fee.vout != qp->feevout ) + return(-9); + if ( strcmp((*autxop)->coinaddr,qp->destaddr) != 0 ) + return(-10); + } + if ( destvalue < qp->desttxfee+qp->destsatoshis || srcvalue < qp->txfee+qp->satoshis ) + { + printf("destvalue %.8f srcvalue %.8f, destsatoshis %.8f or satoshis %.8f is too small txfees %.8f %.8f?\n",dstr(destvalue),dstr(srcvalue),dstr(qp->destsatoshis),dstr(qp->satoshis),dstr(qp->desttxfee),dstr(qp->txfee)); + return(-11); + } + qprice = ((double)qp->destsatoshis / qp->satoshis); + if ( qp->satoshis < (srcvalue / LP_MINVOL) || srcvalue < qp->txfee*LP_MINSIZE_TXFEEMULT ) + { + 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) || destvalue < qp->desttxfee*LP_MINSIZE_TXFEEMULT ) + { + 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); + } + 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); +} + +int32_t LP_arrayfind(cJSON *array,bits256 txid,int32_t vout) +{ + int32_t i,n = cJSON_GetArraySize(array); cJSON *item; + for (i=0; idesttxid,qp->destvout)) != 0 && LP_ismine(utxo) > 0 && LP_isavailable(utxo) > 0 ) + LP_unavailableset(utxo,qp->srchash); + else + { + printf("couldnt find my txid to make request\n"); + return(0.); + } + } + reqjson = LP_quotejson(qp); + if ( bits256_nonz(qp->desthash) != 0 ) + flag = 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 %s/%s\n",i,price,qp->srccoin,qp->destcoin); + break; + } + } + usleep(100000); + } + return(price); +} + +int32_t LP_nanobind(void *ctx,char *pairstr) +{ + 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 ) + printf("error creating utxo->pair\n"); + else + { + for (i=0; i<10; i++) + { + r = (10000 + (rand() % 50000)) & 0xffff; + if ( LP_fixed_pairport != 0 ) + r = LP_fixed_pairport; + nanomsg_transportname(0,pairstr,LP_myipaddr,r); + nanomsg_transportname(1,bindaddr,LP_myipaddr,r); + if ( nn_bind(pairsock,bindaddr) >= 0 ) + { + //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); + if ( LP_fixed_pairport != 0 ) + break; + } + } + } else pairsock = LP_initpublicaddr(ctx,&mypullport,pairstr,"127.0.0.1",0,1); + return(pairsock); +} + +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",LP_myipaddr,jprint(argjson,0),LP_myipaddr); + qp->quotetime = (uint32_t)time(NULL); + if ( (coin= LP_coinfind(utxo->coin)) == 0 ) + { + printf("cant find coin.%s\n",utxo->coin); + 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_mypub25519,qp->srchash) == 0 ) + { + if ( (pair= LP_nanobind(ctx,pairstr)) >= 0 ) + { + 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; + swap->utxo = utxo; + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_bobloop,(void *)swap) == 0 ) + { + retjson = LP_quotejson(qp); + jaddstr(retjson,"method","connected"); + jaddstr(retjson,"pair",pairstr); + jaddnum(retjson,"requestid",qp->R.requestid); + jaddnum(retjson,"quoteid",qp->R.quoteid); + 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_mypub25519,qp->srchash) == 0); + } + if ( retval < 0 ) + { + if ( pair >= 0 ) + nn_close(pair); + LP_availableset(utxo); + } else LP_unavailableset(utxo,utxo->S.otherpubkey); + return(retval); +} + +char *LP_connectedalice(cJSON *argjson) // alice +{ + 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_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 ( 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\"}")); + } + 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); + if ( bits256_nonz(Q.privkey) != 0 && Q.quotetime >= Q.timestamp-3 ) + { + retjson = cJSON_CreateObject(); + if ( (pairstr= jstr(argjson,"pair")) == 0 || (pairsock= nn_socket(AF_SP,NN_PAIR)) < 0 ) + jaddstr(retjson,"error","couldnt create pairsock"); + else if ( nn_connect(pairsock,pairstr) >= 0 ) + { + //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; + swap->utxo = autxo; + printf("alice pairstr.(%s) pairsock.%d\n",pairstr,pairsock); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_aliceloop,(void *)swap) == 0 ) + { + jaddstr(retjson,"result","success"); + jadd(retjson,"trade",LP_quotejson(&Q)); + jaddnum(retjson,"requestid",Q.R.requestid); + jaddnum(retjson,"quoteid",Q.R.quoteid); + } else jaddstr(retjson,"error","couldnt aliceloop"); + } else printf("connect error %s\n",nn_strerror(nn_errno())); + printf("connected result.(%s)\n",jprint(retjson,0)); + if ( jobj(retjson,"error") != 0 ) + LP_availableset(autxo); + else LP_pendingswaps++; + return(jprint(retjson,1)); + } + else + { + LP_availableset(autxo); + printf("no privkey found\n"); + return(clonestr("{\"error\",\"no privkey\"}")); + } +} + +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)); + retval = 1; + 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 ) + { + printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); + return(-3); + } + price = ask; + if ( (qprice= LP_quote_validate(&autxo,&butxo,&Q,1)) <= SMALLVAL ) + { + printf("quote validate error %.0f\n",qprice); + return(-4); + } + 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); + } + if ( butxo->S.swap == 0 && time(NULL) > butxo->T.swappending ) + butxo->T.swappending = 0; + if ( strcmp(method,"request") == 0 ) // bob needs apayment + fee tx's + { + if ( LP_isavailable(butxo) > 0 ) + { + butxo->T.swappending = Q.timestamp + LP_RESERVETIME; + retjson = LP_quotejson(&Q); + butxo->S.otherpubkey = jbits256(argjson,"desthash"); + LP_unavailableset(butxo,butxo->S.otherpubkey); + jaddnum(retjson,"quotetime",juint(argjson,"quotetime")); + jaddnum(retjson,"pending",butxo->T.swappending); + jaddbits256(retjson,"desthash",butxo->S.otherpubkey); + jaddbits256(retjson,"pubkey",butxo->S.otherpubkey); + jaddstr(retjson,"method","reserved"); + 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); + } 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,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)); + } + } + } + return(retval); +} + +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; 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.; + *bestsatoshisp = *bestdestsatoshisp = 0; + if ( duration <= 0 ) + duration = LP_ORDERBOOK_DURATION; + if ( maxprice <= 0. || LP_priceinfofind(base) == 0 ) + return(0); + LP_txfees(&txfee,&desttxfee,base,autxo->coin); + if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 ) + { + if ( (orderbook= cJSON_Parse(obookstr)) != 0 ) + { + if ( (asks= jarray(&numasks,orderbook,"asks")) != 0 ) + { + for (i=0; i 0 && price <= maxprice ) + { + //price *= 1.0001; + //if ( price > maxprice ) + // price = maxprice; + pubkey = jbits256(item,"pubkey"); + 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; + //printf("item.[%d] %s\n",i,jprint(item,0)); + txid = jbits256(item,"txid"); + vout = jint(item,"vout"); + vol = jdouble(item,"volume"); + 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 ) + { + 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 ) + { + 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; + } + //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); + } + } else printf("self trading or blacklisted peer\n"); + } + else + { + if ( i == 0 ) + printf("maxprice %.8f vs %.8f\n",maxprice,price); + break; + } + } + if ( bestutxo == 0 ) + { + int32_t numrestraints; + for (i=numrestraints=0; iT.bestflag = 0; + pubp->numerrors = 0; + } + } + } + printf("no bob utxo found -> cleared %d restraints\n",numrestraints); + } + } + free_json(orderbook); + } + free(obookstr); + } + if ( bestutxo == 0 || *ordermatchpricep == 0. || *bestdestsatoshisp == 0 ) + return(0); + bestutxo->T.bestflag = 1; + int32_t changed; + LP_mypriceset(&changed,autxo->coin,base,1. / *ordermatchpricep); + return(bestutxo); +} + +char *LP_bestfit(char *rel,double relvolume) +{ + struct LP_utxoinfo *autxo; + if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 ) + return(clonestr("{\"error\":\"invalid parameter\"}")); + if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) + return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); + return(jprint(LP_utxojson(autxo),1)); +} + +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 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,&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,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_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,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration) +{ + 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); + return(clonestr("{\"error\":\"cant find alice utxopair\"}")); + } + 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,"request",qp); + bestitem = LP_quotejson(qp); + if ( LP_pricevalid(price) > 0 ) + { + if ( price <= maxprice ) + { + 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 ) + { + if ( aliceutxo->S.swap != 0 ) + break; + sleep(1); + } + if ( aliceutxo->S.swap == 0 ) + { + if ( (pubp= LP_pubkeyadd(bobutxo->pubkey)) != 0 ) + pubp->numerrors++; + jaddstr(bestitem,"status","couldnt establish connection"); + } else jaddstr(bestitem,"status","connected"); + jaddnum(bestitem,"quotedprice",price); + jaddnum(bestitem,"maxprice",maxprice); + jaddnum(bestitem,"requestid",qp->R.requestid); + jaddnum(bestitem,"quoteid",qp->R.quoteid); + printf("Alice r.%u qp->%u\n",qp->R.requestid,qp->R.quoteid); + } + else + { + jaddnum(bestitem,"quotedprice",price); + jaddnum(bestitem,"maxprice",maxprice); + jaddstr(bestitem,"status","too expensive"); + } + } + else + { + jaddnum(bestitem,"maxprice",maxprice); + jaddstr(bestitem,"status","no response to request"); + } + if ( aliceutxo->S.swap == 0 ) + LP_availableset(aliceutxo); + return(jprint(bestitem,0)); +} + +char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration) +{ + 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 ) + timeout = LP_AUTOTRADE_TIMEOUT; + if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 ) + return(clonestr("{\"error\":\"invalid parameter\"}")); + if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) + return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); + 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,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_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,&Q,maxprice,timeout,duration)); +} + + + + diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c new file mode 100644 index 000000000..5e7a26cc3 --- /dev/null +++ b/iguana/exchanges/LP_peers.c @@ -0,0 +1,253 @@ + +/****************************************************************************** + * 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_peers.c +// marketmaker +// + +struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port) +{ + struct LP_peerinfo *peer=0; uint64_t ip_port; + ip_port = ((uint64_t)port << 32) | ipbits; + portable_mutex_lock(&LP_peermutex); + HASH_FIND(hh,LP_peerinfos,&ip_port,sizeof(ip_port),peer); + portable_mutex_unlock(&LP_peermutex); + return(peer); +} + +cJSON *LP_peerjson(struct LP_peerinfo *peer) +{ + cJSON *item = cJSON_CreateObject(); + jaddstr(item,"ipaddr",peer->ipaddr); + jaddnum(item,"port",peer->port); + 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); +} + +char *LP_peers() +{ + struct LP_peerinfo *peer,*tmp; cJSON *peersjson = cJSON_CreateArray(); + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + //if ( peer->errors < LP_MAXPEER_ERRORS ) + jaddi(peersjson,LP_peerjson(peer)); + } + 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,int32_t numpeers,int32_t numutxos,uint32_t sessionid) +{ + 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 ( numpeers > peer->numpeers ) + peer->numpeers = numpeers; + if ( numutxos > peer->numutxos ) + peer->numutxos = numutxos; + if ( peer->sessionid == 0 ) + peer->sessionid = sessionid;*/ + } + else + { + 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 ) + { + nanomsg_transportname(0,pushaddr,peer->ipaddr,pushport); + if ( nn_connect(pushsock,pushaddr) >= 0 ) + { + 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)); + printf("connected to push.(%s) %d\n",pushaddr,pushsock); + peer->connected = (uint32_t)time(NULL); + peer->pushsock = pushsock; + if ( (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 ) + { + timeout = 1; + nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); + nanomsg_transportname(0,subaddr,peer->ipaddr,subport); + if ( nn_connect(subsock,subaddr) >= 0 ) + { + peer->subsock = subsock; + printf("connected to sub.(%s) %d\n",subaddr,peer->subsock); + } else nn_close(subsock); + } + } + else + { + nn_close(pushsock); + 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->ipbits = ipbits; + peer->port = port; + peer->ip_port = ((uint64_t)port << 32) | ipbits; + portable_mutex_lock(&LP_peermutex); + HASH_ADD(hh,LP_peerinfos,ip_port,sizeof(peer->ip_port),peer); + if ( mypeer != 0 ) + { + mypeer->numpeers++; + 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 ( IAMLP != 0 && mypubsock >= 0 ) + { + 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; + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ilasttime = now; + if ( strcmp(argipaddr,destipaddr) == 0 && destport == argport && peer->numpeers != n ) + peer->numpeers = n; + } + } + } + } + free_json(array); + } + return(n); +} + +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,mypeer!=0?mypeer->numpeers:0,mypeer!=0?mypeer->numutxos:0)) != 0 ) + { + //printf("got.(%s)\n",retstr); + now = (uint32_t)time(NULL); + LP_peersparse(mypeer,mypubsock,destipaddr,destport,retstr,now); + free(retstr); + if ( IAMLP != 0 ) + { + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( 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->numpeers,0,peer->sessionid)) != 0 ) + free(retstr); + } + } + if ( flag != 0 ) + printf(" <- missing peers\n"); + } + } +} + +int32_t LP_numpeers() +{ + struct LP_peerinfo *peer,*tmp; int32_t numpeers = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + numpeers++; + } + return(numpeers); +} 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 new file mode 100644 index 000000000..d68ae2257 --- /dev/null +++ b/iguana/exchanges/LP_prices.c @@ -0,0 +1,849 @@ + +/****************************************************************************** + * 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_prices.c +// marketmaker +// + +struct LP_orderbookentry { bits256 txid,txid2,pubkey; double price; uint64_t basesatoshis; int32_t vout,vout2,age; }; + +#define LP_MAXPRICEINFOS 256 +struct LP_priceinfo +{ + char symbol[16]; + uint64_t coinbits; + int32_t ind,pad; + 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; + +struct LP_cacheinfo +{ + UT_hash_handle hh; + struct LP_quoteinfo Q; + uint8_t key[sizeof(bits256)+sizeof(uint64_t)*2+sizeof(int32_t)]; + double price; + uint32_t timestamp; +} *LP_cacheinfos; + +struct LP_pubkeyinfo +{ + UT_hash_handle hh; + bits256 pubkey; + double matrix[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS]; + 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; + if ( symbol == 0 || symbol[0] == 0 ) + return(0); + if ( LP_numpriceinfos > 0 ) + { + coinbits = stringbits(symbol); + pp = LP_priceinfos; + for (i=0; icoinbits == coinbits ) + return(pp); + } + return(0); +} + +struct LP_priceinfo *LP_priceinfoptr(int32_t *indp,char *base,char *rel) +{ + struct LP_priceinfo *basepp,*relpp; + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + *indp = relpp->ind; + return(basepp); + } + else + { + *indp = -1; + return(0); + } +} + +int32_t LP_cachekey(uint8_t *key,char *base,char *rel,bits256 txid,int32_t vout) +{ + uint64_t basebits,relbits; int32_t offset = 0; + basebits = stringbits(base); + relbits = stringbits(rel); + memcpy(&key[offset],&basebits,sizeof(basebits)), offset += sizeof(basebits); + memcpy(&key[offset],&relbits,sizeof(relbits)), offset += sizeof(relbits); + memcpy(&key[offset],&txid,sizeof(txid)), offset += sizeof(txid); + memcpy(&key[offset],&vout,sizeof(vout)), offset += sizeof(vout); + return(offset); +} + +struct LP_cacheinfo *LP_cachefind(char *base,char *rel,bits256 txid,int32_t vout) +{ + struct LP_cacheinfo *ptr=0; uint8_t key[sizeof(bits256)+sizeof(uint64_t)*2+sizeof(vout)]; + if ( base == 0 || rel == 0 ) + return(0); + if ( LP_cachekey(key,base,rel,txid,vout) == sizeof(key) ) + { + portable_mutex_lock(&LP_cachemutex); + HASH_FIND(hh,LP_cacheinfos,key,sizeof(key),ptr); + portable_mutex_unlock(&LP_cachemutex); + } else printf("LP_cachefind keysize mismatch?\n"); + if ( 0 && ptr != 0 && ptr->timestamp != 0 && ptr->timestamp < time(NULL)-LP_CACHEDURATION ) + { + printf("expire price %.8f\n",ptr->price); + ptr->price = 0.; + ptr->timestamp = 0; + memset(&ptr->Q,0,sizeof(ptr->Q)); + } + return(ptr); +} + +struct LP_pubkeyinfo *LP_pubkeyfind(bits256 pubkey) +{ + struct LP_pubkeyinfo *pubp=0; + portable_mutex_lock(&LP_pubkeymutex); + HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp); + portable_mutex_unlock(&LP_pubkeymutex); + return(pubp); +} + +struct LP_pubkeyinfo *LP_pubkeyadd(bits256 pubkey) +{ + struct LP_pubkeyinfo *pubp=0; + if ( (pubp= LP_pubkeyfind(pubkey)) == 0 ) + { + portable_mutex_lock(&LP_pubkeymutex); + pubp = calloc(1,sizeof(*pubp)); + pubp->pubkey = pubkey; + HASH_ADD_KEYPTR(hh,LP_pubkeyinfos,&pubp->pubkey,sizeof(pubp->pubkey),pubp); + portable_mutex_unlock(&LP_pubkeymutex); + if ( (pubp= LP_pubkeyfind(pubkey)) == 0 ) + printf("pubkeyadd find error after add\n"); + } + return(pubp); +} + +int32_t LP_pubkey_istrusted(bits256 pubkey) +{ + struct LP_pubkeyinfo *pubp; + if ( (pubp= LP_pubkeyfind(pubkey)) != 0 ) + return(pubp->istrusted != 0); + return(0); +} + +char *LP_pubkey_trustset(bits256 pubkey,uint32_t trustval) +{ + struct LP_pubkeyinfo *pubp; + if ( (pubp= LP_pubkeyfind(pubkey)) != 0 ) + { + pubp->istrusted = trustval; + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"pubkey not found\"}")); +} + +cJSON *LP_pubkeyjson(struct LP_pubkeyinfo *pubp) +{ + int32_t baseid,relid; char *base; double price; cJSON *item,*array,*obj; + obj = cJSON_CreateObject(); + array = cJSON_CreateArray(); + for (baseid=0; baseidmatrix[baseid][relid]; + if ( LP_pricevalid(price) > 0 ) + { + item = cJSON_CreateArray(); + jaddistr(item,base); + jaddistr(item,LP_priceinfos[relid].symbol); + jaddinum(item,price); + jaddi(array,item); + } + } + } + jaddbits256(obj,"pubkey",pubp->pubkey); + jaddnum(obj,"timestamp",pubp->timestamp); + jadd(obj,"asks",array); + if ( pubp->istrusted != 0 ) + jaddnum(obj,"istrusted",pubp->istrusted); + return(obj); +} + +char *LP_prices() +{ + struct LP_pubkeyinfo *pubp,*tmp; cJSON *array = cJSON_CreateArray(); + HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) + { + jaddi(array,LP_pubkeyjson(pubp)); + } + return(jprint(array,1)); +} + +void LP_prices_parse(cJSON *obj) +{ + 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 ) + { + if ( (timestamp= juint(obj,"timestamp")) > pubp->timestamp && (asks= jarray(&n,obj,"asks")) != 0 ) + { + pubp->timestamp = timestamp; + for (i=0; i 0 ) + { + 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); + } + } + } + } + } + } +} + +void LP_peer_pricesquery(char *destipaddr,uint16_t destport) +{ + char *retstr; cJSON *array; int32_t i,n; + if ( (retstr= issue_LP_getprices(destipaddr,destport)) != 0 ) + { + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( is_cJSON_Array(array) && (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; iQ; + if ( ptr->price == 0. && ptr->Q.satoshis != 0 ) + { + 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); + } + //char str[65]; printf("cachemiss %s/%s %s/v%d\n",base,rel,bits256_str(str,txid),vout); + return(0.); +} + +void LP_priceinfoupdate(char *base,char *rel,double price) +{ + struct LP_priceinfo *basepp,*relpp; + if ( LP_pricevalid(price) > 0 ) + { + 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; + } + } +} + +double LP_myprice(double *bidp,double *askp,char *base,char *rel) +{ + struct LP_priceinfo *basepp,*relpp; double val; + *bidp = *askp = 0.; + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + *askp = basepp->myprices[relpp->ind]; + if ( LP_pricevalid(*askp) > 0 ) + { + val = relpp->myprices[basepp->ind]; + if ( LP_pricevalid(val) > 0 ) + { + *bidp = 1. / val; + return((*askp + *bidp) * 0.5); + } + else + { + *bidp = 0.; + return(*askp); + } + } + else + { + val = relpp->myprices[basepp->ind]; + if ( LP_pricevalid(val) > 0 ) + { + *bidp = 1. / val; + *askp = 0.; + return(*bidp); + } + } + } + return(0.); +} + +char *LP_myprices() +{ + int32_t baseid,relid; double bid,ask; char *base,*rel; cJSON *item,*array; + array = cJSON_CreateArray(); + for (baseid=0; baseid SMALLVAL ) + { + item = cJSON_CreateObject(); + jaddstr(item,"base",base); + jaddstr(item,"rel",rel); + jaddnum(item,"bid",bid); + jaddnum(item,"ask",ask); + jaddi(array,item); + } + } + } + return(jprint(array,1)); +} + +int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) +{ + struct LP_priceinfo *basepp,*relpp; struct LP_pubkeyinfo *pubp; + *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_mypub25519)) != 0 ) + { + pubp->matrix[basepp->ind][relpp->ind] = price; + //pubp->matrix[relpp->ind][basepp->ind] = (1. / price); + pubp->timestamp = (uint32_t)time(NULL); + } + return(0); + } else return(-1); +} + +double LP_price(char *base,char *rel) +{ + struct LP_priceinfo *basepp; int32_t relind; double price = 0.; + if ( (basepp= LP_priceinfoptr(&relind,base,rel)) != 0 ) + { + if ( (price= basepp->myprices[relind]) == 0. ) + price = basepp->relvals[relind]; + } + return(price); +} + +cJSON *LP_priceinfomatrix(int32_t usemyprices) +{ + int32_t i,j,n,m; double total,sum,val; struct LP_priceinfo *pp; uint32_t now; struct LP_cacheinfo *ptr,*tmp; cJSON *vectorjson = cJSON_CreateObject(); + now = (uint32_t)time(NULL); + HASH_ITER(hh,LP_cacheinfos,ptr,tmp) + { + if ( ptr->timestamp < now-3600*2 || ptr->price == 0. ) + continue; + LP_priceinfoupdate(ptr->Q.srccoin,ptr->Q.destcoin,ptr->price); + } + pp = LP_priceinfos; + total = m = 0; + for (i=0; idiagval = sum = n = 0; + for (j=0; jmyprices[j]) == 0. ) + val = pp->relvals[j]; + if ( val > SMALLVAL ) + { + sum += val; + n++; + } + } + if ( n > 0 ) + { + pp->diagval = sum / n; + total += pp->diagval, m++; + } + } + if ( m > 0 ) + { + pp = LP_priceinfos; + for (i=0; idiagval > SMALLVAL ) + { + pp->diagval /= total; + jaddnum(vectorjson,pp->symbol,pp->diagval); + } + } + } + return(vectorjson); +} + +struct LP_priceinfo *LP_priceinfoadd(char *symbol) +{ + struct LP_priceinfo *pp; cJSON *retjson; + if ( symbol == 0 ) + return(0); + if ( LP_numpriceinfos >= sizeof(LP_priceinfos)/sizeof(*LP_priceinfos) ) + { + printf("cant add any more priceinfos\n"); + return(0); + } + pp = &LP_priceinfos[LP_numpriceinfos]; + memset(pp,0,sizeof(*pp)); + safecopy(pp->symbol,symbol,sizeof(pp->symbol)); + pp->coinbits = stringbits(symbol); + pp->ind = LP_numpriceinfos++; + LP_numpriceinfos++; + if ( (retjson= LP_priceinfomatrix(0)) != 0 ) + free_json(retjson); + return(pp); +} + +struct LP_cacheinfo *LP_cacheadd(char *base,char *rel,bits256 txid,int32_t vout,double price,struct LP_quoteinfo *qp) +{ + char str[65]; struct LP_cacheinfo *ptr=0; + if ( base == 0 || rel == 0 ) + return(0); + if ( LP_pricevalid(price) > 0 ) + { + if ( (ptr= LP_cachefind(base,rel,txid,vout)) == 0 ) + { + 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; + } + return(ptr); +} + +static int _cmp_orderbook(const void *a,const void *b) +{ + int32_t retval = 0; +#define ptr_a (*(struct LP_orderbookentry **)a)->price +#define ptr_b (*(struct LP_orderbookentry **)b)->price + if ( ptr_b > ptr_a ) + retval = -1; + else if ( ptr_b < ptr_a ) + retval = 1; + else + { +#undef ptr_a +#undef ptr_b +#define ptr_a ((struct LP_orderbookentry *)a)->basesatoshis +#define ptr_b ((struct LP_orderbookentry *)b)->basesatoshis + if ( ptr_b > ptr_a ) + return(-1); + else if ( ptr_b < ptr_a ) + return(1); + } + // printf("%.8f vs %.8f -> %d\n",ptr_a,ptr_b,retval); + return(retval); +#undef ptr_a +#undef ptr_b +} + +cJSON *LP_orderbookjson(struct LP_orderbookentry *op) +{ + cJSON *item = cJSON_CreateObject(); + if ( LP_pricevalid(op->price) > 0 ) + { + jaddnum(item,"price",op->price); + jaddnum(item,"volume",dstr(op->basesatoshis)); + jaddbits256(item,"txid",op->txid); + jaddnum(item,"vout",op->vout); + jaddbits256(item,"pubkey",op->pubkey); + jaddnum(item,"age",op->age); + } + return(item); +} + +struct LP_orderbookentry *LP_orderbookentry(char *base,char *rel,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2,double price,uint64_t basesatoshis,bits256 pubkey,int32_t age) +{ + struct LP_orderbookentry *op; + if ( (op= calloc(1,sizeof(*op))) != 0 ) + { + op->txid = txid; + op->vout = vout; + op->txid2 = txid2; + op->vout2 = vout2; + op->price = price; + op->basesatoshis = basesatoshis; + op->pubkey = pubkey; + op->age = age; + } + return(op); +} + +int32_t LP_orderbookfind(struct LP_orderbookentry **array,int32_t num,bits256 txid,int32_t vout) +{ + int32_t i; + for (i=0; ivout == vout && bits256_cmp(array[i]->txid,txid) == 0) || (array[i]->vout2 == vout && bits256_cmp(array[i]->txid2,txid) == 0) ) + return(i); + return(-1); +} + +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; + if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 ) + baseid = basepp->ind; + else return(num); + now = (uint32_t)time(NULL); + oldest = now - duration; + HASH_ITER(hh,LP_utxoinfos[1],utxo,tmp) + { + if ( pubp == 0 || bits256_cmp(pubp->pubkey,utxo->pubkey) != 0 ) + pubp = LP_pubkeyfind(utxo->pubkey); + if ( pubp != 0 && pubp->numerrors >= LP_MAXPUBKEY_ERRORS ) + continue; + //char str[65],str2[65]; printf("check utxo.%s/v%d from %s\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,utxo->pubkey)); + if ( strcmp(base,utxo->coin) == 0 && LP_isavailable(utxo) > 0 && pubp != 0 && (price= pubp->matrix[baseid][relid]) > SMALLVAL && pubp->timestamp > oldest && pubp->timestamp <= now ) + { + if ( LP_orderbookfind(*arrayp,cachednum,utxo->payment.txid,utxo->payment.vout) < 0 ) + { + if ( LP_iseligible(&val,&val2,utxo->iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->deposit.txid,utxo->deposit.vout) == 0 ) + continue; + if ( polarity > 0 ) + basesatoshis = utxo->S.satoshis; + else basesatoshis = utxo->S.satoshis * price; + //char str[65]; printf("found utxo not in orderbook %s/v%d %.8f %.8f\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout,dstr(basesatoshis),polarity > 0 ? price : 1./price); + if ( (op= LP_orderbookentry(base,rel,utxo->payment.txid,utxo->payment.vout,utxo->deposit.txid,utxo->deposit.vout,polarity > 0 ? price : 1./price,basesatoshis,utxo->pubkey,now - pubp->timestamp)) != 0 ) + { + *arrayp = realloc(*arrayp,sizeof(*(*arrayp)) * (num+1)); + (*arrayp)[num++] = op; + if ( LP_ismine(utxo) > 0 && utxo->T.lasttime == 0 ) + LP_utxo_clientpublish(utxo); + } + } + } + } + return(num); +} + +char *LP_orderbook(char *base,char *rel,int32_t duration) +{ + uint32_t now,i; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*array; int32_t numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid; + if ( (basepp= LP_priceinfofind(base)) == 0 || (relpp= LP_priceinfofind(rel)) == 0 ) + return(clonestr("{\"error\":\"base or rel not added\"}")); + if ( duration <= 0 ) + duration = LP_ORDERBOOK_DURATION; + baseid = basepp->ind; + relid = relpp->ind; + now = (uint32_t)time(NULL); + cachenumbids = numbids, cachenumasks = numasks; + //printf("start cache.(%d %d) numbids.%d numasks.%d\n",cachenumbids,cachenumasks,numbids,numasks); + numasks = LP_orderbook_utxoentries(now,1,base,rel,&asks,numasks,cachenumasks,duration); + numbids = LP_orderbook_utxoentries(now,-1,rel,base,&bids,numbids,cachenumbids,duration); + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + if ( numbids > 1 ) + qsort(bids,numbids,sizeof(*bids),_cmp_orderbook); + if ( numasks > 1 ) + { + //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; i SMALLVAL && origprice < price ) + price = origprice; + } + if ( LP_pricevalid(price) > 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"method","postprice"); + jaddbits256(retjson,"pubkey",LP_mypub25519); + jaddstr(retjson,"base",base); + jaddstr(retjson,"rel",rel); + jaddnum(retjson,"price",price); + jadd(retjson,"theoretical",LP_priceinfomatrix(0)); + jadd(retjson,"quotes",LP_priceinfomatrix(1)); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"cant find baserel pair\"}")); +} + +void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]) +{ + 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; 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 ) + { + 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 ) + { + 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 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 new file mode 100644 index 000000000..9e25a6241 --- /dev/null +++ b/iguana/exchanges/LP_remember.c @@ -0,0 +1,1075 @@ + +/****************************************************************************** + * 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_remember.c +// marketmaker +// + +void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,int32_t scriptlen) +{ + int32_t i; char scriptstr[513]; + if ( scriptlen != 0 ) + { + for (i=0; iI.req.requestid,swap->I.req.quoteid,rawtx->name), OS_compatible_path(fname); + coinaddr[0] = secretAmstr[0] = secretAm256str[0] = secretBnstr[0] = secretBn256str[0] = 0; + memset(zeroes,0,sizeof(zeroes)); + if ( rawtx != 0 && (fp= fopen(fname,"wb")) != 0 ) + { + fprintf(fp,"{\"name\":\"%s\",\"coin\":\"%s\"",rawtx->name,rawtx->coin->symbol); + if ( rawtx->I.datalen > 0 ) + { + fprintf(fp,",\"tx\":\""); + for (i=0; iI.datalen; i++) + fprintf(fp,"%02x",rawtx->txbytes[i]); + fprintf(fp,"\",\"txid\":\"%s\"",bits256_str(str,bits256_doublesha256(0,rawtx->txbytes,rawtx->I.datalen))); + if ( rawtx == &swap->bobdeposit || rawtx == &swap->bobpayment ) + { + LP_swap_coinaddr(swap,&swap->bobcoin,coinaddr,rawtx->txbytes,rawtx->I.datalen); + if ( coinaddr[0] != 0 ) + { + LP_importaddress(swap->bobcoin.symbol,coinaddr); + if ( rawtx == &swap->bobdeposit ) + safecopy(swap->Bdeposit,coinaddr,sizeof(swap->Bdeposit)); + else safecopy(swap->Bpayment,coinaddr,sizeof(swap->Bpayment)); + } + } + } + if ( swap->Bdeposit[0] != 0 ) + fprintf(fp,",\"%s\":\"%s\"","Bdeposit",swap->Bdeposit); + if ( swap->Bpayment[0] != 0 ) + fprintf(fp,",\"%s\":\"%s\"","Bpayment",swap->Bpayment); + fprintf(fp,",\"expiration\":%u",swap->I.expiration); + fprintf(fp,",\"iambob\":%d",swap->I.iambob); + fprintf(fp,",\"bobcoin\":\"%s\"",swap->bobcoin.symbol); + fprintf(fp,",\"alicecoin\":\"%s\"",swap->alicecoin.symbol); + fprintf(fp,",\"lock\":%u",locktime); + fprintf(fp,",\"amount\":%.8f",dstr(rawtx->I.amount)); + if ( bits256_nonz(triggertxid) != 0 ) + fprintf(fp,",\"trigger\":\"%s\"",bits256_str(str,triggertxid)); + if ( bits256_nonz(swap->I.pubAm) != 0 && bits256_nonz(swap->I.pubBn) != 0 ) + { + basilisk_alicescript(redeemscript,&len,script,0,coinaddr,swap->alicecoin.taddr,swap->alicecoin.p2shtype,swap->I.pubAm,swap->I.pubBn); + LP_importaddress(swap->alicecoin.symbol,coinaddr); + fprintf(fp,",\"Apayment\":\"%s\"",coinaddr); + } + if ( rawtx->I.redeemlen > 0 ) + { + char scriptstr[2049]; + init_hexbytes_noT(scriptstr,rawtx->redeemscript,rawtx->I.redeemlen); + fprintf(fp,",\"redeem\":\"%s\"",scriptstr); + } + /*basilisk_dontforget_userdata("Aclaim",fp,swap->I.userdata_aliceclaim,swap->I.userdata_aliceclaimlen); + basilisk_dontforget_userdata("Areclaim",fp,swap->I.userdata_alicereclaim,swap->I.userdata_alicereclaimlen); + basilisk_dontforget_userdata("Aspend",fp,swap->I.userdata_alicespend,swap->I.userdata_alicespendlen); + basilisk_dontforget_userdata("Bspend",fp,swap->I.userdata_bobspend,swap->I.userdata_bobspendlen); + basilisk_dontforget_userdata("Breclaim",fp,swap->I.userdata_bobreclaim,swap->I.userdata_bobreclaimlen); + basilisk_dontforget_userdata("Brefund",fp,swap->I.userdata_bobrefund,swap->I.userdata_bobrefundlen);*/ + fprintf(fp,"}\n"); + fclose(fp); + } + 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,\"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); + fprintf(fp,",\"secretAm\":\"%s\"",secretAmstr); + } + if ( memcmp(zeroes,swap->I.secretAm256,32) != 0 ) + { + init_hexbytes_noT(secretAm256str,swap->I.secretAm256,32); + fprintf(fp,",\"secretAm256\":\"%s\"",secretAm256str); + } + if ( memcmp(zeroes,swap->I.secretBn,20) != 0 ) + { + init_hexbytes_noT(secretBnstr,swap->I.secretBn,20); + fprintf(fp,",\"secretBn\":\"%s\"",secretBnstr); + } + if ( memcmp(zeroes,swap->I.secretBn256,32) != 0 ) + { + init_hexbytes_noT(secretBn256str,swap->I.secretBn256,32); + fprintf(fp,",\"secretBn256\":\"%s\"",secretBn256str); + } + for (i=0; i<2; i++) + if ( bits256_nonz(swap->I.myprivs[i]) != 0 ) + fprintf(fp,",\"myprivs%d\":\"%s\"",i,bits256_str(str,swap->I.myprivs[i])); + if ( bits256_nonz(swap->I.privAm) != 0 ) + fprintf(fp,",\"privAm\":\"%s\"",bits256_str(str,swap->I.privAm)); + if ( bits256_nonz(swap->I.privBn) != 0 ) + fprintf(fp,",\"privBn\":\"%s\"",bits256_str(str,swap->I.privBn)); + if ( bits256_nonz(swap->I.pubA0) != 0 ) + fprintf(fp,",\"pubA0\":\"%s\"",bits256_str(str,swap->I.pubA0)); + if ( bits256_nonz(swap->I.pubB0) != 0 ) + fprintf(fp,",\"pubB0\":\"%s\"",bits256_str(str,swap->I.pubB0)); + if ( bits256_nonz(swap->I.pubB1) != 0 ) + fprintf(fp,",\"pubB1\":\"%s\"",bits256_str(str,swap->I.pubB1)); + if ( bits256_nonz(swap->bobdeposit.I.actualtxid) != 0 ) + fprintf(fp,",\"Bdeposit\":\"%s\"",bits256_str(str,swap->bobdeposit.I.actualtxid)); + if ( bits256_nonz(swap->bobrefund.I.actualtxid) != 0 ) + fprintf(fp,",\"Brefund\":\"%s\"",bits256_str(str,swap->bobrefund.I.actualtxid)); + if ( bits256_nonz(swap->aliceclaim.I.actualtxid) != 0 ) + fprintf(fp,",\"Aclaim\":\"%s\"",bits256_str(str,swap->aliceclaim.I.actualtxid)); + + if ( bits256_nonz(swap->bobpayment.I.actualtxid) != 0 ) + fprintf(fp,",\"Bpayment\":\"%s\"",bits256_str(str,swap->bobpayment.I.actualtxid)); + if ( bits256_nonz(swap->alicespend.I.actualtxid) != 0 ) + fprintf(fp,",\"Aspend\":\"%s\"",bits256_str(str,swap->alicespend.I.actualtxid)); + if ( bits256_nonz(swap->bobreclaim.I.actualtxid) != 0 ) + fprintf(fp,",\"Breclaim\":\"%s\"",bits256_str(str,swap->bobreclaim.I.actualtxid)); + + if ( bits256_nonz(swap->alicepayment.I.actualtxid) != 0 ) + fprintf(fp,",\"Apayment\":\"%s\"",bits256_str(str,swap->alicepayment.I.actualtxid)); + if ( bits256_nonz(swap->bobspend.I.actualtxid) != 0 ) + fprintf(fp,",\"Bspend\":\"%s\"",bits256_str(str,swap->bobspend.I.actualtxid)); + if ( bits256_nonz(swap->alicereclaim.I.actualtxid) != 0 ) + fprintf(fp,",\"Areclaim\":\"%s\"",bits256_str(str,swap->alicereclaim.I.actualtxid)); + + if ( bits256_nonz(swap->otherfee.I.actualtxid) != 0 ) + fprintf(fp,",\"otherfee\":\"%s\"",bits256_str(str,swap->otherfee.I.actualtxid)); + if ( bits256_nonz(swap->myfee.I.actualtxid) != 0 ) + fprintf(fp,",\"myfee\":\"%s\"",bits256_str(str,swap->myfee.I.actualtxid)); + fprintf(fp,",\"dest33\":\""); + for (i=0; i<33; i++) + fprintf(fp,"%02x",swap->persistent_pubkey33[i]); + fprintf(fp,"\"}\n"); + fclose(fp); + } +} + +void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx) +{ + bits256 triggertxid; + memset(triggertxid.bytes,0,sizeof(triggertxid)); + if ( rawtx == 0 ) + { + basilisk_dontforget(swap,0,0,triggertxid); + return; + } + if ( rawtx == &swap->myfee ) + basilisk_dontforget(swap,&swap->myfee,0,triggertxid); + else if ( rawtx == &swap->otherfee ) + basilisk_dontforget(swap,&swap->otherfee,0,triggertxid); + else if ( rawtx == &swap->bobdeposit ) + { + basilisk_dontforget(swap,&swap->bobdeposit,0,triggertxid); + basilisk_dontforget(swap,&swap->bobrefund,swap->bobdeposit.I.locktime,triggertxid); + } + else if ( rawtx == &swap->bobrefund ) + basilisk_dontforget(swap,&swap->bobrefund,swap->bobdeposit.I.locktime,triggertxid); + else if ( rawtx == &swap->aliceclaim ) + { + basilisk_dontforget(swap,&swap->bobrefund,0,triggertxid); + basilisk_dontforget(swap,&swap->aliceclaim,0,swap->bobrefund.I.actualtxid); + } + else if ( rawtx == &swap->alicepayment ) + { + basilisk_dontforget(swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid); + } + else if ( rawtx == &swap->bobspend ) + { + basilisk_dontforget(swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid); + basilisk_dontforget(swap,&swap->bobspend,0,swap->alicepayment.I.actualtxid); + } + else if ( rawtx == &swap->alicereclaim ) + { + basilisk_dontforget(swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid); + basilisk_dontforget(swap,&swap->alicereclaim,0,swap->bobrefund.I.actualtxid); + } + else if ( rawtx == &swap->bobpayment ) + { + basilisk_dontforget(swap,&swap->bobpayment,0,triggertxid); + basilisk_dontforget(swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid); + } + else if ( rawtx == &swap->alicespend ) + { + basilisk_dontforget(swap,&swap->bobpayment,0,triggertxid); + basilisk_dontforget(swap,&swap->alicespend,0,triggertxid); + } + else if ( rawtx == &swap->bobreclaim ) + basilisk_dontforget(swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid); +} + +bits256 basilisk_swap_privbob_extract(char *symbol,bits256 spendtxid,int32_t vini,int32_t revflag) +{ + bits256 privkey; int32_t i,scriptlen,siglen; uint8_t script[1024]; // from Bob refund of Bob deposit + memset(&privkey,0,sizeof(privkey)); + if ( (scriptlen= basilisk_swap_getsigscript(symbol,script,(int32_t)sizeof(script),spendtxid,vini)) > 0 ) + { + siglen = script[0]; + for (i=0; i<32; i++) + { + if ( revflag != 0 ) + privkey.bytes[31 - i] = script[siglen+2+i]; + else privkey.bytes[i] = script[siglen+2+i]; + } + char str[65]; printf("extracted privbob.(%s)\n",bits256_str(str,privkey)); + } + return(privkey); +} + +bits256 basilisk_swap_privBn_extract(bits256 *bobrefundp,char *bobcoin,bits256 bobdeposit,bits256 privBn) +{ + char destaddr[64]; + if ( bits256_nonz(privBn) == 0 ) + { + if ( bits256_nonz(bobdeposit) != 0 ) + *bobrefundp = LP_swap_spendtxid(bobcoin,destaddr,bobdeposit,0); + if ( bits256_nonz(*bobrefundp) != 0 ) + privBn = basilisk_swap_privbob_extract(bobcoin,*bobrefundp,0,0); + } + return(privBn); +} + +bits256 basilisk_swap_spendupdate(char *symbol,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t vout,char *aliceaddr,char *bobaddr) +{ + bits256 spendtxid,txid; char destaddr[64]; + txid = txids[utxoind]; + memset(&spendtxid,0,sizeof(spendtxid)); + /*if ( aliceaddr != 0 ) + printf("aliceaddr.(%s)\n",aliceaddr); + if ( bobaddr != 0 ) + printf("bobaddr.(%s)\n",bobaddr);*/ + if ( bits256_nonz(txid) != 0 ) + { + //char str[65]; + spendtxid = LP_swap_spendtxid(symbol,destaddr,txid,vout); + if ( bits256_nonz(spendtxid) != 0 ) + { + sentflags[utxoind] = 1; + if ( aliceaddr != 0 && strcmp(destaddr,aliceaddr) == 0 ) + { + //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 + { + //printf("OTHER dest spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); + 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; + } + } + } + } else printf("utxoind.%d null txid\n",utxoind); + return(spendtxid); +} + +#define BASILISK_ALICESPEND 0 +#define BASILISK_BOBSPEND 1 +#define BASILISK_BOBPAYMENT 2 +#define BASILISK_ALICEPAYMENT 3 +#define BASILISK_BOBDEPOSIT 4 +#define BASILISK_OTHERFEE 5 +#define BASILISK_MYFEE 6 +#define BASILISK_BOBREFUND 7 +#define BASILISK_BOBRECLAIM 8 +#define BASILISK_ALICERECLAIM 9 +#define BASILISK_ALICECLAIM 10 +//0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0 +char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" }; + +int32_t basilisk_isbobcoin(int32_t iambob,int32_t ind) +{ + switch ( ind ) + { + case BASILISK_MYFEE: return(iambob); break; + case BASILISK_OTHERFEE: return(!iambob); break; + case BASILISK_BOBSPEND: + case BASILISK_ALICEPAYMENT: + case BASILISK_ALICERECLAIM: + case BASILISK_ALICECLAIM: return(0); + break; + case BASILISK_BOBDEPOSIT: + case BASILISK_ALICESPEND: + case BASILISK_BOBPAYMENT: + case BASILISK_BOBREFUND: + case BASILISK_BOBRECLAIM: return(1); + break; + default: return(-1); break; + } +} + +// add blocktrail presence requirement for BTC +int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflags,bits256 paymentspent,bits256 Apaymentspent,bits256 depositspent) +{ + int32_t i,n = 0; + for (i=0; i>= 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,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)); + memset(secretAm256,0,sizeof(secretAm256)); + memset(secretBn,0,sizeof(secretBn)); + memset(secretBn256,0,sizeof(secretBn256)); + memset(pubkey33,0,sizeof(pubkey33)); + memset(txbytes,0,sizeof(txbytes)); + memset(sentflags,0,sizeof(sentflags)); + memset(myprivs,0,sizeof(myprivs)); + Apaymentspent = paymentspent = depositspent = rev = zero = pubA0 = pubB0 = pubB1 = privAm = privBn = myprivs[0]; + plocktime = dlocktime = 0; + src[0] = dest[0] = bobcoin[0] = alicecoin[0] = 0; + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + if ( (fstr= OS_filestr(&fsize,fname)) != 0 ) + { + if ( (item= cJSON_Parse(fstr)) != 0 ) + { + iambob = jint(item,"iambob"); + if ( (secretstr= jstr(item,"secretAm")) != 0 && strlen(secretstr) == 40 ) + decode_hex(secretAm,20,secretstr); + if ( (secretstr= jstr(item,"secretAm256")) != 0 && strlen(secretstr) == 64 ) + decode_hex(secretAm256,32,secretstr); + if ( (secretstr= jstr(item,"secretBn")) != 0 && strlen(secretstr) == 40 ) + decode_hex(secretBn,20,secretstr); + if ( (secretstr= jstr(item,"secretBn256")) != 0 && strlen(secretstr) == 64 ) + decode_hex(secretBn256,32,secretstr); + if ( (srcstr= jstr(item,"src")) != 0 ) + safecopy(src,srcstr,sizeof(src)); + if ( (deststr= jstr(item,"dest")) != 0 ) + safecopy(dest,deststr,sizeof(dest)); + if ( (dest33= jstr(item,"dest33")) != 0 && strlen(dest33) == 66 ) + { + decode_hex(pubkey33,33,dest33); + //for (i=0; i<33; i++) + // printf("%02x",pubkey33[i]); + //printf(" <- %s dest33\n",dest33); + } + 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"); + privkey = jbits256(item,"myprivs0"); + if ( bits256_nonz(privkey) != 0 ) + myprivs[0] = privkey; + privkey = jbits256(item,"myprivs1"); + if ( bits256_nonz(privkey) != 0 ) + myprivs[1] = privkey; + privkey = jbits256(item,"privAm"); + if ( bits256_nonz(privkey) != 0 ) + { + privAm = privkey; + //printf("set privAm <- %s\n",bits256_str(str,privAm)); + } + privkey = jbits256(item,"privBn"); + if ( bits256_nonz(privkey) != 0 ) + { + privBn = privkey; + //printf("set privBn <- %s\n",bits256_str(str,privBn)); + } + expiration = juint(item,"expiration"); + state = jint(item,"state"); + otherstate = jint(item,"otherstate"); + srcamount = SATOSHIDEN * jdouble(item,"srcamount"); + destamount = SATOSHIDEN * jdouble(item,"destamount"); + txids[BASILISK_BOBDEPOSIT] = jbits256(item,"Bdeposit"); + txids[BASILISK_BOBREFUND] = jbits256(item,"Brefund"); + txids[BASILISK_ALICECLAIM] = jbits256(item,"Aclaim"); + txids[BASILISK_BOBPAYMENT] = jbits256(item,"Bpayment"); + txids[BASILISK_ALICESPEND] = jbits256(item,"Aspend"); + txids[BASILISK_BOBRECLAIM] = jbits256(item,"Breclaim"); + txids[BASILISK_ALICEPAYMENT] = jbits256(item,"Apayment"); + txids[BASILISK_BOBSPEND] = jbits256(item,"Bspend"); + txids[BASILISK_ALICERECLAIM] = jbits256(item,"Areclaim"); + txids[BASILISK_MYFEE] = jbits256(item,"myfee"); + txids[BASILISK_OTHERFEE] = jbits256(item,"otherfee"); + free_json(item); + } + free(fstr); + } + sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + if ( (fstr= OS_filestr(&fsize,fname)) != 0 ) + { + //printf("%s -> (%s)\n",fname,fstr); + if ( (txobj= cJSON_Parse(fstr)) != 0 ) + { + paymentspent = jbits256(txobj,"paymentspent"); + Apaymentspent = jbits256(txobj,"Apaymentspent"); + depositspent = jbits256(txobj,"depositspent"); + if ( (array= jarray(&n,txobj,"values")) != 0 ) + for (i=0; i (%s)\n",fname,fstr); + if ( (txobj= cJSON_Parse(fstr)) != 0 ) + { + //printf("TXOBJ.(%s)\n",jprint(txobj,0)); + iambob = jint(txobj,"iambob"); + txid = jbits256(txobj,"txid"); + if ( bits256_nonz(txid) == 0 ) + continue; + txids[i] = txid; + if ( jstr(txobj,"Apayment") != 0 ) + strcpy(alicepaymentaddr,jstr(txobj,"Apayment")); + if ( jstr(txobj,"Bpayment") != 0 ) + strcpy(bobpaymentaddr,jstr(txobj,"Bpayment")); + if ( jstr(txobj,"Bdeposit") != 0 ) + strcpy(bobdepositaddr,jstr(txobj,"Bdeposit")); + if ( jobj(txobj,"tx") != 0 ) + { + 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; + if ( (symbol= jstr(txobj,"coin")) != 0 ) + { + if ( i == BASILISK_ALICESPEND || i == BASILISK_BOBPAYMENT || i == BASILISK_BOBDEPOSIT || i == BASILISK_BOBREFUND || i == BASILISK_BOBRECLAIM || i == BASILISK_ALICECLAIM ) + safecopy(bobcoin,symbol,sizeof(bobcoin)); + else if ( i == BASILISK_BOBSPEND || i == BASILISK_ALICEPAYMENT || i == BASILISK_ALICERECLAIM ) + safecopy(alicecoin,symbol,sizeof(alicecoin)); + if ( finishedflag == 0 ) + { + if ( (sentobj= LP_gettx(symbol,txid)) == 0 ) + { + char str2[65]; printf("%s %s ready to broadcast\n",symbol,bits256_str(str2,txid)); + } + else + { + struct iguana_info *coin; int32_t ht = -1; uint32_t locktime,blocktime; + checktxid = jbits256(sentobj,"txid"); + if ( (coin= LP_coinfind(symbol)) != 0 && (ht= LP_txheight(&locktime,&blocktime,coin,txid)) > 0 && ht > 0 ) + { + if ( coin->firstrefht == 0 || ht < coin->firstrefht ) + coin->firstrefht = ht; + } + if ( bits256_nonz(checktxid) == 0 ) + checktxid = jbits256(sentobj,"hash"); + if ( bits256_cmp(checktxid,txid) == 0 ) + { + //printf(">>>>>> %s txid %s\n",jprint(sentobj,0),bits256_str(str,txid)); + sentflags[i] = 1; + } + free_json(sentobj); + } + 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 ( 0 && finishedflag == 0 ) + printf("%s not finished\n",fname); + } + //printf("alicepayment.%s bobpayment.%s bobdeposit.%s\n",alicepaymentaddr,bobpaymentaddr,bobdepositaddr); + //printf("iambob.%d src.%s dest.%s bob.%s alice.%s pubA0.(%s)\n",iambob,src,dest,bobcoin,alicecoin,bits256_str(str,pubA0)); + Adestaddr[0] = destaddr[0] = 0; + 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 ) + { + if ( iambob == 0 ) + { + if ( (alice= LP_coinfind(alicecoin)) != 0 ) + { + bitcoin_address(Adestaddr,alice->taddr,alice->pubtype,pubkey33,33); + AAdest = Adestaddr; + } + if ( (bob= LP_coinfind(bobcoin)) != 0 ) + { + bitcoin_address(destaddr,bob->taddr,bob->pubtype,pubkey33,33); + Adest = destaddr; + } + } + else + { + if ( (bob= LP_coinfind(bobcoin)) != 0 ) + { + bitcoin_address(destaddr,bob->taddr,bob->pubtype,pubkey33,33); + Bdest = destaddr; + } + if ( (alice= LP_coinfind(alicecoin)) != 0 ) + { + bitcoin_address(Adestaddr,alice->taddr,alice->pubtype,pubkey33,33); + 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])); + if ( txbytes[BASILISK_ALICEPAYMENT] != 0 ) + sentflags[BASILISK_ALICEPAYMENT] = 1; + else if ( (sentobj= LP_gettx(alicecoin,txids[BASILISK_ALICEPAYMENT])) != 0 ) + { + sentflags[BASILISK_ALICEPAYMENT] = 1; + free_json(sentobj); + } + } + paymentspent = basilisk_swap_spendupdate(bobcoin,sentflags,txids,BASILISK_BOBPAYMENT,BASILISK_ALICESPEND,BASILISK_BOBRECLAIM,0,Adest,Bdest); + Apaymentspent = basilisk_swap_spendupdate(alicecoin,sentflags,txids,BASILISK_ALICEPAYMENT,BASILISK_ALICERECLAIM,BASILISK_BOBSPEND,0,AAdest,ABdest); + depositspent = basilisk_swap_spendupdate(bobcoin,sentflags,txids,BASILISK_BOBDEPOSIT,BASILISK_ALICECLAIM,BASILISK_BOBREFUND,0,Adest,Bdest); + finishedflag = basilisk_swap_isfinished(iambob,txids,sentflags,paymentspent,Apaymentspent,depositspent); + if ( iambob == 0 ) + { + if ( sentflags[BASILISK_ALICESPEND] == 0 ) + { + if ( sentflags[BASILISK_BOBPAYMENT] != 0 && bits256_nonz(paymentspent) == 0 ) + { + //if ( txbytes[BASILISK_ALICESPEND] == 0 ) + { + if ( bits256_nonz(txids[BASILISK_BOBPAYMENT]) != 0 ) + { + // alicespend + for (j=0; j<32; j++) + rev.bytes[j] = privAm.bytes[31 - j]; + //revcalc_rmd160_sha256(secretAm,rev);//privAm); + //vcalc_sha256(0,secretAm256,rev.bytes,sizeof(rev)); + 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]; + bitcoin_pubkey33(ctx,privpub33,myprivs[0]); + bitcoin_address(privaddr,0,60,privpub33,33); + printf("alicespend len.%d redeemlen.%d priv0addr.(%s) priv0.(%s)\n",len,redeemlen,privaddr,bits256_str(str,myprivs[0])); + } + for (j=0; j<32; j++) + rev.bytes[j] = myprivs[0].bytes[31 - j]; + 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]); + } + } + if ( txbytes[BASILISK_ALICESPEND] != 0 ) + { + txids[BASILISK_ALICESPEND] = LP_broadcast("alicespend",bobcoin,txbytes[BASILISK_ALICESPEND],zero); + if ( bits256_nonz(txids[BASILISK_ALICESPEND]) != 0 ) // tested + { + sentflags[BASILISK_ALICESPEND] = 1; + paymentspent = txids[BASILISK_ALICESPEND]; + } + } + } + } + if ( sentflags[BASILISK_ALICECLAIM] == 0 && sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(depositspent) == 0 ) + { + if ( time(NULL) > expiration ) + { + //if ( txbytes[BASILISK_ALICECLAIM] == 0 ) + { + 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,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]); + } + } + if ( txbytes[BASILISK_ALICECLAIM] != 0 ) + { + txids[BASILISK_ALICECLAIM] = LP_broadcast("aliceclaim",bobcoin,txbytes[BASILISK_ALICECLAIM],zero); + if ( bits256_nonz(txids[BASILISK_ALICECLAIM]) != 0 ) // tested + { + sentflags[BASILISK_ALICECLAIM] = 1; + depositspent = txids[BASILISK_ALICECLAIM]; + } + } + } else printf("now %u before expiration %u\n",(uint32_t)time(NULL),expiration); + } + if ( sentflags[BASILISK_ALICEPAYMENT] != 0 && bits256_nonz(Apaymentspent) == 0 && sentflags[BASILISK_ALICECLAIM] == 0 ) + { + //if ( txbytes[BASILISK_ALICERECLAIM] == 0 ) + { + 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,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]); + } + } + if ( txbytes[BASILISK_ALICERECLAIM] != 0 ) + { + txids[BASILISK_ALICERECLAIM] = LP_broadcast("alicereclaim",alicecoin,txbytes[BASILISK_ALICERECLAIM],zero); + if ( bits256_nonz(txids[BASILISK_ALICERECLAIM]) != 0 ) // tested + { + sentflags[BASILISK_ALICERECLAIM] = 1; + Apaymentspent = txids[BASILISK_ALICERECLAIM]; + } + } + } + } + else if ( iambob == 1 ) + { + if ( sentflags[BASILISK_BOBSPEND] == 0 && bits256_nonz(Apaymentspent) == 0 ) + { + printf("try to bobspend aspend.%s have privAm.%d\n",bits256_str(str,txids[BASILISK_ALICESPEND]),bits256_nonz(privAm)); + if ( bits256_nonz(txids[BASILISK_ALICESPEND]) != 0 || bits256_nonz(privAm) != 0 ) + { + //if ( txbytes[BASILISK_BOBSPEND] == 0 ) + { + if ( bits256_nonz(privAm) == 0 ) + { + privAm = basilisk_swap_privbob_extract(bobcoin,txids[BASILISK_ALICESPEND],0,1); + } + if ( bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 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]); + } + } + if ( txbytes[BASILISK_BOBSPEND] != 0 ) + { + txids[BASILISK_BOBSPEND] = LP_broadcast("bobspend",alicecoin,txbytes[BASILISK_BOBSPEND],zero); + if ( bits256_nonz(txids[BASILISK_BOBSPEND]) != 0 ) // tested + { + sentflags[BASILISK_BOBSPEND] = 1; + Apaymentspent = txids[BASILISK_BOBSPEND]; + } + } + } + } + if ( sentflags[BASILISK_BOBRECLAIM] == 0 && sentflags[BASILISK_BOBPAYMENT] != 0 && bits256_nonz(txids[BASILISK_BOBPAYMENT]) != 0 && time(NULL) > expiration && bits256_nonz(paymentspent) == 0 ) + { + //if ( txbytes[BASILISK_BOBRECLAIM] == 0 ) + { + // bobreclaim + redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,plocktime,pubA0,pubB0,pubB1,zero,privBn,secretAm,secretAm256,secretBn,secretBn256); + if ( redeemlen > 0 ) + { + len = basilisk_swapuserdata(userdata,zero,1,myprivs[1],redeemscript,redeemlen); + 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++) + printf("%02x",secretAm[z]); + printf(" secretAm, myprivs[1].(%s) bobreclaim.(%s)\n",bits256_str(str,myprivs[1]),txbytes[BASILISK_BOBRECLAIM]); + } + } + } + if ( txbytes[BASILISK_BOBRECLAIM] != 0 ) + { + txids[BASILISK_BOBRECLAIM] = LP_broadcast("bobreclaim",bobcoin,txbytes[BASILISK_BOBRECLAIM],zero); + if ( bits256_nonz(txids[BASILISK_BOBRECLAIM]) != 0 ) // tested + { + sentflags[BASILISK_BOBRECLAIM] = 1; + paymentspent = txids[BASILISK_BOBRECLAIM]; + } + } + } + if ( sentflags[BASILISK_BOBREFUND] == 0 && sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(depositspent) == 0 ) + { + if ( bits256_nonz(paymentspent) != 0 || time(NULL) > expiration ) + { + printf("do the refund!\n"); + //if ( txbytes[BASILISK_BOBREFUND] == 0 ) + { + revcalc_rmd160_sha256(secretBn,privBn); + 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,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 ) + { + txids[BASILISK_BOBREFUND] = LP_broadcast("bobrefund",bobcoin,txbytes[BASILISK_BOBREFUND],zero); + if ( bits256_nonz(txids[BASILISK_BOBREFUND]) != 0 ) // tested + { + sentflags[BASILISK_BOBREFUND] = 1; + depositspent = txids[BASILISK_BOBREFUND]; + } + } + } else printf("bobrefund's time %u vs expiration %u\n",(uint32_t)time(NULL),expiration); + } + } + } + //printf("finish.%d iambob.%d REFUND %d %d %d %d\n",finishedflag,iambob,sentflags[BASILISK_BOBREFUND] == 0,sentflags[BASILISK_BOBDEPOSIT] != 0,bits256_nonz(txids[BASILISK_BOBDEPOSIT]) != 0,bits256_nonz(depositspent) == 0); + if ( sentflags[BASILISK_ALICESPEND] != 0 || sentflags[BASILISK_BOBRECLAIM] != 0 ) + sentflags[BASILISK_BOBPAYMENT] = 1; + if ( sentflags[BASILISK_ALICERECLAIM] != 0 || sentflags[BASILISK_BOBSPEND] != 0 ) + sentflags[BASILISK_ALICEPAYMENT] = 1; + if ( sentflags[BASILISK_ALICECLAIM] != 0 || sentflags[BASILISK_BOBREFUND] != 0 ) + sentflags[BASILISK_BOBDEPOSIT] = 1; + for (i=0; inumswaps; i++) + if ( (swap= myinfo->swaps[i]) != 0 && swap->I.req.requestid == requestid && swap->I.req.quoteid == quoteid ) + { + jaddi(array,basilisk_swapjson(swap)); + flag = 1; + break; + }*/ + if ( flag == 0 ) + { + if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid)) != 0 ) + { + jaddi(array,item); + //if ( (status= jstr(item,"status")) != 0 && strcmp(status,"pending") == 0 ) + // break; + } + } + } + fclose(fp); + } + jaddstr(retjson,"result","success"); + jadd(retjson,"swaps",array); + if ( cJSON_GetArraySize(array) > 0 ) + { + totalsobj = cJSON_CreateObject(); + for (Btotal=i=0; i 0 && Btotal < 0 ) + jaddnum(retjson,"avebuy",(double)-Btotal/Ktotal); + else if ( Ktotal < 0 && Btotal > 0 ) + jaddnum(retjson,"avesell",(double)-Btotal/Ktotal); + } + array = cJSON_CreateArray(); + /*for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) + { + if ( myinfo->linfos[i].base[0] != 0 && myinfo->linfos[i].rel[0] != 0 ) + jaddi(array,linfo_json(&myinfo->linfos[i])); + } + jadd(retjson,"quotes",array);*/ + portable_mutex_unlock(&LP_swaplistmutex); + return(jprint(retjson,1)); +} + +char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid) +{ + char *liststr,*retstr = 0; cJSON *retjson,*array,*item; int32_t i,n; + if ( (liststr= basilisk_swaplist()) != 0 ) + { + if ( (retjson= cJSON_Parse(liststr)) != 0 ) + { + if ( (array= jarray(&n,retjson,"swaps")) != 0 ) + { + for (i=0; ierrors < maxerrs || peer->good >= LP_MINPEER_GOOD) ) + { + if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) == 0 ) + { + if ( peer != 0 ) + { + peer->errors++; + peer->good *= LP_PEERGOOD_ERRORDECAY; + } else printf("%s error on (%s:%u) without peer\n",debugstr,destip,port); + } + else if ( peer != 0 ) + peer->good++; + } + return(retstr); +} + +char *LP_isitme(char *destip,uint16_t destport) +{ + if ( LP_mypeer != 0 && strcmp(destip,LP_mypeer->ipaddr) == 0 && LP_mypeer->port == destport ) + { + //printf("no need to notify ourselves\n"); + return(clonestr("{\"result\":\"success\"}")); + } else return(0); +} + +char *issue_LP_getpeers(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/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_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&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)); +} + +char *issue_LP_clientgetutxos(char *destip,uint16_t destport,char *coin,int32_t lastn) +{ + char url[512];//,*retstr; + sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=127.0.0.1&port=0",destip,destport,coin,lastn); + return(LP_issue_curl("clientgetutxos",destip,destport,url)); + //retstr = issue_curlt(url,LP_HTTP_TIMEOUT); + //printf("%s clientgetutxos.(%s)\n",url,retstr); + //return(retstr); +} + +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&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_getprices(char *destip,uint16_t destport) +{ + char url[512]; + sprintf(url,"http://%s:%u/api/stats/getprices",destip,destport); + //printf("getutxo.(%s)\n",url); + return(LP_issue_curl("getprices",destip,destport,url)); + //return(issue_curlt(url,LP_HTTP_TIMEOUT)); +} + +cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params) +{ + char *retstr; cJSON *retjson = 0; + 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 || strcmp(method,"validateaddress") == 0 ) + { + retstr = bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,method,params); + if ( retstr != 0 && retstr[0] != 0 ) + { + //printf("%s: %s.%s -> (%s)\n",coin->symbol,method,params,retstr); + retjson = cJSON_Parse(retstr); + free(retstr); + } + //usleep(100); + //printf("dpow_gettxout.(%s)\n",retstr); + } else retjson = cJSON_Parse("{\"result\":\"disabled\"}"); + } else printf("bitcoin_json cant talk to NULL coin\n"); + return(retjson); +} + +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); + return(bitcoin_json(coin,"getinfo","[]")); +} + +cJSON *LP_getmempool(char *symbol) +{ + struct iguana_info *coin = LP_coinfind(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); + return(bitcoin_json(coin,"gettxout",buf)); +} + +cJSON *LP_gettx(char *symbol,bits256 txid) +{ + char buf[128],str[65]; struct iguana_info *coin = LP_coinfind(symbol); + sprintf(buf,"[\"%s\", 1]",bits256_str(str,txid)); + return(bitcoin_json(coin,"getrawtransaction",buf)); +} + +cJSON *LP_getblock(char *symbol,bits256 txid) +{ + char buf[128],str[65]; struct iguana_info *coin = LP_coinfind(symbol); + sprintf(buf,"[\"%s\"]",bits256_str(str,txid)); + return(bitcoin_json(coin,"getblock",buf)); +} + +cJSON *LP_getblockhashstr(char *symbol,char *blockhashstr) +{ + char buf[128]; struct iguana_info *coin = LP_coinfind(symbol); + sprintf(buf,"[\"%s\"]",blockhashstr); + return(bitcoin_json(coin,"getblock",buf)); +} + +cJSON *LP_listunspent(char *symbol,char *coinaddr) +{ + char buf[128]; struct iguana_info *coin = LP_coinfind(symbol); + sprintf(buf,"[0, 99999999, [\"%s\"]]",coinaddr); + return(bitcoin_json(coin,"listunspent",buf)); +} + +cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t count,int32_t skip) +{ + char buf[128]; struct iguana_info *coin = LP_coinfind(symbol); + if ( count == 0 ) + count = 100; + sprintf(buf,"[\"%s\", %d, %d, true]",coinaddr,count,skip); + return(bitcoin_json(coin,"listtransactions",buf)); +} + +cJSON *LP_validateaddress(char *symbol,char *address) +{ + char buf[512]; struct iguana_info *coin = LP_coinfind(symbol); + sprintf(buf,"[\"%s\"]",address); + return(bitcoin_json(coin,"validateaddress",buf)); +} + +cJSON *LP_importprivkey(char *symbol,char *wifstr,char *label,int32_t flag) +{ + 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) +{ + char buf[1024],*retstr; cJSON *validatejson; int32_t isvalid=0,doneflag = 0; struct iguana_info *coin = LP_coinfind(symbol); + if ( coin == 0 ) + return(-2); + if ( (validatejson= LP_validateaddress(symbol,address)) != 0 ) + { + if ( (isvalid= is_cJSON_True(jobj(validatejson,"isvalid")) != 0) != 0 ) + { + if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 ) + doneflag = 1; + } + free_json(validatejson); + } + if ( isvalid == 0 ) + return(-1); + if ( doneflag != 0 ) + return(0); // success + sprintf(buf,"[\"%s\", \"%s\", false]",address,address); + if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"importaddress",buf)) != 0 ) + { + //printf("importaddress.(%s %s) -> (%s)\n",symbol,address,retstr); + free(retstr); + } //else printf("importaddress.(%s %s)\n",symbol,address); + return(1); +} + +double LP_getestimatedrate(char *symbol) +{ + char buf[512],*retstr; double rate = 20; struct iguana_info *coin = LP_coinfind(symbol); + 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] != '-' ) + { + rate = atof(retstr) / 1024.; + //printf("estimated rate.(%s) %s -> %.8f\n",symbol,retstr,rate); + } + free(retstr); + } + } 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 = LP_MIN_TXFEE; + return(txfee); +} + +char *LP_blockhashstr(char *symbol,int32_t height) +{ + cJSON *array; char *paramstr,*retstr; struct iguana_info *coin = LP_coinfind(symbol); + if ( coin == 0 ) + return(0); + array = cJSON_CreateArray(); + jaddinum(array,height); + paramstr = jprint(array,1); + retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"getblockhash",paramstr); + free(paramstr); + return(retstr); +} + +char *LP_sendrawtransaction(char *symbol,char *signedtx) +{ + cJSON *array; char *paramstr,*retstr; struct iguana_info *coin = LP_coinfind(symbol); + if ( coin == 0 ) + return(0); + array = cJSON_CreateArray(); + jaddistr(array,signedtx); + paramstr = jprint(array,1); + retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"sendrawtransaction",paramstr); + //printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr); + free(paramstr); + return(retstr); +} + +char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkeys,struct vin_info *V) +{ + cJSON *array,*json; int32_t len; uint8_t *data; char *paramstr,*retstr,*hexstr,*signedtx=0; struct iguana_info *coin = LP_coinfind(symbol); + memset(signedtxidp,0,sizeof(*signedtxidp)); + *completedp = 0; + if ( coin == 0 ) + { + printf("LP_signrawtx cant find coin.(%s)\n",symbol); + return(0); + } + array = cJSON_CreateArray(); + jaddistr(array,rawtx); + jaddi(array,jduplicate(vins)); + jaddi(array,jduplicate(privkeys)); + paramstr = jprint(array,1); + //printf("signrawtransaction\n"); + if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"signrawtransaction",paramstr)) != 0 ) + { + if ( (json= cJSON_Parse(retstr)) != 0 ) + { + if ( (hexstr= jstr(json,"hex")) != 0 ) + { + len = (int32_t)strlen(hexstr); + signedtx = calloc(1,len+1); + strcpy(signedtx,hexstr); + *completedp = is_cJSON_True(jobj(json,"complete")); + data = malloc(len >> 1); + decode_hex(data,len>>1,hexstr); + *signedtxidp = bits256_doublesha256(0,data,len >> 1); + } + //else + printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr); + free_json(json); + } + free(retstr); + } + free(paramstr); + return(signedtx); +} + +cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t height) +{ + cJSON *json = 0; int32_t flag = 0; + if ( blockhashstr == 0 ) + blockhashstr = LP_blockhashstr(symbol,height), flag = 1; + if ( blockhashstr != 0 ) + { + if ( (json= LP_getblockhashstr(symbol,blockhashstr)) != 0 ) + { + if ( *heightp != 0 ) + { + *heightp = juint(json,"height"); + if ( height >= 0 && *heightp != height ) + { + printf("unexpected height %d vs %d for %s (%s)\n",*heightp,height,blockhashstr,jprint(json,0)); + *heightp = -1; + free_json(json); + json = 0; + } + } + } + if ( flag != 0 && blockhashstr != 0 ) + free(blockhashstr); + } + return(json); +} + diff --git a/iguana/exchanges/LP_scan.c b/iguana/exchanges/LP_scan.c new file mode 100644 index 000000000..60a66c006 --- /dev/null +++ b/iguana/exchanges/LP_scan.c @@ -0,0 +1,747 @@ + +/****************************************************************************** + * 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_scan.c +// marketmaker +// + + +struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr) +{ + struct LP_address *ap; + HASH_FIND(hh,coin->addresses,coinaddr,strlen(coinaddr),ap); + return(ap); +} + +struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr) +{ + struct LP_address *ap; + ap = calloc(1,sizeof(*ap)); + safecopy(ap->coinaddr,coinaddr,sizeof(ap->coinaddr)); + HASH_ADD_KEYPTR(hh,coin->addresses,ap->coinaddr,strlen(ap->coinaddr),ap); + return(ap); +} + +struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr) +{ + struct LP_address *ap; + if ( (ap= _LP_addressfind(coin,coinaddr)) == 0 ) + ap = _LP_addressadd(coin,coinaddr); + return(ap); +} + +struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid) +{ + struct LP_transaction *tx; + portable_mutex_lock(&coin->txmutex); + HASH_FIND(hh,coin->transactions,txid.bytes,sizeof(txid),tx); + portable_mutex_unlock(&coin->txmutex); + return(tx); +} + +struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins,uint32_t timestamp) +{ + struct LP_transaction *tx; int32_t i; + if ( (tx= LP_transactionfind(coin,txid)) == 0 ) + { + //char str[65]; printf("%s ht.%d u.%u NEW TXID.(%s) vouts.[%d]\n",coin->symbol,height,timestamp,bits256_str(str,txid),numvouts); + //if ( bits256_nonz(txid) == 0 && tx->height == 0 ) + // getchar(); + tx = calloc(1,sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts)); + for (i=0; ioutpoints[i].spendvini = -1; + tx->height = height; + tx->numvouts = numvouts; + tx->numvins = numvins; + tx->timestamp = timestamp; + tx->txid = txid; + portable_mutex_lock(&coin->txmutex); + HASH_ADD_KEYPTR(hh,coin->transactions,tx->txid.bytes,sizeof(tx->txid),tx); + portable_mutex_unlock(&coin->txmutex); + } // else printf("warning adding already existing txid %s\n",bits256_str(str,tx->txid)); + return(tx); +} + +int32_t LP_txheight(uint32_t *timestampp,uint32_t *blocktimep,struct iguana_info *coin,bits256 txid) +{ + bits256 blockhash; cJSON *blockobj,*txobj; int32_t height = 0; + if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 ) + { + *timestampp = juint(txobj,"locktime"); + *blocktimep = juint(txobj,"blocktime"); + blockhash = jbits256(txobj,"blockhash"); + if ( bits256_nonz(blockhash) != 0 && (blockobj= LP_getblock(coin->symbol,blockhash)) != 0 ) + { + height = jint(blockobj,"height"); + //printf("%s LP_txheight.%d\n",coin->symbol,height); + free_json(blockobj); + } //else printf("%s LP_txheight error (%s)\n",coin->symbol,jprint(txobj,0)); + free_json(txobj); + } + return(height); +} + +int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight) +{ + int32_t i,ht,num = 0; uint32_t timestamp,blocktime; struct LP_transaction *tx,*tmp; + HASH_ITER(hh,coin->transactions,tx,tmp) + { + for (i=0; inumvouts; i++) + { + if ( bits256_nonz(tx->outpoints[i].spendtxid) == 0 ) + continue; + if ( (ht= tx->outpoints[i].spendheight) == 0 ) + { + tx->outpoints[i].spendheight = LP_txheight(×tamp,&blocktime,coin,tx->outpoints[i].spendtxid); + } + if ( (ht= tx->outpoints[i].spendheight) != 0 && ht > lastheight ) + { + char str[65]; printf("clear spend %s/v%d at ht.%d > lastheight.%d\n",bits256_str(str,tx->txid),i,ht,lastheight); + tx->outpoints[i].spendheight = 0; + tx->outpoints[i].spendvini = -1; + memset(tx->outpoints[i].spendtxid.bytes,0,sizeof(bits256)); + } + } + } + return(num); +} + +uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_info *coin,bits256 txid,int32_t vout) +{ + uint64_t interest,value = 0; cJSON *txobj,*sobj,*array; int32_t n=0; + *interestp = 0; + destaddr[0] = 0; + if ( (txobj= LP_gettxout(coin->symbol,txid,vout)) != 0 ) + { + if ( (value= jdouble(txobj,"amount")*SATOSHIDEN) == 0 && (value= jdouble(txobj,"value")*SATOSHIDEN) == 0 ) + { + char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",coin->symbol,bits256_str(str,txid),jprint(txobj,0),vout); + } + else if ( strcmp(coin->symbol,"KMD") == 0 ) + { + if ( (interest= jdouble(txobj,"interest")) != 0. ) + { + //printf("add interest of %.8f to %.8f\n",interest,dstr(value)); + *interestp = SATOSHIDEN * interest; + } + } + if ( (sobj= jobj(txobj,"scriptPubKey")) != 0 && (array= jarray(&n,sobj,"addresses")) != 0 ) + { + strcpy(destaddr,jstri(array,0)); + 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("%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,int32_t iter) +{ + struct LP_transaction *tx; char *address; int32_t i,n,height,numvouts,numvins,spentvout; uint32_t timestamp,blocktime; cJSON *txobj,*vins,*vouts,*vout,*vin,*sobj,*addresses; bits256 spenttxid; char str[65]; + if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 ) + { + //printf("TX.(%s)\n",jprint(txobj,0)); + height = LP_txheight(×tamp,&blocktime,coin,txid); + if ( timestamp == 0 && height > 0 ) + timestamp = blocktime; + vins = jarray(&numvins,txobj,"vin"); + vouts = jarray(&numvouts,txobj,"vout"); + if ( iter == 0 && vouts != 0 && (tx= LP_transactionadd(coin,txid,height,numvouts,numvins,timestamp)) != 0 ) + { + for (i=0; ioutpoints[i].value= SATOSHIDEN * jdouble(vout,"value")) == 0 ) + tx->outpoints[i].value = SATOSHIDEN * jdouble(vout,"amount"); + tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest"); + if ( (sobj= jobj(vout,"scriptPubKey")) != 0 ) + { + if ( (addresses= jarray(&n,sobj,"addresses")) != 0 && n > 0 ) + { + if ( n > 1 ) + printf("LP_transactioninit: txid.(%s) multiple addresses.[%s]\n",bits256_str(str,txid),jprint(addresses,0)); + if ( (address= jstri(addresses,0)) != 0 && strlen(address) < sizeof(tx->outpoints[i].coinaddr) ) + { + strcpy(tx->outpoints[i].coinaddr,address); + } else if ( tx->outpoints[i].value != 0 ) + printf("LP_transactioninit: unexpected address.(%s)\n",jprint(addresses,0)); + } + //else if ( tx->outpoints[i].value != 0 ) + // printf("LP_transactioninit: pax tx ht.%d i.%d (%s) n.%d\n",height,i,jprint(vout,0),n); + } + } + } + if ( iter == 1 && vins != 0 ) + { + for (i=0; inumvouts ) + { + tx->outpoints[spentvout].spendtxid = txid; + tx->outpoints[spentvout].spendvini = i; + tx->outpoints[spentvout].spendheight = height; + //printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height); + } else printf("LP_transactioninit: %s spentvout.%d < numvouts.%d\n",bits256_str(str,spenttxid),spentvout,tx->numvouts); + } //else printf("LP_transactioninit: couldnt find (%s) ht.%d %s\n",bits256_str(str,spenttxid),height,jprint(vin,0)); + if ( bits256_cmp(spenttxid,txid) == 0 ) + printf("spending same tx's %p vout ht.%d %s.[%d] s%d\n",tx,height,bits256_str(str,txid),tx!=0?tx->numvouts:0,spentvout); + } + } + free_json(txobj); + return(0); + } //else printf("LP_transactioninit error for %s %s\n",coin->symbol,bits256_str(str,txid)); + return(-1); +} + +int32_t LP_blockinit(struct iguana_info *coin,int32_t height) +{ + int32_t i,j,iter,numtx,checkht=-1; cJSON *blockobj,*txs; bits256 txid; struct LP_transaction *tx; + if ( (blockobj= LP_blockjson(&checkht,coin->symbol,0,height)) != 0 && checkht == height ) + { + if ( (txs= jarray(&numtx,blockobj,"tx")) != 0 ) + { + for (iter=0; iter<2; iter++) + for (i=0; iheight == 0 ) + tx->height = height; + else if ( tx->height != height ) + { + printf("LP_blockinit: tx->height %d != %d\n",tx->height,height); + tx->height = height; + } + if ( iter == 1 ) + for (j=0; j<10; j++) + { + if (LP_transactioninit(coin,txid,iter) == 0 ) + break; + printf("transaction ht.%d init error.%d, pause\n",height,j); + sleep(1); + } + } + else + { + for (j=0; j<10; j++) + { + if (LP_transactioninit(coin,txid,iter) == 0 ) + break; + printf("transaction ht.%d init error.%d, pause\n",height,j); + sleep(1); + } + } + } + } + free_json(blockobj); + } + if ( checkht == height ) + return(0); + else return(-1); +} + +int32_t LP_scanblockchain(struct iguana_info *coin,int32_t startheight,int32_t endheight) +{ + int32_t ht,n = 0; + for (ht=startheight; ht<=endheight; ht++) + { + if ( LP_blockinit(coin,ht) < 0 ) + { + printf("error loading block.%d of (%d, %d)\n",ht,startheight,endheight); + return(ht-1); + } + n++; + if ( (n % 1000) == 0 ) + fprintf(stderr,"%.1f%% ",100. * (double)n/(endheight-startheight+1)); + } + return(endheight); +} + +char *banned_txids[] = +{ + "78cb4e21245c26b015b888b14c4f5096e18137d2741a6de9734d62b07014dfca", //233559 + "00697be658e05561febdee1aafe368b821ca33fbb89b7027365e3d77b5dfede5", //234172 + "e909465788b32047c472d73e882d79a92b0d550f90be008f76e1edaee6d742ea", //234187 + "f56c6873748a327d0b92b8108f8ec8505a2843a541b1926022883678fb24f9dc", //234188 + "abf08be07d8f5b3a433ddcca7ef539e79a3571632efd6d0294ec0492442a0204", //234213 + "3b854b996cc982fba8c06e76cf507ae7eed52ab92663f4c0d7d10b3ed879c3b0", //234367 + "fa9e474c2cda3cb4127881a40eb3f682feaba3f3328307d518589024a6032cc4", //234635 + "ca746fa13e0113c4c0969937ea2c66de036d20274efad4ce114f6b699f1bc0f3", //234662 + "43ce88438de4973f21b1388ffe66e68fda592da38c6ef939be10bb1b86387041", //234697 + "0aeb748de82f209cd5ff7d3a06f65543904c4c17387c9d87c65fd44b14ad8f8c", //234899 + "bbd3a3d9b14730991e1066bd7c626ca270acac4127131afe25f877a5a886eb25", //235252 + "fa9943525f2e6c32cbc243294b08187e314d83a2870830180380c3c12a9fd33c", //235253 + "a01671c8775328a41304e31a6693bbd35e9acbab28ab117f729eaba9cb769461", //235265 + "2ef49d2d27946ad7c5d5e4ab5c089696762ff04e855f8ab48e83bdf0cc68726d", //235295 + "c85dcffb16d5a45bd239021ad33443414d60224760f11d535ae2063e5709efee", //235296 + // all vouts banned + "c4ea1462c207547cd6fb6a4155ca6d042b22170d29801a465db5c09fec55b19d", //246748 + "305dc96d8bc23a69d3db955e03a6a87c1832673470c32fe25473a46cc473c7d1", //247204 +}; + +int32_t komodo_bannedset(int32_t *indallvoutsp,bits256 *array,int32_t max) +{ + int32_t i; + if ( sizeof(banned_txids)/sizeof(*banned_txids) > max ) + { + fprintf(stderr,"komodo_bannedset: buffer too small %ld vs %d\n",sizeof(banned_txids)/sizeof(*banned_txids),max); + exit(-1); + } + for (i=0; i b) + */ + aval = ((struct LP_address *)a)->balance; + bval = ((struct LP_address *)b)->balance; + //printf("%.8f vs %.8f -> %d\n",dstr(aval),dstr(bval),(int32_t)(bval - aval)); + return((aval == bval) ? 0 : ((aval < bval) ? 1 : -1)); +} + +// a primitive restore can be done by loading the previous snapshot and creating a virtual tx for all the balance at height-1. this wont allow anything but new snapshots, but for many use cases that is all that is needed + +cJSON *LP_snapshot(struct iguana_info *coin,int32_t height) +{ + static bits256 bannedarray[64]; static int32_t numbanned,indallvouts,maxsnapht; static char lastcoin[16]; + struct LP_transaction *tx,*tmp; struct LP_address *ap,*atmp; int32_t isKMD,i,j,n,skipflag=0,startht,endht,ht; uint64_t banned_balance=0,balance=0,noaddr_balance=0; cJSON *retjson,*array,*item; + if ( bannedarray[0].txid == 0 ) + numbanned = komodo_bannedset(&indallvouts,bannedarray,(int32_t)(sizeof(bannedarray)/sizeof(*bannedarray))); + startht = 1; + endht = height-1; + if ( strcmp(coin->symbol,lastcoin) == 0 ) + { + if ( maxsnapht > height ) + skipflag = 1; + else startht = maxsnapht+1; + } + else + { + maxsnapht = 0; + strcpy(lastcoin,coin->symbol); + } + retjson = cJSON_CreateObject(); + if ( skipflag == 0 && startht < endht ) + { + if ( (ht= LP_scanblockchain(coin,startht,endht)) < endht ) + { + if ( ht > maxsnapht ) + { + maxsnapht = ht; + printf("maxsnapht.%d for %s\n",maxsnapht,coin->symbol); + } + sleep(10); + if ( (ht= LP_scanblockchain(coin,maxsnapht+1,endht)) < endht ) + { + if ( ht > maxsnapht ) + { + maxsnapht = ht; + printf("maxsnapht.%d for %s\n",maxsnapht,coin->symbol); + } + jaddstr(retjson,"error","blockchain scan error"); + return(retjson); + } + } + if ( ht > maxsnapht ) + { + maxsnapht = ht; + printf("maxsnapht.%d for %s\n",maxsnapht,coin->symbol); + } + } + portable_mutex_lock(&coin->txmutex); + HASH_ITER(hh,coin->addresses,ap,atmp) + { + ap->balance = 0; + } + isKMD = (strcmp(coin->symbol,"KMD") == 0) ? 1 : 0; + HASH_ITER(hh,coin->transactions,tx,tmp) + { + if ( tx->height < height ) + { + if ( isKMD != 0 ) + { + for (j=0; jtxid) == 0 ) + break; + if ( j < numbanned ) + { + for (i=0; inumvouts; i++) + banned_balance += tx->outpoints[i].value; + //char str[256]; printf("skip banned %s bannedtotal: %.8f\n",bits256_str(str,tx->txid),dstr(banned_balance)); + continue; + } + } + for (i=0; inumvouts; i++) + { + if ( (ht=tx->outpoints[i].spendheight) > 0 && ht < height ) + continue; + if ( tx->outpoints[i].coinaddr[0] != 0 && (ap= _LP_address(coin,tx->outpoints[i].coinaddr)) != 0 ) + { + balance += tx->outpoints[i].value; + ap->balance += tx->outpoints[i].value; + //printf("(%s/%s) %.8f %.8f\n",tx->outpoints[i].coinaddr,ap->coinaddr,dstr(tx->outpoints[i].value),dstr(ap->balance)); + } else noaddr_balance += tx->outpoints[i].value; + } + } + } + HASH_SORT(coin->addresses,sort_balance); + portable_mutex_unlock(&coin->txmutex); + printf("%s balance %.8f at height.%d\n",coin->symbol,dstr(balance),height); + array = cJSON_CreateArray(); + n = 0; + HASH_ITER(hh,coin->addresses,ap,atmp) + { + if ( ap->balance != 0 ) + { + item = cJSON_CreateObject(); + jaddnum(item,ap->coinaddr,dstr(ap->balance)); + jaddi(array,item); + n++; + } + } + jadd(retjson,"balances",array); + jaddstr(retjson,"coin",coin->symbol); + jaddnum(retjson,"height",height); + jaddnum(retjson,"numaddresses",n); + jaddnum(retjson,"total",dstr(balance)); + jaddnum(retjson,"noaddr_total",dstr(noaddr_balance)); + return(retjson); +} + +char *LP_snapshot_balance(struct iguana_info *coin,int32_t height,cJSON *argjson) +{ + cJSON *snapjson,*retjson,*balances,*array,*addrs,*child,*item,*item2; char *coinaddr,*refaddr; int32_t i,n,j,m; uint64_t total=0,value,balance = 0; + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + if ( (snapjson= LP_snapshot(coin,height)) != 0 ) + { + total = jdouble(snapjson,"total") * SATOSHIDEN; + if ( (addrs= jarray(&m,argjson,"addresses")) != 0 ) + { + if ( (balances= jarray(&n,snapjson,"balances")) != 0 ) + { + for (i=0; ichild) != 0 ) + { + value = (uint64_t)(child->valuedouble * SATOSHIDEN); + if ( (refaddr= get_cJSON_fieldname(child)) != 0 ) + { + //printf("check %s %.8f against %d\n",refaddr,dstr(value),m); + for (j=0; jsymbol); + jaddnum(retjson,"height",height); + jaddnum(retjson,"balance",dstr(balance)); + jaddnum(retjson,"total",dstr(total)); + return(jprint(retjson,1)); +} + +char *LP_dividends(struct iguana_info *coin,int32_t height,cJSON *argjson) +{ + cJSON *array,*retjson,*item,*child,*exclude=0; int32_t i,j,emitted=0,dusted=0,n,execflag=0,flag,iter,numexcluded=0; char buf[1024],*field,*prefix="",*suffix=""; uint64_t dustsum=0,excluded=0,total=0,dividend=0,value,val,emit=0,dust=0; double ratio = 1.; + if ( (retjson= LP_snapshot(coin,height)) != 0 ) + { + //printf("SNAPSHOT.(%s)\n",retstr); + if ( (array= jarray(&n,retjson,"balances")) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) != 0 ) + { + if ( argjson != 0 ) + { + exclude = jarray(&numexcluded,argjson,"exclude"); + dust = (uint64_t)(jdouble(argjson,"dust") * SATOSHIDEN); + dividend = (uint64_t)(jdouble(argjson,"dividend") * SATOSHIDEN); + if ( jstr(argjson,"prefix") != 0 ) + prefix = jstr(argjson,"prefix"); + if ( jstr(argjson,"suffix") != 0 ) + suffix = jstr(argjson,"suffix"); + execflag = jint(argjson,"system"); + } + for (iter=0; iter<2; iter++) + { + for (i=0; ichild) != 0 ) + { + value = (uint64_t)(child->valuedouble * SATOSHIDEN); + if ( (field= get_cJSON_fieldname(child)) != 0 ) + { + for (j=0; j= dust ) + { + sprintf(buf,"%s %s %.8f %s",prefix,field,dstr(val),suffix); + if ( execflag != 0 ) + { + if ( system(buf) != 0 ) + printf("error system.(%s)\n",buf); + } + else printf("%s\n",buf); + emit += val; + emitted++; + } else dustsum += val, dusted++; + } + } + } + } + if ( iter == 0 ) + { + if ( total > 0 ) + { + if ( dividend == 0 ) + dividend = total; + ratio = (double)dividend / total; + } else break; + } + } + } + } + free_json(retjson); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"coin",coin->symbol); + jaddnum(retjson,"height",height); + jaddnum(retjson,"total",dstr(total)); + jaddnum(retjson,"emitted",emitted); + jaddnum(retjson,"excluded",dstr(excluded)); + if ( dust != 0 ) + { + jaddnum(retjson,"dust",dstr(dust)); + jaddnum(retjson,"dusted",dusted); + } + if ( dustsum != 0 ) + jaddnum(retjson,"dustsum",dstr(dustsum)); + jaddnum(retjson,"dividend",dstr(dividend)); + jaddnum(retjson,"dividends",dstr(emit)); + jaddnum(retjson,"ratio",ratio); + if ( execflag != 0 ) + jaddnum(retjson,"system",execflag); + /*if ( prefix[0] != 0 ) + jaddstr(retjson,"prefix",prefix); + if ( suffix[0] != 0 ) + jaddstr(retjson,"suffix",suffix);*/ + return(jprint(retjson,1)); + } + return(clonestr("{\"error\":\"symbol not found\"}")); +} + +int64_t basilisk_txvalue(char *symbol,bits256 txid,int32_t vout) +{ + char destaddr[64]; uint64_t value,interest = 0; struct iguana_info *coin; + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(0); + //char str[65]; printf("%s txvalue.(%s)\n",symbol,bits256_str(str,txid)); + value = LP_txinterestvalue(&interest,destaddr,coin,txid,vout); + return(value + interest); +} + +uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout) +{ + struct LP_transaction *tx; char _coinaddr[64]; uint64_t interest = 0,value = 0; struct iguana_info *coin; + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(0); + if ( coinaddr != 0 ) + coinaddr[0] = 0; + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + { + if ( vout < tx->numvouts ) + { + if ( bits256_nonz(tx->outpoints[vout].spendtxid) != 0 ) + { + //char str[65]; printf("%s/v%d is spent\n",bits256_str(str,txid),vout); + return(0); + } + else + { + 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); + } + } else printf("vout.%d >= tx->numvouts.%d\n",vout,tx->numvouts); + } + if ( tx == 0 ) + { + LP_transactioninit(coin,txid,0); + LP_transactioninit(coin,txid,1); + } + if ( coinaddr == 0 ) + coinaddr = _coinaddr; + value = LP_txinterestvalue(&interest,coinaddr,coin,txid,vout); + //printf("coinaddr.(%s) value %.8f interest %.8f\n",coinaddr,dstr(value),dstr(interest)); + return(value + interest); +} + +int32_t LP_spendsearch(bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 searchtxid,int32_t searchvout) +{ + struct LP_transaction *tx; struct iguana_info *coin; + *indp = -1; + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(-1); + memset(spendtxidp,0,sizeof(*spendtxidp)); + if ( (tx= LP_transactionfind(coin,searchtxid)) != 0 ) + { + if ( searchvout < tx->numvouts && tx->outpoints[searchvout].spendvini >= 0 ) + { + *spendtxidp = tx->outpoints[searchvout].spendtxid; + *indp = tx->outpoints[searchvout].spendvini; + return(tx->outpoints[searchvout].spendheight); + } + } + return(-1); +} + +int32_t LP_mempoolscan(char *symbol,bits256 searchtxid) +{ + int32_t i,n; cJSON *array; bits256 txid; struct iguana_info *coin; struct LP_transaction *tx; + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(-1); + if ( (array= LP_getmempool(symbol)) != 0 ) + { + if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; icoin->symbol)) == 0 || coin->inactive != 0 ) + return(-1); + numconfirms = -1; + if ( (txobj= LP_gettx(rawtx->coin->symbol,rawtx->I.signedtxid)) != 0 ) + { + numconfirms = jint(txobj,"confirmations"); + free_json(txobj); + } + else if ( mempool != 0 && LP_mempoolscan(rawtx->coin->symbol,rawtx->I.signedtxid) >= 0 ) + numconfirms = 0; +//#endif + return(numconfirms); +} + +int32_t LP_waitmempool(char *symbol,bits256 txid,int32_t duration) +{ + uint32_t expiration = (uint32_t)time(NULL) + duration; + while ( time(NULL) < expiration ) + { + if ( LP_mempoolscan(symbol,txid) >= 0 ) + return(0); + usleep(500000); + } + return(-1); +} + +int32_t LP_mempool_vinscan(bits256 *spendtxidp,int32_t *spendvinp,char *symbol,bits256 searchtxid,int32_t searchvout,bits256 searchtxid2,int32_t searchvout2) +{ + struct iguana_info *coin; int32_t selector; cJSON *array; + if ( symbol == 0 || symbol[0] == 0 || bits256_nonz(searchtxid) == 0 || bits256_nonz(searchtxid2) == 0 ) + return(-1); + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(-1); + if ( time(NULL) > coin->lastmempool+LP_MEMPOOL_TIMEINCR ) + { + if ( (array= LP_getmempool(symbol)) != 0 ) + { + free_json(array); + coin->lastmempool = (uint32_t)time(NULL); + } + } + if ( (selector= LP_spendsearch(spendtxidp,spendvinp,symbol,searchtxid,searchvout)) >= 0 ) + return(selector); + else if ( (selector= LP_spendsearch(spendtxidp,spendvinp,symbol,searchtxid2,searchvout2)) >= 0 ) + return(selector); + return(-1); +} + + diff --git a/iguana/exchanges/LP_secp.c b/iguana/exchanges/LP_secp.c new file mode 100644 index 000000000..7d4409911 --- /dev/null +++ b/iguana/exchanges/LP_secp.c @@ -0,0 +1,186 @@ + +/****************************************************************************** + * 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_secp.c +// marketmaker +// + + +#include +#include +#include +#include +#include "../../includes/curve25519.h" +#include "../secp256k1/include/secp256k1.h" +#include "../secp256k1/include/secp256k1_ecdh.h" +#include "../secp256k1/include/secp256k1_schnorr.h" +#include "../secp256k1/include/secp256k1_rangeproof.h" +#include "../secp256k1/include/secp256k1_recovery.h" + +SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; + +#define bits256_nonz(a) (((a).ulongs[0] | (a).ulongs[1] | (a).ulongs[2] | (a).ulongs[3]) != 0) + +#define SECP_ENSURE_CTX int32_t flag = 0; if ( ctx == 0 ) { ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(ctx); secp256k1_rangeproof_context_initialize(ctx); flag++; } else flag = 0; if ( ctx != 0 ) +#define ENDSECP_ENSURE_CTX if ( flag != 0 ) secp256k1_context_destroy(ctx); + +void *bitcoin_ctx() +{ + void *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + secp256k1_pedersen_context_initialize(ctx); + secp256k1_rangeproof_context_initialize(ctx); + return(ctx); +} + +bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey) +{ + size_t plen; bits256 pubkey; secp256k1_pubkey secppub; + memset(pubkey.bytes,0,sizeof(pubkey)); + SECP_ENSURE_CTX + { + if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) + { + //printf("bitcoin_sign illegal privkey\n"); + return(pubkey); + } + if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) != 0 ) + { + plen = 33; + secp256k1_ec_pubkey_serialize(ctx,data,&plen,&secppub,SECP256K1_EC_COMPRESSED); + if ( plen == 33 ) + memcpy(pubkey.bytes,data+1,sizeof(pubkey)); + } + ENDSECP_ENSURE_CTX + } + return(pubkey); +} + +bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even) +{ + bits256 pub256; uint8_t pubkey[33]; int32_t i; + for (i=0; i<100; i++) + { + *privkeyp = rand256(0); + pub256 = bitcoin_pubkey33(ctx,pubkey,*privkeyp); + if ( pubkey[0] == odd_even+2 ) + return(pub256); + } + printf("bitcoin_pub256 couldnt generate pubkey.%d\n",odd_even+2); + memset(pub256.bytes,0,sizeof(pub256)); + return(pub256); +} + +int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag) +{ + int32_t fCompressed = 1; + secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; int32_t recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB; + seed = rand256(0); + extra_entropy = rand256(0); + SECP_ENSURE_CTX + { + if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) + { + //printf("bitcoin_sign illegal privkey\n"); + return(-1); + } + if ( secp256k1_context_randomize(ctx,seed.bytes) != 0 ) + { + if ( recoverflag != 0 ) + { + if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 ) + { + recid = -1; + secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx,sig+1,&recid,&rSIG); + if ( secp256k1_ecdsa_recover(ctx,&SECPUB,&rSIG,txhash2.bytes) != 0 ) + { + if ( secp256k1_ec_pubkey_create(ctx,&CHECKPUB,privkey.bytes) != 0 ) + { + if ( memcmp(&SECPUB,&CHECKPUB,sizeof(SECPUB)) == 0 ) + { + sig[0] = 27 + recid + (fCompressed != 0 ? 4 : 0); + retval = 64 + 1; + //size_t i,plen = 33; uint8_t pubkey[33]; + //secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&CHECKPUB,SECP256K1_EC_COMPRESSED); + //for (i=0; i<33; i++) + // printf("%02x",pubkey[i]); + //printf(" bitcoin_sign's pubkey\n"); + + } //else printf("secpub mismatch\n"); + } else printf("pubkey create error\n"); + } //else printf("recover error\n"); + } else printf("secp256k1_ecdsa_sign_recoverable error\n"); + } + else + { + if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 ) + { + if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) != 0 ) + retval = (int32_t)siglen; + } + } + } + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig,bits256 messagehash2,uint8_t *pubkey,size_t plen) +{ + int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; + pubkey[0] = 0; + SECP_ENSURE_CTX + { + if ( plen == 0 ) + { + plen = (sig[0] <= 31) ? 65 : 33; + sig++; + } + secp256k1_ecdsa_recoverable_signature_parse_compact(ctx,&rSIG,sig,0); + secp256k1_ecdsa_recoverable_signature_convert(ctx,&SIG,&rSIG); + if ( secp256k1_ecdsa_recover(ctx,&PUB,&rSIG,messagehash2.bytes) != 0 ) + { + plen = 33; + memset(pubkey,0,33); + secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,SECP256K1_EC_COMPRESSED);//plen == 65 ? SECP256K1_EC_UNCOMPRESSED : SECP256K1_EC_COMPRESSED); + if ( secp256k1_ecdsa_verify(ctx,&SIG,messagehash2.bytes,&PUB) != 0 ) + { + retval = 0; + /*if ( pubkey[0] == 4 ) // experimentally looks like 04 is set + pubkey[0] = 2; + else if ( pubkey[0] != 2 ) + pubkey[0] = 3;*/ + } else printf("secp256k1_ecdsa_verify error\n"); + } else printf("secp256k1_ecdsa_recover error\n"); + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen) +{ + int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; + SECP_ENSURE_CTX + { + if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) != 0 ) + { + secp256k1_ecdsa_signature_parse_der(ctx,&SIG,sig,siglen); + if ( secp256k1_ecdsa_verify(ctx,&SIG,txhash2.bytes,&PUB) != 0 ) + retval = 0; + } + ENDSECP_ENSURE_CTX + } + return(retval); +} diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c new file mode 100644 index 000000000..dcb67c8a9 --- /dev/null +++ b/iguana/exchanges/LP_statemachine.c @@ -0,0 +1,1603 @@ + +/****************************************************************************** + * 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_statemachine.c +// marketmaker +// +/*struct LP_cacheinfo *ptr,*tmp; + HASH_ITER(hh,LP_cacheinfos,ptr,tmp) + { + if ( ptr->timestamp < now-3600*2 || ptr->price == 0. ) + continue; + if ( strcmp(ptr->Q.srccoin,base) == 0 && strcmp(ptr->Q.destcoin,rel) == 0 ) + { + asks = realloc(asks,sizeof(*asks) * (numasks+1)); + if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->Q.txid2,ptr->Q.vout2,ptr->price,ptr->Q.satoshis,ptr->Q.srchash)) != 0 ) + asks[numasks++] = op; + } + else if ( strcmp(ptr->Q.srccoin,rel) == 0 && strcmp(ptr->Q.destcoin,base) == 0 ) + { + bids = realloc(bids,sizeof(*bids) * (numbids+1)); + if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->Q.txid2,ptr->Q.vout2,1./ptr->price,ptr->Q.satoshis,ptr->Q.srchash)) != 0 ) + bids[numbids++] = op; + } + }*/ + +/*void basilisk_swaps_init(struct supernet_info *myinfo) + { + char fname[512]; uint32_t iter,swapcompleted,requestid,quoteid,optionduration,statebits; FILE *fp; bits256 privkey;struct basilisk_request R; struct basilisk_swapmessage M; struct basilisk_swap *swap = 0; + sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (myinfo->swapsfp= fopen(fname,"rb+")) != 0 ) + { + while ( fread(&requestid,1,sizeof(requestid),myinfo->swapsfp) == sizeof(requestid) && fread("eid,1,sizeof(quoteid),myinfo->swapsfp) == sizeof(quoteid) ) + { + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + printf("%s\n",fname); + if ( (fp= fopen(fname,"rb+")) != 0 ) // check to see if completed + { + memset(&M,0,sizeof(M)); + swapcompleted = 1; + for (iter=0; iter<2; iter++) + { + if ( fread(privkey.bytes,1,sizeof(privkey),fp) == sizeof(privkey) && + fread(&R,1,sizeof(R),fp) == sizeof(R) && + fread(&statebits,1,sizeof(statebits),fp) == sizeof(statebits) && + fread(&optionduration,1,sizeof(optionduration),fp) == sizeof(optionduration) ) + { + while ( 0 && fread(&M,1,sizeof(M),fp) == sizeof(M) ) + { + M.data = 0; + //printf("entry iter.%d crc32.%x datalen.%d\n",iter,M.crc32,M.datalen); + if ( M.datalen < 100000 ) + { + M.data = malloc(M.datalen); + if ( fread(M.data,1,M.datalen,fp) == M.datalen ) + { + if ( calc_crc32(0,M.data,M.datalen) == M.crc32 ) + { + if ( iter == 1 ) + { + if ( swap == 0 ) + { + swap = basilisk_thread_start(privkey,&R,statebits,optionduration,1); + swap->I.choosei = swap->I.otherchoosei = -1; + } + if ( swap != 0 ) + basilisk_swapgotdata(swap,M.crc32,M.srchash,M.desthash,M.quoteid,M.msgbits,M.data,M.datalen,1); + } + } else printf("crc mismatch %x vs %x\n",calc_crc32(0,M.data,M.datalen),M.crc32); + } else printf("error reading M.datalen %d\n",M.datalen); + free(M.data), M.data = 0; + } + } + } + if ( swapcompleted != 0 ) + break; + rewind(fp); + } + } + } + } else myinfo->swapsfp = fopen(fname,"wb+"); + }*/ + +FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit) +{ + FILE *fp=0; /*char fname[512]; + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,rp->requestid,rp->quoteid), OS_compatible_path(fname); + if ( (fp= fopen(fname,"rb+")) == 0 ) + { + if ( (fp= fopen(fname,"wb+")) != 0 ) + { + fwrite(privkey.bytes,1,sizeof(privkey),fp); + fwrite(rp,1,sizeof(*rp),fp); + fwrite(&statebits,1,sizeof(statebits),fp); + fwrite(&optionduration,1,sizeof(optionduration),fp); + fflush(fp); + } + } + else if ( reinit != 0 ) + { + }*/ + 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) +{ + FILE *fp=0; char fname[512]; int32_t retval = -1; + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + if ( (fp= fopen(fname,"rb+")) != 0 ) + { + if ( fread(privkeyp,1,sizeof(*privkeyp),fp) == sizeof(*privkeyp) && + fread(rp,1,sizeof(*rp),fp) == sizeof(*rp) && + fread(statebitsp,1,sizeof(*statebitsp),fp) == sizeof(*statebitsp) && + fread(optiondurationp,1,sizeof(*optiondurationp),fp) == sizeof(*optiondurationp) ) + retval = 0; + fclose(fp); + } + return(retval); +} + +void basilisk_swap_saveupdate(struct basilisk_swap *swap) +{ + FILE *fp; char fname[512]; + sprintf(fname,"%s/SWAPS/%u-%u.swap",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + fwrite(&swap->I,1,sizeof(swap->I),fp); + /*fwrite(&swap->bobdeposit,1,sizeof(swap->bobdeposit),fp); + fwrite(&swap->bobpayment,1,sizeof(swap->bobpayment),fp); + fwrite(&swap->alicepayment,1,sizeof(swap->alicepayment),fp); + fwrite(&swap->myfee,1,sizeof(swap->myfee),fp); + fwrite(&swap->otherfee,1,sizeof(swap->otherfee),fp); + fwrite(&swap->aliceclaim,1,sizeof(swap->aliceclaim),fp); + fwrite(&swap->alicespend,1,sizeof(swap->alicespend),fp); + fwrite(&swap->bobreclaim,1,sizeof(swap->bobreclaim),fp); + fwrite(&swap->bobspend,1,sizeof(swap->bobspend),fp); + fwrite(&swap->bobrefund,1,sizeof(swap->bobrefund),fp); + fwrite(&swap->alicereclaim,1,sizeof(swap->alicereclaim),fp);*/ + fwrite(swap->privkeys,1,sizeof(swap->privkeys),fp); + fwrite(swap->otherdeck,1,sizeof(swap->otherdeck),fp); + fwrite(swap->deck,1,sizeof(swap->deck),fp); + fclose(fp); + } +} + +/*int32_t basilisk_swap_loadtx(struct basilisk_rawtx *rawtx,FILE *fp,char *bobcoinstr,char *alicecoinstr) + { + if ( fread(rawtx,1,sizeof(*rawtx),fp) == sizeof(*rawtx) ) + { + rawtx->coin = 0; + rawtx->vins = 0; + if ( strcmp(rawtx->I.coinstr,bobcoinstr) == 0 || strcmp(rawtx->I.coinstr,alicecoinstr) == 0 ) + { + rawtx->coin = LP_coinfind(rawtx->I.coinstr); + if ( rawtx->vinstr[0] != 0 ) + rawtx->vins = cJSON_Parse(rawtx->vinstr); + printf("loaded.%s len.%d\n",rawtx->name,rawtx->I.datalen); + return(0); + } + } + return(-1); + }*/ + +void basilisk_swap_sendabort(struct basilisk_swap *swap) +{ + uint32_t msgbits = 0; uint8_t buf[sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2]; int32_t sentbytes,offset=0; + memset(buf,0,sizeof(buf)); + offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); + offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits); + if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset ) + { + if ( sentbytes < 0 ) + { + if ( swap->pushsock >= 0 ) // + nn_close(swap->pushsock), swap->pushsock = -1; + if ( swap->subsock >= 0 ) // + nn_close(swap->subsock), swap->subsock = -1; + swap->connected = 0; + } + } else printf("basilisk_swap_sendabort\n"); +} + +void basilisk_psockinit(struct basilisk_swap *swap,int32_t amlp); + +void basilisk_swapgotdata(struct basilisk_swap *swap,uint32_t crc32,bits256 srchash,bits256 desthash,uint32_t quoteid,uint32_t msgbits,uint8_t *data,int32_t datalen,int32_t reinit) +{ + int32_t i; struct basilisk_swapmessage *mp; + for (i=0; inummessages; i++) + if ( crc32 == swap->messages[i].crc32 && msgbits == swap->messages[i].msgbits && bits256_cmp(srchash,swap->messages[i].srchash) == 0 && bits256_cmp(desthash,swap->messages[i].desthash) == 0 ) + return; + //printf(" new message.[%d] datalen.%d Q.%x msg.%x [%llx]\n",swap->nummessages,datalen,quoteid,msgbits,*(long long *)data); + swap->messages = realloc(swap->messages,sizeof(*swap->messages) * (swap->nummessages + 1)); + mp = &swap->messages[swap->nummessages++]; + mp->crc32 = crc32; + mp->srchash = srchash; + mp->desthash = desthash; + mp->msgbits = msgbits; + mp->quoteid = quoteid; + mp->data = malloc(datalen); + mp->datalen = datalen; + memcpy(mp->data,data,datalen); + if ( reinit == 0 && swap->fp != 0 ) + { + fwrite(mp,1,sizeof(*mp),swap->fp); + fwrite(data,1,datalen,swap->fp); + fflush(swap->fp); + } +} + +int32_t basilisk_swapget(struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,int32_t (*basilisk_verify_func)(void *ptr,uint8_t *data,int32_t datalen)) +{ + uint8_t *ptr; bits256 srchash,desthash; uint32_t crc32,_msgbits,quoteid; int32_t i,size,offset,retval = -1; struct basilisk_swapmessage *mp = 0; + while ( (size= nn_recv(swap->subsock,&ptr,NN_MSG,NN_DONTWAIT)) >= 0 ) + { + swap->lasttime = (uint32_t)time(NULL); + memset(srchash.bytes,0,sizeof(srchash)); + memset(desthash.bytes,0,sizeof(desthash)); + //printf("gotmsg.[%d] crc.%x\n",size,crc32); + offset = 0; + for (i=0; i<32; i++) + srchash.bytes[i] = ptr[offset++]; + for (i=0; i<32; i++) + desthash.bytes[i] = ptr[offset++]; + offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),"eid); + offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&_msgbits); + if ( size > offset ) + { + crc32 = calc_crc32(0,&ptr[offset],size-offset); + if ( size > offset ) + { + //printf("size.%d offset.%d datalen.%d\n",size,offset,size-offset); + basilisk_swapgotdata(swap,crc32,srchash,desthash,quoteid,_msgbits,&ptr[offset],size-offset,0); + } + } + else if ( bits256_nonz(srchash) == 0 && bits256_nonz(desthash) == 0 ) + { + if ( swap->aborted == 0 ) + { + swap->aborted = (uint32_t)time(NULL); + printf("got abort signal from other side\n"); + } + } else printf("basilisk_swapget: got strange packet\n"); + if ( ptr != 0 ) + nn_freemsg(ptr), ptr = 0; + } + //char str[65],str2[65]; + for (i=0; inummessages; i++) + { + //printf("%d: %s vs %s\n",i,bits256_str(str,swap->messages[i].srchash),bits256_str(str2,swap->messages[i].desthash)); + if ( bits256_cmp(swap->messages[i].desthash,swap->I.myhash) == 0 ) + { + if ( swap->messages[i].msgbits == msgbits ) + { + if ( swap->I.iambob == 0 && swap->lasttime != 0 && time(NULL) > swap->lasttime+360 ) + { + printf("nothing received for a while from Bob, try new sockets\n"); + if ( swap->pushsock >= 0 ) // + nn_close(swap->pushsock), swap->pushsock = -1; + if ( swap->subsock >= 0 ) // + nn_close(swap->subsock), swap->subsock = -1; + swap->connected = 0; + basilisk_psockinit(swap,swap->I.iambob != 0); + } + mp = &swap->messages[i]; + if ( msgbits != 0x80000000 ) + break; + } + } + } + if ( mp != 0 ) + retval = (*basilisk_verify_func)(swap,mp->data,mp->datalen); + //printf("mine/other %s vs %s\n",bits256_str(str,swap->I.myhash),bits256_str(str2,swap->I.otherhash)); + return(retval); +} + +int32_t basilisk_messagekeyread(uint8_t *key,uint32_t *channelp,uint32_t *msgidp,bits256 *srchashp,bits256 *desthashp) +{ + int32_t keylen = 0; + keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),channelp); + keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),msgidp); + keylen += iguana_rwbignum(0,&key[keylen],sizeof(*srchashp),srchashp->bytes); + keylen += iguana_rwbignum(0,&key[keylen],sizeof(*desthashp),desthashp->bytes); + return(keylen); +} + +int32_t basilisk_messagekey(uint8_t *key,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash) +{ + int32_t keylen = 0; + keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&channel); + keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&msgid); + keylen += iguana_rwbignum(1,&key[keylen],sizeof(srchash),srchash.bytes); + keylen += iguana_rwbignum(1,&key[keylen],sizeof(desthash),desthash.bytes); + return(keylen); +} + +void LP_channelsend(bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen) +{ + int32_t keylen; uint8_t key[BASILISK_KEYSIZE]; //char *retstr; + keylen = basilisk_messagekey(key,channel,msgid,srchash,desthash); + //if ( (retstr= _dex_reqsend(myinfo,"DEX",key,keylen,data,datalen)) != 0 ) + // free(retstr); +} + + +#ifdef adfafds +void iguana_ensure_privkey(struct iguana_info *coin,bits256 privkey) +{ + uint8_t pubkey33[33]; struct iguana_waccount *wacct; struct iguana_waddress *waddr,addr; char coinaddr[128]; + bitcoin_pubkey33(swap->ctx,pubkey33,privkey); + bitcoin_address(coinaddr,coin->pubtype,pubkey33,33); + //printf("privkey for (%s)\n",coinaddr); + if ( myinfo->expiration != 0 && ((waddr= iguana_waddresssearch(&wacct,coinaddr)) == 0 || bits256_nonz(waddr->privkey) == 0) ) + { + if ( waddr == 0 ) + { + memset(&addr,0,sizeof(addr)); + iguana_waddresscalc(coin->pubtype,coin->wiftype,&addr,privkey); + if ( (wacct= iguana_waccountfind("default")) != 0 ) + waddr = iguana_waddressadd(coin,wacct,&addr,0); + } + if ( waddr != 0 ) + { + waddr->privkey = privkey; + if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->wiftype) > 0 ) + { + if ( (0) && waddr->wiftype != coin->wiftype ) + printf("ensurepriv warning: mismatched wiftype %02x != %02x\n",waddr->wiftype,coin->wiftype); + if ( (0) && waddr->addrtype != coin->pubtype ) + printf("ensurepriv warning: mismatched addrtype %02x != %02x\n",waddr->addrtype,coin->pubtype); + } + } + } +} +#endif + + +int32_t basilisk_rawtx_return(struct basilisk_rawtx *rawtx,cJSON *item,int32_t lockinputs,struct vin_info *V) +{ + char *signedtx,*txbytes; cJSON *vins,*privkeyarray; int32_t i,n,retval = -1; + if ( (txbytes= jstr(item,"rawtx")) != 0 && (vins= jobj(item,"vins")) != 0 ) + { + privkeyarray = cJSON_CreateArray(); + jaddistr(privkeyarray,wifstr); + if ( (signedtx= LP_signrawtx(rawtx->coin->symbol,&rawtx->I.signedtxid,&rawtx->I.completed,vins,txbytes,privkeyarray,V)) != 0 ) + { + if ( lockinputs != 0 ) + { + //printf("lockinputs\n"); + LP_unspentslock(rawtx->coin->symbol,vins); + if ( (n= cJSON_GetArraySize(vins)) != 0 ) + { + bits256 txid; int32_t vout; + for (i=0; iI.datalen = (int32_t)strlen(signedtx) >> 1; + //rawtx->txbytes = calloc(1,rawtx->I.datalen); + decode_hex(rawtx->txbytes,rawtx->I.datalen,signedtx); + //printf("%s SIGNEDTX.(%s)\n",rawtx->name,signedtx); + free(signedtx); + retval = 0; + } else printf("error signrawtx\n"); //do a very short timeout so it finishes via local poll + free_json(privkeyarray); + } + return(retval); +} + +cJSON *LP_createvins(struct basilisk_rawtx *dest,struct vin_info *V,struct basilisk_rawtx *rawtx,uint8_t *userdata,int32_t userdatalen,uint32_t sequenceid) +{ + cJSON *vins,*item,*sobj; char hexstr[8192]; + vins = cJSON_CreateArray(); + item = cJSON_CreateObject(); + if ( userdata != 0 && userdatalen > 0 ) + { + memcpy(V[0].userdata,userdata,userdatalen); + V[0].userdatalen = userdatalen; + init_hexbytes_noT(hexstr,userdata,userdatalen); + jaddstr(item,"userdata",hexstr); +#ifdef DISABLE_CHECKSIG + needsig = 0; +#endif + } + //printf("rawtx B\n"); + if ( bits256_nonz(rawtx->I.actualtxid) != 0 ) + jaddbits256(item,"txid",rawtx->I.actualtxid); + else jaddbits256(item,"txid",rawtx->I.signedtxid); + jaddnum(item,"vout",0); + //sobj = cJSON_CreateObject(); + init_hexbytes_noT(hexstr,rawtx->spendscript,rawtx->I.spendlen); + //jaddstr(sobj,"hex",hexstr); + //jadd(item,"scriptPubKey",sobj); + jaddstr(item,"scriptPubKey",hexstr); + jaddnum(item,"suppress",dest->I.suppress_pubkeys); + jaddnum(item,"sequence",sequenceid); + if ( (dest->I.redeemlen= rawtx->I.redeemlen) != 0 ) + { + init_hexbytes_noT(hexstr,rawtx->redeemscript,rawtx->I.redeemlen); + memcpy(dest->redeemscript,rawtx->redeemscript,rawtx->I.redeemlen); + jaddstr(item,"redeemScript",hexstr); + } + jaddi(vins,item); + return(vins); +} + +int32_t _basilisk_rawtx_gen(char *str,uint32_t swapstarted,uint8_t *pubkey33,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf,int32_t delay,bits256 privkey) +{ + char scriptstr[1024],wifstr[256],coinaddr[64],*signedtx,*rawtxbytes; uint32_t basilisktag; int32_t retval = -1; cJSON *vins,*privkeys,*addresses,*valsobj; struct vin_info *V; + init_hexbytes_noT(scriptstr,script,scriptlen); + basilisktag = (uint32_t)rand(); + valsobj = cJSON_CreateObject(); + jaddstr(valsobj,"coin",rawtx->coin->symbol); + jaddstr(valsobj,"spendscript",scriptstr); + jaddstr(valsobj,"changeaddr",rawtx->coin->smartaddr); + jadd64bits(valsobj,"satoshis",rawtx->I.amount); + if ( strcmp(rawtx->coin->symbol,"BTC") == 0 && txfee > 0 && txfee < 50000 ) + txfee = 50000; + jadd64bits(valsobj,"txfee",txfee); + jaddnum(valsobj,"minconf",minconf); + if ( locktime == 0 ) + locktime = (uint32_t)time(NULL) - 777; + jaddnum(valsobj,"locktime",locktime); + jaddnum(valsobj,"timeout",30000); + jaddnum(valsobj,"timestamp",swapstarted+delay); + addresses = cJSON_CreateArray(); + bitcoin_address(coinaddr,rawtx->coin->pubtype,pubkey33,33); + jaddistr(addresses,coinaddr); + jadd(valsobj,"addresses",addresses); + rawtx->I.locktime = locktime; + printf("%s locktime.%u\n",rawtx->name,locktime); + V = calloc(256,sizeof(*V)); + privkeys = cJSON_CreateArray(); + bitcoin_priv2wif(wifstr,privkey,rawtx->coin->wiftype); + jaddistr(privkeys,wifstr); + vins = LP_createvins(rawtx,V,rawtx,0,0,0xffffffff); + rawtx->vins = jduplicate(vins); + jdelete(valsobj,"vin"); + jadd(valsobj,"vin",vins); + if ( (rawtxbytes= bitcoin_json2hex(rawtx->coin->isPoS,&rawtx->I.txid,valsobj,V)) != 0 ) + { + //printf("rawtx.(%s) vins.%p\n",rawtxbytes,vins); + if ( (signedtx= LP_signrawtx(rawtx->coin->symbol,&rawtx->I.signedtxid,&rawtx->I.completed,vins,rawtxbytes,privkeys,V)) != 0 ) + { + rawtx->I.datalen = (int32_t)strlen(signedtx) >> 1; + if ( rawtx->I.datalen <= sizeof(rawtx->txbytes) ) + decode_hex(rawtx->txbytes,rawtx->I.datalen,signedtx); + else printf("DEX tx is too big %d vs %d\n",rawtx->I.datalen,(int32_t)sizeof(rawtx->txbytes)); + if ( signedtx != rawtxbytes ) + free(signedtx); + if ( rawtx->I.completed != 0 ) + retval = 0; + else printf("couldnt complete sign transaction %s\n",rawtx->name); + } else printf("error signing\n"); + free(rawtxbytes); + } else printf("error making rawtx\n"); + free_json(privkeys); + free_json(valsobj); + free(V); + return(retval); +} + +int32_t _basilisk_rawtx_sign(char *symbol,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,struct basilisk_swap *swap,uint32_t timestamp,uint32_t locktime,uint32_t sequenceid,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr) +{ + char *rawtxbytes=0,*signedtx=0,wifstr[128]; cJSON *txobj,*vins,*privkeys; int32_t needsig=1,retval = -1; struct vin_info *V; + V = calloc(256,sizeof(*V)); + V[0].signers[0].privkey = privkey; + bitcoin_pubkey33(swap->ctx,V[0].signers[0].pubkey,privkey); + privkeys = cJSON_CreateArray(); + bitcoin_priv2wif(wifstr,privkey,wiftype); + jaddistr(privkeys,wifstr); + if ( privkey2 != 0 ) + { + V[0].signers[1].privkey = *privkey2; + bitcoin_pubkey33(swap->ctx,V[0].signers[1].pubkey,*privkey2); + bitcoin_priv2wif(wifstr,*privkey2,wiftype); + jaddistr(privkeys,wifstr); + V[0].N = V[0].M = 2; + //char str[65]; printf("add second privkey.(%s) %s\n",jprint(privkeys,0),bits256_str(str,*privkey2)); + } else V[0].N = V[0].M = 1; + V[0].suppress_pubkeys = dest->I.suppress_pubkeys; + V[0].ignore_cltverr = ignore_cltverr; + if ( dest->I.redeemlen != 0 ) + memcpy(V[0].p2shscript,dest->redeemscript,dest->I.redeemlen), V[0].p2shlen = dest->I.redeemlen; + txobj = bitcoin_txcreate(symbol,isPoS,locktime,userdata == 0 ? 1 : 1,timestamp);//rawtx->coin->locktime_txversion); + vins = LP_createvins(dest,V,rawtx,userdata,userdatalen,sequenceid); + jdelete(txobj,"vin"); + jadd(txobj,"vin",vins); + //printf("basilisk_rawtx_sign locktime.%u/%u for %s spendscript.%s -> %s, suppress.%d\n",rawtx->I.locktime,dest->I.locktime,rawtx->name,hexstr,dest->name,dest->I.suppress_pubkeys); + txobj = bitcoin_txoutput(txobj,dest->spendscript,dest->I.spendlen,dest->I.amount); + if ( (rawtxbytes= bitcoin_json2hex(isPoS,&dest->I.txid,txobj,V)) != 0 ) + { + //printf("rawtx.(%s) vins.%p\n",rawtxbytes,vins); + if ( needsig == 0 ) + signedtx = rawtxbytes; + if ( signedtx != 0 || (signedtx= LP_signrawtx(symbol,&dest->I.signedtxid,&dest->I.completed,vins,rawtxbytes,privkeys,V)) != 0 ) + { + dest->I.datalen = (int32_t)strlen(signedtx) >> 1; + if ( dest->I.datalen <= sizeof(dest->txbytes) ) + decode_hex(dest->txbytes,dest->I.datalen,signedtx); + else printf("DEX tx is too big %d vs %d\n",dest->I.datalen,(int32_t)sizeof(dest->txbytes)); + if ( signedtx != rawtxbytes ) + free(signedtx); + if ( dest->I.completed != 0 ) + retval = 0; + else printf("couldnt complete sign transaction %s\n",rawtx->name); + } else printf("error signing\n"); + free(rawtxbytes); + } else printf("error making rawtx\n"); + free_json(privkeys); + free_json(txobj); + free(V); + return(retval); +} + +int32_t basilisk_process_swapverify(void *ptr,int32_t (*internal_func)(void *ptr,uint8_t *data,int32_t datalen),uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t expiration,uint32_t duration) +{ + struct basilisk_swap *swap = ptr; + if ( internal_func != 0 ) + return((*internal_func)(swap,data,datalen)); + else return(0); +} + +int32_t basilisk_priviextract(struct iguana_info *coin,char *name,bits256 *destp,uint8_t secret160[20],bits256 srctxid,int32_t srcvout) +{ + /*bits256 txid; char str[65]; int32_t i,vini,scriptlen; uint8_t rmd160[20],scriptsig[IGUANA_MAXSCRIPTSIZE]; + memset(privkey.bytes,0,sizeof(privkey)); + // use dex_listtransactions! + if ( (vini= iguana_vinifind(coin,&txid,srctxid,srcvout)) >= 0 ) + { + if ( (scriptlen= iguana_scriptsigextract(coin,scriptsig,sizeof(scriptsig),txid,vini)) > 32 ) + { + for (i=0; i<32; i++) + privkey.bytes[i] = scriptsig[scriptlen - 33 + i]; + revcalc_rmd160_sha256(rmd160,privkey);//.bytes,sizeof(privkey)); + if ( memcmp(secret160,rmd160,sizeof(rmd160)) == sizeof(rmd160) ) + { + *destp = privkey; + printf("basilisk_priviextract found privi %s (%s)\n",name,bits256_str(str,privkey)); + return(0); + } + } + }*/ + return(-1); +} +int32_t basilisk_verify_privi(void *ptr,uint8_t *data,int32_t datalen); + +int32_t basilisk_privBn_extract(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + if ( basilisk_priviextract(&swap->bobcoin,"privBn",&swap->I.privBn,swap->I.secretBn,swap->bobrefund.I.actualtxid,0) == 0 ) + { + printf("extracted privBn from blockchain\n"); + } + else if ( basilisk_swapget(swap,0x40000000,data,maxlen,basilisk_verify_privi) == 0 ) + { + } + if ( bits256_nonz(swap->I.privBn) != 0 && swap->alicereclaim.I.datalen == 0 ) + { + char str[65]; printf("got privBn.%s\n",bits256_str(str,swap->I.privBn)); + return(basilisk_alicepayment_spend(swap,&swap->alicereclaim)); + } + return(-1); +} + +int32_t basilisk_privAm_extract(struct basilisk_swap *swap) +{ + if ( basilisk_priviextract(&swap->bobcoin,"privAm",&swap->I.privAm,swap->I.secretAm,swap->bobpayment.I.actualtxid,0) == 0 ) + { + printf("extracted privAm from blockchain\n"); + } + if ( bits256_nonz(swap->I.privAm) != 0 && swap->bobspend.I.datalen == 0 ) + { + char str[65]; printf("got privAm.%s\n",bits256_str(str,swap->I.privAm)); + return(basilisk_alicepayment_spend(swap,&swap->bobspend)); + } + return(-1); +} + +int32_t basilisk_verify_otherstatebits(void *ptr,uint8_t *data,int32_t datalen) +{ + int32_t retval; struct basilisk_swap *swap = ptr; + if ( datalen == sizeof(swap->I.otherstatebits) ) + { + retval = iguana_rwnum(0,data,sizeof(swap->I.otherstatebits),&swap->I.otherstatebits); + return(retval); + } else return(-1); +} + +int32_t basilisk_verify_statebits(void *ptr,uint8_t *data,int32_t datalen) +{ + int32_t retval = -1; uint32_t statebits; struct basilisk_swap *swap = ptr; + if ( datalen == sizeof(swap->I.statebits) ) + { + retval = iguana_rwnum(0,data,sizeof(swap->I.statebits),&statebits); + if ( statebits != swap->I.statebits ) + { + printf("statebits.%x != %x\n",statebits,swap->I.statebits); + return(-1); + } + } + return(retval); +} + +void basilisk_sendstate(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t datalen=0; + datalen = iguana_rwnum(1,data,sizeof(swap->I.statebits),&swap->I.statebits); + LP_swapsend(swap,0x80000000,data,datalen,0,0); +} + +int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t j,datalen,retval = 0; uint32_t savestatebits=0,saveotherbits=0; + if ( swap->I.iambob != 0 ) + swap->I.statebits |= 0x80; + while ( swap->aborted == 0 && ((swap->I.otherstatebits & 0x80) == 0 || (swap->I.statebits & 0x80) == 0) && retval == 0 && time(NULL) < swap->I.expiration ) + { + if ( swap->connected == 0 ) + basilisk_psockinit(swap,swap->I.iambob != 0); + printf("D r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL))); + if ( swap->I.iambob != 0 && (swap->I.statebits & 0x80) == 0 ) // wait for fee + { + if ( basilisk_swapget(swap,0x80,data,maxlen,basilisk_verify_otherfee) == 0 ) + { + // verify and submit otherfee + swap->I.statebits |= 0x80; + basilisk_sendstate(swap,data,maxlen); + } + } + else if ( swap->I.iambob == 0 ) + swap->I.statebits |= 0x80; + basilisk_sendstate(swap,data,maxlen); + basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + if ( (swap->I.otherstatebits & 0x80) != 0 && (swap->I.statebits & 0x80) != 0 ) + break; + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + basilisk_sendstate(swap,data,maxlen); + if ( (swap->I.otherstatebits & 0x80) == 0 ) + LP_swapdata_rawtxsend(swap,0x80,data,maxlen,&swap->myfee,0x40,0); + } + basilisk_swap_saveupdate(swap); + while ( swap->aborted == 0 && retval == 0 && time(NULL) < swap->I.expiration ) // both sides have setup required data and paid txfee + { + basilisk_swap_saveupdate(swap); + if ( swap->connected == 0 ) + basilisk_psockinit(swap,swap->I.iambob != 0); + //if ( (rand() % 30) == 0 ) + printf("E r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL))); + if ( swap->I.iambob != 0 ) + { + //printf("BOB\n"); + if ( (swap->I.statebits & 0x100) == 0 ) + { + printf("send bobdeposit\n"); + swap->I.statebits |= LP_swapdata_rawtxsend(swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0); + } + // [BLOCKING: altfound] make sure altpayment is confirmed and send payment + else if ( (swap->I.statebits & 0x1000) == 0 ) + { + printf("check alicepayment\n"); + if ( basilisk_swapget(swap,0x1000,data,maxlen,basilisk_verify_alicepaid) == 0 ) + { + swap->I.statebits |= 0x1000; + printf("got alicepayment aliceconfirms.%d\n",swap->I.aliceconfirms); + } + } + else if ( (swap->I.statebits & 0x2000) == 0 ) + { + 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"); + } + } + else if ( (swap->I.statebits & 0x4000) == 0 ) + { + basilisk_bobscripts_set(swap,0,1); + printf("send bobpayment\n"); + swap->I.statebits |= LP_swapdata_rawtxsend(swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0); + } + // [BLOCKING: privM] Bob waits for privAm either from Alice or alice blockchain + else if ( (swap->I.statebits & 0xc0000) != 0xc0000 ) + { + if ( basilisk_swapget(swap,0x40000,data,maxlen,basilisk_verify_privi) == 0 || basilisk_privAm_extract(swap) == 0 ) // divulges privAm + { + //printf("got privi spend alicepayment, dont divulge privBn until bobspend propagated\n"); + basilisk_alicepayment_spend(swap,&swap->bobspend); + if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->bobspend,0x40000,1) == 0 ) + printf("Bob error spending alice payment\n"); + else + { + 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,1) >= swap->I.aliceconfirms ) + { + printf("bobspend confirmed\n"); + swap->I.statebits |= 0x80000; + printf("Bob confirming spend of Alice's payment\n"); + sleep(DEX_SLEEP); + } + retval = 1; + } + } + } + if ( swap->bobpayment.I.locktime != 0 && time(NULL) > swap->bobpayment.I.locktime ) + { + // submit reclaim of payment + printf("bob reclaims bobpayment\n"); + swap->I.statebits |= (0x40000 | 0x80000); + if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->bobreclaim,0,0) == 0 ) + printf("Bob error reclaiming own payment after alice timed out\n"); + else + { + 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) >= 1 ) + { + printf("bobreclaim confirmed\n"); + swap->I.statebits |= 0x100000; + printf("Bob confirms reclain of payment\n"); + break; + } + } + retval = 1; + } + } + } + else + { + //printf("ALICE\n"); + // [BLOCKING: depfound] Alice waits for deposit to confirm and sends altpayment + if ( (swap->I.statebits & 0x200) == 0 ) + { + printf("checkfor deposit\n"); + if ( basilisk_swapget(swap,0x200,data,maxlen,basilisk_verify_bobdeposit) == 0 ) + { + // verify deposit and submit, set confirmed height + printf("got bobdeposit\n"); + swap->I.statebits |= 0x200; + } else printf("no valid deposit\n"); + } + else if ( (swap->I.statebits & 0x400) == 0 ) + { + 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; + } + } + else if ( (swap->I.statebits & 0x800) == 0 ) + { + printf("send alicepayment\n"); + swap->I.statebits |= LP_swapdata_rawtxsend(swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0); + } + // [BLOCKING: payfound] make sure payment is confrmed and send in spend or see bob's reclaim and claim + else if ( (swap->I.statebits & 0x8000) == 0 ) + { + if ( basilisk_swapget(swap,0x8000,data,maxlen,basilisk_verify_bobpaid) == 0 ) + { + printf("got bobpayment\n"); + tradebot_swap_balancingtrade(swap,0); + // verify payment and submit, set confirmed height + swap->I.statebits |= 0x8000; + } + } + else if ( (swap->I.statebits & 0x10000) == 0 ) + { + 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; + } + } + else if ( (swap->I.statebits & 0x20000) == 0 ) + { + printf("alicespend bobpayment\n"); + if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->alicespend,0x20000,0) != 0 )//&& (swap->aliceunconf != 0 || basilisk_numconfirms(swap,&swap->alicespend) > 0) ) + { + swap->I.statebits |= 0x20000; + } + } + else if ( (swap->I.statebits & 0x40000) == 0 ) + { + int32_t numconfs; + 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]; + printf("send privAm %x\n",swap->I.statebits); + swap->I.statebits |= LP_swapsend(swap,0x40000,data,datalen,0x20000,swap->I.crcs_mypriv); + printf("Alice confirms spend of Bob's payment\n"); + retval = 1; + } else printf("alicespend numconfs.%d < %d\n",numconfs,swap->I.bobconfirms); + } + if ( swap->bobdeposit.I.locktime != 0 && time(NULL) > swap->bobdeposit.I.locktime ) + { + printf("Alice claims deposit\n"); + if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->aliceclaim,0,0) == 0 ) + printf("Alice couldnt claim deposit\n"); + else + { + printf("Alice claimed deposit\n"); + retval = 1; + } + } + else if ( swap->aborted != 0 || basilisk_privBn_extract(swap,data,maxlen) == 0 ) + { + printf("Alice reclaims her payment\n"); + swap->I.statebits |= 0x40000000; + if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->alicereclaim,0x40000000,0) == 0 ) + printf("Alice error sending alicereclaim\n"); + else + { + printf("Alice reclaimed her payment\n"); + retval = 1; + } + } + } + if ( (rand() % 30) == 0 ) + printf("finished swapstate.%x other.%x\n",swap->I.statebits,swap->I.otherstatebits); + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + basilisk_sendstate(swap,data,maxlen); + basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + } + return(retval); +} + +int32_t swapcompleted(struct basilisk_swap *swap) +{ + if ( swap->I.iambob != 0 ) + return(swap->I.bobspent); + else return(swap->I.alicespent); +} + +cJSON *swapjson(struct basilisk_swap *swap) +{ + cJSON *retjson = cJSON_CreateObject(); + return(retjson); +} + +int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,struct basilisk_request *rp) +{ + int32_t len = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->requestid),&rp->requestid); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->timestamp),&rp->timestamp); // must be 2nd + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quoteid),&rp->quoteid); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quotetime),&rp->quotetime); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->optionhours),&rp->optionhours); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->srcamount),&rp->srcamount); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->unused),&rp->unused); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->srchash),rp->srchash.bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->desthash),rp->desthash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->destamount),&rp->destamount); + if ( rwflag != 0 ) + { + memcpy(&serialized[len],rp->src,sizeof(rp->src)), len += sizeof(rp->src); + memcpy(&serialized[len],rp->dest,sizeof(rp->dest)), len += sizeof(rp->dest); + } + else + { + memcpy(rp->src,&serialized[len],sizeof(rp->src)), len += sizeof(rp->src); + memcpy(rp->dest,&serialized[len],sizeof(rp->dest)), len += sizeof(rp->dest); + } + //len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->DEXselector),&rp->DEXselector); + //len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->extraspace),&rp->extraspace); + if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid ) + printf(" basilisk_rwDEXquote.%d: quoteid.%u mismatch calc %u rp.%p\n",rwflag,rp->quoteid,basilisk_quoteid(rp),rp); + if ( basilisk_requestid(rp) != rp->requestid ) + printf(" basilisk_rwDEXquote.%d: requestid.%u mismatch calc %u rp.%p\n",rwflag,rp->requestid,basilisk_requestid(rp),rp); + return(len); +} + +struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *reqjson) +{ + uint32_t requestid,quoteid; + memset(rp,0,sizeof(*rp)); + rp->srchash = jbits256(reqjson,"srchash"); + rp->desthash = jbits256(reqjson,"desthash"); + rp->srcamount = j64bits(reqjson,"srcamount"); + //rp->minamount = j64bits(reqjson,"minamount"); + //rp->destamount = j64bits(reqjson,"destamount"); + rp->destamount = j64bits(reqjson,"destsatoshis"); + //printf("parse DESTSATOSHIS.%llu (%s)\n",(long long)rp->destamount,jprint(reqjson,0)); + requestid = juint(reqjson,"requestid"); + quoteid = juint(reqjson,"quoteid"); + //if ( jstr(reqjson,"relay") != 0 ) + // rp->relaybits = (uint32_t)calc_ipbits(jstr(reqjson,"relay")); + rp->timestamp = juint(reqjson,"timestamp"); + rp->quotetime = juint(reqjson,"quotetime"); + safecopy(rp->src,jstr(reqjson,"src"),sizeof(rp->src)); + safecopy(rp->dest,jstr(reqjson,"dest"),sizeof(rp->dest)); + if ( quoteid != 0 ) + { + rp->quoteid = basilisk_quoteid(rp); + if ( quoteid != rp->quoteid ) + printf("basilisk_parsejson quoteid.%u != %u error\n",quoteid,rp->quoteid); + } + rp->requestid = basilisk_requestid(rp); + if ( requestid != rp->requestid ) + { + int32_t i; for (i=0; irequestid); + } + return(rp); +} + +cJSON *basilisk_requestjson(struct basilisk_request *rp) +{ + cJSON *item = cJSON_CreateObject(); + /*if ( rp->relaybits != 0 ) + { + expand_ipbits(ipaddr,rp->relaybits); + jaddstr(item,"relay",ipaddr); + }*/ + jaddbits256(item,"srchash",rp->srchash); + if ( bits256_nonz(rp->desthash) != 0 ) + jaddbits256(item,"desthash",rp->desthash); + jaddstr(item,"src",rp->src); + if ( rp->srcamount != 0 ) + jadd64bits(item,"srcamount",rp->srcamount); + //if ( rp->minamount != 0 ) + // jadd64bits(item,"minamount",rp->minamount); + jaddstr(item,"dest",rp->dest); + if ( rp->destamount != 0 ) + { + //jadd64bits(item,"destamount",rp->destamount); + jadd64bits(item,"destsatoshis",rp->destamount); + //printf("DESTSATOSHIS.%llu\n",(long long)rp->destamount); + } + jaddnum(item,"quotetime",rp->quotetime); + jaddnum(item,"timestamp",rp->timestamp); + jaddnum(item,"requestid",rp->requestid); + jaddnum(item,"quoteid",rp->quoteid); + //jaddnum(item,"DEXselector",rp->DEXselector); + jaddnum(item,"optionhours",rp->optionhours); + //jaddnum(item,"profit",(double)rp->profitmargin / 1000000.); + if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid ) + printf("quoteid mismatch %u vs %u\n",basilisk_quoteid(rp),rp->quoteid); + if ( basilisk_requestid(rp) != rp->requestid ) + printf("requestid mismatch %u vs calc %u\n",rp->requestid,basilisk_requestid(rp)); + { + int32_t i; struct basilisk_request R; + if ( basilisk_parsejson(&R,item) != 0 ) + { + if ( memcmp(&R,rp,sizeof(*rp)-sizeof(uint32_t)) != 0 ) + { + for (i=0; iI.req.requestid); + jaddnum(item,"quoteid",swap->I.req.quoteid); + jaddnum(item,"state",swap->I.statebits); + jaddnum(item,"otherstate",swap->I.otherstatebits); + jadd(item,"request",basilisk_requestjson(&swap->I.req)); + return(item); +} + +#ifdef later + +cJSON *basilisk_privkeyarray(struct iguana_info *coin,cJSON *vins) +{ + cJSON *privkeyarray,*item,*sobj; struct iguana_waddress *waddr; struct iguana_waccount *wacct; char coinaddr[64],account[128],wifstr[64],str[65],typestr[64],*hexstr; uint8_t script[1024]; int32_t i,n,len,vout; bits256 txid,privkey; double bidasks[2]; + privkeyarray = cJSON_CreateArray(); + if ( (n= cJSON_GetArraySize(vins)) > 0 ) + { + for (i=0; i= 0 ) + { + iguana_txidcategory(coin,account,coinaddr,txid,vout); + if ( coinaddr[0] == 0 && (sobj= jobj(item,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && is_hexstr(hexstr,0) > 0 ) + { + len = (int32_t)strlen(hexstr) >> 1; + if ( len < (sizeof(script) << 1) ) + { + decode_hex(script,len,hexstr); + if ( len == 25 && script[0] == 0x76 && script[1] == 0xa9 && script[2] == 0x14 ) + bitcoin_address(coinaddr,coin->chain->pubtype,script+3,20); + } + } + if ( coinaddr[0] != 0 ) + { + if ( (waddr= iguana_waddresssearch(&wacct,coinaddr)) != 0 ) + { + bitcoin_priv2wif(wifstr,waddr->privkey,coin->chain->wiftype); + jaddistr(privkeyarray,waddr->wifstr); + } + else if ( smartaddress(typestr,bidasks,&privkey,coin->symbol,coinaddr) >= 0 ) + { + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + jaddistr(privkeyarray,wifstr); + } + else printf("cant find (%s) in wallet\n",coinaddr); + } else printf("cant coinaddr from (%s).v%d\n",bits256_str(str,txid),vout); + } else printf("invalid txid/vout %d of %d\n",i,n); + } + } + return(privkeyarray); +} + + +#endif + + +#ifdef old +void basilisk_swaploop(void *_utxo) +{ + uint8_t *data; uint32_t expiration,savestatebits=0,saveotherbits=0; uint32_t channel; int32_t iters,retval=0,j,datalen,maxlen; struct basilisk_swap *swap; struct LP_utxoinfo *utxo = _utxo; + swap = utxo->swap; + fprintf(stderr,"start swap iambob.%d\n",swap->I.iambob); + maxlen = 1024*1024 + sizeof(*swap); + data = malloc(maxlen); + expiration = (uint32_t)time(NULL) + 300; + //myinfo->DEXactive = expiration; + channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + while ( swap->aborted == 0 && (swap->I.statebits & (0x08|0x02)) != (0x08|0x02) && time(NULL) < expiration ) + { + LP_channelsend(swap->I.req.srchash,swap->I.req.desthash,channel,0x4000000,(void *)&swap->I.req.requestid,sizeof(swap->I.req.requestid)); //,60); + if ( swap->connected == 0 ) + basilisk_psockinit(swap,swap->I.iambob != 0); + if ( swap->connected > 0 ) + { + printf("A r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits); + basilisk_sendstate(swap,data,maxlen); + basilisk_sendpubkeys(swap,data,maxlen); // send pubkeys + if ( basilisk_checkdeck(swap,data,maxlen) == 0) // check for other deck 0x02 + basilisk_sendchoosei(swap,data,maxlen); + basilisk_waitchoosei(swap,data,maxlen); // wait for choosei 0x08 + if ( (swap->I.statebits & (0x08|0x02)) == (0x08|0x02) ) + break; + } + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + } + if ( swap->connected == 0 ) + { + printf("couldnt establish connection\n"); + retval = -1; + } + while ( swap->aborted == 0 && retval == 0 && (swap->I.statebits & 0x20) == 0 ) + { + if ( swap->connected == 0 ) + basilisk_psockinit(swap,swap->I.iambob != 0); + printf("B r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits); + basilisk_sendstate(swap,data,maxlen); + basilisk_sendchoosei(swap,data,maxlen); + basilisk_sendmostprivs(swap,data,maxlen); + if ( basilisk_swapget(swap,0x20,data,maxlen,basilisk_verify_privkeys) == 0 ) + { + swap->I.statebits |= 0x20; + break; + } + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + if ( time(NULL) > expiration ) + break; + } + //myinfo->DEXactive = swap->I.expiration; + if ( time(NULL) >= expiration ) + { + retval = -1; + //myinfo->DEXactive = 0; + } + if ( swap->aborted != 0 ) + { + printf("swap aborted before tx sent\n"); + retval = -1; + } + printf("C r%u/q%u swapstate.%x retval.%d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,retval); + iters = 0; + while ( swap->aborted == 0 && retval == 0 && (swap->I.statebits & 0x40) == 0 && iters++ < 10 ) // send fee + { + if ( swap->connected == 0 ) + basilisk_psockinit(swap,swap->I.iambob != 0); + //printf("sendstate.%x\n",swap->I.statebits); + basilisk_sendstate(swap,data,maxlen); + //printf("swapget\n"); + basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + //printf("after swapget\n"); + if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen == 0 ) + { + printf("bobscripts set\n"); + if ( basilisk_bobscripts_set(swap,1,1) < 0 ) + { + sleep(DEX_SLEEP); + printf("bobscripts set error\n"); + continue; + } + } + if ( swap->I.iambob == 0 ) + { + /*for (i=0; i<20; i++) + printf("%02x",swap->secretAm[i]); + printf(" <- secretAm\n"); + for (i=0; i<32; i++) + printf("%02x",swap->secretAm256[i]); + printf(" <- secretAm256\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubAm.bytes[i]); + printf(" <- pubAm\n"); + for (i=0; i<20; i++) + printf("%02x",swap->secretBn[i]); + printf(" <- secretBn\n"); + for (i=0; i<32; i++) + printf("%02x",swap->secretBn256[i]); + printf(" <- secretBn256\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubBn.bytes[i]); + printf(" <- pubBn\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubA0.bytes[i]); + printf(" <- pubA0\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubA1.bytes[i]); + printf(" <- pubA1\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubB0.bytes[i]); + printf(" <- pubB0\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubB1.bytes[i]); + printf(" <- pubB1\n");*/ + if ( (retval= basilisk_alicetxs(swap,data,maxlen)) != 0 ) + { + printf("basilisk_alicetxs error\n"); + break; + } + } + } + if ( swap->I.iambob == 0 && (swap->I.statebits & 0x40) == 0 ) + { + printf("couldnt send fee\n"); + retval = -8; + } + if ( retval == 0 ) + { + if ( swap->I.iambob == 0 && (swap->myfee.I.datalen == 0 || swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.datalen == 0) ) + { + printf("ALICE's error %d %d %d\n",swap->myfee.I.datalen,swap->alicepayment.I.datalen,swap->alicepayment.I.datalen); + retval = -7; + } + else if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen == 0 ) //swap->bobpayment.I.datalen == 0 + { + printf("BOB's error %d %d %d\n",swap->myfee.I.datalen,swap->bobpayment.I.datalen,swap->bobdeposit.I.datalen); + retval = -7; + } + } + while ( swap->aborted == 0 && retval == 0 && basilisk_swapiteration(swap,data,maxlen) == 0 ) + { + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + basilisk_sendstate(swap,data,maxlen); + basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + basilisk_swap_saveupdate(swap); + if ( time(NULL) > swap->I.expiration ) + break; + } + if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen != 0 && bits256_nonz(swap->bobdeposit.I.actualtxid) != 0 ) + { + printf("BOB waiting for confirm state.%x\n",swap->I.statebits); + sleep(60); // wait for confirm/propagation of msig + printf("BOB reclaims refund\n"); + basilisk_bobdeposit_refund(swap,0); + if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->bobrefund,0x40000000,0) == 0 ) // use secretBn + { + printf("Bob submit error getting refund of deposit\n"); + } + else + { + // maybe wait for bobrefund to be confirmed + for (j=datalen=0; j<32; j++) + data[datalen++] = swap->I.privBn.bytes[j]; + LP_swapsend(swap,0x40000000,data,datalen,0x40000000,swap->I.crcs_mypriv); + } + basilisk_swap_saveupdate(swap); + } + if ( retval != 0 ) + basilisk_swap_sendabort(swap); + printf("end of atomic swap\n"); + if ( swapcompleted(swap) > 0 ) // only if swap completed + { + if ( swap->I.iambob != 0 ) + tradebot_pendingadd(swapjson(swap),swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount)); + else tradebot_pendingadd(swapjson(swap),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.src,dstr(swap->I.req.srcamount)); + } + printf("%s swap finished statebits %x\n",swap->I.iambob!=0?"BOB":"ALICE",swap->I.statebits); + //basilisk_swap_purge(swap); + free(data); +} +#endif + +int32_t bitcoin_coinptrs(bits256 pubkey,struct iguana_info **bobcoinp,struct iguana_info **alicecoinp,char *src,char *dest,bits256 srchash,bits256 desthash) +{ + struct iguana_info *coin = LP_coinfind(src); + if ( coin == 0 || LP_coinfind(dest) == 0 ) + return(0); + *bobcoinp = *alicecoinp = 0; + *bobcoinp = LP_coinfind(dest); + *alicecoinp = LP_coinfind(src); + if ( bits256_cmp(pubkey,srchash) == 0 ) + { + if ( strcmp(src,(*bobcoinp)->symbol) == 0 ) + return(1); + else if ( strcmp(dest,(*alicecoinp)->symbol) == 0 ) + return(-1); + else return(0); + } + else if ( bits256_cmp(pubkey,desthash) == 0 ) + { + if ( strcmp(src,(*bobcoinp)->symbol) == 0 ) + return(-1); + else if ( strcmp(dest,(*alicecoinp)->symbol) == 0 ) + return(1); + else return(0); + } + return(0); +} + +/*void basilisk_swap_purge(struct basilisk_swap *swap) + { + int32_t i,n; + // while still in orderbook, wait + //return; + portable_mutex_lock(&myinfo->DEX_swapmutex); + n = myinfo->numswaps; + for (i=0; iswaps[i] == swap ) + { + myinfo->swaps[i] = myinfo->swaps[--myinfo->numswaps]; + myinfo->swaps[myinfo->numswaps] = 0; + basilisk_swap_finished(swap); + break; + } + portable_mutex_unlock(&myinfo->DEX_swapmutex); + }*/ + +/*int32_t LP_priceping(int32_t pubsock,struct LP_utxoinfo *utxo,char *rel,double origprice) + { + double price,bid,ask; uint32_t now; cJSON *retjson; struct LP_quoteinfo Q; char *retstr; + if ( (now= (uint32_t)time(NULL)) > utxo->T.swappending && utxo->S.swap == 0 ) + utxo->T.swappending = 0; + if ( now > utxo->T.published+60 && LP_isavailable(utxo) && (price= LP_myprice(&bid,&ask,utxo->coin,rel)) != 0. ) + { + if ( origprice < price ) + price = origprice; + if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 ) + return(-1); + Q.timestamp = (uint32_t)time(NULL); + retjson = LP_quotejson(&Q); + jaddstr(retjson,"method","quote"); + retstr = jprint(retjson,1); + //printf("PING.(%s)\n",retstr); + if ( pubsock >= 0 ) + LP_send(pubsock,retstr,1); + else + { + // verify it is in list + // push if it isnt + } + utxo->T.published = now; + return(0); + } + return(-1); + }*/ +/*if ( addflag != 0 && LP_utxofind(1,Q.txid,Q.vout) == 0 ) + { + LP_utxoadd(1,-1,Q.srccoin,Q.txid,Q.vout,Q.value,Q.txid2,Q.vout2,Q.value2,"",Q.srcaddr,Q.srchash,0.); + LP_utxoadd(0,-1,Q.destcoin,Q.desttxid,Q.destvout,Q.destvalue,Q.feetxid,Q.feevout,Q.feevalu,"",Q.destaddr,Q.desthash,0.); + }*/ + +/*struct LP_utxoinfo *utxo,*tmp; + HASH_ITER(hh,LP_utxoinfos[1],utxo,tmp) + { + if ( LP_ismine(utxo) > 0 && strcmp(utxo->coin,base) == 0 ) + LP_priceping(LP_mypubsock,utxo,rel,price * LP_profitratio); + }*/ +/* +bestprice = 0.; +if ( (array= LP_tradecandidates(base)) != 0 ) +{ + printf("candidates.(%s)\nn.%d\n",jprint(array,0),cJSON_GetArraySize(array)); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + memset(prices,0,sizeof(prices)); + memset(Q,0,sizeof(Q)); + for (i=0; icoin,zero); + Q[i].destsatoshis = price * Q[i].satoshis; + } + if ( (prices[i]= price) > SMALLVAL && (bestprice == 0. || price < bestprice) ) + bestprice = price; + char str[65]; printf("i.%d of %d: (%s) -> txid.%s price %.8f best %.8f dest %.8f\n",i,n,jprint(item,0),bits256_str(str,Q[i].txid),price,bestprice,dstr(Q[i].destsatoshis)); + } + if ( bestprice > SMALLVAL ) + { + bestmetric = 0.; + besti = -1; + for (i=0; i SMALLVAL && myutxo->S.satoshis >= Q[i].destsatoshis+Q[i].desttxfee ) + { + metric = price / bestprice; + printf("%f %f %f %f ",price,metric,dstr(Q[i].destsatoshis),metric * metric * metric); + if ( metric < 1.1 ) + { + metric = dstr(Q[i].destsatoshis) * metric * metric * metric; + printf("%f\n",metric); + if ( bestmetric == 0. || metric < bestmetric ) + { + besti = i; + bestmetric = metric; + } + } + } else printf("(%f %f) ",dstr(myutxo->S.satoshis),dstr(Q[i].destsatoshis)); + } + printf("metrics, best %f\n",bestmetric); +*/ + +/*cJSON *LP_tradecandidates(char *base) + { + struct LP_peerinfo *peer,*tmp; struct LP_quoteinfo Q; char *utxostr,coinstr[16]; cJSON *array,*retarray=0,*item; int32_t i,n,totaladded,added; + totaladded = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + printf("%s:%u %s\n",peer->ipaddr,peer->port,base); + n = added = 0; + if ( (utxostr= issue_LP_clientgetutxos(peer->ipaddr,peer->port,base,100)) != 0 ) + { + printf("%s:%u %s %s\n",peer->ipaddr,peer->port,base,utxostr); + if ( (array= cJSON_Parse(utxostr)) != 0 ) + { + if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + retarray = cJSON_CreateArray(); + for (i=0; i 0 ) + { + memset(&Q,0,sizeof(Q)); + for (i=0; i 0 ) + { + printf("iterate through all locally generated quotes and update, or change to price feed\n"); + // jl777: iterated Q's + if ( strcmp(utxo->coin,"KMD") == 0 ) + LP_priceping(pubsock,utxo,"BTC",profitmargin); + else LP_priceping(pubsock,utxo,"KMD",profitmargin); + }*/ +/*if ( LP_txvalue(destaddr,symbol,searchtxid,searchvout) > 0 ) + return(0); + if ( (txobj= LP_gettx(symbol,searchtxid)) == 0 ) + return(0); + hash = jbits256(txobj,"blockhash"); + free_json(txobj); + if ( bits256_nonz(hash) == 0 ) + return(0); + if ( (blockjson= LP_getblock(symbol,hash)) == 0 ) + return(0); + loadheight = jint(blockjson,"height"); + free_json(blockjson); + if ( loadheight <= 0 ) + return(0); + while ( errs == 0 && *indp < 0 ) + { + //printf("search %s ht.%d\n",symbol,loadheight); + if ( (blockjson= LP_blockjson(&h,symbol,0,loadheight)) != 0 && h == loadheight ) + { + if ( (txids= jarray(&numtxids,blockjson,"tx")) != 0 ) + { + for (i=0; i= 0 ) + break; + } + } + free_json(blockjson); + } else errs++; + loadheight++; + } + char str[65]; printf("reached %s ht.%d %s/v%d\n",symbol,loadheight,bits256_str(str,*spendtxidp),*indp); + if ( bits256_nonz(*spendtxidp) != 0 && *indp >= 0 ) + return(loadheight); + else return(0);*/ + +/*if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i= 0 ) + return(selector); + } + }*/ + + diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c new file mode 100644 index 000000000..89edc2ce6 --- /dev/null +++ b/iguana/exchanges/LP_swap.c @@ -0,0 +1,1080 @@ + +/****************************************************************************** + * 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_swap.c +// marketmaker +// + +/* + make sure to broadcast deposit before claiming refund, or to just skip it if neither is done + */ + + +// included from basilisk.c +/* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271 + https://bitcointalk.org/index.php?topic=1364951 + Tier Nolan's approach is followed with the following changes: + a) instead of cutting 1000 keypairs, only INSTANTDEX_DECKSIZE are a + b) instead of sending the entire 256 bits, it is truncated to 64 bits. With odds of collision being so low, it is dwarfed by the ~0.1% insurance factor. + c) D is set to ~100x the insurance rate of 1/777 12.87% + BTC amount + d) insurance is added to Bob's payment, which is after the deposit and bailin + e) BEFORE Bob broadcasts deposit, Alice broadcasts BTC denominated fee in cltv so if trade isnt done fee is reclaimed + */ + +//#define DISABLE_CHECKSIG // unsolved MITM (evil peer) + +/* + both fees are standard payments: OP_DUP OP_HASH160 FEE_RMD160 OP_EQUALVERIFY OP_CHECKSIG + + Alice altpayment: OP_2 OP_2 OP_CHECKMULTISIG + + Bob deposit: + #ifndef DISABLE_CHECKSIG + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF + #else + OP_IF + OP_CLTV OP_DROP OP_SHA256 OP_EQUAL + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_SHA256 OP_EQUAL + OP_ENDIF + #endif + + Bob paytx: + #ifndef DISABLE_CHECKSIG + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF + #else + OP_IF + OP_CLTV OP_DROP OP_SHA256 OP_EQUAL + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_SHA256 OP_EQUAL + OP_ENDIF + #endif + + Naming convention are pubAi are alice's pubkeys (seems only pubA0 and not pubA1) + pubBi are Bob's pubkeys + + privN is Bob's privkey from the cut and choose deck as selected by Alice + privM is Alice's counterpart + pubN and pubM are the corresponding pubkeys for these chosen privkeys + + Alice timeout event is triggered if INSTANTDEX_LOCKTIME elapses from the start of a FSM instance. Bob timeout event is triggered after INSTANTDEX_LOCKTIME*2 + */ + +/* + Bob sends bobdeposit and waits for alicepayment to confirm before sending bobpayment + Alice waits for bobdeposit to confirm and sends alicepayment + + Alice spends bobpayment immediately divulging privAm + Bob spends alicepayment immediately after getting privAm and divulges privBn + + Bob will spend bobdeposit after end of trade or INSTANTDEX_LOCKTIME, divulging privBn + Alice spends alicepayment as soon as privBn is seen + + Bob will spend bobpayment after INSTANTDEX_LOCKTIME + Alice spends bobdeposit in 2*INSTANTDEX_LOCKTIME + */ + +//Bobdeposit includes a covered put option for alicecoin, duration INSTANTDEX_LOCKTIME +//alicepayment includes a covered call option for alicecoin, duration (2*INSTANTDEX_LOCKTIME - elapsed) + + +/* in case of following states, some funds remain unclaimable, but all identified cases are due to one or both sides not spending when they were the only eligible party: + + Bob failed to claim deposit during exclusive period and since alice put in the claim, the alicepayment is unspendable. if alice is nice, she can send privAm to Bob. + Apaymentspent.(0000000000000000000000000000000000000000000000000000000000000000) alice.0 bob.0 + paymentspent.(f91da4e001360b95276448e7b01904d9ee4d15862c5af7f5c7a918df26030315) alice.0 bob.1 + depositspent.(f34e04ad74e290f63f3d0bccb7d0d50abfa54eea58de38816fdc596a19767add) alice.1 bob.0 + + */ + + +void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx) +{ + if ( rawtx->vins != 0 ) + free_json(rawtx->vins); + //if ( rawtx->txbytes != 0 ) + // free(rawtx->txbytes), rawtx->txbytes = 0; +} + +void basilisk_swap_finished(struct basilisk_swap *swap) +{ + int32_t i; + if ( swap->utxo != 0 && swap->sentflag == 0 ) + LP_availableset(swap->utxo); + swap->I.finished = (uint32_t)time(NULL); + // save to permanent storage + basilisk_rawtx_purge(&swap->bobdeposit); + basilisk_rawtx_purge(&swap->bobpayment); + basilisk_rawtx_purge(&swap->alicepayment); + basilisk_rawtx_purge(&swap->myfee); + basilisk_rawtx_purge(&swap->otherfee); + basilisk_rawtx_purge(&swap->aliceclaim); + basilisk_rawtx_purge(&swap->alicespend); + basilisk_rawtx_purge(&swap->bobreclaim); + basilisk_rawtx_purge(&swap->bobspend); + basilisk_rawtx_purge(&swap->bobrefund); + basilisk_rawtx_purge(&swap->alicereclaim); + for (i=0; inummessages; i++) + if ( swap->messages[i].data != 0 ) + free(swap->messages[i].data), swap->messages[i].data = 0; + free(swap->messages), swap->messages = 0; + swap->nummessages = 0; + if ( swap->N.pair >= 0 ) + nn_close(swap->N.pair), swap->N.pair = -1; +} + +uint32_t basilisk_quoteid(struct basilisk_request *rp) +{ + struct basilisk_request R; + R = *rp; + R.unused = R.requestid = R.quoteid = R.DEXselector = 0; + return(calc_crc32(0,(void *)&R,sizeof(R))); +} + +uint32_t basilisk_requestid(struct basilisk_request *rp) +{ + struct basilisk_request R; + R = *rp; + R.requestid = R.quoteid = R.quotetime = R.DEXselector = 0; + R.destamount = R.unused = 0; + memset(R.desthash.bytes,0,sizeof(R.desthash.bytes)); + if ( 0 ) + { + int32_t i; + for (i=0; i %s %.8f %s crc.%u q%u\n",R.timestamp,R.requestid,R.quoteid,R.src,dstr(R.srcamount),bits256_str(str,R.srchash),R.dest,dstr(R.destamount),bits256_str(str2,R.desthash),calc_crc32(0,(void *)&R,sizeof(R)),basilisk_quoteid(&R)); + } + return(calc_crc32(0,(void *)&R,sizeof(R))); +} + +int32_t LP_pubkeys_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t i,datalen = 0; + for (i=0; ideck)/sizeof(swap->deck[0][0]); i++) + datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->deck[i>>1][i&1]),&swap->deck[i>>1][i&1]); + return(datalen); +} + +int32_t LP_pubkeys_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + int32_t i,len = 0; + if ( datalen == sizeof(swap->otherdeck) ) + { + for (i=0; iotherdeck)/sizeof(swap->otherdeck[0][0]); i++) + len += iguana_rwnum(0,&data[len],sizeof(swap->otherdeck[i>>1][i&1]),&swap->otherdeck[i>>1][i&1]); + return(0); + } + printf("pubkeys verify size mismatch %d != %d\n",datalen,(int32_t)sizeof(swap->otherdeck)); + return(-1); +} + +int32_t LP_choosei_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t i,datalen; char str[65]; + datalen = iguana_rwnum(1,data,sizeof(swap->I.choosei),&swap->I.choosei); + if ( swap->I.iambob != 0 ) + { + for (i=0; i<32; i++) + data[datalen++] = swap->I.pubB0.bytes[i]; + for (i=0; i<32; i++) + data[datalen++] = swap->I.pubB1.bytes[i]; + printf("SEND pubB0/1 %s\n",bits256_str(str,swap->I.pubB0)); + } + else + { + for (i=0; i<32; i++) + data[datalen++] = swap->I.pubA0.bytes[i]; + for (i=0; i<32; i++) + data[datalen++] = swap->I.pubA1.bytes[i]; + printf("SEND pubA0/1 %s\n",bits256_str(str,swap->I.pubA0)); + } + return(datalen); +} + +int32_t LP_choosei_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + int32_t otherchoosei=-1,i,len = 0; uint8_t pubkey33[33]; char str[65],str2[65]; + if ( datalen == sizeof(otherchoosei)+sizeof(bits256)*2 ) + { + len += iguana_rwnum(0,data,sizeof(otherchoosei),&otherchoosei); + if ( otherchoosei >= 0 && otherchoosei < INSTANTDEX_DECKSIZE ) + { + swap->I.otherchoosei = otherchoosei; + if ( swap->I.iambob != 0 ) + { + for (i=0; i<32; i++) + swap->I.pubA0.bytes[i] = data[len++]; + for (i=0; i<32; i++) + swap->I.pubA1.bytes[i] = data[len++]; + printf("GOT pubA0/1 %s\n",bits256_str(str,swap->I.pubA0)); + swap->I.privBn = swap->privkeys[swap->I.otherchoosei]; + memset(&swap->privkeys[swap->I.otherchoosei],0,sizeof(swap->privkeys[swap->I.otherchoosei])); + revcalc_rmd160_sha256(swap->I.secretBn,swap->I.privBn);//.bytes,sizeof(swap->privBn)); + vcalc_sha256(0,swap->I.secretBn256,swap->I.privBn.bytes,sizeof(swap->I.privBn)); + swap->I.pubBn = bitcoin_pubkey33(swap->ctx,pubkey33,swap->I.privBn); + printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256)); + //basilisk_bobscripts_set(swap,1,1); + } + else + { + for (i=0; i<32; i++) + swap->I.pubB0.bytes[i] = data[len++]; + for (i=0; i<32; i++) + swap->I.pubB1.bytes[i] = data[len++]; + printf("GOT pubB0/1 %s\n",bits256_str(str,swap->I.pubB0)); + swap->I.privAm = swap->privkeys[swap->I.otherchoosei]; + memset(&swap->privkeys[swap->I.otherchoosei],0,sizeof(swap->privkeys[swap->I.otherchoosei])); + revcalc_rmd160_sha256(swap->I.secretAm,swap->I.privAm);//.bytes,sizeof(swap->privAm)); + vcalc_sha256(0,swap->I.secretAm256,swap->I.privAm.bytes,sizeof(swap->I.privAm)); + swap->I.pubAm = bitcoin_pubkey33(swap->ctx,pubkey33,swap->I.privAm); + printf("set privAm.%s %s\n",bits256_str(str,swap->I.privAm),bits256_str(str2,*(bits256 *)swap->I.secretAm256)); + swap->bobdeposit.I.pubkey33[0] = 2; + swap->bobpayment.I.pubkey33[0] = 2; + for (i=0; i<32; i++) + swap->bobpayment.I.pubkey33[i+1] = swap->bobdeposit.I.pubkey33[i+1] = swap->I.pubA0.bytes[i]; + printf("SET bobdeposit pubkey33.(02%s)\n",bits256_str(str,swap->I.pubA0)); + //basilisk_bobscripts_set(swap,0); + } + return(0); + } + } + printf("illegal otherchoosei.%d datalen.%d vs %d\n",otherchoosei,datalen,(int32_t)(sizeof(otherchoosei)+sizeof(bits256)*2)); + return(-1); +} + +int32_t LP_mostprivs_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t i,j,datalen; + datalen = 0; + for (i=0; iprivkeys)/sizeof(*swap->privkeys); i++) + { + for (j=0; j<32; j++) + data[datalen++] = (i == swap->I.otherchoosei) ? 0 : swap->privkeys[i].bytes[j]; + } + if ( swap->I.iambob != 0 ) + { + for (i=0; i<32; i++) + data[datalen++] = swap->I.pubBn.bytes[i]; + for (i=0; i<20; i++) + data[datalen++] = swap->I.secretBn[i]; + for (i=0; i<32; i++) + data[datalen++] = swap->I.secretBn256[i]; + } + else + { + for (i=0; i<32; i++) + data[datalen++] = swap->I.pubAm.bytes[i]; + for (i=0; i<20; i++) + data[datalen++] = swap->I.secretAm[i]; + for (i=0; i<32; i++) + data[datalen++] = swap->I.secretAm256[i]; + } + return(datalen); +} + +int32_t basilisk_verify_pubpair(int32_t *wrongfirstbytep,struct basilisk_swap *swap,int32_t ind,uint8_t pub0,bits256 pubi,uint64_t txid) +{ + if ( pub0 != (swap->I.iambob ^ 1) + 0x02 ) + { + (*wrongfirstbytep)++; + printf("wrongfirstbyte[%d] %02x\n",ind,pub0); + return(-1); + } + else if ( swap->otherdeck[ind][1] != pubi.txid ) + { + printf("otherdeck[%d] priv ->pub mismatch %llx != %llx\n",ind,(long long)swap->otherdeck[ind][1],(long long)pubi.txid); + return(-1); + } + else if ( swap->otherdeck[ind][0] != txid ) + { + printf("otherdeck[%d] priv mismatch %llx != %llx\n",ind,(long long)swap->otherdeck[ind][0],(long long)txid); + return(-1); + } + return(0); +} + +int32_t basilisk_verify_privi(void *ptr,uint8_t *data,int32_t datalen) +{ + int32_t j,wrongfirstbyte,len = 0; bits256 privkey,pubi; char str[65],str2[65]; uint8_t secret160[20],pubkey33[33]; uint64_t txid; struct basilisk_swap *swap = ptr; + memset(privkey.bytes,0,sizeof(privkey)); + if ( datalen == sizeof(bits256) ) + { + for (j=0; j<32; j++) + privkey.bytes[j] = data[len++]; + revcalc_rmd160_sha256(secret160,privkey);//.bytes,sizeof(privkey)); + memcpy(&txid,secret160,sizeof(txid)); + pubi = bitcoin_pubkey33(swap->ctx,pubkey33,privkey); + if ( basilisk_verify_pubpair(&wrongfirstbyte,swap,swap->I.choosei,pubkey33[0],pubi,txid) == 0 ) + { + if ( swap->I.iambob != 0 ) + { + swap->I.privAm = privkey; + vcalc_sha256(0,swap->I.secretAm256,privkey.bytes,sizeof(privkey)); + printf("set privAm.%s %s\n",bits256_str(str,swap->I.privAm),bits256_str(str2,*(bits256 *)swap->I.secretAm256)); + basilisk_bobscripts_set(swap,0,1); + } + else + { + swap->I.privBn = privkey; + vcalc_sha256(0,swap->I.secretBn256,privkey.bytes,sizeof(privkey)); + printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256)); + } + basilisk_dontforget_update(swap,0); + char str[65]; printf("privi verified.(%s)\n",bits256_str(str,privkey)); + return(0); + } else printf("pubpair doesnt verify privi\n"); + } else printf("verify privi size mismatch %d != %d\n",datalen,(int32_t)sizeof(bits256)); + return(-1); +} + +int32_t LP_mostprivs_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + int32_t i,j,wrongfirstbyte=0,errs=0,len = 0; bits256 otherpriv,pubi; uint8_t secret160[20],otherpubkey[33]; uint64_t txid; + //printf("verify privkeys choosei.%d otherchoosei.%d datalen.%d vs %d\n",swap->choosei,swap->otherchoosei,datalen,(int32_t)sizeof(swap->privkeys)+20+32); + memset(otherpriv.bytes,0,sizeof(otherpriv)); + if ( swap->I.cutverified == 0 && swap->I.otherchoosei >= 0 && datalen == sizeof(swap->privkeys)+20+2*32 ) + { + for (i=errs=0; iprivkeys)/sizeof(*swap->privkeys); i++) + { + for (j=0; j<32; j++) + otherpriv.bytes[j] = data[len++]; + if ( i != swap->I.choosei ) + { + pubi = bitcoin_pubkey33(swap->ctx,otherpubkey,otherpriv); + revcalc_rmd160_sha256(secret160,otherpriv);//.bytes,sizeof(otherpriv)); + memcpy(&txid,secret160,sizeof(txid)); + errs += basilisk_verify_pubpair(&wrongfirstbyte,swap,i,otherpubkey[0],pubi,txid); + } + } + if ( errs == 0 && wrongfirstbyte == 0 ) + { + swap->I.cutverified = 1, printf("CUT VERIFIED\n"); + if ( swap->I.iambob != 0 ) + { + for (i=0; i<32; i++) + swap->I.pubAm.bytes[i] = data[len++]; + for (i=0; i<20; i++) + swap->I.secretAm[i] = data[len++]; + for (i=0; i<32; i++) + swap->I.secretAm256[i] = data[len++]; + //basilisk_bobscripts_set(swap,1,1); + } + else + { + for (i=0; i<32; i++) + swap->I.pubBn.bytes[i] = data[len++]; + for (i=0; i<20; i++) + swap->I.secretBn[i] = data[len++]; + for (i=0; i<32; i++) + swap->I.secretBn256[i] = data[len++]; + //basilisk_bobscripts_set(swap,0); + } + } else printf("failed verification: wrong firstbyte.%d errs.%d\n",wrongfirstbyte,errs); + } + //printf("privkeys errs.%d wrongfirstbyte.%d\n",errs,wrongfirstbyte); + return(errs); +} + +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)) +{ + struct nn_pollfd pfd; void *data; int32_t datalen,retval = -1; uint32_t expiration = (uint32_t)time(NULL) + timeout; + while ( time(NULL) < expiration ) + { + memset(&pfd,0,sizeof(pfd)); + pfd.fd = pairsock; + pfd.events = NN_POLLIN; + if ( nn_poll(&pfd,1,1) > 0 ) + { + //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 timeout.%d\n",statename,timeout); + if ( LP_waitfor(pairsock,swap,timeout,verify) == 0 ) + { + //printf("waited for %s\n",statename); + if ( (datalen= (*datagen)(swap,data,maxlen)) > 0 ) + { + if ( (sendlen= swap_nn_send(pairsock,data,datalen,0,timeout)) == datalen ) + { + //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); + } else printf("didnt get valid data after %d\n",timeout); + return(retval); +} + +int32_t LP_sendwait(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("sendwait.%s\n",statename); + if ( (datalen= (*datagen)(swap,data,maxlen)) > 0 ) + { + //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 ) + { + //printf("waited! sendwait.%s sent %d\n",statename,sendlen); + retval = 0; + } else printf("didnt get %s\n",statename); + } else printf("send %s error\n",statename); + } else printf("no datagen for %s\n",statename); + return(retval); +} + +void LP_swapsfp_update(struct basilisk_request *rp) +{ + static FILE *swapsfp; + if ( swapsfp == 0 ) + { + char fname[512]; + sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (swapsfp= fopen(fname,"rb+")) == 0 ) + swapsfp = fopen(fname,"wb+"); + else fseek(swapsfp,0,SEEK_END); + //printf("LIST fp.%p\n",swapsfp); + } + if ( swapsfp != 0 ) + { + fwrite(&rp->requestid,1,sizeof(rp->requestid),swapsfp); + fwrite(&rp->quoteid,1,sizeof(rp->quoteid),swapsfp); + fflush(swapsfp); + } +} + +struct basilisk_rawtx *LP_swapdata_rawtx(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx) +{ + if ( rawtx->I.datalen != 0 && rawtx->I.datalen <= maxlen ) + { + memcpy(data,rawtx->txbytes,rawtx->I.datalen); + return(rawtx); + } + printf("swapdata rawtx has null txbytes\n"); + return(0); +} + +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; 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++) + myhash.bytes[i] = recvbuf[offset++]; + offset += iguana_rwnum(0,&recvbuf[offset],sizeof(quoteid),"eid); + offset += iguana_rwnum(0,&recvbuf[offset],sizeof(msgbits),&msgbits); + datalen = recvbuf[offset++]; + datalen += (int32_t)recvbuf[offset++] << 8; + if ( datalen > 1024 ) + { + printf("LP_rawtx_spendscript %s datalen.%d too big\n",rawtx->name,datalen); + return(-1); + } + rawtx->I.redeemlen = recvbuf[offset++]; + data = &recvbuf[offset]; + if ( rawtx->I.redeemlen > 0 && rawtx->I.redeemlen < 0x100 ) + { + memcpy(rawtx->redeemscript,&data[datalen],rawtx->I.redeemlen); + for (i=0; iI.redeemlen; i++) + printf("%02x",rawtx->redeemscript[i]); + bitcoin_address(redeemaddr,rawtx->coin->taddr,rawtx->coin->p2shtype,rawtx->redeemscript,rawtx->I.redeemlen); + printf(" received redeemscript.(%s) %s taddr.%d\n",redeemaddr,rawtx->coin->symbol,rawtx->coin->taddr); + LP_swap_coinaddr(swap,rawtx->coin,checkaddr,data,datalen); + if ( strcmp(redeemaddr,checkaddr) != 0 ) + { + printf("REDEEMADDR MISMATCH??? %s != %s\n",redeemaddr,checkaddr); + return(-1); + } + } + //printf("recvlen.%d datalen.%d redeemlen.%d\n",recvlen,datalen,rawtx->redeemlen); + if ( rawtx->I.datalen == 0 ) + { + //for (i=0; itxbytes,data,datalen); + rawtx->I.datalen = datalen; + } + else if ( datalen != rawtx->I.datalen || memcmp(rawtx->txbytes,data,datalen) != 0 ) + { + for (i=0; iI.datalen; i++) + printf("%02x",rawtx->txbytes[i]); + printf(" <- rawtx\n"); + printf("%s rawtx data compare error, len %d vs %d <<<<<<<<<< warning\n",rawtx->name,rawtx->I.datalen,datalen); + return(-1); + } + if ( recvlen != datalen+rawtx->I.redeemlen+75 ) + printf("RECVLEN %d != %d + %d\n",recvlen,datalen,rawtx->I.redeemlen); + txid = bits256_doublesha256(0,data,datalen); + //char str[65]; printf("rawtx.%s txid %s\n",rawtx->name,bits256_str(str,txid)); + if ( bits256_cmp(txid,rawtx->I.actualtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) + rawtx->I.actualtxid = txid; + if ( (txobj= bitcoin_data2json(rawtx->coin->taddr,rawtx->coin->pubtype,rawtx->coin->p2shtype,rawtx->coin->isPoS,height,&rawtx->I.signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),data,datalen,0,suppress_pubkeys)) != 0 ) + { + rawtx->I.actualtxid = rawtx->I.signedtxid; + rawtx->I.locktime = rawtx->msgtx.lock_time; + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && v < n ) + { + vout = jitem(vouts,v); + 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) ) + { + decode_hex(rawtx->spendscript,hexlen,hexstr); + rawtx->I.spendlen = hexlen; + //if ( swap != 0 ) + // basilisk_txlog(swap->myinfoptr,swap,rawtx,-1); // bobdeposit, bobpayment or alicepayment + retval = 0; + if ( rawtx == &swap->otherfee ) + { + 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) 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); + } + return(retval); +} + +uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend) +{ + uint8_t sendbuf[32768]; int32_t sendlen,retval = -1; + if ( LP_swapdata_rawtx(swap,data,maxlen,rawtx) != 0 ) + { + if ( bits256_nonz(rawtx->I.signedtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) + { + rawtx->I.actualtxid = LP_broadcast_tx(rawtx->name,rawtx->coin->symbol,rawtx->txbytes,rawtx->I.datalen); + if ( bits256_cmp(rawtx->I.actualtxid,rawtx->I.signedtxid) != 0 ) + { + //printf("%s rawtxsend.[%d] %s vs %s\n",rawtx->name,rawtx->I.datalen,bits256_str(str,rawtx->I.signedtxid),bits256_str(str2,rawtx->I.actualtxid)); + rawtx->I.actualtxid = rawtx->I.signedtxid; + } + if ( bits256_nonz(rawtx->I.actualtxid) != 0 && msgbits != 0 ) + { + sendlen = 0; + sendbuf[sendlen++] = rawtx->I.datalen & 0xff; + sendbuf[sendlen++] = (rawtx->I.datalen >> 8) & 0xff; + sendbuf[sendlen++] = rawtx->I.redeemlen; + //int32_t z; for (z=0; zI.datalen; z++) printf("%02x",rawtx->txbytes[z]); printf(" >>>>>>> send.%d %s\n",rawtx->I.datalen,rawtx->name); + //printf("datalen.%d redeemlen.%d\n",rawtx->I.datalen,rawtx->I.redeemlen); + memcpy(&sendbuf[sendlen],rawtx->txbytes,rawtx->I.datalen), sendlen += rawtx->I.datalen; + if ( rawtx->I.redeemlen > 0 && rawtx->I.redeemlen < 0x100 ) + { + memcpy(&sendbuf[sendlen],rawtx->redeemscript,rawtx->I.redeemlen); + sendlen += rawtx->I.redeemlen; + } + basilisk_dontforget_update(swap,rawtx); + //printf("sendlen.%d datalen.%d redeemlen.%d\n",sendlen,rawtx->datalen,rawtx->redeemlen); + if ( suppress_swapsend == 0 ) + { + retval = LP_swapsend(pairsock,swap,msgbits,sendbuf,sendlen,nextbits,rawtx->I.crcs); + if ( LP_waitmempool(rawtx->coin->symbol,rawtx->I.signedtxid,LP_SWAPSTEP_TIMEOUT) < 0 ) + { + char str[65]; printf("failed to find %s %s in the mempool?\n",rawtx->name,bits256_str(str,rawtx->I.actualtxid)); + retval = -1; + } + return(retval); + } + else + { + printf("suppress swapsend %x\n",msgbits); + return(0); + } + } + } + return(nextbits); + } //else if ( swap->I.iambob == 0 ) + printf("error from basilisk_swapdata_rawtx.%s %p len.%d\n",rawtx->name,rawtx->txbytes,rawtx->I.datalen); + return(0); +} + +int32_t LP_swapwait(uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t sleeptime) +{ + char *retstr; cJSON *retjson=0; uint32_t divisor=8,expiration = (uint32_t)(time(NULL) + duration); + printf("wait %d:%d for SWAP.(r%u/q%u) to complete\n",duration,sleeptime,requestid,quoteid); + sleep(10); + if ( sleeptime < divisor*60 ) + sleeptime = divisor * 60; + while ( time(NULL) < expiration ) + { + if ( (retstr= basilisk_swapentry(requestid,quoteid)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jstr(retjson,"status") != 0 && strcmp(jstr(retjson,"status"),"finished") == 0 ) + break; + free_json(retjson); + retjson = 0; + } + free(retstr); + } + sleep(sleeptime/divisor); + if ( divisor > 1 ) + divisor--; + } + if ( retjson != 0 ) + { + printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>\nSWAP completed! %u-%u %s\n",requestid,quoteid,jprint(retjson,0)); + free_json(retjson); + if ( (retstr= basilisk_swapentry(requestid,quoteid)) != 0 ) + { + printf("second call.(%s)\n",retstr); + free(retstr); + } + return(0); + } else return(-1); +} + +void LP_bobloop(void *_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",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"); + else if ( LP_waitsend("mostprivs",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 ) + printf("error waitsend mostprivs\n"); + else if ( basilisk_bobscripts_set(swap,1,1) < 0 ) + printf("error bobscripts deposit\n"); + else + { + swap->bobrefund.utxovout = 0; + swap->bobrefund.utxotxid = swap->bobdeposit.I.signedtxid; + 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*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*3,LP_verify_alicepayment) < 0 ) + printf("error waiting for alicepayment\n"); + else + { + if ( basilisk_bobscripts_set(swap,0,1) < 0 ) + printf("error bobscripts payment\n"); + else + { + 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); + } + if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 ) + printf("error sending bobpayment\n"); + swap->sentflag = 1; + swap->bobreclaim.utxovout = 0; + swap->bobreclaim.utxotxid = swap->bobpayment.I.signedtxid; + basilisk_bobpayment_reclaim(swap,swap->I.callduration); + if ( swap->N.pair >= 0 ) + nn_close(swap->N.pair), swap->N.pair = -1; + LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,4*3600,300); + } + } + } + basilisk_swap_finished(swap); + free(swap); + } else printf("swap timed out\n"); +} + +void LP_aliceloop(void *_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",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"); + else if ( LP_sendwait("mostprivs",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 ) + printf("error LP_sendwait mostprivs\n"); + else if ( basilisk_alicetxs(swap->N.pair,swap,data,maxlen) != 0 ) + printf("basilisk_alicetxs error\n"); + else + { + 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*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 + { + 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*3,LP_verify_bobpayment) < 0 ) + printf("error waiting for bobpayment\n"); + else + { + 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,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); + } + if ( swap->N.pair >= 0 ) + nn_close(swap->N.pair), swap->N.pair = -1; + LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,4*3600,300); + } + } + } + basilisk_swap_finished(swap); + free(swap); + } + free(data); + 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) +{ + bits256 sharedsecret; + sharedsecret = curve25519_shared(privkey,orderhash); + vcalc_sha256cat(newprivp->bytes,orderhash.bytes,sizeof(orderhash),sharedsecret.bytes,sizeof(sharedsecret)); + return(bitcoin_pubkey33(ctx,pubkey,*newprivp)); +} + +bits256 basilisk_revealkey(bits256 privkey,bits256 pubkey) +{ + bits256 reveal; +#ifdef DISABLE_CHECKSIG + vcalc_sha256(0,reveal.bytes,privkey.bytes,sizeof(privkey)); + //reveal = revcalc_sha256(privkey); + char str[65],str2[65]; printf("priv.(%s) -> reveal.(%s)\n",bits256_str(str,privkey),bits256_str(str2,reveal)); +#else + reveal = pubkey; +#endif + return(reveal); +} + +int32_t instantdex_pubkeyargs(struct basilisk_swap *swap,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte) +{ + char buf[3]; int32_t i,n,m,len=0; bits256 pubi,reveal; uint64_t txid; uint8_t secret160[20],pubkey[33]; + sprintf(buf,"%c0",'A' - 0x02 + firstbyte); + if ( numpubs > 2 ) + { + if ( swap->I.numpubs+2 >= numpubs ) + return(numpubs); + //fprintf(stderr,">>>>>> start generating %s\n",buf); + } + for (i=n=m=0; ictx,&privkey,pubkey,privkey,hash); + //fprintf(stderr,"i.%d n.%d numpubs.%d %02x vs %02x\n",i,n,numpubs,pubkey[0],firstbyte); + if ( pubkey[0] != firstbyte ) + continue; + if ( n < 2 ) + { + if ( bits256_nonz(swap->I.mypubs[n]) == 0 ) + { + swap->I.myprivs[n] = privkey; + memcpy(swap->I.mypubs[n].bytes,pubkey+1,sizeof(bits256)); + reveal = basilisk_revealkey(privkey,swap->I.mypubs[n]); + if ( swap->I.iambob != 0 ) + { + if ( n == 0 ) + swap->I.pubB0 = reveal; + else if ( n == 1 ) + swap->I.pubB1 = reveal; + } + else if ( swap->I.iambob == 0 ) + { + if ( n == 0 ) + swap->I.pubA0 = reveal; + else if ( n == 1 ) + swap->I.pubA1 = reveal; + } + } + } + if ( m < INSTANTDEX_DECKSIZE ) + { + swap->privkeys[m] = privkey; + revcalc_rmd160_sha256(secret160,privkey);//.bytes,sizeof(privkey)); + memcpy(&txid,secret160,sizeof(txid)); + len += iguana_rwnum(1,(uint8_t *)&swap->deck[m][0],sizeof(txid),&txid); + len += iguana_rwnum(1,(uint8_t *)&swap->deck[m][1],sizeof(pubi.txid),&pubi.txid); + m++; + if ( m > swap->I.numpubs ) + swap->I.numpubs = m; + } + n++; + } + if ( n > 2 || m > 2 ) + printf("n.%d m.%d len.%d numpubs.%d\n",n,m,len,swap->I.numpubs); + return(n); +} + +void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx *rawtx,struct iguana_info *coin,int32_t numconfirms,int32_t vintype,uint64_t satoshis,int32_t vouttype,uint8_t *pubkey33,int32_t jumblrflag) +{ +#ifdef BASILISK_DISABLEWAITTX + numconfirms = 0; +#endif + strcpy(rawtx->name,name); + rawtx->coin = coin; + strcpy(rawtx->I.coinstr,coin->symbol); + rawtx->I.numconfirms = numconfirms; + 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 ) + { + if ( strcmp(coin->symbol,"BTC") == 0 && (quoteid % 10) == 0 ) + decode_hex(rawtx->I.rmd160,20,TIERNOLAN_RMD160); + else decode_hex(rawtx->I.rmd160,20,INSTANTDEX_RMD160); + bitcoin_address(rawtx->I.destaddr,rawtx->coin->taddr,rawtx->coin->pubtype,rawtx->I.rmd160,20); + } + if ( pubkey33 != 0 ) + { + memcpy(rawtx->I.pubkey33,pubkey33,33); + bitcoin_address(rawtx->I.destaddr,rawtx->coin->taddr,rawtx->coin->pubtype,rawtx->I.pubkey33,33); + bitcoin_addr2rmd160(rawtx->coin->taddr,&rawtx->I.addrtype,rawtx->I.rmd160,rawtx->I.destaddr); + } + if ( rawtx->I.vouttype <= 1 && rawtx->I.destaddr[0] != 0 ) + { + rawtx->I.spendlen = bitcoin_standardspend(rawtx->spendscript,0,rawtx->I.rmd160); + printf("%s spendlen.%d %s <- %.8f\n",name,rawtx->I.spendlen,rawtx->I.destaddr,dstr(rawtx->I.amount)); + } else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->I.vouttype,rawtx->I.destaddr); +} + +struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 pubkey25519,struct basilisk_swap *swap,int32_t optionduration,uint32_t statebits,struct LP_quoteinfo *qp) +{ + //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; + else if ( optionduration > 0 ) + 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)) < 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); + swap->I.expiration = swap->I.req.timestamp + swap->I.putduration + swap->I.callduration; + OS_randombytes((uint8_t *)&swap->I.choosei,sizeof(swap->I.choosei)); + if ( swap->I.choosei < 0 ) + swap->I.choosei = -swap->I.choosei; + swap->I.choosei %= INSTANTDEX_DECKSIZE; + swap->I.otherchoosei = -1; + swap->I.myhash = pubkey25519; + if ( statebits != 0 ) + { + swap->I.iambob = 0; + swap->I.otherhash = swap->I.req.desthash; + aliceistrusted = 1; + bobistrusted = LP_pubkey_istrusted(swap->I.req.desthash); + } + else + { + swap->I.iambob = 1; + swap->I.otherhash = swap->I.req.srchash; + bobistrusted = 1; + aliceistrusted = LP_pubkey_istrusted(swap->I.req.desthash); + } + if ( bits256_nonz(privkey) == 0 || (x= instantdex_pubkeyargs(swap,2 + INSTANTDEX_DECKSIZE,privkey,swap->I.orderhash,0x02+swap->I.iambob)) != 2 + INSTANTDEX_DECKSIZE ) + { + char str[65]; printf("couldnt generate privkeys %d %s\n",x,bits256_str(str,privkey)); + return(0); + } + if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) + swap->alicecoin = *coin; + else + { + printf("missing bobcoin.%p or missing alicecoin.%p src.%p dest.%p\n",&swap->bobcoin,&swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); + free(swap); + return(0); + } + if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + swap->bobcoin = *coin; + else + { + printf("missing bobcoin.%p or missing alicecoin.%p src.%p dest.%p\n",&swap->bobcoin,&swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); + free(swap); + return(0); + } + if ( strcmp("BTC",swap->bobcoin.symbol) == 0 ) + { + swap->I.bobconfirms = (1 + sqrt(dstr(swap->I.bobsatoshis) * .1)); + swap->I.aliceconfirms = MIN(BASILISK_DEFAULT_NUMCONFIRMS,swap->I.bobconfirms); + } + else if ( strcmp("BTC",swap->alicecoin.symbol) == 0 ) + { + swap->I.aliceconfirms = (1 + sqrt(dstr(swap->I.alicesatoshis) * .1)); + swap->I.bobconfirms = MIN(BASILISK_DEFAULT_NUMCONFIRMS,swap->I.aliceconfirms); + } + else + { + swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS; + swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS; + } + swap->I.bobconfirms *= !bobistrusted; + swap->I.aliceconfirms *= !aliceistrusted; + printf(">>>>>>>>>> jumblrflag.%d <<<<<<<<< use smart address, %.8f bobconfs.%d, %.8f aliceconfs.%d taddr.%d %d\n",jumblrflag,dstr(swap->I.bobsatoshis),swap->I.bobconfirms,dstr(swap->I.alicesatoshis),swap->I.aliceconfirms,swap->bobcoin.taddr,swap->alicecoin.taddr); + if ( swap->I.iambob != 0 ) + { + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,&swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis),0,0,jumblrflag); + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,&swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis),0,0,jumblrflag); + bobpub33 = pubkey33; + } + else + { + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,&swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis),0,0,jumblrflag); + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,&swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis),0,0,jumblrflag); + alicepub33 = pubkey33; + } + basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,&swap->bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + swap->bobcoin.txfee,4,0,jumblrflag); + basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,&swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,bobpub33,jumblrflag); + swap->bobrefund.I.suppress_pubkeys = 1; + basilisk_rawtx_setparms("aliceclaim",swap->I.req.quoteid,&swap->aliceclaim,&swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,alicepub33,jumblrflag); + swap->aliceclaim.I.suppress_pubkeys = 1; + swap->aliceclaim.I.locktime = swap->I.started + swap->I.putduration+swap->I.callduration + 1; + + basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,&swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + swap->bobcoin.txfee,3,0,jumblrflag); + basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,&swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag); + swap->alicespend.I.suppress_pubkeys = 1; + basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,&swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag); + swap->bobreclaim.I.suppress_pubkeys = 1; + swap->bobreclaim.I.locktime = swap->I.started + swap->I.putduration + 1; + basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,&swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis+swap->alicecoin.txfee,2,0,jumblrflag); + basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,&swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag); + swap->bobspend.I.suppress_pubkeys = 1; + basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,&swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag); + swap->alicereclaim.I.suppress_pubkeys = 1; + swap->bobpayment.utxotxid = qp->txid, swap->bobpayment.utxovout = qp->vout; + swap->bobdeposit.utxotxid = qp->txid2, swap->bobdeposit.utxovout = qp->vout2; + swap->alicepayment.utxotxid = qp->desttxid, swap->alicepayment.utxovout = qp->destvout; + if ( swap->I.iambob != 0 ) + swap->otherfee.utxotxid = qp->feetxid, swap->otherfee.utxovout = qp->feevout; + else swap->myfee.utxotxid = qp->feetxid, swap->myfee.utxovout = qp->feevout; + char str[65],str2[65],str3[65]; printf("IAMBOB.%d %s %s %s\n",swap->I.iambob,bits256_str(str,qp->txid),bits256_str(str2,qp->txid2),bits256_str(str3,qp->feetxid)); + return(swap); +} + +struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp) +{ + 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) 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; + swap->persistent_privkey = privkey; + memcpy(swap->persistent_pubkey33,pubkey33,33); + calc_rmd160_sha256(swap->changermd160,pubkey33,33); + if ( bitcoin_swapinit(privkey,pubkey33,pubkey25519,swap,optionduration,!iambob,qp) == 0 ) + { + printf("error doing swapinit\n"); + free(swap); + swap = 0; + } + return(swap); +} + diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c new file mode 100644 index 000000000..2fcb6d89a --- /dev/null +++ b/iguana/exchanges/LP_transaction.c @@ -0,0 +1,1490 @@ + +/****************************************************************************** + * 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_transaction.c +// marketmaker +// + +bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxid) +{ + char *retstr; bits256 txid; cJSON *retjson,*errorobj; int32_t i,sentflag = 0; + memset(&txid,0,sizeof(txid)); + for (i=0; i<1; i++) + { + if ( (retstr= LP_sendrawtransaction(symbol,txbytes)) != 0 ) + { + if ( is_hexstr(retstr,0) == 64 ) + { + decode_hex(txid.bytes,32,retstr); + if ( bits256_cmp(txid,expectedtxid) == 0 || (bits256_nonz(expectedtxid) == 0 && bits256_nonz(txid) != 0) ) + sentflag = 1; + } + else if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (errorobj= jobj(retjson,"error")) != 0 ) + { + if ( jint(errorobj,"code") == -27 ) // "transaction already in block chain" + { + txid = expectedtxid; + sentflag = 1; + } + } + free_json(retjson); + } + 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 ) + break; + } + return(txid); +} + +bits256 LP_broadcast_tx(char *name,char *symbol,uint8_t *data,int32_t datalen) +{ + bits256 txid; char *signedtx; + memset(txid.bytes,0,sizeof(txid)); + if ( data != 0 && datalen != 0 ) + { + signedtx = malloc(datalen*2 + 1); + init_hexbytes_noT(signedtx,data,datalen); + txid = bits256_doublesha256(0,data,datalen); +#ifdef BASILISK_DISABLESENDTX + char str[65]; printf("%s <- dont sendrawtransaction (%s) %s\n",name,bits256_str(str,txid),signedtx); +#else + txid = LP_broadcast(name,symbol,signedtx,txid); +#endif + free(signedtx); + } + return(txid); +} + +int32_t iguana_msgtx_Vset(uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,struct vin_info *V) +{ + int32_t vini,j,scriptlen,p2shlen,userdatalen,siglen,plen,need_op0=0,len = 0; uint8_t *script,*redeemscript=0,*userdata=0; struct vin_info *vp; + for (vini=0; vinitx_in; vini++) + { + vp = &V[vini]; + if ( (userdatalen= vp->userdatalen) == 0 ) + { + userdatalen = vp->userdatalen = msgtx->vins[vini].userdatalen; + userdata = msgtx->vins[vini].userdata; + } else userdata = vp->userdata; + if ( (p2shlen= vp->p2shlen) == 0 ) + { + p2shlen = vp->p2shlen = msgtx->vins[vini].p2shlen; + redeemscript = msgtx->vins[vini].redeemscript; + } + else + { + redeemscript = vp->p2shscript; + msgtx->vins[vini].redeemscript = redeemscript; + } + if ( msgtx->vins[vini].spendlen > 33 && msgtx->vins[vini].spendscript[msgtx->vins[vini].spendlen - 1] == SCRIPT_OP_CHECKMULTISIG ) + { + need_op0 = 1; + printf("found multisig spendscript\n"); + } + if ( redeemscript != 0 && p2shlen > 33 && redeemscript[p2shlen - 1] == SCRIPT_OP_CHECKMULTISIG ) + { + need_op0 = 1; + //printf("found multisig redeemscript\n"); + } + msgtx->vins[vini].vinscript = script = &serialized[len]; + msgtx->vins[vini].vinscript[0] = 0; + scriptlen = need_op0; + for (j=0; jN; j++) + { + if ( (siglen= vp->signers[j].siglen) > 0 ) + { + script[scriptlen++] = siglen; + memcpy(&script[scriptlen],vp->signers[j].sig,siglen); + scriptlen += siglen; + } + } + msgtx->vins[vini].scriptlen = scriptlen; + if ( vp->suppress_pubkeys == 0 && (vp->N > 1 || bitcoin_pubkeylen(&vp->spendscript[1]) != vp->spendscript[0] || vp->spendscript[vp->spendlen-1] != 0xac) ) + { + for (j=0; jN; j++) + { + if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) > 0 ) + { + script[scriptlen++] = plen; + memcpy(&script[scriptlen],vp->signers[j].pubkey,plen); + scriptlen += plen; + } + } + msgtx->vins[vini].scriptlen = scriptlen; + } + if ( userdatalen != 0 ) + { + memcpy(&script[scriptlen],userdata,userdatalen); + msgtx->vins[vini].userdata = &script[scriptlen]; + msgtx->vins[vini].userdatalen = userdatalen; + scriptlen += userdatalen; + } + //printf("USERDATALEN.%d scriptlen.%d redeemlen.%d\n",userdatalen,scriptlen,p2shlen); + if ( p2shlen != 0 ) + { + if ( p2shlen < 76 ) + script[scriptlen++] = p2shlen; + else if ( p2shlen <= 0xff ) + { + script[scriptlen++] = 0x4c; + script[scriptlen++] = p2shlen; + } + else if ( p2shlen <= 0xffff ) + { + script[scriptlen++] = 0x4d; + script[scriptlen++] = (p2shlen & 0xff); + script[scriptlen++] = ((p2shlen >> 8) & 0xff); + } else return(-1); + msgtx->vins[vini].p2shlen = p2shlen; + memcpy(&script[scriptlen],redeemscript,p2shlen); + scriptlen += p2shlen; + } + len += scriptlen; + } + if ( (0) ) + { + int32_t i; for (i=0; i 0 ) + { + activescript = V[vini].p2shscript; + activescriptlen = V[vini].p2shlen; + } + else + { + activescript = V[vini].spendscript; + activescriptlen = V[vini].spendlen; + } + memcpy(V[vini].spendscript,activescript,activescriptlen); + V[vini].spendlen = activescriptlen; + spendscript = iguana_spendasm(activescript,activescriptlen); + if ( activescriptlen < 16 ) + continue; + //printf("interpreter.(%s)\n",jprint(spendscript,0)); + //printf("bitcoin_assembler ignore_cltverr.%d suppress.%d\n",V[vini].ignore_cltverr,V[vini].suppress_pubkeys); + if ( (scriptlen= bitcoin_assembler(coin,logarray,script,spendscript,1,nLockTime,&V[vini])) < 0 ) + { + //printf("bitcoin_assembler error scriptlen.%d\n",scriptlen); + errs++; + } + else if ( scriptlen != activescriptlen || memcmp(script,activescript,scriptlen) != 0 ) + { + if ( logarray != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"error","script reconstruction failed"); + } + init_hexbytes_noT(str,activescript,activescriptlen); + //printf("activescript.(%s)\n",str); + if ( logarray != 0 && item != 0 ) + jaddstr(item,"original",str); + init_hexbytes_noT(str,script,scriptlen); + //printf("reconstructed.(%s)\n",str); + if ( logarray != 0 ) + { + jaddstr(item,"reconstructed",str); + jaddi(logarray,item); + } else printf(" scriptlen mismatch.%d vs %d or miscompare\n",scriptlen,activescriptlen); + errs++; + } + memcpy(V[vini].spendscript,savescript,savelen); + V[vini].spendlen = savelen; + } + if ( errs != 0 ) + return(-errs); + if ( logarray != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"result","success"); + jaddi(logarray,item); + } + return(0); +} + +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)); + if ( str != 0 ) + { + 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(wiftaddr,&addrtype,&privkey,str) != sizeof(bits256) ) + { + //if ( (waddr= iguana_waddresssearch(&wacct,str)) != 0 ) + // privkey = waddr->privkey; + //else memset(privkey.bytes,0,sizeof(privkey)); + } + } + return(privkey); +} + +int32_t iguana_vininfo_create(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msgtx,cJSON *vins,int32_t numinputs,struct vin_info *V) +{ + int32_t i,plen,finalized = 1,len = 0; struct vin_info *vp; //struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint32_t sigsize,pubkeysize,p2shsize,userdatalen; + msgtx->tx_in = numinputs; + maxsize -= (sizeof(struct iguana_msgvin) * msgtx->tx_in); + msgtx->vins = (struct iguana_msgvin *)&serialized[maxsize]; + memset(msgtx->vins,0,sizeof(struct iguana_msgvin) * msgtx->tx_in); + if ( msgtx->tx_in > 0 && msgtx->tx_in*sizeof(struct iguana_msgvin) < maxsize ) + { + for (i=0; itx_in; i++) + { + vp = &V[i]; + //printf("VINS.(%s)\n",jprint(jitem(vins,i),0)); + len += iguana_parsevinobj(&serialized[len],maxsize,&msgtx->vins[i],jitem(vins,i),vp); + if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) + finalized = 0; + if ( msgtx->vins[i].spendscript == 0 ) + { + /*if ( iguana_RTunspentindfind(coin,&outpt,vp->coinaddr,vp->spendscript,&vp->spendlen,&vp->amount,&vp->height,msgtx->vins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1,0) == 0 ) + { + vp->unspentind = outpt.unspentind; + msgtx->vins[i].spendscript = vp->spendscript; + msgtx->vins[i].spendlen = vp->spendlen; + vp->hashtype = iguana_vinscriptparse(coin,vp,&sigsize,&pubkeysize,&p2shsize,&userdatalen,vp->spendscript,vp->spendlen); + vp->userdatalen = userdatalen; + printf("V %.8f (%s) spendscript.[%d] userdatalen.%d\n",dstr(vp->amount),vp->coinaddr,vp->spendlen,userdatalen); + }*/ + } + else + { + memcpy(vp->spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen); + vp->spendlen = msgtx->vins[i].spendlen; + _iguana_calcrmd160(taddr,pubtype,p2shtype,vp); + if ( (plen= bitcoin_pubkeylen(vp->signers[0].pubkey)) > 0 ) + bitcoin_address(vp->coinaddr,taddr,pubtype,vp->signers[0].pubkey,plen); + } + if ( vp->M == 0 && vp->N == 0 ) + vp->M = vp->N = 1; + /*if ( vp->coinaddr[i] != 0 && (waddr= iguana_waddresssearch(&wacct,vp->coinaddr)) != 0 ) + { + vp->signers[0].privkey = waddr->privkey; + if ( (plen= bitcoin_pubkeylen(waddr->pubkey)) != vp->spendscript[1] || vp->spendscript[vp->spendlen-1] != 0xac ) + { + if ( plen > 0 && plen < sizeof(vp->signers[0].pubkey) ) + memcpy(vp->signers[0].pubkey,waddr->pubkey,plen); + } + }*/ + } + } + return(finalized); +} + +int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxlen,struct vin_info *V,uint32_t sighash,int32_t signtx,int32_t suppress_pubkeys) +{ + bits256 sigtxid; uint8_t *sig,*script; struct vin_info *vp; char vpnstr[64]; int32_t scriptlen,complete=0,j,vini=0,flag=0,siglen,numvouts,numsigs; + numvouts = msgtx->tx_out; + vpnstr[0] = 0; + *signedtx = 0; + memset(signedtxidp,0,sizeof(*signedtxidp)); + for (vini=0; vinitx_in; vini++) + { + if ( V->p2shscript[0] != 0 && V->p2shlen != 0 ) + { + script = V->p2shscript; + scriptlen = V->p2shlen; + //for (j=0; jp2shlen.%d\n",V->p2shlen); + } + else + { + script = msgtx->vins[vini].spendscript; + scriptlen = msgtx->vins[vini].spendlen; + } + sigtxid = bitcoin_sigtxid(taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys); + if ( bits256_nonz(sigtxid) != 0 ) + { + vp = &V[vini]; + vp->sigtxid = sigtxid; + for (j=numsigs=0; jN; j++) + { + sig = vp->signers[j].sig; + siglen = vp->signers[j].siglen; + if ( signtx != 0 && bits256_nonz(vp->signers[j].privkey) != 0 ) + { + siglen = bitcoin_sign(ctx,symbol,sig,sigtxid,vp->signers[j].privkey,0); + //if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) <= 0 ) + bitcoin_pubkey33(ctx,vp->signers[j].pubkey,vp->signers[j].privkey); + sig[siglen++] = sighash; + vp->signers[j].siglen = siglen; + /*char str[65]; printf("SIGTXID.(%s) ",bits256_str(str,sigtxid)); + int32_t i; for (i=0; isigners[j].pubkey[i]); + // s2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1; + printf(" SIGNEDTX.[%02x] siglen.%d priv.%s\n",sig[siglen-1],siglen,bits256_str(str,vp->signers[j].privkey));*/ + } + if ( sig == 0 || siglen == 0 ) + { + memset(vp->signers[j].pubkey,0,sizeof(vp->signers[j].pubkey)); + continue; + } + if ( bitcoin_verify(ctx,sig,siglen-1,sigtxid,vp->signers[j].pubkey,bitcoin_pubkeylen(vp->signers[j].pubkey)) < 0 ) + { + int32_t k; for (k=0; ksigners[j].pubkey); k++) + printf("%02x",vp->signers[j].pubkey[k]); + printf(" SIG.%d.%d ERROR siglen.%d\n",vini,j,siglen); + } + else + { + flag++; + numsigs++; + /*int32_t z; char tmpaddr[64]; + for (z=0; zsigners[j].pubkey[z]); + bitcoin_address(tmpaddr,60,vp->signers[j].pubkey,33); + printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr);*/ + } + } + if ( numsigs >= vp->M ) + complete = 1; + } + } + iguana_msgtx_Vset(serialized,maxlen,msgtx,V); + cJSON *txobj = cJSON_CreateObject(); + *signedtx = iguana_rawtxbytes(taddr,pubtype,p2shtype,isPoS,height,txobj,msgtx,suppress_pubkeys); + //printf("SIGNEDTX.(%s)\n",jprint(txobj,1)); + *signedtxidp = msgtx->txid; + return(complete); +} + +int64_t iguana_lockval(int32_t finalized,int64_t locktime) +{ + int64_t lockval = -1; + if ( finalized == 0 ) + return(locktime); + return(lockval); +} + +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; + memset(privkey.bytes,0,sizeof(privkey)); + if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize ) + { + serialized = malloc(maxsize); + serialized2 = malloc(maxsize); + serialized3 = malloc(maxsize); + serialized4 = malloc(maxsize); + extraspace = malloc(extralen); + memset(msgtx,0,sizeof(*msgtx)); + decode_hex(serialized,len,rawtx); + // printf("call hex2json.(%s) vins.(%s)\n",rawtx,jprint(vins,0)); + if ( (txobj= bitcoin_hex2json(taddr,pubtype,p2shtype,isPoS,height,&txid,msgtx,rawtx,extraspace,extralen,serialized4,vins,V->suppress_pubkeys)) != 0 ) + { + //printf("back from bitcoin_hex2json (%s)\n",jprint(vins,0)); + } else fprintf(stderr,"no txobj from bitcoin_hex2json\n"); + if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) + { + //printf("numinputs.%d msgtx.%d\n",numinputs,msgtx->tx_in); + memset(msgtx,0,sizeof(*msgtx)); + if ( iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,65536,vins,V->suppress_pubkeys) > 0 && numinputs == msgtx->tx_in ) + { + memset(pubkeys,0,sizeof(pubkeys)); + memset(privkeys,0,sizeof(privkeys)); + if ( (n= cJSON_GetArraySize(privkeysjson)) > 0 ) + { + for (i=0; itx_in); + for (i=0; itx_in; i++) + { + if ( msgtx->vins[i].p2shlen != 0 ) + { + char coinaddr[64]; uint32_t userdatalen,sigsize,pubkeysize; uint8_t *userdata; int32_t j,k,hashtype,type,flag; struct vin_info mvin,mainvin; bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + coinaddr[0] = 0; + sigsize = 0; + flag = (msgtx->vins[i].vinscript[0] == 0); + type = bitcoin_scriptget(taddr,pubtype,p2shtype,&hashtype,&sigsize,&pubkeysize,&userdata,&userdatalen,&mainvin,msgtx->vins[i].vinscript+flag,msgtx->vins[i].scriptlen-flag,0); + //printf("i.%d flag.%d type.%d scriptlen.%d\n",i,flag,type,msgtx->vins[i].scriptlen); + if ( msgtx->vins[i].redeemscript != 0 ) + { + //for (j=0; jvins[i].p2shlen; j++) + // printf("%02x",msgtx->vins[i].redeemscript[j]); + bitcoin_address(coinaddr,taddr,p2shtype,msgtx->vins[i].redeemscript,msgtx->vins[i].p2shlen); + type = iguana_calcrmd160(taddr,pubtype,p2shtype,0,&mvin,msgtx->vins[i].redeemscript,msgtx->vins[i].p2shlen,zero,0,0); + for (j=0; jsuppress_pubkeys == 0 ) + { + for (z=0; z<33; z++) + V[i].signers[j].pubkey[z] = mvin.signers[j].pubkey[z]; + } + if ( flag != 0 && pubkeysize == 33 && mainvin.signers[0].siglen != 0 ) // jl777: need to generalize + { + if ( memcmp(mvin.signers[j].pubkey,mainvin.signers[0].pubkey,33) == 0 ) + { + for (z=0; zsuppress_pubkeys == 0 ) + { + for (z=0; z<33; z++) + V[i].signers[j].pubkey[z] = pubkeys[k][z]; + } + //printf("%s -> V[%d].signer.[%d] <- privkey.%d\n",mvin.signers[j].coinaddr,i,j,k); + break; + } + } + } + //printf("type.%d p2sh.[%d] -> %s M.%d N.%d\n",type,i,mvin.coinaddr,mvin.M,mvin.N); + } + } + if ( i < V->N ) + V->signers[i].privkey = privkey; + if ( i < numinputs ) + V[i].signers[0].privkey = privkey; + plen = bitcoin_pubkeylen(V->signers[i].pubkey); + if ( V->suppress_pubkeys == 0 && plen <= 0 ) + { + if ( i < numinputs ) + { + for (z=0; zsigners[i].pubkey[z]; + } + } + } + finalized = iguana_vininfo_create(taddr,pubtype,p2shtype,isPoS,serialized2,maxsize,msgtx,vins,numinputs,V); + //printf("finalized.%d ignore_cltverr.%d suppress.%d\n",finalized,V[0].ignore_cltverr,V[0].suppress_pubkeys); + if ( (complete= bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys)) > 0 && signedtx != 0 ) + { + /*int32_t tmp; //char str[65]; + if ( (tmp= iguana_interpreter(ctx,cJSON_CreateArray(),iguana_lockval(finalized,jint(txobj,"locktime")),V,numinputs)) < 0 ) + { + printf("iguana_interpreter %d error.(%s)\n",tmp,signedtx); + complete = 0; + } else printf("interpreter passed\n");*/ + } else printf("complete.%d\n",complete); + } else printf("rwmsgtx error\n"); + } else fprintf(stderr,"no inputs in vins.(%s)\n",vins!=0?jprint(vins,0):"null"); + free(extraspace); + free(serialized), free(serialized2), free(serialized3), free(serialized4); + } else return(-1); + if ( txobj != 0 ) + free_json(txobj); + *signedtxp = signedtx; + return(complete); +} + +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; + memset(signedtxidp,0,sizeof(*signedtxidp)); + if ( finalseqid == 0 ) + locktime = expiration; + //printf("bobtxspend.%s redeem.[%d]\n",symbol,redeemlen); + if ( redeemlen < 0 ) + return(0); +#ifndef BASILISK_DISABLESENDTX + if ( (value= LP_txvalue(txdestaddr,symbol,utxotxid,vout)) == 0 ) + { + char str[65]; + printf("basilisk_swap_bobtxspend.%s %s utxo.(%s) already spent or doesnt exist\n",name,symbol,bits256_str(str,utxotxid)); + return(0); + } +#else + value = satoshis; +#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)); + 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); + memset(V,0,sizeof(V)); + privkeys = cJSON_CreateArray(); + if ( privkey2p != 0 ) + { + V[0].signers[1].privkey = *privkey2p; + bitcoin_pubkey33(ctx,V[0].signers[1].pubkey,*privkey2p); + 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(wiftaddr,wifstr,privkey,wiftype); + jaddistr(privkeys,wifstr); + V[0].suppress_pubkeys = suppress_pubkeys; + V[0].ignore_cltverr = ignore_cltverr; + if ( redeemlen != 0 ) + memcpy(V[0].p2shscript,redeemscript,redeemlen), V[0].p2shlen = redeemlen; + txobj = bitcoin_txcreate(symbol,isPoS,locktime,1,timestamp); + vins = cJSON_CreateArray(); + item = cJSON_CreateObject(); + if ( userdata != 0 && userdatalen > 0 ) + { + memcpy(V[0].userdata,userdata,userdatalen); + V[0].userdatalen = userdatalen; + init_hexbytes_noT(hexstr,userdata,userdatalen); + jaddstr(item,"userdata",hexstr); + } + jaddbits256(item,"txid",utxotxid); + jaddnum(item,"vout",vout); + bitcoin_address(tmpaddr,taddr,pubtype,pubkey33,33); + bitcoin_addr2rmd160(taddr,&addrtype,rmd160,tmpaddr); + if ( redeemlen != 0 ) + { + init_hexbytes_noT(hexstr,redeemscript,redeemlen); + jaddstr(item,"redeemScript",hexstr); + if ( vinaddr != 0 ) + bitcoin_addr2rmd160(taddr,&addrtype,rmd160,vinaddr); + spendlen = bitcoin_p2shspend(spendscript,0,rmd160); + //printf("P2SH path.%s\n",vinaddr!=0?vinaddr:0); + } else spendlen = bitcoin_standardspend(spendscript,0,rmd160); + init_hexbytes_noT(hexstr,spendscript,spendlen); + jaddstr(item,"scriptPubKey",hexstr); + jaddnum(item,"suppress",suppress_pubkeys); + jaddnum(item,"sequence",sequenceid); + jaddi(vins,item); + jdelete(txobj,"vin"); + jadd(txobj,"vin",vins); + if ( destaddr == 0 ) + { + destaddr = _destaddr; + bitcoin_address(destaddr,taddr,pubtype,pubkey33,33); + } + bitcoin_addr2rmd160(taddr,&addrtype,rmd160,destaddr); + if ( addrtype == p2shtype ) + spendlen = bitcoin_p2shspend(spendscript,0,rmd160); + else spendlen = bitcoin_standardspend(spendscript,0,rmd160); + if ( change != 0 && strcmp(changeaddr,destaddr) == 0 ) + { + printf("combine change %.8f -> %s\n",dstr(change),changeaddr); + satoshis += change; + change = 0; + } + txobj = bitcoin_txoutput(txobj,spendscript,spendlen,satoshis); + if ( change != 0 ) + { + int32_t changelen; uint8_t changescript[1024],changetype,changermd160[20]; + bitcoin_addr2rmd160(taddr,&changetype,changermd160,changeaddr); + changelen = bitcoin_standardspend(changescript,0,changermd160); + txobj = bitcoin_txoutput(txobj,changescript,changelen,change); + } + if ( (rawtxbytes= bitcoin_json2hex(isPoS,&txid,txobj,V)) != 0 ) + { + char str[65]; + 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,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 ) + { + printf("incomplete signing suppress.%d %s (%s)\n",suppress_pubkeys,name,jprint(vins,0)); + if ( signedtx != 0 ) + free(signedtx), signedtx = 0; + } else printf("basilisk_swap_bobtxspend %s -> %s\n",name,bits256_str(str,*signedtxidp)); + free(rawtxbytes); + } else printf("error making rawtx suppress.%d\n",suppress_pubkeys); + free_json(privkeys); + free_json(txobj); + return(signedtx); +} + +int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pubkey33,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf,int32_t delay,bits256 privkey,uint8_t *changermd160,char *vinaddr) +{ + int32_t retval=-1,len,iter; char *signedtx,*changeaddr = 0,_changeaddr[64]; struct iguana_info *coin; int64_t newtxfee=0,destamount; + char str2[65]; printf("%s rawtxgen.(%s/v%d)\n",rawtx->name,bits256_str(str2,rawtx->utxotxid),rawtx->utxovout); + if ( (coin= rawtx->coin) == 0 ) + return(-1); + //return(_basilisk_rawtx_gen(str,swapstarted,pubkey33,iambob,lockinputs,rawtx,locktime,script,scriptlen,txfee,minconf,delay,privkey)); + if ( changermd160 != 0 ) + { + changeaddr = _changeaddr; + 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->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) ) + { + decode_hex(rawtx->txbytes,rawtx->I.datalen,signedtx); + rawtx->I.completed = 1; + retval = 0; + } + free(signedtx); + if ( strcmp(coin->symbol,"BTC") != 0 ) + return(retval); + len = rawtx->I.datalen; + 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 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); + timestamp = swap->I.started; + if ( dest == &swap->aliceclaim ) + 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 : LP_MIN_TXFEE; + if ( changermd160 != 0 ) + { + changeaddr = _changeaddr; + bitcoin_address(changeaddr,taddr,pubtype,changermd160,20); + //printf("changeaddr.(%s)\n",changeaddr); + } + for (iter=0; iter<2; iter++) + { + 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) ) + { + decode_hex(dest->txbytes,dest->I.datalen,signedtx); + dest->I.completed = 1; + retval = 0; + } + free(signedtx); + if ( strcmp(symbol,"BTC") != 0 ) + return(retval); + estimatedrate = LP_getestimatedrate(symbol); + newtxfee = estimatedrate * dest->I.datalen; + } else break; + } + return(retval); + //return(_basilisk_rawtx_sign(symbol,pubtype,p2shtype,isPoS,wiftype,swap,timestamp,locktime,sequenceid,dest,rawtx,privkey,privkey2,userdata,userdatalen,ignore_cltverr)); +} + +int32_t basilisk_alicescript(uint8_t *redeemscript,int32_t *redeemlenp,uint8_t *script,int32_t n,char *msigaddr,uint8_t taddr,uint8_t altps2h,bits256 pubAm,bits256 pubBn) +{ + uint8_t p2sh160[20]; struct vin_info V; + memset(&V,0,sizeof(V)); + memcpy(&V.signers[0].pubkey[1],pubAm.bytes,sizeof(pubAm)), V.signers[0].pubkey[0] = 0x02; + memcpy(&V.signers[1].pubkey[1],pubBn.bytes,sizeof(pubBn)), V.signers[1].pubkey[0] = 0x03; + V.M = V.N = 2; + *redeemlenp = bitcoin_MofNspendscript(p2sh160,redeemscript,n,&V); + bitcoin_address(msigaddr,taddr,altps2h,p2sh160,sizeof(p2sh160)); + n = bitcoin_p2shspend(script,0,p2sh160); + //for (i=0; i<*redeemlenp; i++) + // printf("%02x",redeemscript[i]); + //printf(" <- redeemscript alicetx\n"); + return(n); +} + +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 ) + { + pubAm = bitcoin_pubkey33(ctx,tmp33,privAm); + pubBn = bitcoin_pubkey33(ctx,tmp33,privBn); + //char str[65]; + //printf("pubAm.(%s)\n",bits256_str(str,pubAm)); + //printf("pubBn.(%s)\n",bits256_str(str,pubBn)); + spendlen = basilisk_alicescript(redeemscript,&redeemlen,spendscript,0,msigaddr,taddr,p2shtype,pubAm,pubBn); + //char str[65]; printf("%s utxo.(%s) redeemlen.%d spendlen.%d\n",msigaddr,bits256_str(str,utxotxid),redeemlen,spendlen); + /*rev = privAm; + for (i=0; i<32; i++) + privAm.bytes[i] = rev.bytes[31 - i]; + rev = privBn; + for (i=0; i<32; i++) + privBn.bytes[i] = rev.bytes[31 - i];*/ + 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); +} + +int32_t LP_swap_txdestaddr(char *destaddr,bits256 txid,int32_t vout,cJSON *txobj) +{ + int32_t n,m,retval = -1; cJSON *vouts,*item,*addresses,*skey; char *addr; + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && vout < n ) + { + item = jitem(vouts,vout); + if ( (skey= jobj(item,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 ) + { + item = jitem(addresses,0); + if ( (addr= jstr(item,0)) != 0 ) + { + safecopy(destaddr,addr,64); + retval = 0; + } + //printf("item.(%s) -> dest.(%s)\n",jprint(item,0),destaddr); + } + } + return(retval); +} + +int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vout) +{ + cJSON *retjson; + coinaddr[0] = 0; + if ( (retjson= LP_gettx(symbol,txid)) != 0 ) + { + LP_swap_txdestaddr(coinaddr,txid,vout,retjson); + free_json(retjson); + } + return(coinaddr[0] != 0); +} + +int32_t basilisk_swap_getsigscript(char *symbol,uint8_t *script,int32_t maxlen,bits256 txid,int32_t vini) +{ + cJSON *retjson,*vins,*item,*skey; int32_t n,scriptlen = 0; char *hexstr; + if ( (retjson= LP_gettx(symbol,txid)) != 0 ) + { + if ( (vins= jarray(&n,retjson,"vin")) != 0 && vini < n ) + { + item = jitem(vins,vini); + if ( (skey= jobj(item,"scriptSig")) != 0 && (hexstr= jstr(skey,"hex")) != 0 && (scriptlen= (int32_t)strlen(hexstr)) < maxlen*2 ) + { + scriptlen >>= 1; + decode_hex(script,scriptlen,hexstr); + //char str[65]; printf("%s/v%d sigscript.(%s)\n",bits256_str(str,txid),vini,hexstr); + } + } + free_json(retjson); + } + 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; + memset(&spendtxid,0,sizeof(spendtxid)); + if ( (retstr= blocktrail_listtransactions(symbol,coinaddr,100,0)) != 0 ) + { + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i %s\n",bits256_str(str,spendtxid),destaddr); + break; + } + } + } + } + free_json(array); + } + free(retstr); + } + return(spendtxid); +} +#endif + +bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t vout) +{ + bits256 spendtxid,txid; char *catstr,*addr; cJSON *array,*item,*item2,*txobj,*vins; int32_t i,n,m,spendvin; char coinaddr[64],str[65]; + // listtransactions or listspents + destaddr[0] = 0; + coinaddr[0] = 0; + memset(&spendtxid,0,sizeof(spendtxid)); + if ( LP_spendsearch(&spendtxid,&spendvin,symbol,utxotxid,vout) > 0 ) + 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 ) + { + //[{"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); + if ( coinaddr[0] != 0 ) + spendtxid = _LP_swap_spendtxid(symbol,destaddr,coinaddr,utxotxid,vout);*/ + } + else + { + if ( (array= LP_listtransactions(symbol,destaddr,1000,0)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0 ) + { + for (i=0; i jint(item,"vout") ) + { + item2 = jitem(vins,jint(item,"vout")); + if ( bits256_cmp(utxotxid,jbits256(item2,"txid")) == 0 && vout == jint(item2,"vout") ) + { + spendtxid = txid; + break; + } + } + } + } + } + if ( i == n ) + printf("dpowlist: native couldnt find spendtxid for %s\n",bits256_str(str,utxotxid)); + } + free_json(array); + } + if ( bits256_nonz(spendtxid) != 0 ) + return(spendtxid); + } + /*if ( iguana_isnotarychain(symbol) >= 0 ) + { + LP_swap_getcoinaddr(symbol,coinaddr,utxotxid,vout); + printf("fallback use DEX for native (%s) (%s)\n",coinaddr,bits256_str(str,utxotxid)); + if ( coinaddr[0] != 0 ) + { + spendtxid = _LP_swap_spendtxid(symbol,destaddr,coinaddr,utxotxid,vout); + printf("spendtxid.(%s)\n",bits256_str(str,spendtxid)); + } + }*/ + } + return(spendtxid); +} + +int32_t basilisk_swap_bobredeemscript(int32_t depositflag,int32_t *secretstartp,uint8_t *redeemscript,uint32_t locktime,bits256 pubA0,bits256 pubB0,bits256 pubB1,bits256 privAm,bits256 privBn,uint8_t *secretAm,uint8_t *secretAm256,uint8_t *secretBn,uint8_t *secretBn256) +{ + int32_t i,n=0; bits256 cltvpub,destpub,privkey; uint8_t pubkeyA[33],pubkeyB[33],secret160[20],secret256[32]; + if ( depositflag != 0 ) + { + pubkeyA[0] = 0x02, cltvpub = pubA0; + pubkeyB[0] = 0x03, destpub = pubB0; + privkey = privBn; + memcpy(secret160,secretBn,20); + memcpy(secret256,secretBn256,32); + } + else + { + pubkeyA[0] = 0x03, cltvpub = pubB1; + pubkeyB[0] = 0x02, destpub = pubA0; + privkey = privAm; + memcpy(secret160,secretAm,20); + memcpy(secret256,secretAm256,32); + } + //for (i=0; i<32; i++) + // printf("%02x",secret256[i]); + //printf(" <- secret256 depositflag.%d nonz.%d\n",depositflag,bits256_nonz(privkey)); + if ( bits256_nonz(cltvpub) == 0 || bits256_nonz(destpub) == 0 ) + return(-1); + for (i=0; i<20; i++) + if ( secret160[i] != 0 ) + break; + if ( i == 20 ) + return(-1); + memcpy(pubkeyA+1,cltvpub.bytes,sizeof(cltvpub)); + memcpy(pubkeyB+1,destpub.bytes,sizeof(destpub)); + redeemscript[n++] = SCRIPT_OP_IF; + n = bitcoin_checklocktimeverify(redeemscript,n,locktime); +#ifdef DISABLE_CHECKSIG + n = bitcoin_secret256spend(redeemscript,n,cltvpub); +#else + n = bitcoin_pubkeyspend(redeemscript,n,pubkeyA); +#endif + redeemscript[n++] = SCRIPT_OP_ELSE; + if ( secretstartp != 0 ) + *secretstartp = n + 2; + if ( 1 ) + { + if ( 1 && bits256_nonz(privkey) != 0 ) + { + uint8_t bufA[20],bufB[20]; + revcalc_rmd160_sha256(bufA,privkey); + calc_rmd160_sha256(bufB,privkey.bytes,sizeof(privkey)); + /*if ( memcmp(bufA,secret160,sizeof(bufA)) == 0 ) + printf("MATCHES BUFA\n"); + else if ( memcmp(bufB,secret160,sizeof(bufB)) == 0 ) + printf("MATCHES BUFB\n"); + else printf("secret160 matches neither\n"); + for (i=0; i<20; i++) + printf("%02x",bufA[i]); + printf(" <- revcalc\n"); + for (i=0; i<20; i++) + printf("%02x",bufB[i]); + printf(" <- calc\n");*/ + memcpy(secret160,bufB,20); + } + n = bitcoin_secret160verify(redeemscript,n,secret160); + } + else + { + redeemscript[n++] = 0xa8;//IGUANA_OP_SHA256; + redeemscript[n++] = 0x20; + memcpy(&redeemscript[n],secret256,0x20), n += 0x20; + redeemscript[n++] = 0x88; //SCRIPT_OP_EQUALVERIFY; + } +#ifdef DISABLE_CHECKSIG + n = bitcoin_secret256spend(redeemscript,n,destpub); +#else + n = bitcoin_pubkeyspend(redeemscript,n,pubkeyB); +#endif + redeemscript[n++] = SCRIPT_OP_ENDIF; + return(n); +} + +int32_t basilisk_bobscript(uint8_t *rmd160,uint8_t *redeemscript,int32_t *redeemlenp,uint8_t *script,int32_t n,uint32_t *locktimep,int32_t *secretstartp,struct basilisk_swapinfo *swap,int32_t depositflag) +{ + if ( depositflag != 0 ) + *locktimep = swap->started + swap->putduration + swap->callduration; + else *locktimep = swap->started + swap->putduration; + *redeemlenp = n = basilisk_swap_bobredeemscript(depositflag,secretstartp,redeemscript,*locktimep,swap->pubA0,swap->pubB0,swap->pubB1,swap->privAm,swap->privBn,swap->secretAm,swap->secretAm256,swap->secretBn,swap->secretBn256); + if ( n > 0 ) + { + calc_rmd160_sha256(rmd160,redeemscript,n); + n = bitcoin_p2shspend(script,0,rmd160); + int32_t i; for (i=0; i if path, 0 -> else path + return(len); +} + +/*Bob paytx: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF*/ + +int32_t basilisk_bobpayment_reclaim(struct basilisk_swap *swap,int32_t delay) +{ + uint8_t userdata[512]; int32_t retval,len = 0; static bits256 zero; + //printf("basilisk_bobpayment_reclaim\n"); + 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.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]); + //printf(" <- bobreclaim\n"); + //basilisk_txlog(swap,&swap->bobreclaim,delay); + return(retval); + } + return(-1); +} + +int32_t basilisk_bobdeposit_refund(struct basilisk_swap *swap,int32_t delay) +{ + uint8_t userdata[512]; int32_t i,retval,len = 0; char str[65]; + 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.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]); + printf(" <- bobrefund.(%s)\n",bits256_str(str,swap->bobrefund.I.txid)); + //basilisk_txlog(swap,&swap->bobrefund,delay); + return(retval); + } + return(-1); +} + +void LP_swap_coinaddr(struct basilisk_swap *swap,struct iguana_info *coin,char *coinaddr,uint8_t *data,int32_t datalen) +{ + cJSON *txobj,*vouts,*vout,*addresses,*item,*skey; uint8_t extraspace[8192]; bits256 signedtxid; struct iguana_msgtx msgtx; char *addr; int32_t n,m,suppress_pubkeys = 0; + if ( (txobj= bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&signedtxid,&msgtx,extraspace,sizeof(extraspace),data,datalen,0,suppress_pubkeys)) != 0 ) + { + //char str[65]; printf("got txid.%s (%s)\n",bits256_str(str,signedtxid),jprint(txobj,0)); + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n > 0 ) + { + vout = jitem(vouts,0); + //printf("VOUT.(%s)\n",jprint(vout,0)); + if ( (skey= jobj(vout,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 ) + { + item = jitem(addresses,0); + //printf("item.(%s)\n",jprint(item,0)); + if ( (addr= jstr(item,0)) != 0 ) + { + safecopy(coinaddr,addr,64); + //printf("extracted.(%s)\n",coinaddr); + } + } + } + free_json(txobj); + } +} + +int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,int32_t genflag) +{ + int32_t j; char coinaddr[64],checkaddr[64]; + bitcoin_address(coinaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->changermd160,20); + if ( genflag != 0 && swap->I.iambob == 0 ) + printf("basilisk_bobscripts_set WARNING: alice generating BOB tx\n"); + if ( depositflag == 0 ) + { + swap->bobpayment.I.spendlen = basilisk_bobscript(swap->bobpayment.I.rmd160,swap->bobpayment.redeemscript,&swap->bobpayment.I.redeemlen,swap->bobpayment.spendscript,0,&swap->bobpayment.I.locktime,&swap->bobpayment.I.secretstart,&swap->I,0); + 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); + //LP_importaddress(swap->bobcoin.symbol,swap->bobpayment.I.destaddr); + //int32_t i; for (i=0; ibobpayment.I.redeemlen; i++) + // printf("%02x",swap->bobpayment.redeemscript[i]); + //printf(" <- bobpayment redeem %d %s\n",i,swap->bobpayment.I.destaddr); + if ( genflag != 0 && bits256_nonz(*(bits256 *)swap->I.secretBn256) != 0 && swap->bobpayment.I.datalen == 0 ) + { + basilisk_rawtx_gen(swap->ctx,"payment",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobpayment,swap->bobpayment.I.locktime,swap->bobpayment.spendscript,swap->bobpayment.I.spendlen,swap->bobpayment.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); + if ( swap->bobpayment.I.spendlen == 0 || swap->bobpayment.I.datalen == 0 ) + { + printf("error bob generating %p payment.%d\n",swap->bobpayment.txbytes,swap->bobpayment.I.spendlen); + sleep(DEX_SLEEP); + } + else + { + for (j=0; jbobpayment.I.datalen; j++) + printf("%02x",swap->bobpayment.txbytes[j]); + printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen); + for (j=0; jbobpayment.I.redeemlen; j++) + printf("%02x",swap->bobpayment.redeemscript[j]); + printf(" <- redeem.%d\n",swap->bobpayment.I.redeemlen); + printf(" <- GENERATED BOB PAYMENT.%d destaddr.(%s)\n",swap->bobpayment.I.datalen,swap->bobpayment.I.destaddr); + LP_swap_coinaddr(swap,&swap->bobcoin,checkaddr,swap->bobpayment.txbytes,swap->bobpayment.I.datalen); + if ( strcmp(swap->bobpayment.I.destaddr,checkaddr) != 0 ) + { + printf("BOBPAYMENT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobpayment.I.destaddr,checkaddr); + return(-1); + } + LP_unspents_mark(swap->bobcoin.symbol,swap->bobpayment.vins); + //printf("bobscripts set completed\n"); + return(0); + } + } + } + else + { + swap->bobdeposit.I.spendlen = basilisk_bobscript(swap->bobdeposit.I.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.I.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.I.locktime,&swap->bobdeposit.I.secretstart,&swap->I,1); + 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); + //LP_importaddress(swap->bobcoin.symbol,swap->bobdeposit.I.destaddr); + int32_t i; for (i=0; ibobdeposit.I.redeemlen; i++) + printf("%02x",swap->bobdeposit.redeemscript[i]); + printf(" <- bobdeposit redeem %d %s\n",i,swap->bobdeposit.I.destaddr); + if ( genflag != 0 && (swap->bobdeposit.I.datalen == 0 || swap->bobrefund.I.datalen == 0) ) + { + basilisk_rawtx_gen(swap->ctx,"deposit",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobdeposit,swap->bobdeposit.I.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.I.spendlen,swap->bobdeposit.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); + if ( swap->bobdeposit.I.datalen == 0 || swap->bobdeposit.I.spendlen == 0 ) + { + printf("error bob generating %p deposit.%d\n",swap->bobdeposit.txbytes,swap->bobdeposit.I.spendlen); + sleep(DEX_SLEEP); + } + else + { + for (j=0; jbobdeposit.I.datalen; j++) + printf("%02x",swap->bobdeposit.txbytes[j]); + printf(" <- GENERATED BOB DEPOSIT.%d (%s)\n",swap->bobdeposit.I.datalen,swap->bobdeposit.I.destaddr); + LP_swap_coinaddr(swap,&swap->bobcoin,checkaddr,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen); + if ( strcmp(swap->bobdeposit.I.destaddr,checkaddr) != 0 ) + { + printf("BOBDEPOSIT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobdeposit.I.destaddr,checkaddr); + return(-1); + } + LP_unspents_mark(swap->bobcoin.symbol,swap->bobdeposit.vins); + printf("bobscripts set completed\n"); + return(0); + } + } + } + return(0); +} + +/**/ + +#ifdef old +int32_t basilisk_alicepayment_spend(struct basilisk_swap *swap,struct basilisk_rawtx *dest) +{ + int32_t i,retval; + printf("alicepayment_spend\n"); + swap->alicepayment.I.spendlen = basilisk_alicescript(swap->alicepayment.redeemscript,&swap->alicepayment.I.redeemlen,swap->alicepayment.spendscript,0,swap->alicepayment.I.destaddr,swap->alicecoin.p2shtype,swap->I.pubAm,swap->I.pubBn); + printf("alicepayment_spend len.%d\n",swap->alicepayment.I.spendlen); + if ( swap->I.iambob == 0 ) + { + memcpy(swap->I.userdata_alicereclaim,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen); + swap->I.userdata_alicereclaimlen = swap->alicepayment.I.spendlen; + } + else + { + memcpy(swap->I.userdata_bobspend,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen); + swap->I.userdata_bobspendlen = swap->alicepayment.I.spendlen; + } + if ( (retval= basilisk_rawtx_sign(swap->alicecoin.symbol,swap->alicecoin.pubtype,swap->alicecoin.p2shtype,swap->alicecoin.isPoS,swap->alicecoin.wiftype,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1,swap->changermd160)) == 0 ) + { + for (i=0; iI.datalen; i++) + printf("%02x",dest->txbytes[i]); + printf(" <- msigspend\n\n"); + if ( dest == &swap->bobspend ) + swap->I.bobspent = 1; + //basilisk_txlog(swap,dest,0); // bobspend or alicereclaim + return(retval); + } + return(-1); +} +#endif + +void basilisk_alicepayment(struct basilisk_swap *swap,struct iguana_info *coin,struct basilisk_rawtx *alicepayment,bits256 pubAm,bits256 pubBn) +{ + char coinaddr[64]; + alicepayment->I.spendlen = basilisk_alicescript(alicepayment->redeemscript,&alicepayment->I.redeemlen,alicepayment->spendscript,0,alicepayment->I.destaddr,coin->taddr,coin->p2shtype,pubAm,pubBn); + /*for (i=0; i<33; i++) + printf("%02x",swap->persistent_pubkey33[i]); + printf(" pubkey33, "); + for (i=0; i<20; i++) + printf("%02x",swap->changermd160[i]); + 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,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) +{ + char coinaddr[64]; int32_t i,retval = -1; + if ( swap->alicepayment.I.datalen == 0 ) + basilisk_alicepayment(swap,swap->alicepayment.coin,&swap->alicepayment,swap->I.pubAm,swap->I.pubBn); + if ( swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.spendlen == 0 ) + printf("error alice generating payment.%d\n",swap->alicepayment.I.spendlen); + else + { + bitcoin_address(swap->alicepayment.I.destaddr,swap->alicecoin.taddr,swap->alicecoin.p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen); + //LP_importaddress(swap->alicecoin.symbol,swap->alicepayment.I.destaddr); + strcpy(swap->alicepayment.p2shaddr,swap->alicepayment.I.destaddr); + retval = 0; + for (i=0; ialicepayment.I.datalen; i++) + printf("%02x",swap->alicepayment.txbytes[i]); + printf(" ALICE PAYMENT created.(%s)\n",swap->alicepayment.I.destaddr); + LP_unspents_mark(swap->alicecoin.symbol,swap->alicepayment.vins); + //LP_importaddress(swap->alicecoin.symbol,swap->alicepayment.I.destaddr); + //basilisk_txlog(swap,&swap->alicepayment,-1); + } + if ( swap->myfee.I.datalen == 0 ) + { + 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,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 %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); + for (i=0; imyfee.I.datalen; i++) + printf("%02x",swap->myfee.txbytes[i]); + printf(" <- fee state.%x\n",swap->I.statebits); + swap->I.statebits |= 0x40; + } + else + { + printf("error creating myfee\n"); + return(-2); + } + } + if ( swap->alicepayment.I.datalen != 0 && swap->alicepayment.I.spendlen > 0 && swap->myfee.I.datalen != 0 && swap->myfee.I.spendlen > 0 ) + return(0); + return(-1); +} + +int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + if ( LP_rawtx_spendscript(swap,swap->bobcoin.longestchain,&swap->otherfee,0,data,datalen,0) == 0 ) + { + printf("otherfee amount %.8f -> %s vs %s\n",dstr(swap->otherfee.I.amount),swap->otherfee.p2shaddr,swap->otherfee.I.destaddr); + if ( strcmp(swap->otherfee.I.destaddr,swap->otherfee.p2shaddr) == 0 ) + { + printf("dexfee verified\n"); + return(0); + } + } + return(-1); +} + +/* Bob deposit: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF*/ + +int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + uint8_t userdata[512]; int32_t retval=-1,len = 0; static bits256 zero; + if ( LP_rawtx_spendscript(swap,swap->bobcoin.longestchain,&swap->bobdeposit,0,data,datalen,0) == 0 ) + { + swap->aliceclaim.utxovout = 0; + 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; + 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]); + printf(" <- bobdeposit.%d %s\n",swap->bobdeposit.I.datalen,bits256_str(str,swap->bobdeposit.I.signedtxid)); + for (i=0; ibobdeposit.I.redeemlen; i++) + printf("%02x",swap->bobdeposit.redeemscript[i]); + printf(" <- bobdeposit redeem %d %s suppress.%d\n",i,swap->bobdeposit.I.destaddr,swap->aliceclaim.I.suppress_pubkeys);*/ + memcpy(swap->aliceclaim.redeemscript,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + swap->aliceclaim.I.redeemlen = swap->bobdeposit.I.redeemlen; + 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.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]); + printf(" <- bobdeposit\n"); + for (i=0; ialiceclaim.I.datalen; i++) + printf("%02x",swap->aliceclaim.txbytes[i]); + printf(" <- aliceclaim\n");*/ + //basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration); + return(LP_waitmempool(swap->bobcoin.symbol,swap->bobdeposit.I.signedtxid,10)); + } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr); + } + printf("error with bobdeposit\n"); + return(retval); +} + +int32_t LP_verify_alicepayment(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + if ( LP_rawtx_spendscript(swap,swap->alicecoin.longestchain,&swap->alicepayment,0,data,datalen,0) == 0 ) + { + swap->bobspend.utxovout = 0; + swap->bobspend.utxotxid = swap->alicepayment.I.signedtxid = LP_broadcast_tx(swap->alicepayment.name,swap->alicecoin.symbol,swap->alicepayment.txbytes,swap->alicepayment.I.datalen); + bitcoin_address(swap->alicepayment.p2shaddr,swap->alicecoin.taddr,swap->alicecoin.p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen); + strcpy(swap->alicepayment.I.destaddr,swap->alicepayment.p2shaddr); + if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 ) + swap->aliceunconf = 1; + basilisk_dontforget_update(swap,&swap->alicepayment); + return(LP_waitmempool(swap->alicecoin.symbol,swap->alicepayment.I.signedtxid,10)); + //printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr); + //LP_importaddress(swap->alicecoin.symbol,swap->alicepayment.p2shaddr); + return(0); + } + printf("error validating alicepayment\n"); + return(-1); +} + +int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + uint8_t userdata[512]; int32_t i,retval=-1,len = 0; bits256 revAm; + memset(revAm.bytes,0,sizeof(revAm)); + if ( LP_rawtx_spendscript(swap,swap->bobcoin.longestchain,&swap->bobpayment,0,data,datalen,0) == 0 ) + { + swap->alicespend.utxovout = 0; + 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; + 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]); + printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen); + for (i=0; ibobpayment.I.redeemlen; i++) + printf("%02x",swap->bobpayment.redeemscript[i]); + printf(" <- bobpayment redeem %d %s %s\n",i,swap->bobpayment.I.destaddr,bits256_str(str,swap->bobpayment.I.signedtxid));*/ + memcpy(swap->I.userdata_alicespend,userdata,len); + swap->I.userdata_alicespendlen = len; + retval = 0; + 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.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]); + printf(" <- bobpayment\n"); + for (i=0; ialicespend.I.datalen; i++) + printf("%02x",swap->alicespend.txbytes[i]); + printf(" <- alicespend\n\n");*/ + swap->I.alicespent = 1; + return(LP_waitmempool(swap->bobcoin.symbol,swap->bobpayment.I.signedtxid,10)); + } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->alicespend.I.suppress_pubkeys,swap->bobpayment.I.destaddr); + } + printf("error validating bobpayment\n"); + return(-1); +} diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c new file mode 100644 index 000000000..71134a365 --- /dev/null +++ b/iguana/exchanges/LP_utxos.c @@ -0,0 +1,1022 @@ + +/****************************************************************************** + * 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_utxos.c +// marketmaker +// + +int32_t LP_ismine(struct LP_utxoinfo *utxo) +{ + if ( utxo != 0 && bits256_cmp(utxo->pubkey,LP_mypub25519) == 0 ) + return(1); + else return(0); +} + +int32_t LP_isavailable(struct LP_utxoinfo *utxo) +{ + if ( time(NULL) > utxo->T.swappending ) + utxo->T.swappending = 0; + if ( utxo != 0 && utxo->T.swappending == 0 && utxo->S.swap == 0 ) + return(1); + else return(0); +} + +int32_t LP_isunspent(struct LP_utxoinfo *utxo) +{ + if ( utxo != 0 && utxo->T.spentflag == 0 && LP_isavailable(utxo) > 0 ) + return(1); + else return(0); +} + +void LP_utxosetkey(uint8_t *key,bits256 txid,int32_t vout) +{ + memcpy(key,txid.bytes,sizeof(txid)); + memcpy(&key[sizeof(txid)],&vout,sizeof(vout)); +} + +struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout) +{ + struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)]; + LP_utxosetkey(key,txid,vout); + HASH_FIND(hh,LP_utxoinfos[iambob],key,sizeof(key),utxo); + return(utxo); +} + +struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo=0; uint8_t key2[sizeof(txid2) + sizeof(vout2)]; + LP_utxosetkey(key2,txid2,vout2); + HASH_FIND(hh2,LP_utxoinfos2[iambob],key2,sizeof(key2),utxo); + return(utxo); +} + +struct LP_utxoinfo *LP_utxofind(int32_t iambob,bits256 txid,int32_t vout) +{ + struct LP_utxoinfo *utxo=0; + portable_mutex_lock(&LP_utxomutex); + utxo = _LP_utxofind(iambob,txid,vout); + portable_mutex_unlock(&LP_utxomutex); + return(utxo); +} + +struct LP_utxoinfo *LP_utxopairfind(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo=0; struct _LP_utxoinfo u; + if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 ) + { + u = (iambob != 0) ? utxo->deposit : utxo->fee; + if (vout2 == u.vout && bits256_cmp(u.txid,txid2) == 0 ) + return(utxo); + } + return(0); +} + +struct LP_utxoinfo *LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo=0; + portable_mutex_lock(&LP_utxomutex); + utxo = _LP_utxo2find(iambob,txid2,vout2); + portable_mutex_unlock(&LP_utxomutex); + return(utxo); +} + +struct LP_utxoinfo *LP_utxofinds(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo; + if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxofind(iambob,txid2,vout2)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid2,vout2)) != 0 ) + return(utxo); + else return(0); +} + +int32_t LP_utxoaddptrs(struct LP_utxoinfo *ptrs[],int32_t n,struct LP_utxoinfo *utxo) +{ + int32_t i; + for (i=0; ipayment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo ) + n = LP_utxoaddptrs(ptrs,n,utxo); + if ( (utxo= _LP_utxo2find(iambob,refutxo->payment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo ) + n = LP_utxoaddptrs(ptrs,n,utxo); + u = (refutxo->iambob != 0) ? refutxo->deposit : refutxo->fee; + if ( (utxo= _LP_utxofind(iambob,u.txid,u.vout)) != 0 && utxo != refutxo ) + n = LP_utxoaddptrs(ptrs,n,utxo); + if ( (utxo= _LP_utxo2find(iambob,u.txid,u.vout)) != 0 && utxo != refutxo ) + n = LP_utxoaddptrs(ptrs,n,utxo); + } + portable_mutex_unlock(&LP_utxomutex); + if ( 0 && n > 0 ) + printf("LP_utxocollisions n.%d\n",n); + return(n); +} + +int32_t _LP_availableset(struct LP_utxoinfo *utxo) +{ + int32_t flag = 0; + if ( utxo != 0 ) + { + if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) + flag = 1, memset(&utxo->S.otherpubkey,0,sizeof(utxo->S.otherpubkey)); + if ( utxo->S.swap != 0 ) + flag = 1, utxo->S.swap = 0; + if ( utxo->T.swappending != 0 ) + flag = 1, utxo->T.swappending = 0; + return(flag); + } + return(0); +} + +void _LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey) +{ + if ( utxo != 0 ) + { + utxo->T.swappending = (uint32_t)(time(NULL) + LP_RESERVETIME); + utxo->S.otherpubkey = otherpubkey; + } +} + +void LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey) +{ + struct LP_utxoinfo *ptrs[8]; int32_t i,n; struct _LP_utxoinfo u; + memset(ptrs,0,sizeof(ptrs)); + if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 ) + { + for (i=0; iiambob != 0) ? utxo->deposit : utxo->fee; + char str[65],str2[65]; printf("UTXO.[%d] RESERVED %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); + _LP_unavailableset(utxo,otherpubkey); +} + +void LP_availableset(struct LP_utxoinfo *utxo) +{ + struct LP_utxoinfo *ptrs[8]; int32_t i,n,count = 0; struct _LP_utxoinfo u; + if ( utxo != 0 ) + { + 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_mypub25519)); + portable_mutex_lock(&LP_utxomutex); + for (iambob=0; iambob<=1; iambob++) + { + HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp) + { + if ( LP_isavailable(utxo) > 0 ) + { + if ( allutxos != 0 || LP_ismine(utxo) > 0 ) + { + printf("iambob.%d delete.(%s)\n",iambob,bits256_str(str,utxo->payment.txid)); + HASH_DELETE(hh,LP_utxoinfos[iambob],utxo); + //free(utxo); let the LP_utxoinfos2 free the utxo, should be 1:1 + } else n++; + } else n++; + } + HASH_ITER(hh,LP_utxoinfos2[iambob],utxo,tmp) + { + if ( LP_isavailable(utxo) > 0 ) + { + if ( allutxos != 0 || LP_ismine(utxo) > 0 ) + { + printf("iambob.%d delete2.(%s)\n",iambob,bits256_str(str,utxo->payment.txid)); + HASH_DELETE(hh2,LP_utxoinfos2[iambob],utxo); + free(utxo); + } else n++; + } else n++; + } + } + portable_mutex_unlock(&LP_utxomutex); + return(n); +} + +cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo) +{ + struct _LP_utxoinfo u; + 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,"iambob",utxo->iambob); + jaddstr(item,"address",utxo->coinaddr); + jaddbits256(item,"txid",utxo->payment.txid); + jaddnum(item,"vout",utxo->payment.vout); + jadd64bits(item,"value",utxo->payment.value); + jadd64bits(item,"satoshis",utxo->S.satoshis); + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( bits256_nonz(u.txid) != 0 ) + { + jaddbits256(item,"txid2",u.txid); + jaddnum(item,"vout2",u.vout); + jadd64bits(item,"value2",u.value); + } + if ( utxo->T.swappending != 0 ) + jaddnum(item,"pending",utxo->T.swappending); + if ( utxo->iambob != 0 ) + { + jaddbits256(item,"srchash",utxo->pubkey);//LP_mypub25519); + if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) + jaddbits256(item,"desthash",utxo->S.otherpubkey); + } + else + { + jaddbits256(item,"desthash",utxo->pubkey);//LP_mypub25519); + if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) + jaddbits256(item,"srchash",utxo->S.otherpubkey); + } + if ( utxo->S.swap != 0 ) + jaddstr(item,"swap","in progress"); + if ( utxo->T.spentflag != 0 ) + jaddnum(item,"spent",utxo->T.spentflag); + jaddnum(item,"session",utxo->T.sessionid); + return(item); +} + +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); + jaddstr(item,"base",utxo->coin); + jaddstr(item,"script",utxo->spendscript); + return(item); +} + +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) +{ + //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 ( 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 ( bypass == 0 && strcmp(destaddr,destaddr2) != 0 ) + printf("mismatched %s destaddr (%s) vs (%s)\n",symbol,destaddr,destaddr2); + 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 + { + *valp = val; + *val2p = val2; + return(1); + } + } // 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 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 ) + { + //printf("iambob.%d case 00\n",iter); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + } + if ( (utxo= LP_utxo2find(iter,txid,vout)) != 0 ) + { + //printf("iambob.%d case 01\n",iter); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + } + if ( (utxo= LP_utxofind(iter,txid2,vout2)) != 0 ) + { + //printf("iambob.%d case 10\n",iter); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + } + if ( (utxo= LP_utxo2find(iter,txid2,vout2)) != 0 ) + { + //printf("iambob.%d case 11\n",iter); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + } + }*/ + *valp = val; + *val2p = val2; + return(0); +} + +char *LP_utxos(int32_t iambob,struct LP_peerinfo *mypeer,char *symbol,int32_t lastn) +{ + 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; + 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 ( (symbol == 0 || symbol[0] == 0 || strcmp(symbol,utxo->coin) == 0) && utxo->T.spentflag == 0 ) + { + u = (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 ) + { + char str[65]; printf("iambob.%d not eligible (%.8f %.8f) %s %s/v%d\n",iambob,dstr(val),dstr(val2),utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout); + continue; + } else jaddi(utxosjson,LP_utxojson(utxo)); + } + } + if ( (n= cJSON_GetArraySize(utxosjson)) > lastn ) + { + m = n - lastn; + for (i=0; iT.spentflag != 0 ) + { + //char str[65]; printf("prevent adding %s/v%d to inventory\n",bits256_str(str,txid),vout); + return(1); + } + } + return(0); +} + +struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) +{ + uint64_t srcvalue,srcvalue2; struct LP_utxoinfo *utxo,*tmp,*bestutxo = 0; + if ( symbol == 0 || destsatoshis == 0 ) + { + printf("LP_utxo_bestfit error symbol.%p %.8f\n",symbol,dstr(destsatoshis)); + return(0); + } + HASH_ITER(hh,LP_utxoinfos[0],utxo,tmp) + { + //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 ( strcmp(symbol,utxo->coin) != 0 ) + continue; + if ( LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 ) + { + 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); + continue; + } + bestutxo = utxo; + } //else printf("skip alice utxo %.8f vs dest %.8f\n",dstr(utxo->S.satoshis),dstr(destsatoshis)); + } + } + return(bestutxo); +} + +void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector) +{ + //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 ) + { + argjson = cJSON_CreateObject(); + jaddstr(argjson,"method","checktxid"); + jaddbits256(argjson,"txid",utxo->payment.txid); + jaddnum(argjson,"vout",utxo->payment.vout); + if ( selector != 0 ) + { + if ( bits256_nonz(utxo->deposit.txid) != 0 ) + u = utxo->deposit; + else u = utxo->fee; + jaddbits256(argjson,"checktxid",u.txid); + jaddnum(argjson,"checkvout",u.vout); + } + msg = jprint(argjson,1); + /LP_send(LP_mypubsock,msg,(int32_t)strlen(msg)+1,1); + }*/ +} + +char *LP_spentcheck(cJSON *argjson) +{ + bits256 txid,checktxid; int32_t vout,checkvout; struct LP_utxoinfo *utxo; int32_t iambob,retval = 0; + txid = jbits256(argjson,"txid"); + vout = jint(argjson,"vout"); + for (iambob=0; iambob<=1; iambob++) + { + if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 && utxo->T.spentflag == 0 ) + { + if ( jobj(argjson,"check") == 0 ) + checktxid = txid, checkvout = vout; + else + { + checktxid = jbits256(argjson,"checktxid"); + checkvout = jint(argjson,"checkvout"); + } + if ( LP_txvalue(0,utxo->coin,checktxid,checkvout) == 0 ) + { + if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 ) + LP_mypeer->numutxos--; + utxo->T.spentflag = (uint32_t)time(NULL); + retval++; + //printf("indeed txid was spent\n"); + } + } + } + if ( retval > 0 ) + return(clonestr("{\"result\":\"marked as spent\"}")); + return(clonestr("{\"error\":\"cant find txid to check spent status\"}")); +} + +void LP_utxo_clientpublish(struct LP_utxoinfo *utxo) +{ + 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) + { + 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 || (IAMLP == 0 && coin->inactive != 0) ) + { + printf("LP_utxoadd reject inactive %s\n",symbol); + return(0); + } + txfee = LP_txfeecalc(coin->symbol,0); + if ( iambob != 0 && value2 < 9 * (value >> 3) + 2*txfee ) // big txfee padding + { + if ( value2 > 2*txfee ) + tmpsatoshis = (((value2 - 2*txfee) / 9) << 3); + else return(0); + } else tmpsatoshis = (value - txfee); + char str[65],str2[65],dispflag = (iambob == 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 ) + { + 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 spent in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); + return(0); + } + if ( (utxo= LP_utxofinds(iambob,txid,vout,txid2,vout2)) != 0 ) + { + if ( 0 && LP_ismine(utxo) == 0 ) + { + char str2[65],str3[65]; printf("iambob.%d %s %s utxoadd.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,pubkey),symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2)); + printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(tmpsatoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis)); + } + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || tmpsatoshis != utxo->S.satoshis || vout2 != u.vout || value2 != u.value || strcmp(symbol,utxo->coin) != 0 || strcmp(spendscript,utxo->spendscript) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || bits256_cmp(pubkey,utxo->pubkey) != 0 ) + { + utxo->T.errors++; + char str[65],str2[65],str3[65],str4[65],str5[65],str6[65]; + if ( utxo->T.spentflag != 0 || LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) < utxo->payment.value || LP_txvalue(0,utxo->coin,u.txid,u.vout) < u.value ) + { + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + printf("original utxo pair not valid\n"); + if ( dispflag != 0 ) + printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,tmpsatoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(spendscript,utxo->spendscript) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey)); + utxo = 0; + } + } + 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->pubkey = pubkey; + safecopy(utxo->gui,gui,sizeof(utxo->gui)); + safecopy(utxo->coin,symbol,sizeof(utxo->coin)); + safecopy(utxo->coinaddr,coinaddr,sizeof(utxo->coinaddr)); + safecopy(utxo->spendscript,spendscript,sizeof(utxo->spendscript)); + utxo->payment.txid = txid; + utxo->payment.vout = vout; + utxo->payment.value = value; + utxo->S.satoshis = tmpsatoshis; + if ( (utxo->iambob= iambob) != 0 ) + { + utxo->deposit.txid = txid2; + utxo->deposit.vout = vout2; + utxo->deposit.value = value2; + } + else + { + utxo->fee.txid = txid2; + utxo->fee.vout = vout2; + utxo->fee.value = value2; + } + 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 ) + HASH_ADD_KEYPTR(hh2,LP_utxoinfos2[iambob],utxo->key2,sizeof(utxo->key2),utxo); + portable_mutex_unlock(&LP_utxomutex); + if ( iambob != 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); +} + +struct LP_utxoinfo *LP_utxoaddjson(int32_t iambob,int32_t pubsock,cJSON *argjson) +{ + struct LP_utxoinfo *utxo; + if ( jobj(argjson,"iambob") == 0 || iambob != jint(argjson,"iambob") ) + { + printf("LP_utxoaddjson: iambob.%d != arg.%d obj.%p (%s)\n",iambob,jint(argjson,"iambob"),jobj(argjson,"iambob"),jprint(argjson,0)); + 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"),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); +} + +int32_t LP_utxosparse(char *destipaddr,uint16_t destport,char *retstr,uint32_t now) +{ + struct LP_peerinfo *destpeer,*peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; bits256 txid; struct LP_utxoinfo *utxo; + //printf("parse.(%s)\n",retstr); + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; iT.lasttime = now; + } + } + if ( (destpeer= LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport)) != 0 ) + { + destpeer->numutxos = n; + } + } + free_json(array); + } + 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,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); + if ( coin == 0 ) + coin = ""; + //printf("utxo query.(%s)\n",destipaddr); + if ( IAMLP != 0 ) + 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); + retval = LP_utxosparse(destipaddr,destport,retstr,now); + //printf("got.(%s)\n",retstr); + free(retstr); + /*i = 0; + if ( lastn >= mypeer->numutxos ) + firsti = -1; + else firsti = (mypeer->numutxos - lastn); + HASH_ITER(hh,LP_utxoinfos,utxo,tmp) + { + if ( i++ < firsti ) + continue; + if ( utxo->lasttime != now && strcmp(utxo->ipaddr,"127.0.0.1") != 0 ) + { + char str[65]; printf("{%s:%u %s} ",utxo->ipaddr,utxo->port,bits256_str(str,utxo->txid)); + flag++; + if ( (retstr= issue_LP_notifyutxo(destipaddr,destport,utxo)) != 0 ) + free(retstr); + } + } + if ( flag != 0 ) + printf(" <- missing utxos\n");*/ + } + return(retval); +} + +cJSON *LP_inventory(char *symbol,int32_t iambob) +{ + struct LP_utxoinfo *utxo,*tmp; struct _LP_utxoinfo u; char *myipaddr; cJSON *array; uint64_t val,val2; + array = cJSON_CreateArray(); + if ( LP_mypeer != 0 ) + myipaddr = LP_mypeer->ipaddr; + 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_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; + if ( LP_iseligible(&val,&val2,iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,u.txid,u.vout) == 0 ) + { + 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); + } + return(array); +} + +int32_t LP_maxvalue(uint64_t *values,int32_t n) +{ + int32_t i,maxi = -1; uint64_t maxval = 0; + for (i=0; i maxval ) + { + maxi = i; + maxval = values[i]; + } + return(maxi); +} + +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; + mindist = dist; + } + } + return(mini); +} + +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,txfee,depositval,targetval,value,total = 0; + if ( coin == 0 ) + { + printf("coin not active\n"); + return(0); + } + //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++) + { + if ( iambob == 0 ) + values = calloc(n,sizeof(*values)); + else memset(values,0,n * sizeof(*values)); + //if ( iambob == 0 && IAMLP != 0 ) + // continue; + used = 0; + for (i=0; i 0 ) + { + //printf("%s\n",jprint(item,0)); + values[i] = satoshis; + } else used++; + //printf("%.8f ",dstr(satoshis)); + } + //printf("array.%d\n",n); + while ( used < n-1 ) + { + //for (i=0; i= 0 ) + { + item = jitem(array,i); + deposittxid = jbits256(item,"txid"); + depositvout = juint(item,"vout"); + script = jstr(item,"scriptPubKey"); + depositval = values[i]; + values[i] = 0, used++; + if ( iambob == 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"); + vout = juint(item,"vout"); + if ( jstr(item,"scriptPubKey") != 0 && strcmp(script,jstr(item,"scriptPubKey")) == 0 ) + { + value = values[i]; + values[i] = 0, used++; + 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_gui,LP_sessionid)) != 0 ) + { + } + } + else + { + 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 ) + free(values); + } + } + free_json(array); + } + //printf("privkey.%s %.8f\n",symbol,dstr(total)); + return(total); +} + +char *LP_secretaddresses(void *ctx,char *passphrase,int32_t n,uint8_t taddr,uint8_t pubtype) +{ + int32_t i; uint8_t tmptype,pubkey33[33],rmd160[20]; char output[777*45],str[65],str2[65],buf[8192],wifstr[128],coinaddr[64]; bits256 checkprivkey,privkey,pubkey; cJSON *retjson; + retjson = cJSON_CreateObject(); + if ( passphrase == 0 || passphrase[0] == 0 ) + passphrase = "password"; + if ( n <= 0 ) + n = 16; + else if ( n > 777 ) + n = 777; + conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,taddr,pubtype); + printf("generator (%s) secrets.[%d] <%s> t.%u p.%u\n",coinaddr,n,passphrase,taddr,pubtype); + sprintf(output,"\"addresses\":["); + for (i=0; i %s vs %s?\n",wifstr,bits256_str(str,privkey),bits256_str(str2,checkprivkey)); + free_json(retjson); + return(clonestr("{\"error\":\"couldnt validate wifstr\"}")); + } + else if ( tmptype != pubtype ) + { + printf("checktype.%d != pubtype.%d\n",tmptype,pubtype); + free_json(retjson); + return(clonestr("{\"error\":\"couldnt validate pubtype\"}")); + } + jaddstr(retjson,coinaddr,wifstr); + sprintf(output+strlen(output),"\\\"%s\\\"%c ",coinaddr,ibytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + else + { + 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)); + } + } + bitcoin_priv2pub(ctx,coin->pubkey33,coin->smartaddr,privkey,coin->taddr,coin->pubtype); + if ( coin->counter == 0 ) + { + coin->counter++; + 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(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)); + } + if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 ) + { + if ( jobj(retjson,"error") != 0 ) + { + printf("cant importprivkey.%s -> (%s), abort session\n",coin->symbol,jprint(retjson,1)); + exit(-1); + } + } + } + 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); +} + +void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase,int32_t initonly) +{ + struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33]; + memset(privkey.bytes,0,sizeof(privkey)); + pubkey = privkey; + HASH_ITER(hh,LP_coins,coin,tmp) + { + //printf("i.%d of %d\n",i,LP_numcoins); + 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); + } +} + + diff --git a/iguana/exchanges/README.md b/iguana/exchanges/README.md new file mode 100644 index 000000000..eab6d5720 --- /dev/null +++ b/iguana/exchanges/README.md @@ -0,0 +1,77 @@ +Latest Readme is at http://pad.supernet.org/barterdex-readme + +DEPENDENCIES +First of all you are going to need to have the komodod daemon and the assetchains running. +Install dependency packages: +sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib autoconf libtool libncurses5-dev unzip git python zlib1g-dev wget bsdmainutils automake libboost-all-dev libssl-dev libprotobuf-dev protobuf-compiler libqt4-dev libqrencode-dev libdb++-dev ntp ntpdate vim software-properties-common curl libcurl4-gnutls-dev cmake clang +Some Linux machines are now providing nanomsg package version 1.0. If it is available via package manager, you can install it from there. Else, you should use github repo of nanomsg and compile it yourself. +For Ubuntu 14.04 you need to install it yourself +cd /tmp +wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz -O nanomsg-1.0.0.tar.gz +tar -xzvf nanomsg-1.0.0.tar.gz +cd nanomsg-1.0.0 +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=/usr +cmake --build . +sudo cmake --build . --target install +sudo ldconfig +Or the following for 16.04 +git clone https://github.com/nanomsg/nanomsg +cd nanomsg +cmake . +make +sudo make install +sudo ldconfig +COMPILE LP NODE +To compile the BarterDEX you need to build iguana one time: +cd ~ +git clone https://github.com/jl777/SuperNET +cd SuperNET/iguana +git checkout dev +./m_LP +IGUANA DAEMON STARTUP +Then launch the iguana daemon by executing: +../agents/iguana & +Now iguana should be running and providing port 7778 API: 127.0.0.1:7778 page in the browser will show the API testpage, but for marketmaker these functions are not used very much. it is port 7779 that is used and the marketmaker program is what provides those functions. +BarterDEX EXCHANGE INSTALL +cd ~/SuperNET/iguana/exchanges +./install +Now, move to ~/SuperNET/iguana/dexscripts: +cd ~/SuperNET/iguana/dexscripts +Now in the ~/SuperNET/iguana/dexscripts directory you will have example scripts that you can change without new git updates overwriting them. These scripts will have example commands that you will need to customize to work with the coins you want to trade. Of course, if a new update to a script is made and you dont run install again then you wont have the latest versions. +For example: if you want to enable the JUMBLR coin, you need to edit the enable file: +nano ~SuperNET/iguana/dexscripts/enable +copy the default command and paste it below but with the coin edited to JUMBLR in this case: +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"JUMBLR\"}" +The same will happen for any other script in the dexscripts directory. You will need to edit the scripts to include or exclude the coins you want to trade. +IMPORTANT: All these scripts are expecting a userpass file, which contains the definition of the $userpass variable to authenticate API access. This avoids evil webpages that try to issue port 7779 calls to steal your money. At first you wont know the value of userpass. To find out, just run any API script. The first one will return all the required data, the "userpass" field is first and you can copy that value and put it into ~/SuperNET/iguana/dexscripts/userpass file. If you dont, all subsequent API calls will get authorization errors.The userpass variable is linked to each passphrase and that is defined in the passphrase file. Put your passphrase in that file. You can find templates for these two files in the iguana/exchanges dir. (you need to copy the edited version of these files to ~/SuperNET/iguana/dexscripts). +cd ~/SuperNET/iguana/dexscripts +./enable +(look for the userpass passphrase that will be generated and copy it) +Now you have to paste the passphrase in both userpass and passphrase files: +nano ./userpass +nano ./passphrase +( paste the passphrase generated into the files where it says: “”) +EXCHANGE CLIENT STARTUP +Next step is to actually start the marketmaker from ~/SuperNET/iguana/dexscripts. + cd ~/SuperNET/iguana/dexscripts + ./client (for client mode) or + ./run (for LPnode mode) +Assuming you created the userpass file properly, you can now issue barterDEX api calls using all the scripts in the dexscripts dir. Please look at these scripts, they are simple curl invocations of a couple lines. Nothing scary and should be self explanatory. +The help script displays all the api endpoints you should need. You can customize any of the dexscripts for your desired usage, make sure you edit them with the right coins, as if you issue a script for BTC it will do it for BTC instead of the coin you wanted. These scripts wont read your mind, they just do what is in them +FUNDING SMARTADDRESS +In order to start trading, you need to fund your smartaddress (as listed on the first API call return) from the getcoins API call. +To see which is your smart address go to ~/SuperNET/iguana/dexscritps and execute: +./getcoins +To make sure you have utxo pairs for both the bob and alice usage, it is best to send utxo in triplets of X, 1.2 X and 0.01 X. So if X is 10, send 10, 12, and 0.1 coins using sendtoaddress to your smartaddress. This means you will have to send 3 different transactions to the same address with 3 different quantities +for example: +If i want to fund my komodo smartaddress with 100 komodo i need to first send a tx with 100kmd then another tx with 120kmd and a third tx with only 10kmd +After this, it should appear in the inventory. To see the inventory you need to execute: +./inv +SETTING PRICE + To set price you need to edit the ./setprice script in the dexscripts folder. This scripts contains a curl command that looks like this: +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":1.234}" +In this command you should edit the coin (in this case is REVS) and then set the price per coin based in Komodo. In the command above we are setting a price of 1.23KMD per REVS. +After you setprice (./setprice), then it will appear in orderbooks with that coin in either the base or rel. + 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/autotrade b/iguana/exchanges/autotrade new file mode 100755 index 000000000..f88b157bb --- /dev/null +++ b/iguana/exchanges/autotrade @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autotrade\",\"base\":\"REVS\",\"rel\":\"KMD\",\"relvolume\":1.01,\"price\":1.234}" diff --git a/iguana/exchanges/balance_loop b/iguana/exchanges/balance_loop new file mode 100755 index 000000000..fcc1b8cb5 --- /dev/null +++ b/iguana/exchanges/balance_loop @@ -0,0 +1,11 @@ +source userpass +ht=$1 +while true +do +#curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"snapshot\",\"coin\":\"KMD\",\"height\":$ht}" +ht=`curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"snapshot\",\"coin\":\"KMD\"}" | jq .blocks` + +echo next height $ht +sleep 600 +done + diff --git a/iguana/exchanges/bestfit b/iguana/exchanges/bestfit new file mode 100755 index 000000000..9ed9e4df2 --- /dev/null +++ b/iguana/exchanges/bestfit @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"bestfit\",\"rel\":\"KMD\",\"relvolume\":1.01}" diff --git a/iguana/exchanges/bitcoin.c b/iguana/exchanges/bitcoin.c index bf37462f0..62c0ed592 100755 --- a/iguana/exchanges/bitcoin.c +++ b/iguana/exchanges/bitcoin.c @@ -19,7 +19,7 @@ cJSON *instantdex_statemachinejson(struct bitcoin_swapinfo *swap); char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params) { - return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params)); + return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,0)); } int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr) @@ -107,29 +107,59 @@ int32_t base58encode_checkbuf(uint8_t addrtype,uint8_t *data,int32_t data_len) int32_t bitcoin_wif2priv(uint8_t *addrtypep,bits256 *privkeyp,char *wifstr) { - int32_t len = -1; bits256 hash; uint8_t buf[64]; + int32_t len = -1; bits256 hash; uint8_t buf[256]; + memset(buf,0,sizeof(buf)); if ( (len= bitcoin_base58decode(buf,wifstr)) >= 4 ) { // validate with trailing hash, then remove hash + if ( len < 38 ) + len = 38; hash = bits256_doublesha256(0,buf,len - 4); *addrtypep = *buf; memcpy(privkeyp,buf+1,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] ) + 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] ) { - //printf("coinaddr.(%s) valid checksum\n",coinaddr); + //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)); + } + } + return((int32_t)strlen(wifstr)); +} + +int32_t bitcoin_priv2wiflong(char *wifstr,bits256 privkey,uint8_t addrtype) +{ + uint8_t data[128]; int32_t len = 32; memcpy(data+1,privkey.bytes,sizeof(privkey)); - data[33] = 1; - len = base58encode_checkbuf(addrtype,data,33); - + len = base58encode_checkbuf(addrtype,data,len); if ( bitcoin_base58encode(wifstr,data,len) == 0 ) return(-1); if ( 1 ) diff --git a/iguana/exchanges/bittrex.c b/iguana/exchanges/bittrex.c index 227cab9b1..d0e5025e9 100755 --- a/iguana/exchanges/bittrex.c +++ b/iguana/exchanges/bittrex.c @@ -169,7 +169,7 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha if ( //CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,payload,payload)) != 0 ) { - if ( *retstrp != 0 ) + if ( 0 && *retstrp != 0 ) printf("SIGNPOST returned.(%s) %s\n",*retstrp,jprint(json,0)); if ( is_cJSON_True(cJSON_GetObjectItem(json,"success")) != 0 && (resultobj= cJSON_GetObjectItem(json,"result")) != 0 ) { @@ -179,13 +179,13 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha uuidstr.buf[j++] = uuidstr.buf[i]; uuidstr.buf[j] = 0; n = (int32_t)strlen(uuidstr.buf); - printf("-> uuidstr.(%s).%d\n",uuidstr.buf,n); + //printf("-> uuidstr.(%s).%d\n",uuidstr.buf,n); decode_hex(databuf,n/2,uuidstr.buf); if ( n >= 16 ) for (i=0; i<8; i++) databuf[i] ^= databuf[8 + i]; memcpy(&txid,databuf,8); - printf("-> %llx\n",(long long)txid); + //printf("-> %llx\n",(long long)txid); } free_json(json); } 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/client b/iguana/exchanges/client new file mode 100755 index 000000000..8b3f8a7ba --- /dev/null +++ b/iguana/exchanges/client @@ -0,0 +1,8 @@ +source passphrase +source coins +pkill -15 marketmaker; +git pull; +cd ..; +./m_mm; +./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & + diff --git a/iguana/exchanges/client_osx b/iguana/exchanges/client_osx new file mode 100755 index 000000000..9e1cada67 --- /dev/null +++ b/iguana/exchanges/client_osx @@ -0,0 +1,8 @@ +source passphrase +source coins +pkill -15 marketmaker; +git pull; +cd ..; +./m_mm; +./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}/Library/Application\ Support\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & + diff --git a/iguana/exchanges/coins b/iguana/exchanges/coins new file mode 100644 index 000000000..672a72d67 --- /dev/null +++ b/iguana/exchanges/coins @@ -0,0 +1,2 @@ +export coins="[ {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":1000000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"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\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"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\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"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\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"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/disable b/iguana/exchanges/disable new file mode 100755 index 000000000..c74b84fd5 --- /dev/null +++ b/iguana/exchanges/disable @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"disable\",\"coin\":\"REVS\"}" diff --git a/iguana/exchanges/dividends b/iguana/exchanges/dividends new file mode 100755 index 000000000..f3dde55a0 --- /dev/null +++ b/iguana/exchanges/dividends @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"dividends\",\"coin\":\"KMD\",\"height\":$1,\"prefix\":\"fiat/jumblr sendtoaddress\",\"suffix\":\"\",\"dividend\":50000,\"dust\":1}" diff --git a/iguana/exchanges/enable b/iguana/exchanges/enable new file mode 100755 index 000000000..a974c1860 --- /dev/null +++ b/iguana/exchanges/enable @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BTC\"}" 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/getcoins b/iguana/exchanges/getcoins new file mode 100755 index 000000000..132e9a9c0 --- /dev/null +++ b/iguana/exchanges/getcoins @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"getcoins\"}" 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/getpeers b/iguana/exchanges/getpeers new file mode 100755 index 000000000..32852ba6a --- /dev/null +++ b/iguana/exchanges/getpeers @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"getpeers\"}" diff --git a/iguana/exchanges/getpeersIP b/iguana/exchanges/getpeersIP new file mode 100755 index 000000000..feef2e5d8 --- /dev/null +++ b/iguana/exchanges/getpeersIP @@ -0,0 +1,10 @@ +curl --url "http://5.9.253.195:7779" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.196:7779" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.197:7779" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.198:7779" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.199:7779" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.200:7779" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.201:7779" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.202:7779" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.203:7779" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.204:7779" --data "{\"method\":\"getpeers\"}" diff --git a/iguana/exchanges/getprices b/iguana/exchanges/getprices new file mode 100755 index 000000000..216b2b86c --- /dev/null +++ b/iguana/exchanges/getprices @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"getprices\",\"coin\":\"REVS\"}" diff --git a/iguana/exchanges/getutxos b/iguana/exchanges/getutxos new file mode 100755 index 000000000..a84c72fb0 --- /dev/null +++ b/iguana/exchanges/getutxos @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"getutxos\",\"coin\":\"REVS\"}" 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/help b/iguana/exchanges/help new file mode 100755 index 000000000..a5f08aa50 --- /dev/null +++ b/iguana/exchanges/help @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"help\"}" diff --git a/iguana/exchanges/install b/iguana/exchanges/install new file mode 100755 index 000000000..0df9ec681 --- /dev/null +++ b/iguana/exchanges/install @@ -0,0 +1,4 @@ +cp snapshot_balance snapshot_loop secretaddresses dividends snapshot 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 +#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/inv b/iguana/exchanges/inv new file mode 100755 index 000000000..b0b5e52b1 --- /dev/null +++ b/iguana/exchanges/inv @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"inventory\",\"coin\":\"KMD\"}" diff --git a/iguana/exchanges/loop b/iguana/exchanges/loop new file mode 100755 index 000000000..8703827ba --- /dev/null +++ b/iguana/exchanges/loop @@ -0,0 +1,7 @@ +while true +do +source userpass +#curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":1.234}" +./s +sleep 3600 +done diff --git a/iguana/exchanges/message b/iguana/exchanges/message new file mode 100755 index 000000000..701f63049 --- /dev/null +++ b/iguana/exchanges/message @@ -0,0 +1,2 @@ +source userpass +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 69502f02f..ffde8b2f3 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -19,11 +19,35 @@ // Copyright © 2017 SuperNET. All rights reserved. // +#define FROM_MARKETMAKER #include #include #include "OS_portable.h" #define MAX(a,b) ((a) > (b) ? (a) : (b)) +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]); +//defined(__APPLE__) || +#if defined(WIN32) || defined(USE_STATIC_NANOMSG) +#include "../../crypto777/nanosrc/nn.h" +#include "../../crypto777/nanosrc/bus.h" +#include "../../crypto777/nanosrc/pubsub.h" +#include "../../crypto777/nanosrc/pipeline.h" +#include "../../crypto777/nanosrc/reqrep.h" +#include "../../crypto777/nanosrc/tcp.h" +#include "../../crypto777/nanosrc/pair.h" +#else +#include "/usr/local/include/nanomsg/nn.h" +#include "/usr/local/include/nanomsg/bus.h" +#include "/usr/local/include/nanomsg/pubsub.h" +#include "/usr/local/include/nanomsg/pipeline.h" +#include "/usr/local/include/nanomsg/reqrep.h" +#include "/usr/local/include/nanomsg/tcp.h" +#include "/usr/local/include/nanomsg/pair.h" +#endif + +char DEX_baseaddr[64],DEX_reladdr[64]; struct mmpending_order { double price,volume; @@ -36,17 +60,26 @@ int32_t Num_Pending; #define IGUANA_URL "http://127.0.0.1:7778" -char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies +/*char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies -}; +};*/ double PAXPRICES[sizeof(CURRENCIES)/sizeof(*CURRENCIES)]; +uint32_t PAXACTIVE; + +char *DEX_swapstatus() +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"getswaplist\"}"); + return(bitcoind_RPC(0,"InstantDEX",url,0,"getswaplist",postdata,0)); +} char *DEX_amlp(char *blocktrail) { char url[512],postdata[1024]; sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"amlp\",\"blocktrail\":\"%s\"}",blocktrail); - return(bitcoind_RPC(0,"tradebot",url,0,"amlp",postdata)); + return(bitcoind_RPC(0,"tradebot",url,0,"amlp",postdata,0)); } char *DEX_openorders(char *exchange) @@ -54,7 +87,7 @@ char *DEX_openorders(char *exchange) char url[512],postdata[1024]; sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"openorders\",\"exchange\":\"%s\"}",exchange); - return(bitcoind_RPC(0,"InstantDEX",url,0,"openorders",postdata)); + return(bitcoind_RPC(0,"InstantDEX",url,0,"openorders",postdata,0)); } char *DEX_tradehistory(char *exchange) @@ -62,7 +95,7 @@ char *DEX_tradehistory(char *exchange) char url[512],postdata[1024]; sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"tradehistory\",\"exchange\":\"%s\"}",exchange); - return(bitcoind_RPC(0,"InstantDEX",url,0,"tradehistory",postdata)); + return(bitcoind_RPC(0,"InstantDEX",url,0,"tradehistory",postdata,0)); } char *DEX_orderstatus(char *exchange,char *orderid) @@ -70,7 +103,7 @@ char *DEX_orderstatus(char *exchange,char *orderid) char url[512],postdata[1024]; sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"orderstatus\",\"exchange\":\"%s\",\"orderid\":\"%s\"}",exchange,orderid); - return(bitcoind_RPC(0,"InstantDEX",url,0,"orderstatus",postdata)); + return(bitcoind_RPC(0,"InstantDEX",url,0,"orderstatus",postdata,0)); } char *DEX_cancelorder(char *exchange,char *orderid) @@ -78,7 +111,7 @@ char *DEX_cancelorder(char *exchange,char *orderid) char url[512],postdata[1024]; sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"cancelorder\",\"exchange\":\"%s\",\"orderid\":\"%s\"}",exchange,orderid); - return(bitcoind_RPC(0,"InstantDEX",url,0,"cancelorder",postdata)); + return(bitcoind_RPC(0,"InstantDEX",url,0,"cancelorder",postdata,0)); } char *DEX_balance(char *exchange,char *base,char *coinaddr) @@ -88,12 +121,12 @@ char *DEX_balance(char *exchange,char *base,char *coinaddr) if ( strcmp(exchange,"DEX") == 0 ) { sprintf(postdata,"{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"%s\",\"symbol\":\"%s\"}",coinaddr,base); - return(bitcoind_RPC(0,"dex",url,0,"getbalance",postdata)); + return(bitcoind_RPC(0,"dex",url,0,"getbalance",postdata,0)); } else { sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"balance\",\"exchange\":\"%s\",\"base\":\"%s\"}",exchange,base); - return(bitcoind_RPC(0,"InstantDEX",url,0,"balance",postdata)); + return(bitcoind_RPC(0,"InstantDEX",url,0,"balance",postdata,0)); } } @@ -102,7 +135,7 @@ char *DEX_apikeypair(char *exchange,char *apikey,char *apisecret) char url[512],postdata[1024]; sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"apikeypair\",\"exchange\":\"%s\",\"apikey\":\"%s\",\"apisecret\":\"%s\"}",exchange,apikey,apisecret); - return(bitcoind_RPC(0,"InstantDEX",url,0,"apikeypair",postdata)); + return(bitcoind_RPC(0,"InstantDEX",url,0,"apikeypair",postdata,0)); } char *DEX_setuserid(char *exchange,char *userid,char *tradepassword) @@ -110,7 +143,7 @@ char *DEX_setuserid(char *exchange,char *userid,char *tradepassword) char url[512],postdata[1024]; sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"setuserid\",\"exchange\":\"%s\",\"userid\":\"%s\",\"tradepassword\":\"%s\"}",exchange,userid,tradepassword); - return(bitcoind_RPC(0,"InstantDEX",url,0,"setuserid",postdata)); + return(bitcoind_RPC(0,"InstantDEX",url,0,"setuserid",postdata,0)); } char *DEX_trade(char *exchange,char *base,char *rel,int32_t dir,double price,double volume) @@ -119,7 +152,7 @@ char *DEX_trade(char *exchange,char *base,char *rel,int32_t dir,double price,dou sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"%s\",\"exchange\":\"%s\",\"base\":\"%s\",\"rel\":\"%s\",\"price\":%.8f,\"volume\":%.8f,\"dotrade\":1}",dir>0?"buy":"sell",exchange,base,rel,price,volume); //printf("DEX_trade.(%s)\n",postdata); - return(bitcoind_RPC(0,"InstantDEX",url,0,dir>0?"buy":"sell",postdata)); + return(bitcoind_RPC(0,"InstantDEX",url,0,dir>0?"buy":"sell",postdata,0)); } char *DEX_withdraw(char *exchange,char *base,char *destaddr,double amount) @@ -127,7 +160,7 @@ char *DEX_withdraw(char *exchange,char *base,char *destaddr,double amount) char url[512],postdata[1024]; sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"withdraw\",\"exchange\":\"%s\",\"destaddr\":\"%s\",\"amount\":%.8f}",exchange,destaddr,amount); - return(bitcoind_RPC(0,"InstantDEX",url,0,"withdraw",postdata)); + return(bitcoind_RPC(0,"InstantDEX",url,0,"withdraw",postdata,0)); } char *iguana_walletpassphrase(char *passphrase,int32_t timeout) @@ -135,7 +168,56 @@ char *iguana_walletpassphrase(char *passphrase,int32_t timeout) char url[512],postdata[1024]; sprintf(url,"%s/coin=KMD&agent=bitcoinrpc&method=walletpassphrase?",IGUANA_URL); sprintf(postdata,"[\"%s\", %d]",passphrase,timeout); - return(bitcoind_RPC(0,"",url,0,"walletpassphrase",postdata)); + return(bitcoind_RPC(0,"",url,0,"walletpassphrase",postdata,0)); +} + +/*char *iguana_listunspent(char *coin,char *coinaddr) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/coin=%s&agent=bitcoinrpc&method=listunspent?",IGUANA_URL,coin); + sprintf(postdata,"[\"%s\"]",coinaddr); + return(bitcoind_RPC(0,"",url,0,"listunspent",postdata)); +}*/ + +/*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&numpeers=%d",destip,destport,ipaddr,port,numpeers); + printf("(%s)\n",url); + return(issue_curl(url)); +}*/ + +// +// http://127.0.0.1:7779/api/stats/getpeers + +char *DEX_listunspent(char *coin,char *coinaddr) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"%s\",\"symbol\":\"%s\",\"timeout\":60000}",coinaddr,coin); + return(bitcoind_RPC(0,"dex",url,0,"listunspent",postdata,0)); +} + +bits256 iguana_wif2privkey(char *wifstr) +{ + char url[512],postdata[1024],*retstr,*privstr; bits256 privkey; cJSON *retjson; + memset(privkey.bytes,0,sizeof(privkey)); + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"SuperNET\",\"method\":\"wif2priv\",\"wif\":\"%s\"}",wifstr); + if ( (retstr= bitcoind_RPC(0,"SuperNET",url,0,"wif2priv",postdata,0)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (privstr= jstr(retjson,"privkey")) != 0 ) + { + if ( strlen(privstr) == 64 ) + decode_hex(privkey.bytes,32,privstr); + } + free_json(retjson); + } + free(retstr); + } + return(privkey); } double bittrex_balance(char *base,char *coinaddr) @@ -313,7 +395,8 @@ void marketmaker_pendingupdate(char *exchange,char *base,char *rel) void marketmaker_pendinginit(char *exchange,char *base,char *rel) { - char *retstr,*orderid; cJSON *retjson,*array,*item; int32_t i,j,n,dir; struct mmpending_order *ptr; + char *retstr,*orderid,*pairstr,relbase[64]; cJSON *retjson,*array,*item; int32_t i,j,n,dir; struct mmpending_order *ptr; + sprintf(relbase,"%s-%s",rel,base); if ( (retstr= DEX_openorders(exchange)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) @@ -324,6 +407,13 @@ void marketmaker_pendinginit(char *exchange,char *base,char *rel) for (i=0; ipending != 0 && ptr->cancelstarted == 0 ) { if ( bid > SMALLVAL && bidvol > SMALLVAL && ptr->dir > 0 && fabs(bid - ptr->price) < separation ) + { + //printf("bid %.8f near %.8f\n",bid,ptr->price); nearflags[0]++; + } if ( ask > SMALLVAL && askvol > SMALLVAL && ptr->dir < 0 && fabs(ask - ptr->price) < separation ) + { + //printf("%.8f near %.8f\n",ask,ptr->price); nearflags[1]++; + } } } } @@ -505,8 +601,8 @@ int32_t marketmaker_spread(char *exchange,char *base,char *rel,double bid,double jaddnum(vals,"minvol",vol*0.1 > 100 ? 100 : vol * 0.1); sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"%s\",\"vals\":%s}",base,jprint(vals,1)); - printf("(%s)\n",postdata); - if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata)) != 0 ) + //printf("(%s)\n",postdata); + if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata,0)) != 0 ) { //printf("(%s) -> (%s)\n",postdata,retstr); free(retstr); @@ -514,6 +610,8 @@ int32_t marketmaker_spread(char *exchange,char *base,char *rel,double bid,double spread_ratio = .5 * ((ask - bid) / (bid + ask)); for (i=0; i SMALLVAL ) { vals = cJSON_CreateObject(); @@ -524,13 +622,13 @@ int32_t marketmaker_spread(char *exchange,char *base,char *rel,double bid,double jaddnum(vals,"minvol",MAX(1,(int32_t)(vol * 0.01 * PAXPRICES[i]))); sprintf(url,"%s/?",IGUANA_URL); sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"%s\",\"vals\":%s}","KMD",jprint(vals,1)); - if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata)) != 0 ) + if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata,0)) != 0 ) { //printf("(%s) -> (%s)\n",postdata,retstr); free(retstr); } } -break; +//break; } } else printf("unsupported ask only for DEX %s/%s\n",base,rel); } @@ -543,7 +641,7 @@ break; free_json(retjson); } free(retstr); - } + } //else printf("skip bid %s %.8f vol %f\n",exchange,bid,bidvol); } if ( ask > SMALLVAL && askvol > SMALLVAL && nearflags[1] == 0 && strcmp("DEX",exchange) != 0 ) { @@ -557,49 +655,59 @@ break; } free(retstr); } - } + } //else printf("skip ask %s %.8f vol %f\n",exchange,bid,bidvol); return(n); } -void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double start_BASE,double start_REL,double profitmargin,double maxexposure,double ratioincr,char *exchange,char *name,char *base,char *rel) +double marketmaker_updateprice(char *name,char *base,char *rel,double theoretical,double *incrp) { static uint32_t counter; - cJSON *fiatjson; double bid,ask,start_DEXbase,start_DEXrel,USD_average=0.,DEX_base = 0.,DEX_rel = 0.,balance_base=0.,balance_rel=0.,mmbid,mmask,usdprice=0.,CMC_average=0.,aveprice,incr,pendingbids,pendingasks,buyvol,sellvol,bidincr,askincr,filledprice,avebid=0.,aveask=0.,val,changes[3],highbid=0.,lowask=0.,theoretical = 0.; uint32_t lasttime = 0; + cJSON *fiatjson; double USD_average=0.,usdprice=0.,CMC_average=0.,avebid=0.,aveask=0.,val,changes[3],highbid=0.,lowask=0.; + if ( (val= get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,name,base,rel,&USD_average)) != 0. ) + { + if ( theoretical == 0. ) + { + theoretical = val; + if ( *incrp > 2 ) + { + *incrp = (int32_t)*incrp; + *incrp += 0.777; + } + } else theoretical = (theoretical + val) * 0.5; + if ( (counter++ % 12) == 0 ) + { + if ( USD_average > SMALLVAL && CMC_average > SMALLVAL && theoretical > SMALLVAL ) + { + usdprice = USD_average * (theoretical / CMC_average); + printf("USD %.4f <- (%.6f * (%.8f / %.8f))\n",usdprice,USD_average,theoretical,CMC_average); + PAXPRICES[0] = usdprice; + if ( (fiatjson= yahoo_allcurrencies()) != 0 ) + { + marketmaker_fiatupdate(fiatjson); + free_json(fiatjson); + } + } + } + LP_priceupdate(base,rel,theoretical,avebid,aveask,highbid,lowask,PAXPRICES); + } + return(theoretical); +} + +void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double start_BASE,double start_REL,double profitmargin,double maxexposure,double ratioincr,char *exchange,char *name,char *base,char *rel) +{ + char *retstr; double bid,ask,start_DEXbase,start_DEXrel,DEX_base = 0.,DEX_rel = 0.,balance_base=0.,balance_rel=0.,mmbid,mmask,aveprice,incr,pendingbids,pendingasks,buyvol,sellvol,bidincr,askincr,filledprice,avebid=0.,aveask=0.,highbid=0.,lowask=0.,theoretical = 0.; uint32_t lasttime = 0; incr = maxexposure * ratioincr; buyvol = sellvol = 0.; start_DEXbase = dex_balance(base,baseaddr); start_DEXrel = dex_balance(rel,reladdr); while ( 1 ) { - if ( time(NULL) > lasttime+300 ) + if ( time(NULL) > lasttime+60 ) { - if ( (val= get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,name,base,rel,&USD_average)) != 0. ) + if ( (theoretical= marketmaker_updateprice(name,base,rel,theoretical,&incr)) != 0. ) { - if ( theoretical == 0. ) - { - theoretical = val; - incr /= theoretical; + if ( lasttime == 0 ) maxexposure /= theoretical; - if ( incr > 2 ) - { - incr = (int32_t)incr; - incr += 0.777; - } - } else theoretical = (theoretical + val) * 0.5; - if ( (counter++ % 12) == 0 ) - { - if ( USD_average > SMALLVAL && CMC_average > SMALLVAL && theoretical > SMALLVAL ) - { - usdprice = USD_average * (theoretical / CMC_average); - printf("USD %.4f <- (%.6f * (%.8f / %.8f))\n",usdprice,USD_average,theoretical,CMC_average); - PAXPRICES[0] = usdprice; - if ( (fiatjson= yahoo_allcurrencies()) != 0 ) - { - marketmaker_fiatupdate(fiatjson); - free_json(fiatjson); - } - } - } } if ( strcmp(exchange,"bittrex") == 0 ) { @@ -630,29 +738,36 @@ void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double marketmaker_prune(exchange,base,rel,1,mmbid - theoretical*profitmargin,mmask + theoretical*profitmargin,0.); // if new prices crosses existing order, cancel old order first marketmaker_prune(exchange,base,rel,-1,mmbid,mmask,0.); - printf("(%.8f %.8f) ",mmbid,mmask); + //printf("(%.8f %.8f) ",mmbid,mmask); if ( (1) ) { if ( mmbid >= lowask || (maxbid > SMALLVAL && mmbid > maxbid) ) //mmbid < highbid || + { + printf("clear mmbid %.8f lowask %.8f maxbid %.8f\n",mmbid,lowask,maxbid); mmbid = 0.; + } if ( mmask <= highbid || (minask > SMALLVAL && mmask < minask) ) // mmask > lowask || mmask = 0.; } marketmaker_volumeset(&bidincr,&askincr,incr,buyvol,pendingbids,sellvol,pendingasks,maxexposure); printf("AVE.(%.8f %.8f) hbla %.8f %.8f bid %.8f ask %.8f theory %.8f buys.(%.6f %.6f) sells.(%.6f %.6f) incr.(%.6f %.6f) balances.(%.8f + %.8f, %.8f + %.8f) test %f\n",avebid,aveask,highbid,lowask,mmbid,mmask,theoretical,buyvol,pendingbids,sellvol,pendingasks,bidincr,askincr,balance_base,DEX_base,balance_rel,DEX_rel,(aveask - avebid)/aveprice); - if ( (aveask - avebid)/aveprice > 4*profitmargin ) - bid = highbid * (1 - 4*profitmargin), ask = lowask * (1 + 4*profitmargin); + if ( (retstr= DEX_swapstatus()) != 0 ) + printf("%s\n",retstr), free(retstr); + printf("%s %s %s, %s %s %s\n",base,DEX_baseaddr,DEX_balance("DEX",base,DEX_baseaddr),rel,DEX_reladdr,DEX_balance("DEX",rel,DEX_reladdr)); + if ( (aveask - avebid)/aveprice > profitmargin ) + bid = highbid * (1 - profitmargin), ask = lowask * (1 + profitmargin); else bid = avebid - profitmargin*aveprice, ask = avebid + profitmargin*aveprice; marketmaker_spread("DEX",base,rel,bid,incr,ask,incr,profitmargin*aveprice*0.5); - if ( (pendingbids + buyvol) > (pendingasks + sellvol) ) + if ( (pendingbids + buyvol) > (pendingasks + sellvol) && (pendingbids + buyvol) > bidincr ) { - bidincr *= (double)(pendingasks + sellvol) / ((pendingbids + buyvol) + (pendingasks + sellvol)); + bidincr *= ((double)(pendingasks + sellvol) / ((pendingbids + buyvol) + (pendingasks + sellvol))); + printf("bidincr %f buy.(%f + %f) sell.(%f + %f)\n",bidincr,pendingbids,buyvol,pendingasks,sellvol); if ( bidincr < 0.1*incr ) bidincr = 0.1*incr; if ( bidincr > 1. ) bidincr = (int32_t)bidincr + 0.777; } - if ( (pendingbids + buyvol) < (pendingasks + sellvol) ) + if ( (pendingbids + buyvol) < (pendingasks + sellvol) && (pendingasks + sellvol) > askincr ) { askincr *= (double)(pendingbids + buyvol) / ((pendingbids + buyvol) + (pendingasks + sellvol)); if ( askincr < 0.1*incr ) @@ -661,27 +776,55 @@ void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double askincr = (int32_t)askincr + 0.777; } //printf("mmbid %.8f %.6f, mmask %.8f %.6f\n",mmbid,bidincr,mmask,askincr); - //marketmaker_spread(exchange,base,rel,mmbid,bidincr,mmask,askincr,profitmargin*aveprice*0.5); - sleep(6000); + marketmaker_spread(exchange,base,rel,mmbid,bidincr,mmask,askincr,profitmargin*aveprice*0.5); + sleep(60); } } } +#include "LP_nativeDEX.c" + +void LP_main(void *ptr) +{ + char *passphrase; double profitmargin; uint16_t port; cJSON *argjson = ptr; + if ( (passphrase= jstr(argjson,"passphrase")) != 0 ) + { + profitmargin = jdouble(argjson,"profitmargin"); + LP_profitratio += profitmargin; + if ( (port= juint(argjson,"rpcport")) < 1000 ) + port = 7779; + LPinit(port,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; - double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid; - cJSON *retjson,*addrjson; char *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 ) + jaddstr(retjson,"passphrase","test"); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_main,(void *)retjson) != 0 ) + { + printf("error launching LP_main (%s)\n",jprint(retjson,0)); + exit(-1); + } else printf("(%s) launched.(%s)\n",argv[1],passphrase); + incr = 100.; + while ( 1 ) + sleep(1); + profitmargin = jdouble(retjson,"profitmargin"); minask = jdouble(retjson,"minask"); maxbid = jdouble(retjson,"maxbid"); - profitmargin = jdouble(retjson,"profitmargin"); maxexposure = jdouble(retjson,"maxexposure"); incrratio = jdouble(retjson,"lotratio"); start_base = jdouble(retjson,"start_base"); start_rel = jdouble(retjson,"start_rel"); - passphrase = jstr(retjson,"passphrase"); apikey = jstr(retjson,"apikey"); apisecret = jstr(retjson,"apisecret"); base = jstr(retjson,"base"); @@ -689,6 +832,7 @@ int main(int argc, const char * argv[]) rel = jstr(retjson,"rel"); blocktrail = jstr(retjson,"blocktrail"); exchange = jstr(retjson,"exchange"); + PAXACTIVE = juint(retjson,"paxactive"); if ( profitmargin < 0. || maxexposure <= 0. || incrratio <= 0. || apikey == 0 || apisecret == 0 || base == 0 || name == 0 || rel == 0 || exchange == 0 || blocktrail == 0 ) { printf("illegal parameter (%s)\n",jprint(retjson,0)); @@ -696,23 +840,38 @@ int main(int argc, const char * argv[]) } if ( (retstr= iguana_walletpassphrase(passphrase,999999)) != 0 ) { - printf("%s\n",DEX_apikeypair(exchange,apikey,apisecret)); - printf("%s %s\n",base,DEX_balance(exchange,base,"")); - printf("%s %s\n",rel,DEX_balance(exchange,rel,"")); - marketmaker_pendinginit(exchange,base,rel); - if ( (addrjson= cJSON_Parse(retstr)) != 0 ) + printf("(%s/%s) login.(%s)\n",base,rel,retstr); + if ( (loginjson= cJSON_Parse(retstr)) != 0 ) { - baseaddr = jstr(addrjson,base); - reladdr = jstr(addrjson,rel); + if ( PAXACTIVE != 0 ) + { + for (i=0; i<32; i++) + { + if ( ((1<NXTAPIURL,0,0,cmdstr) +#define issue_NXTPOST(cmdstr) bitcoind_RPC(0,"curl",myinfo->NXTAPIURL,0,0,cmdstr,0) #define NXT_MSTYPE 5 #define NXT_ASSETTYPE 2 #define NXT_GENESISTIME 1385294400 diff --git a/iguana/exchanges/orderbook b/iguana/exchanges/orderbook new file mode 100755 index 000000000..3ec8ffbdf --- /dev/null +++ b/iguana/exchanges/orderbook @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"orderbook\",\"base\":\"JUMBLR\",\"rel\":\"KMD\"}" diff --git a/iguana/exchanges/ordermatch b/iguana/exchanges/ordermatch new file mode 100755 index 000000000..05d30ba7e --- /dev/null +++ b/iguana/exchanges/ordermatch @@ -0,0 +1,3 @@ +source userpass +#ordermatch(base, txfee=0, rel, desttxfee=0, price, txid, vout, feetxid, feevout, duration=3600)\n\ +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"ordermatch\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":1.234,\"duration\":600,\"txfee\":0,\"desttxfee\":0,\"txid\":\"$1\",\"vout\":$2,\"feetxid\":\"$3\",\"feevout\":$4}" diff --git a/iguana/exchanges/passphrase b/iguana/exchanges/passphrase new file mode 100644 index 000000000..eb00095d6 --- /dev/null +++ b/iguana/exchanges/passphrase @@ -0,0 +1 @@ +export passphrase="" 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/pub b/iguana/exchanges/pub new file mode 100755 index 000000000..edafc5b98 --- /dev/null +++ b/iguana/exchanges/pub @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"6578099f6474d9b8bd66a7a136b922029a989818ec0309aee962dd6ac1862b74\",\"method\":\"forward\",\"method2\":\"publish\",\"data\":\"nonsense\"}" diff --git a/iguana/exchanges/register b/iguana/exchanges/register new file mode 100755 index 000000000..bbe660faa --- /dev/null +++ b/iguana/exchanges/register @@ -0,0 +1,2 @@ +source userpass +curl --url "http://5.9.253.195:7779" --data "{\"userpass\":\"9bb4846d24136fc7c33515e45bccbab5c8fb7b57b411aa20057b371da9358255\",\"agent\":\"stats\",\"method\":\"register\",\"client\":\"6d3332be4904feafd326609bd76b66528dc7b2e2d75a7bd110c6bf8d19c4cf58\",\"pushaddr\":\"5.9.253.195\",\"pushport\":\"10000\"}" diff --git a/iguana/exchanges/registerall b/iguana/exchanges/registerall new file mode 100755 index 000000000..9024b8230 --- /dev/null +++ b/iguana/exchanges/registerall @@ -0,0 +1,3 @@ + +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"registerall\",\"numnodes\":10}" diff --git a/iguana/exchanges/run b/iguana/exchanges/run new file mode 100755 index 000000000..59e4ec2e4 --- /dev/null +++ b/iguana/exchanges/run @@ -0,0 +1,7 @@ +source passphrase +source coins +pkill -15 marketmaker; +git pull; +cd ..; +./m_mm; + $1 ./marketmaker "{\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & diff --git a/iguana/exchanges/run_osx b/iguana/exchanges/run_osx new file mode 100755 index 000000000..c8924d6f4 --- /dev/null +++ b/iguana/exchanges/run_osx @@ -0,0 +1,7 @@ +source passphrase +source coins +pkill -15 marketmaker; +git pull; +cd ..; +./m_mm; +$1 ./marketmaker "{\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}/Library/Application\ Support\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & diff --git a/iguana/exchanges/secretaddresses b/iguana/exchanges/secretaddresses new file mode 100755 index 000000000..38088a6bc --- /dev/null +++ b/iguana/exchanges/secretaddresses @@ -0,0 +1,5 @@ +source userpass +echo "usage: ./secretaddresses 'passphrase'" + +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"secretaddresses\",\"num\":16,\"passphrase\":\"$1\"}" + diff --git a/iguana/exchanges/setprice b/iguana/exchanges/setprice new file mode 100755 index 000000000..e5a9c3c9c --- /dev/null +++ b/iguana/exchanges/setprice @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":1.234}" diff --git a/iguana/exchanges/snapshot b/iguana/exchanges/snapshot new file mode 100755 index 000000000..2b875af59 --- /dev/null +++ b/iguana/exchanges/snapshot @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"snapshot\",\"coin\":\"KMD\",\"height\":$1}" diff --git a/iguana/exchanges/snapshot_balance b/iguana/exchanges/snapshot_balance new file mode 100644 index 000000000..4cbe11cf3 --- /dev/null +++ b/iguana/exchanges/snapshot_balance @@ -0,0 +1,4 @@ +source userpass +ht=$1 +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"snapshot_balance\",\"coin\":\"KMD\",\"height\":$ht,\"addresses\":[\"RSAzPFzgTZHNcxLNLdGyVPbjbMA8PRY7Ss\", \"RBgD5eMGwZppid4x7PTEC2Wg1AzvxbsQqB\"]}" + diff --git a/iguana/exchanges/snapshot_loop b/iguana/exchanges/snapshot_loop new file mode 100755 index 000000000..aef95969b --- /dev/null +++ b/iguana/exchanges/snapshot_loop @@ -0,0 +1,11 @@ +source userpass +ht=$1 +while true +do +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"snapshot\",\"coin\":\"KMD\",\"height\":$ht}" +#ht=`komodo-cli getinfo | jq .blocks` +ht=$(( $ht + 1000 )) +echo next height $ht +sleep 1 +done + diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c new file mode 100644 index 000000000..3c98b48f5 --- /dev/null +++ b/iguana/exchanges/stats.c @@ -0,0 +1,1072 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ +// +// main.c +// stats +// +// Copyright © 2017 SuperNET. All rights reserved. +// + +#include +#include +#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 +#define MSG_NOSIGNAL 0x4000 // Do not generate SIGPIPE +#endif +#else +#define MSG_NOSIGNAL 0 +#endif + +#define GLOBAL_HELPDIR "/root/SuperNET/iguana/help" + +char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies + "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies +}; + +char ASSETCHAINS_SYMBOL[16] = { "KV" }; + +struct komodo_state +{ + bits256 NOTARIZED_HASH,NOTARIZED_DESTTXID; + int32_t SAVEDHEIGHT,CURRENT_HEIGHT,NOTARIZED_HEIGHT; + uint32_t SAVEDTIMESTAMP; + uint64_t deposited,issued,withdrawn,approved,redeemed,shorted; + struct notarized_checkpoint *NPOINTS; int32_t NUM_NPOINTS; + struct komodo_event **Komodo_events; int32_t Komodo_numevents; + uint32_t RTbufs[64][3]; uint64_t RTmask; +}; + +struct komodo_state KOMODO_STATE[2]; + +int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) +{ + int32_t opt,sock,result; char ipaddr[64],checkipaddr[64]; struct timeval timeout; + struct sockaddr_in saddr; socklen_t addrlen,slen; + addrlen = sizeof(saddr); + struct hostent *hostent; + + /** + * gethostbyname() is deprecated and cause crash on x64 windows + * the solution is to implement similar functionality by using getaddrinfo() + * it is standard posix function and is correctly supported in win32/win64/linux + * @author - fadedreamz@gmail.com + */ +#if defined(_M_X64) + struct addrinfo *addrresult = NULL; + struct addrinfo *returnptr = NULL; + struct addrinfo hints; + struct sockaddr_in * sockaddr_ipv4; + int retVal; + int found = 0; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; +#endif + + if ( parse_ipaddr(ipaddr,hostname) != 0 ) + port = parse_ipaddr(ipaddr,hostname); + +#if defined(_M_X64) + retVal = getaddrinfo(ipaddr, NULL, &hints, &addrresult); + for (returnptr = addrresult; returnptr != NULL && found == 0; returnptr = returnptr->ai_next) { + switch (returnptr->ai_family) { + case AF_INET: + sockaddr_ipv4 = (struct sockaddr_in *) returnptr->ai_addr; + // we want to break from the loop after founding the first ipv4 address + found = 1; + break; + } + } + + // if we iterate through the loop and didn't find anything, + // that means we failed in the dns lookup + if (found == 0) { + printf("getaddrinfo(%s) returned error\n", hostname); + freeaddrinfo(addrresult); + return(-1); + } +#else + hostent = gethostbyname(ipaddr); + if ( hostent == NULL ) + { + printf("gethostbyname(%s) returned error: %d port.%d ipaddr.(%s)\n",hostname,errno,port,ipaddr); + return(-1); + } +#endif + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + //#ifdef WIN32 + // saddr.sin_addr.s_addr = (uint32_t)calc_ipbits("127.0.0.1"); + //#else + +#if defined(_M_X64) + saddr.sin_addr.s_addr = sockaddr_ipv4->sin_addr.s_addr; + // graceful cleanup + sockaddr_ipv4 = NULL; + freeaddrinfo(addrresult); +#else + memcpy(&saddr.sin_addr.s_addr,hostent->h_addr_list[0],hostent->h_length); +#endif + expand_ipbits(checkipaddr,saddr.sin_addr.s_addr); + if ( strcmp(ipaddr,checkipaddr) != 0 ) + printf("bindflag.%d iguana_socket mismatch (%s) -> (%s)?\n",bindflag,checkipaddr,ipaddr); + //#endif + if ( (sock= socket(AF_INET,SOCK_STREAM,0)) < 0 ) + { + if ( errno != ETIMEDOUT ) + printf("socket() failed: %s errno.%d", strerror(errno),errno); + return(-1); + } + opt = 1; + slen = sizeof(opt); + //printf("set keepalive.%d\n",setsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,slen)); +#ifndef WIN32 + if ( 1 )//&& bindflag != 0 ) + { + opt = 0; + getsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,&slen); + opt = 1; + //printf("keepalive.%d\n",opt); + } + setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt)); +#ifdef __APPLE__ + setsockopt(sock,SOL_SOCKET,SO_NOSIGPIPE,&opt,sizeof(opt)); +#endif +#endif + if ( bindflag == 0 ) + { + timeout.tv_sec = 10; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + result = connect(sock,(struct sockaddr *)&saddr,addrlen); + if ( result != 0 ) + { + if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) + { + //printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + } + if ( sock >= 0 ) + closesocket(sock); + return(-1); + } + timeout.tv_sec = 10000000; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + } + else + { + while ( (result= bind(sock,(struct sockaddr*)&saddr,addrlen)) != 0 ) + { + if ( errno == EADDRINUSE ) + { + sleep(1); + printf("ERROR BINDING PORT.%d. this is normal tcp timeout, unless another process is using port\n",port); + sleep(3); + printf("%s(%s) port.%d try again: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + if ( bindflag == 1 ) + { + closesocket(sock); + return(-1); + } + sleep(13); + //continue; + } + if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) + { + printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + closesocket(sock); + return(-1); + } + } + if ( listen(sock,64) != 0 ) + { + printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); + if ( sock >= 0 ) + closesocket(sock); + return(-1); + } + } +#ifdef __APPLE__ + //timeout.tv_sec = 0; + //timeout.tv_usec = 30000; + //setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(void *)&timeout,sizeof(timeout)); +#endif + return(sock); +} + +int32_t Supernet_lineparse(char *key,int32_t keymax,char *value,int32_t valuemax,char *src) +{ + int32_t a,b,c,n = 0; //char *origkey=key,*origvalue=value; + key[0] = value[0] = 0; + while ( (c= src[n]) == ' ' || c == '\t' || c == '\n' || c == '\t' ) + n++; + while ( (c= src[n]) != ':' && c != 0 ) + { + *key++ = c; + //printf("(%c) ",c); + if ( ++n >= keymax-1 ) + { + *key = 0; + printf("lineparse overflow key.(%s)\n",src); + return(-1); + } + } + *key = 0; + //printf("-> key.(%s)\n",origkey); + if ( src[n] != ':' ) + return(n); + n++; + while ( (c= src[n]) == ' ' || c == '\t' ) + n++; + while ( (c= src[n]) != 0 && c != '\r' && c != '\n' ) + { + if ( c == '%' && (a= src[n+1]) != 0 && (b= src[n+2]) != 0 ) + c = ((unhex(a) << 4) | unhex(b)), n += 2; + *value++ = c; + n++; + if ( n >= valuemax-1 ) + { + *value = 0; + printf("lineparse overflow.(%s)\n",src); + return(-1); + } + } + *value = 0; + if ( src[n] != 0 ) + { + n++; + while ( (c= src[n]) == '\r' || c == '\n' ) + n++; + } + //printf("key.(%s) value.(%s)\n",origkey,origvalue); + return(n); +} + +cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) +{ + int32_t i,n,totallen,datalen,len = 0; cJSON *json,*array; char key[8192],*data; + json = cJSON_CreateObject(); + array = cJSON_CreateArray(); + totallen = (int32_t)strlen(urlstr); + while ( 1 ) + { + for (i=len; urlstr[i]!=0; i++) + if ( urlstr[i] == '\r' || urlstr[i] == '\n' ) + break; + if ( i == len && (urlstr[len] == '\r' || urlstr[len] == '\n') ) + { + len++; + continue; + } + urlstr[i] = 0; + //printf("URLSTR[%d]=%s\n",i,&urlstr[len]); + if ( (n= Supernet_lineparse(key,sizeof(key),value,bufsize,&urlstr[len])) > 0 ) + { + if ( value[0] != 0 ) + jaddstr(json,key,value); + else jaddistr(array,key); + len += (n + 1); + if ( strcmp(key,"Content-Length") == 0 && (datalen= atoi(value)) > 0 ) + { + data = &urlstr[totallen - datalen]; + data[-1] = 0; + //printf("post.(%s) (%c)\n",data,data[0]); + jaddstr(json,"POST",data); + } + } else break; + } + jadd(json,"lines",array); + //printf("urlconv.(%s)\n",jprint(json,0)); + return(json); +} + +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; 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(); + for (i=0; i0; i--) + if ( url[i] == '.' || url[i] == '/' ) + break; + if ( url[i] == '.' ) + strcpy(filetype,url+i+1); + //printf("return filetype.(%s) size.%ld\n",filetype,filesize); + return(filestr); + } + if ( strncmp(&url[i],"/api",strlen("/api")) == 0 ) + { + *jsonflagp = 1; + i += strlen("/api"); + } else *jsonflagp = 0; + if ( strcmp(url,"/favicon.ico") == 0 ) + { + *jsonflagp = 1; + return(0); + } + if ( url[i] != '/' ) + token = &url[i]; + n = i; + tokens = cJSON_CreateArray(); + for (; url[i]!=0; i++) + { + //printf("i.%d (%c)\n",i,url[i]); + if ( url[i] == '/' ) + { + url[i] = 0; + if ( token != 0 ) + { + //printf("TOKEN.(%s) i.%d\n",token,i); + jaddistr(tokens,token); + num++; + } + token = &url[i+1]; + i++; + //printf("new token.(%s) i.%d\n",token,i+1); + continue; + } + } + if ( token != 0 ) + { + //printf("add token.(%s)\n",token); + jaddistr(tokens,token); + num++; + } + argjson = cJSON_CreateObject(); + if ( num > 0 ) + jaddstr(argjson,"agent",jstri(tokens,0)); + if ( num > 1 ) + jaddstr(argjson,"method",jstri(tokens,1)); + if ( (json= SuperNET_urlconv(retbuf,bufsize,urlstr+n)) != 0 ) + { + jadd(json,"tokens",tokens); + jaddstr(json,"urlmethod",urlmethod); + if ( (data= jstr(json,"POST")) == 0 || (argjson= cJSON_Parse(data)) == 0 ) + { + userpass = jstr(argjson,"userpass"); + //printf("userpass.(%s)\n",userpass); + if ( (n= cJSON_GetArraySize(tokens)) > 0 ) + { + if ( n > 1 ) + { + if ( jstri(tokens,1) != 0 ) + { + char *key,*value; + strcpy(buf,jstri(tokens,1)); + key = value = 0; + i = 0; + for (; buf[i]!=0; i++) + { + if ( buf[i] == '?' ) + { + buf[i] = 0; + jdelete(argjson,"method"); + jaddstr(argjson,"method",buf); + i++; + key = &buf[i]; + break; + } + } + while ( buf[i] != 0 ) + { + //printf("iter.[%s]\n",&buf[i]); + if ( buf[i] != 0 && key != 0 ) + { + for (; buf[i]!=0; i++) + { + if ( buf[i] == '=' ) + { + buf[i] = 0; + i++; + //printf("got key.(%s)\n",key); + value = &buf[i]; + break; + } + } + if ( buf[i] != 0 && value != 0 ) + { + for (; buf[i]!=0; i++) + { + if ( buf[i] == '&' ) + { + buf[i] = 0; + jaddstr(argjson,key,value); + i++; + //printf("got value.(%s)\n",value); + value = 0; + key = &buf[i]; + break; + } + else if ( buf[i] == '+' ) + buf[i] = ' '; + } + } + } + } + if ( key != 0 && value != 0 ) + jaddstr(argjson,key,value); + } + else + { + //jdelete(argjson,"method"); + //jaddstr(argjson,"method",buf); + } + } + for (i=2; i 0 ) + { + cJSON *retitem,*retarray = cJSON_CreateArray(); + origargjson = argjson; + symbol[0] = 0; + for (i=0; i (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),cJSON_Print(json),*postflagp,retstr); + } + free_json(origargjson); + retstr = jprint(retarray,1); + } + else + { + cJSON *arg; + if ( jstr(argjson,"agent") != 0 && strcmp(jstr(argjson,"agent"),"bitcoinrpc") != 0 && jobj(argjson,"params") != 0 ) + { + arg = jobj(argjson,"params"); + if ( is_cJSON_Array(arg) != 0 && cJSON_GetArraySize(arg) == 1 ) + arg = jitem(arg,0); + } else arg = argjson; + //printf("ARGJSON.(%s)\n",jprint(arg,0)); + if ( userpass != 0 && jstr(arg,"userpass") == 0 ) + jaddstr(arg,"userpass",userpass); + retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port); + } + free_json(argjson); + free_json(json); + if ( tmpjson != 0 ) + free(tmpjson); + return(retstr); + } + free_json(argjson); + if ( tmpjson != 0 ) + free(tmpjson); + *jsonflagp = 1; + return(clonestr("{\"error\":\"couldnt process packet\"}")); +} + +int32_t iguana_getcontentlen(char *buf,int32_t recvlen) +{ + char *str,*clenstr = "Content-Length: "; int32_t len = -1; + if ( (str= strstr(buf,clenstr)) != 0 ) + { + //printf("strstr.(%s)\n",str); + str += strlen(clenstr); + len = atoi(str); + //printf("len.%d\n",len); + } + return(len); +} + +int32_t iguana_getheadersize(char *buf,int32_t recvlen) +{ + char *str,*delim = "\r\n\r\n"; + if ( (str= strstr(buf,delim)) != 0 ) + return((int32_t)(((long)str - (long)buf) + strlen(delim))); + return(recvlen); +} + +void stats_rpcloop(void *args) +{ + static char *jsonbuf; + 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 = 32*IGUANA_MAXPACKETSIZE + 512; + if ( (port= *(uint16_t *)args) == 0 ) + port = 7779; + if ( jsonbuf == 0 ) + jsonbuf = calloc(1,IGUANA_MAXPACKETSIZE); + while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) + { + //if ( coin->MAXPEERS == 1 ) + // break; + //exit(-1); + sleep(3); + } + printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock); + space = calloc(1,size); + while ( bindsock >= 0 ) + { + clilen = sizeof(cli_addr); + sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); + if ( sock < 0 ) + { + //printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); + continue; + } + memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); + expand_ipbits(remoteaddr,ipbits); + //printf("remote RPC request from (%s) %x\n",remoteaddr,ipbits); + + memset(jsonbuf,0,IGUANA_MAXPACKETSIZE); + remains = (int32_t)(IGUANA_MAXPACKETSIZE - 1); + buf = jsonbuf; + recvlen = flag = 0; + retstr = 0; + while ( remains > 0 ) + { + //printf("flag.%d remains.%d recvlen.%d\n",flag,remains,recvlen); + if ( (len= (int32_t)recv(sock,buf,remains,0)) < 0 ) + { + if ( errno == EAGAIN ) + { + printf("EAGAIN for len %d, remains.%d\n",len,remains); + usleep(10000); + } + break; + } + else + { + if ( len > 0 ) + { + buf[len] = 0; + if ( recvlen == 0 ) + { + if ( (contentlen= iguana_getcontentlen(buf,recvlen)) > 0 ) + { + hdrsize = iguana_getheadersize(buf,recvlen); + if ( hdrsize > 0 ) + { + if ( len < (hdrsize + contentlen) ) + { + remains = (hdrsize + contentlen) - len; + buf = &buf[len]; + flag = 1; + //printf("got.(%s) %d remains.%d of len.%d contentlen.%d hdrsize.%d remains.%d\n",buf,recvlen,remains,len,contentlen,hdrsize,(hdrsize+contentlen)-len); + continue; + } + } + } + } + recvlen += len; + remains -= len; + buf = &buf[len]; + if ( flag == 0 || remains <= 0 ) + break; + } + else + { + usleep(10000); + //printf("got.(%s) %d remains.%d of total.%d\n",jsonbuf,recvlen,remains,len); + //retstr = iguana_rpcparse(space,size,&postflag,jsonbuf); + if ( flag == 0 ) + break; + } + } + } + content_type[0] = 0; + if ( recvlen > 0 ) + { + retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,port); + if ( filetype[0] != 0 ) + { + static cJSON *mimejson; char *tmp,*typestr=0; long tmpsize; + sprintf(helpname,"%s/mime.json",GLOBAL_HELPDIR); + if ( (tmp= OS_filestr(&tmpsize,helpname)) != 0 ) + { + mimejson = cJSON_Parse(tmp); + free(tmp); + } + if ( mimejson != 0 ) + { + if ( (typestr= jstr(mimejson,filetype)) != 0 ) + sprintf(content_type,"Content-Type: %s\r\n",typestr); + } else printf("parse error.(%s)\n",tmp); + //printf("filetype.(%s) json.%p type.%p tmp.%p [%s]\n",filetype,mimejson,typestr,tmp,content_type); + } + } + if ( retstr != 0 ) + { + char *response,hdrs[1024]; + //printf("RETURN.(%s) jsonflag.%d postflag.%d\n",retstr,jsonflag,postflag); + if ( jsonflag != 0 || postflag != 0 ) + { + if ( retstr == 0 ) + retstr = clonestr("{}"); + response = malloc(strlen(retstr)+1024+1+1); + sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr)); + response[0] = '\0'; + strcat(response,hdrs); + strcat(response,retstr); + strcat(response,"\n"); + if ( retstr != space ) + free(retstr); + retstr = response; + //printf("RET.(%s)\n",retstr); + } + remains = (int32_t)strlen(retstr); + i = 0; + while ( remains > 0 ) + { + if ( (numsent= (int32_t)send(sock,&retstr[i],remains,MSG_NOSIGNAL)) < 0 ) + { + if ( errno != EAGAIN && errno != EWOULDBLOCK ) + { + //printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",retstr,ipaddr,numsent,remains,recvlen,errno,strerror(errno),sock); + break; + } + } + else if ( remains > 0 ) + { + remains -= numsent; + i += numsent; + if ( remains > 0 ) + printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,recvlen); + } + } + if ( retstr != space) + free(retstr); + } + closesocket(sock); + } +} + +#ifndef FROM_MARKETMAKER +void stats_kvjson(FILE *logfp,int32_t height,int32_t savedheight,uint32_t timestamp,char *key,cJSON *kvjson,bits256 pubkey,bits256 sigprev) +{ + struct tai T; int32_t seconds,datenum,n; + datenum = OS_conv_unixtime(&T,&seconds,timestamp); + jaddstr(kvjson,"key",key); + jaddnum(kvjson,"datenum",datenum); + jaddnum(kvjson,"hour",seconds/3600); + jaddnum(kvjson,"seconds",seconds % 3600); + jaddnum(kvjson,"height",height); + //printf("(%s)\n",jprint(kvjson,0)); + if ( logfp != 0 ) + { + stats_priceupdate(datenum,seconds/3600,seconds % 3600,timestamp,height,key,jstr(kvjson,"pubkey"),jarray(&n,kvjson,"trade")); + fprintf(logfp,"%s\n",jprint(kvjson,0)); + fflush(logfp); + } +} + +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,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); + iguana_rwnum(0,&opretbuf[9],sizeof(flags),&flags); + key = &opretbuf[13]; + if ( keylen+13 > opretlen ) + { + printf("komodo_kvupdate: keylen.%d + 13 > opretlen.%d\n",keylen,opretlen); + return; + } + valueptr = &key[keylen]; + coresize = (int32_t)(sizeof(flags)+sizeof(height)+sizeof(keylen)+sizeof(valuesize)+keylen+valuesize+1); + if ( opretlen == coresize || opretlen == coresize+sizeof(bits256) || opretlen == coresize+2*sizeof(bits256) ) + { + memset(&pubkey,0,sizeof(pubkey)); + memset(&sig,0,sizeof(sig)); + if ( (haspubkey= (opretlen >= coresize+sizeof(bits256))) != 0 ) + { + for (i=0; i<32; i++) + ((uint8_t *)&pubkey)[i] = opretbuf[coresize+i]; + } + if ( (hassig= (opretlen == coresize+sizeof(bits256)*2)) != 0 ) + { + for (i=0; i<32; i++) + ((uint8_t *)&sig)[i] = opretbuf[coresize+sizeof(bits256)+i]; + } + /*if ( (refvaluesize= komodo_kvsearch((bits256 *)&refpubkey,height,&flags,&kvheight,&keyvalue[keylen],key,keylen)) >= 0 ) + { + if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 ) + { + if ( komodo_kvsigverify(keyvalue,keylen+refvaluesize,refpubkey,sig) < 0 ) + { + //printf("komodo_kvsigverify error [%d]\n",coresize-13); + return; + } + } + }*/ + //for (i=0; i "); + //printf(" (%s) [%d] %s/v%d ht.%d height.%d\n",decodestr,valuesize,bits256_str(str,txid),vout,ht,height); + key[keylen] = 0; + stats_kvjson(logfp,ht,sp->SAVEDHEIGHT,sp->SAVEDTIMESTAMP,(char *)key,kvjson,pubkey,sig); + free_json(kvjson); + } + } +} + +void komodo_eventadd_opreturn(FILE *logfp,struct komodo_state *sp,char *symbol,int32_t height,bits256 txid,uint64_t value,uint16_t vout,uint8_t *opretbuf,uint16_t opretlen) +{ + if ( sp != 0 ) + { + if ( opretbuf[0] == 'K' && opretlen != 40 ) + { + komodo_kvupdate(logfp,sp,height,txid,vout,opretbuf,opretlen,value); + } + } +} + +void komodo_setkmdheight(struct komodo_state *sp,int32_t kmdheight,uint32_t timestamp) +{ + if ( sp != 0 ) + { + if ( kmdheight > sp->SAVEDHEIGHT ) + { + sp->SAVEDHEIGHT = kmdheight; + sp->SAVEDTIMESTAMP = timestamp; + //printf("ht.%d t.%u\n",kmdheight,timestamp); + } + if ( kmdheight > sp->CURRENT_HEIGHT ) + sp->CURRENT_HEIGHT = kmdheight; + } +} + +void komodo_eventadd_kmdheight(struct komodo_state *sp,char *symbol,int32_t height,int32_t kmdheight,uint32_t timestamp) +{ + uint32_t buf[2]; + if ( kmdheight > 0 ) + { + buf[0] = (uint32_t)kmdheight; + buf[1] = timestamp; + //komodo_eventadd(sp,height,symbol,KOMODO_EVENT_KMDHEIGHT,(uint8_t *)buf,sizeof(buf)); + if ( sp != 0 ) + komodo_setkmdheight(sp,kmdheight,timestamp); + } + else + { + kmdheight = -kmdheight; + //komodo_eventadd(sp,height,symbol,KOMODO_EVENT_REWIND,(uint8_t *)&height,sizeof(height)); + //if ( sp != 0 ) + // komodo_event_rewind(sp,symbol,height); + } +} + +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; cJSON *argjson; + if ( ht > 300000 && pvals[32] != 0 ) + { + datenum = OS_conv_unixtime(&T,&seconds,sp->SAVEDTIMESTAMP); + //printf("(%s)\n",jprint(kvjson,0)); + argjson = cJSON_CreateArray(); + jaddistr(argjson,"KMD"); + jaddinum(argjson,1); + jaddistr(argjson,"BTC"); + jaddinum(argjson,dstr(pvals[32]) / 10000.); + stats_priceupdate(datenum,seconds/3600,seconds % 3600,sp->SAVEDTIMESTAMP,sp->SAVEDHEIGHT,0,0,argjson); + free_json(argjson); + } +} + +int32_t komodo_parsestatefile(FILE *logfp,struct komodo_state *sp,FILE *fp,char *symbol,int32_t iter) +{ + static int32_t errs; + int32_t func,ht,notarized_height,num,matched=0; bits256 notarized_hash,notarized_desttxid; uint8_t pubkeys[64][33]; + if ( (func= fgetc(fp)) != EOF ) + { + if ( ASSETCHAINS_SYMBOL[0] == 0 && strcmp(symbol,"KMD") == 0 ) + matched = 1; + else matched = (strcmp(symbol,ASSETCHAINS_SYMBOL) == 0); + if ( fread(&ht,1,sizeof(ht),fp) != sizeof(ht) ) + errs++; + //printf("fpos.%ld func.(%d %c) ht.%d ",ftell(fp),func,func,ht); + if ( func == 'P' ) + { + if ( (num= fgetc(fp)) <= 64 ) + { + if ( fread(pubkeys,33,num,fp) != num ) + errs++; + else + { + //printf("updated %d pubkeys at %s ht.%d\n",num,symbol,ht); + //if ( (KOMODO_EXTERNAL_NOTARIES != 0 && matched != 0) || (strcmp(symbol,"KMD") == 0 && KOMODO_EXTERNAL_NOTARIES == 0) ) + // komodo_eventadd_pubkeys(sp,symbol,ht,num,pubkeys); + } + } else printf("illegal num.%d\n",num); + } + else if ( func == 'N' ) + { + if ( fread(¬arized_height,1,sizeof(notarized_height),fp) != sizeof(notarized_height) ) + errs++; + if ( fread(¬arized_hash,1,sizeof(notarized_hash),fp) != sizeof(notarized_hash) ) + errs++; + if ( fread(¬arized_desttxid,1,sizeof(notarized_desttxid),fp) != sizeof(notarized_desttxid) ) + errs++; + //if ( matched != 0 ) global independent states -> inside *sp + //komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height); + } + else if ( func == 'U' ) // deprecated + { + uint8_t n,nid; bits256 hash; uint64_t mask; + n = fgetc(fp); + nid = fgetc(fp); + //printf("U %d %d\n",n,nid); + if ( fread(&mask,1,sizeof(mask),fp) != sizeof(mask) ) + errs++; + if ( fread(&hash,1,sizeof(hash),fp) != sizeof(hash) ) + errs++; + //if ( matched != 0 ) + // komodo_eventadd_utxo(sp,symbol,ht,nid,hash,mask,n); + } + else if ( func == 'K' ) + { + int32_t kheight; + if ( fread(&kheight,1,sizeof(kheight),fp) != sizeof(kheight) ) + errs++; + //if ( matched != 0 ) global independent states -> inside *sp + //printf("%s.%d load[%s] ht.%d\n",ASSETCHAINS_SYMBOL,ht,symbol,kheight); + komodo_eventadd_kmdheight(sp,symbol,ht,kheight,0); + } + else if ( func == 'T' ) + { + int32_t kheight,ktimestamp; + if ( fread(&kheight,1,sizeof(kheight),fp) != sizeof(kheight) ) + errs++; + if ( fread(&ktimestamp,1,sizeof(ktimestamp),fp) != sizeof(ktimestamp) ) + errs++; + //if ( matched != 0 ) global independent states -> inside *sp + //printf("%s.%d load[%s] ht.%d t.%u\n",ASSETCHAINS_SYMBOL,ht,symbol,kheight,ktimestamp); + komodo_eventadd_kmdheight(sp,symbol,ht,kheight,ktimestamp); + } + else if ( func == 'R' ) + { + uint16_t olen,v; uint64_t ovalue; bits256 txid; uint8_t opret[16384]; + if ( fread(&txid,1,sizeof(txid),fp) != sizeof(txid) ) + errs++; + if ( fread(&v,1,sizeof(v),fp) != sizeof(v) ) + errs++; + if ( fread(&ovalue,1,sizeof(ovalue),fp) != sizeof(ovalue) ) + errs++; + if ( fread(&olen,1,sizeof(olen),fp) != sizeof(olen) ) + errs++; + if ( olen < sizeof(opret) ) + { + if ( fread(opret,1,olen,fp) != olen ) + errs++; + if ( (0) && matched != 0 ) + { + int32_t i; for (i=0; i global PAX + } else + { + int32_t i; + for (i=0; i global PVALS + //printf("load pvals ht.%d numpvals.%d\n",ht,numpvals); + } else printf("error loading pvals[%d]\n",numpvals); + } + else printf("[%s] %s illegal func.(%d %c)\n",ASSETCHAINS_SYMBOL,symbol,func,func); + return(func); + } else return(-1); +} + +int32_t stats_stateupdate(FILE *logfp,char *destdir,char *statefname,int32_t maxseconds,char *komodofile) +{ + static long lastpos[2]; + char symbol[64],base[64]; int32_t iter,n; FILE *fp; uint32_t starttime; struct komodo_state *sp; + starttime = (uint32_t)time(NULL); + strcpy(base,"KV"); + strcpy(symbol,"KV"); + n = 0; + for (iter=0; iter<2; iter++) + { + sp = &KOMODO_STATE[iter]; + if ( (fp= fopen(iter == 0 ? statefname : komodofile,"rb")) != 0 ) + { + fseek(fp,0,SEEK_END); + if ( ftell(fp) > lastpos[iter] ) + { + fseek(fp,lastpos[iter],SEEK_SET); + while ( komodo_parsestatefile(logfp,sp,fp,symbol,iter) >= 0 && n < 100000 ) + { + if ( n == 99999 ) + { + if ( time(NULL) < starttime+maxseconds ) + n = 0; + else break; + } + n++; + } + lastpos[iter] = ftell(fp); + } + fclose(fp); + } + strcpy(base,"KMD"); + strcpy(symbol,"KMD"); + } + return(n); +} + +char *stats_update(FILE *logfp,char *destdir,char *statefname,char *komodofname) +{ + int32_t i; + cJSON *retjson = cJSON_CreateArray(); + for (i=0; i<100; i++) + if ( stats_stateupdate(logfp,destdir,statefname,10,komodofname) <= 0 ) + break; + return(jprint(retjson,1)); +} + +int main(int argc, const char * argv[]) +{ + struct tai T; uint32_t timestamp; struct DEXstats_disp prices[365]; int32_t i,n,seconds,leftdatenum; FILE *fp,*logfp; char *filestr,*retstr,*statefname,logfname[512],komodofile[512]; uint16_t port = 7779; + if ( argc < 2 ) + { + statefname = "/root/.komodo/KV/komodostate"; + strcpy(komodofile,"/root/.komodo/komodostate"); + } + else + { + statefname = (char *)argv[1]; + strcpy(komodofile,statefname); + n = (int32_t)strlen(komodofile); + for (i=0; i<=strlen("komodostate"); i++) + komodofile[n-14+i] = komodofile[n-11+i]; + printf("komodofile.(%s)\n",komodofile); + } + sprintf(logfname,"%s/logfile",STATS_DESTDIR), OS_portable_path(logfname); + logfp = fopen(logfname,"wb"); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&port) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",port); + exit(-1); + } + printf("DEX stats running\n"); + while ( 1 ) + { + if ( (filestr= stats_update(logfp,STATS_DEST,statefname,komodofile)) != 0 ) + { + timestamp = (uint32_t)time(NULL); + leftdatenum = OS_conv_unixtime(&T,&seconds,timestamp - 30*24*3600); + //printf("%u: leftdatenum.%d %s\n",timestamp,leftdatenum,filestr); + memset(prices,0,sizeof(prices)); + if ( (retstr= stats_prices("KMD","BTC",prices,leftdatenum,30+1)) != 0 ) + { + //printf("%s\n",retstr); + free(retstr); + } + if ( (fp= fopen(STATS_DEST,"wb")) != 0 ) + { + fwrite(filestr,1,strlen(filestr)+1,fp); + fclose(fp); + } + free(filestr); + } + sleep(60); + } + return 0; +} +#endif diff --git a/iguana/exchanges/status b/iguana/exchanges/status new file mode 100755 index 000000000..7e7b4bb0e --- /dev/null +++ b/iguana/exchanges/status @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"swapstatus\"}" diff --git a/iguana/exchanges/swapstatus b/iguana/exchanges/swapstatus new file mode 100755 index 000000000..e7ba89318 --- /dev/null +++ b/iguana/exchanges/swapstatus @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"swapstatus\",\"requestid\":2291973695,\"quoteid\":3387529385}" diff --git a/iguana/exchanges/tmp/.tmpmarker b/iguana/exchanges/tmp/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/trade b/iguana/exchanges/trade new file mode 100755 index 000000000..cf7d9ec2f --- /dev/null +++ b/iguana/exchanges/trade @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"trade\",\"price\":1.234,\"base\":\"REVS\",\"rel\":\"KMD\",\"quote\":{}}" diff --git a/iguana/exchanges/userpass b/iguana/exchanges/userpass new file mode 100644 index 000000000..d097e0445 --- /dev/null +++ b/iguana/exchanges/userpass @@ -0,0 +1,2 @@ +#export userpass="" +export userpass="c3d8c2a364b7d18c1f9d7321d017b92e9f9c791e4f5c741214fefdea8a071256" diff --git a/iguana/exchanges/utxos b/iguana/exchanges/utxos new file mode 100755 index 000000000..a84c72fb0 --- /dev/null +++ b/iguana/exchanges/utxos @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"getutxos\",\"coin\":\"REVS\"}" diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 50bcb42fd..d998b4b81 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -105,25 +105,6 @@ void iguana_recvalloc(struct iguana_info *coin,int32_t numitems) //coin->blocks.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/iguana777.h b/iguana/iguana777.h index 682d3da13..74412e6f0 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -15,6 +15,7 @@ /* adding assetchain coin: copy genCOIN to SuperNET/iguana/coins, make a _7776 variant with RELAY=-1 and VALIDATE=0 + copy that into basilisk as coin, changing RELAY -> 0 */ #ifndef iguana777_net_h @@ -94,10 +95,15 @@ struct supernet_address char NXTADDR[32],BTC[64],BTCD[64]; }; +struct smartaddress_symbol { double maxbid,minask,srcavail,destamount; char symbol[16]; }; + struct smartaddress { bits256 privkey,pubkey; + int32_t numsymbols; uint8_t pubkey33[33],rmd160[20]; + char typestr[16]; + struct smartaddress_symbol *symbols; }; struct pending_trade { UT_hash_handle hh; double basevolume,relvolume,dir; char base[32],rel[32]; }; @@ -140,7 +146,7 @@ struct supernet_info struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; int32_t numexchanges; struct iguana_waccount *wallet; struct iguana_info *allcoins; int32_t allcoins_being_added,allcoins_numvirts; - portable_mutex_t bu_mutex,allcoins_mutex,gecko_mutex,basilisk_mutex,DEX_mutex,DEX_reqmutex,DEX_swapmutex; + portable_mutex_t bu_mutex,allcoins_mutex,gecko_mutex,basilisk_mutex,DEX_mutex,DEX_reqmutex,DEX_swapmutex,smart_mutex; struct queueitem *DEX_quotes; cJSON *Cunspents,*Cspends; struct basilisk_swap *swaps[256]; int32_t numswaps; struct basilisk_message *messagetable; portable_mutex_t messagemutex; queue_t msgQ,p2pQ; @@ -158,7 +164,12 @@ struct supernet_info struct liquidity_info linfos[512]; cJSON *liquidity_currencies; struct pending_trade *trades; portable_mutex_t pending_mutex; struct komodo_notaries NOTARY; char seedipaddr[64]; uint32_t dpowipbits[128]; int32_t numdpowipbits; portable_mutex_t notarymutex,dpowmutex; - char dexseed_ipaddrs[2][64]; uint32_t dexipbits[128]; int32_t numdexipbits; portable_mutex_t dexmutex; +#ifdef NOTARY_TESTMODE + char dexseed_ipaddrs[1][64]; +#else + char dexseed_ipaddrs[4][64]; +#endif + uint32_t dexipbits[128]; int32_t numdexipbits; portable_mutex_t dexmutex; // compatibility bits256 pangea_category,instantdex_category; uint8_t logs[256],exps[510]; @@ -167,7 +178,8 @@ struct supernet_info uint16_t psockport,numpsocks; struct psock *PSOCKS; portable_mutex_t psockmutex; uint8_t notaries[64][33]; int32_t numnotaries,DEXEXPLORER; FILE *swapsfp; - struct smartaddress smartaddrs[64]; int32_t numsmartaddrs,cancelrefresh; + double DEXratio; + struct smartaddress smartaddrs[64]; int32_t numsmartaddrs,cancelrefresh,runsilent,DEXtrades; }; struct basilisk_swapmessage @@ -181,13 +193,14 @@ struct basilisk_swap { struct supernet_info *myinfoptr; struct iguana_info *bobcoin,*alicecoin; void (*balancingtrade)(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob); - int32_t subsock,pushsock,connected; uint32_t lasttime; + int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; uint32_t lasttime,aborted; FILE *fp; bits256 persistent_privkey,persistent_pubkey; struct basilisk_swapinfo I; struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim; bits256 privkeys[INSTANTDEX_DECKSIZE]; struct basilisk_swapmessage *messages; int32_t nummessages; + char Bdeposit[64],Bpayment[64]; uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; uint8_t persistent_pubkey33[33],pad[15],verifybuf[65536]; diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c index e86c74bcf..2463a09a8 100755 --- a/iguana/iguana_accept.c +++ b/iguana/iguana_accept.c @@ -115,7 +115,7 @@ void iguana_acceptloop(void *args) printf("another daemon running, no need to have iguana accept connections\n"); return; } - //if ( port != IGUANA_RPCPORT ) + //if ( port != myinfo->rpcport ) // return; sleep(5); } diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index b5749f8f5..4fc5a0b76 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -232,7 +232,12 @@ void set_coinconfname(char *fname,char *coinstr,char *userhome,char *coindir,cha sprintf(confname,"%s.conf",buf); } printf("userhome.(%s) coindir.(%s) confname.(%s)\n",userhome,coindir,confname); - sprintf(fname,"%s/%s/%s",userhome,coindir,confname); +#ifdef WIN32 + if ( userhome == 0 || userhome[0] == 0 ) + sprintf(fname,"%s/%s",coindir,confname); + else +#endif + sprintf(fname,"%s/%s/%s",userhome,coindir,confname); } uint16_t extract_userpass(char *serverport,char *userpass,char *coinstr,char *userhome,char *coindir,char *confname) diff --git a/iguana/iguana_exchanges.c b/iguana/iguana_exchanges.c index d7445f681..d2cd1c267 100755 --- a/iguana/iguana_exchanges.c +++ b/iguana/iguana_exchanges.c @@ -784,7 +784,8 @@ void exchanges777_loop(void *ptr) printf("exchanges loop.(%s)\n",exchange->name); while ( 1 ) { - PAX_idle(myinfo); + if ( strcmp("bitcoin",exchange->name) == 0 ) + PAX_idle(myinfo); flag = retval = 0; retstr = 0; if ( (req= queue_dequeue(&exchange->requestQ)) != 0 ) diff --git a/iguana/iguana_interpreter.c b/iguana/iguana_interpreter.c index 341f92b55..d979752f6 100755 --- a/iguana/iguana_interpreter.c +++ b/iguana/iguana_interpreter.c @@ -785,7 +785,7 @@ int32_t iguana_checkmultisig(struct iguana_info *coin,struct iguana_interpreter printf("iguana_checkmultisig n.%d != N.%d\n",n,N); return(0); } - //printf("n.%d stackdepth.%d\n",n,stacks->stackdepth); +//printf("n.%d stackdepth.%d\n",n,stacks->stackdepth); for (i=0; istackdepth <= 0 ) @@ -810,7 +810,7 @@ int32_t iguana_checkmultisig(struct iguana_info *coin,struct iguana_interpreter if ( stacks->stackdepth <= 0 ) return(0); m = (int32_t)iguana_num(iguana_pop(stacks)); - //printf("m.%d stackdepth.%d\n",m,stacks->stackdepth); +//printf("m.%d stackdepth.%d\n",m,stacks->stackdepth); if ( m != M ) { @@ -830,7 +830,7 @@ int32_t iguana_checkmultisig(struct iguana_info *coin,struct iguana_interpreter } if ( i == numsigners ) { - //char str[65]; printf("sigtxid.(%s)\n",bits256_str(str,txhash2)); + //char str[65]; printf("depth.%d sigtxid.(%s)\n",stacks->stackdepth,bits256_str(str,txhash2)); if ( stacks->stackdepth > 0 ) iguana_pop(stacks); // for backward compatibility j = numsigners-1; @@ -849,7 +849,7 @@ int32_t iguana_checkmultisig(struct iguana_info *coin,struct iguana_interpreter } } } - //printf("valid.%d j.%d M.%d N.%d numsigners.%d\n",valid,j,M,N,numsigners); + printf("checkmultisig: valid.%d j.%d M.%d N.%d numsigners.%d\n",valid,j,M,N,numsigners); return(0); } diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index 7e38b1ad7..99d851641 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -18,7 +18,7 @@ cJSON *helpjson(cJSON *json,cJSON *array,cJSON *agents,char *agentstr,char *method,cJSON *methodargs) { - cJSON *methodobj,*item; int32_t i,n; char url[2048],curl[2048]; + cJSON *methodobj,*item; int32_t i,n; char url[2048],curl[2048]; struct supernet_info *myinfo = SuperNET_MYINFO(0); /*if ( *agentstrp == 0 || strcmp(*agentstrp,agentstr) != 0 ) { if ( array != 0 ) @@ -43,8 +43,8 @@ cJSON *helpjson(cJSON *json,cJSON *array,cJSON *agents,char *agentstr,char *meth methodobj = cJSON_CreateObject(); jaddstr(methodobj,"agent",agentstr); jaddstr(methodobj,"method",method); - sprintf(url,"http://127.0.0.1:7778/api/%s/%s",agentstr,method); - sprintf(curl,"curl --url \"http://127.0.0.1:7778\" --data \"{\\\"agent\\\":\\\"%s\\\",\\\"method\\\":\\\"%s\\\"",agentstr,method); + sprintf(url,"http://127.0.0.1:%u/api/%s/%s",myinfo->rpcport,agentstr,method); + sprintf(curl,"curl --url \"http://127.0.0.1:%u\" --data \"{\\\"agent\\\":\\\"%s\\\",\\\"method\\\":\\\"%s\\\"",myinfo->rpcport,agentstr,method); if ( methodargs != 0 && (n= cJSON_GetArraySize(methodargs)) > 0 ) { //printf("method.%s n.%d %s\n",method,n,jprint(methodargs,0)); @@ -203,7 +203,7 @@ cJSON *SuperNET_helpjson() int32_t agentform(FILE *fp,char *form,int32_t max,char *agent,cJSON *methoditem) { - cJSON *item,*fieldsarray; int32_t j,m,width=1,size = 0; + cJSON *item,*fieldsarray; int32_t j,m,width=1,size = 0; struct supernet_info *myinfo = SuperNET_MYINFO(0); char *methodstr,*typestr,outstr[2048],outstr2[2048],fields[8192],str[2],agent_method[256],*fieldname; form[0] = 0; if ( (methodstr= jstr(methoditem,"method")) == 0 ) @@ -252,7 +252,7 @@ int32_t agentform(FILE *fp,char *form,int32_t max,char *agent,cJSON *methoditem) //printf("fields[%d] (%s)\n",j,fields); } } else sprintf(fields+strlen(fields),"%s ",agent_method); - sprintf(&form[size],"
%s
",agent,methodstr,outstr,fields,outstr2,methodstr); + sprintf(&form[size],"
%s
",myinfo->rpcport,agent,methodstr,outstr,fields,outstr2,methodstr); if ( fp != 0 ) fprintf(fp,"%s\n",&form[size]); //printf("%s\n",&form[size]); diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index 8ad05f5d9..bbdd7a6d6 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -640,7 +640,7 @@ int32_t iguana_rwtx(struct supernet_info *myinfo,uint8_t zcash,int32_t rwflag,st len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); } len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); - if ( rwflag == 0 ) + if ( rwflag == 0 && msg->tx_in > 0 ) msg->vins = iguana_memalloc(mem,msg->tx_in * sizeof(*msg->vins),1); if ( maxsize-len <= 0 ) return(-1); @@ -671,7 +671,7 @@ int32_t iguana_rwtx(struct supernet_info *myinfo,uint8_t zcash,int32_t rwflag,st return(-1); } //printf("numvouts.%d ",msg->tx_out); - if ( rwflag == 0 ) + if ( rwflag == 0 && msg->tx_out > 0 ) msg->vouts = iguana_memalloc(mem,msg->tx_out * sizeof(*msg->vouts),1); for (i=0; itx_out; i++) { diff --git a/iguana/iguana_notary.c b/iguana/iguana_notary.c index dc4d436d8..a8518be7b 100755 --- a/iguana/iguana_notary.c +++ b/iguana/iguana_notary.c @@ -71,9 +71,7 @@ void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t he else { freq = 1; - //minsigs = 7;//(komodo_notaries(dp->symbol,pubkeys,height) >> 1) + 1; - //if ( minsigs < DPOW_MINSIGS ) - minsigs = DPOW_MINSIGS; + minsigs = 11; } printf("%s/%s src ht.%d dest.%u nonz.%d %s minsigs.%d\n",dp->symbol,dp->dest,checkpoint.blockhash.height,dp->destupdated,bits256_nonz(checkpoint.blockhash.hash),bits256_str(str,dp->last.blockhash.hash),minsigs); dpow_fifoupdate(myinfo,dp->srcfifo,dp->last); @@ -437,7 +435,7 @@ STRING_ARG(iguana,addnotary,ipaddr) char NOTARY_CURRENCIES[][16] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", - "REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "SHARK", "BOTS", "MGW", "MVP", "WIRELESS", "KV", "CEAL", "MESH" }; + "REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "SHARK", "BOTS", "MGW", "COQUI", "WLC", "KV", "CEAL", "MESH", "LTC" }; ZERO_ARGS(dpow,notarychains) { @@ -605,17 +603,29 @@ TWOINTS_AND_ARRAY(dpow,ratify,minsigs,timestamp,ratified) HASH_AND_STRING(dex,gettransaction,txid,symbol) { + /*char str[65],url[1024],*retstr; + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && myinfo->blocktrail_apikey[0] != 0 ) + { + sprintf(url,"https://api.blocktrail.com/v1/btc/transaction/%s?api_key=%s",bits256_str(str,txid),myinfo->blocktrail_apikey); + + sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/unspent-outputs?api_key=%s",address,myinfo->blocktrail_apikey); + }*/ return(_dex_getrawtransaction(myinfo,symbol,txid)); } HASH_AND_STRING_AND_INT(dex,gettxout,txid,symbol,vout) { + /*char str[65],url[1024],*retstr; + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && myinfo->blocktrail_apikey[0] != 0 ) + { + sprintf(url,"https://api.blocktrail.com/v1/btc/transaction/%s?api_key=%s",bits256_str(str,txid),myinfo->blocktrail_apikey); + }*/ return(_dex_gettxout(myinfo,symbol,txid,vout)); } TWO_STRINGS(dex,listunspent,symbol,address) { - if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && coin->FULLNODE == 0 && myinfo->blocktrail_apikey[0] != 0 ) + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && myinfo->blocktrail_apikey[0] != 0 ) { char url[1024],*retstr,*coinaddr,*script; int32_t i,n,vout; cJSON *retjson,*data,*item,*item3,*data3; bits256 txid; uint64_t val; sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/unspent-outputs?api_key=%s",address,myinfo->blocktrail_apikey); @@ -665,12 +675,15 @@ TWO_STRINGS(dex,listunspent,symbol,address) return(retstr); } } + else if ( coin != 0 && coin->FULLNODE < 0 ) + return(jprint(dpow_listunspent(myinfo,coin,address),1)); + //printf("call _dex_listunspent\n"); return(_dex_listunspent(myinfo,symbol,address)); } TWO_STRINGS_AND_TWO_DOUBLES(dex,listtransactions,symbol,address,count,skip) { - if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && coin->FULLNODE == 0 && myinfo->blocktrail_apikey[0] != 0 ) + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && myinfo->blocktrail_apikey[0] != 0 ) { char url[1024],*retstr,*retstr2; cJSON *retjson,*retjson2,*retjson3,*data,*data2; int32_t i,n; sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/transactions?api_key=%s",address,myinfo->blocktrail_apikey); @@ -689,7 +702,7 @@ TWO_STRINGS_AND_TWO_DOUBLES(dex,listtransactions,symbol,address,count,skip) for (i=0; i (%s)\n",retstr,retstr2,jprint(retjson3,0)); + //printf("combined (%s) and (%s) -> (%s)\n",retstr,retstr2,jprint(retjson3,0)); free(retstr); free(retstr2); free_json(retjson); @@ -863,6 +876,7 @@ TWO_STRINGS(dex,getbalance,symbol,address) char url[512],*retstr; cJSON *retjson; uint64_t val; if ( myinfo->DEXEXPLORER != 0 ) { + //printf("DEXEXPLORER\n"); if ( symbol != 0 && address != 0 && (coin= iguana_coinfind(symbol)) != 0 && coin->DEXEXPLORER != 0 ) return(jprint(kmd_getbalance(myinfo,coin,address),1)); if ( coin != 0 ) @@ -907,7 +921,7 @@ TWO_STRINGS(dex,getbalance,symbol,address) jdelete(retjson,"unconfirmed_received"); jaddnum(retjson,"unconfirmed_received",dstr(val)); } - //printf("(%s) -> (%s)\n",retstr,jprint(retjson,0)); + //printf("blocktrail.(%s) -> (%s)\n",retstr,jprint(retjson,0)); free(retstr); retstr = jprint(retjson,1); } diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c index 0517b94a3..a5b2876cf 100755 --- a/iguana/iguana_payments.c +++ b/iguana/iguana_payments.c @@ -341,25 +341,47 @@ bits256 iguana_sendrawtransaction(struct supernet_info *myinfo,struct iguana_inf return(txid); } -uint64_t _iguana_interest(uint32_t now,int32_t chainheight,uint32_t txlocktime,uint64_t value) +uint64_t _iguana_interest(uint32_t now,int32_t txheight,uint32_t txlocktime,uint64_t value) { - int32_t minutes; uint64_t numerator=0,denominator=0,interest = 0; + int32_t minutes; uint64_t numerator=0,denominator=0,interest=0; uint32_t activation = 1491350400; + if ( (minutes= ((uint32_t)time(NULL) - 60 - txlocktime) / 60) >= 60 ) { + if ( minutes > 365 * 24 * 60 ) + minutes = 365 * 24 * 60; + if ( txheight >= 250000 ) + minutes -= 59; denominator = (((uint64_t)365 * 24 * 60) / minutes); if ( denominator == 0 ) denominator = 1; // max KOMODO_INTEREST per transfer, do it at least annually! - if ( value > 25000LL*SATOSHIDEN && chainheight > 155949 ) + if ( value > 25000LL*SATOSHIDEN && txheight > 155949 ) { numerator = (value / 20); // assumes 5%! - interest = (numerator / denominator); + if ( txheight < 250000 ) + interest = (numerator / denominator); + else interest = (numerator * minutes) / ((uint64_t)365 * 24 * 60); } else if ( value >= 10*SATOSHIDEN ) { + /*numerator = (value * KOMODO_INTEREST); + if ( txheight < 250000 || numerator * minutes < 365 * 24 * 60 ) + interest = (numerator / denominator) / SATOSHIDEN; + else interest = ((numerator * minutes) / ((uint64_t)365 * 24 * 60)) / SATOSHIDEN;*/ numerator = (value * KOMODO_INTEREST); - interest = (numerator / denominator) / SATOSHIDEN; + if ( txheight < 250000 || now < activation ) + { + if ( txheight < 250000 || numerator * minutes < 365 * 24 * 60 ) + interest = (numerator / denominator) / SATOSHIDEN; + else interest = ((numerator * minutes) / ((uint64_t)365 * 24 * 60)) / SATOSHIDEN; + } + else + { + numerator = (value / 20); // assumes 5%! + interest = ((numerator * minutes) / ((uint64_t)365 * 24 * 60)); + //fprintf(stderr,"interest %llu %.8f <- numerator.%llu minutes.%d\n",(long long)interest,(double)interest/COIN,(long long)numerator,(int32_t)minutes); + } } - //fprintf(stderr,"komodo_interest.%d %lld %.8f nLockTime.%u tiptime.%u minutes.%d interest %lld %.8f (%llu / %llu)\n",chainheight,(long long)value,(double)value/SATOSHIDEN,txlocktime,now,minutes,(long long)interest,(double)interest/SATOSHIDEN,(long long)numerator,(long long)denominator); + //fprintf(stderr,"komodo_interest.%d %lld %.8f nLockTime.%u tiptime.%u minutes.%d interest %lld %.8f (%llu / %llu)\n",txheight,(long long)value,(double)value/SATOSHIDEN,txlocktime,now,minutes,(long long)interest,(double)interest/SATOSHIDEN,(long long)numerator,(long long)denominator); } return(interest); } @@ -426,7 +448,7 @@ char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJS coinaddr = jstri(addresses,i); if ( (array= basilisk_unspents(myinfo,coin,coinaddr)) != 0 ) { - //printf("unspents.(%s) %s\n",coinaddr,jprint(array,0)); + //printf("iguana_calcrawtx unspents.(%s) %s\n",coinaddr,jprint(array,0)); if ( (m= cJSON_GetArraySize(array)) > 0 ) { for (j=0; jtxids,key,keylen,tmp); @@ -184,7 +184,7 @@ uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 { if ( t->txidind != txidind || memcmp(t->txid.bytes,txid.bytes,sizeof(bits256)) != 0 || t->numvouts != numvouts || t->numvins != numvins || t->firstvout != ramchain->H.unspentind || t->firstvin != ramchain->H.spendind || t->locktime != locktime || t->version != version || t->timestamp != timestamp ) { - printf("iguana_ramchain_addtxid.RO: addtxid mismatch (%u %d %d %u %u) vs. (%d %d %d %d %d)\n",(uint32_t)t->txidind,t->numvouts,t->numvins,(uint32_t)t->firstvout,(uint32_t)t->firstvin,txidind,numvouts,numvins,ramchain->H.unspentind,ramchain->H.spendind); + printf("iguana_ramchain_addtxid.RO: addtxid mismatch b.%d (%u %d %d %u %u) vs. (%d %d %d %d %d)\n",bundlei,(uint32_t)t->txidind,t->numvouts,t->numvins,(uint32_t)t->firstvout,(uint32_t)t->firstvin,txidind,numvouts,numvins,ramchain->H.unspentind,ramchain->H.spendind); //getchar(); return(0); } @@ -258,7 +258,9 @@ uint32_t iguana_ramchain_addpkhash(struct iguana_info *coin,RAMCHAIN_FUNC,uint8_ P[pkind].firstunspentind = unspentind; printf("%p P[%d] <- firstunspent.%d\n",&P[pkind],pkind,unspentind); }*/ - memcpy(P[pkind].rmd160,rmd160,sizeof(P[pkind].rmd160)); + //memcpy(P[pkind].rmd160,rmd160,sizeof(P[pkind].rmd160)); + for (i=0; i<20; i++) + P[pkind].rmd160[i] = rmd160[i]; //for (i=0; i<20; i++) // printf("%02x",rmd160[i]); //printf(" -> rmd160 pkind.%d \n",pkind); @@ -276,7 +278,7 @@ uint32_t iguana_ramchain_addpkhash(struct iguana_info *coin,RAMCHAIN_FUNC,uint8_ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_peer *addr,RAMCHAIN_FUNC,uint64_t value,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vout,int8_t type,struct iguana_bundle *bp,uint8_t rmd160[20]) { - uint32_t unspentind; struct iguana_unspent20 *u; long scriptpos; struct vin_info V; char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; + uint32_t unspentind,i; struct iguana_unspent20 *u; long scriptpos; struct vin_info V; char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; unspentind = ramchain->H.unspentind++; u = &U[unspentind]; if ( scriptlen > 0 ) @@ -287,14 +289,16 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee type = iguana_calcrmd160(coin,asmstr,&V,script,scriptlen,txid,vout,0xffffffff); if ( (type == 12 && scriptlen == 0) || (type == 1 && bitcoin_pubkeylen(script+1) <= 0) ) { - int32_t i; for (i=0; iH.ROflag != 0 ) @@ -309,7 +313,9 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee { u->value = value; u->type = type; - memcpy(u->rmd160,rmd160,sizeof(u->rmd160)); + //memcpy(u->rmd160,rmd160,sizeof(u->rmd160)); + for (i=0; i<20; i++) + u->rmd160[i] = rmd160[i]; if ( type == IGUANA_SCRIPT_76AC ) { static uint64_t totalsize; @@ -693,7 +699,7 @@ void *iguana_ramchain_offset(char *fname,void *dest,uint8_t *lhash,FILE *fp,uint int32_t iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t flag) { RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; - struct iguana_pkhash p; struct iguana_unspent u; struct iguana_txid txid; uint32_t i,numpkinds,numtxids,numunspents,numexternal,tlen,plen,nonz=0; uint8_t *ptr; struct iguana_ramchaindata *rdata; + struct iguana_pkhash p; struct iguana_unspent u; struct iguana_txid txid; uint32_t i,j,numpkinds,numtxids,numunspents,numexternal,tlen,plen,nonz=0; uint8_t *ptr; struct iguana_ramchaindata *rdata; //return(0); if ( (rdata= ramchain->H.data) != 0 ) { @@ -716,7 +722,9 @@ int32_t iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain tlen = (rdata->numtxsparse * rdata->txsparsebits) >> 3; for (i=0; inumvouts; k++,ramchain->H.unspentind++) + for (k=0; knumvouts; k++) { u = &Ux[ramchain->H.unspentind]; if ( u->txidind != ramchain->H.txidind ) @@ -1140,17 +1148,19 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * printf("%p itemind.%d pkind.%d %d unspentind?\n",p,ptr->hh.itemind,pkind,ramchain->H.unspentind); return(-9); } + ramchain->H.unspentind++; } } else { - for (k=0; knumvouts; k++,ramchain->H.unspentind++) + for (k=0; knumvouts; k++) { if ( U[ramchain->H.unspentind].txidind != ramchain->H.txidind ) { printf(" k.%d U.%d u->txidind.%x != txidind.%d\n",k,ramchain->H.unspentind,U[ramchain->H.unspentind].txidind,ramchain->H.txidind); return(-6); } + ramchain->H.unspentind++; } } ramchain->H.spendind += t->numvins; @@ -1159,7 +1169,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) { t = &T[ramchain->H.txidind]; - for (k=0; knumvins; k++,ramchain->H.spendind++) + for (k=0; knumvins; k++) { if ( ramchain->expanded != 0 ) { @@ -1182,6 +1192,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * } } } + ramchain->H.spendind++; } } if ( ramchain->expanded != 0 && ramchain->A != ramchain->creditsA ) @@ -1647,6 +1658,8 @@ int32_t iguana_ramchain_iterate(struct supernet_info *myinfo,struct iguana_info printf("iguana_ramchain_iterate cant iterate without data\n"); return(-1); } + if ( rdata->firsti != 1 ) + printf("unexpected firsti.%d %s.%d\n",rdata->firsti,coin->symbol,bundlei); if ( dest != 0 ) { // required to do one block at a time, all vins/vouts the same height are assumed to happen simultaneously with vouts before vins @@ -1891,14 +1904,15 @@ long iguana_ramchain_data(struct supernet_info *myinfo,struct iguana_info *coin, } if ( block != 0 ) block->fpipbits = 1; - for (i=0; iH.txidind++) + for (i=0; itxid,tx->tx_out,tx->tx_in,tx->lock_time,tx->version,tx->timestamp,bundlei); - if ( tx->tx_out == 0 && tx->tx_in == 0 ) + if ( tx->tx_out == 0 ) { - printf("strange tx without any inputs or outputs? ht.%d\n",bp->bundleheight); - break; + if ( coin->chain->zcash == 0 ) + printf("strange tx without any inputs or outputs? ht.%d\n",bp->bundleheight); + continue; } for (j=0; jtx_out; j++) { @@ -1907,16 +1921,18 @@ long iguana_ramchain_data(struct supernet_info *myinfo,struct iguana_info *coin, iguana_ramchain_addunspent20(coin,addr,RAMCHAIN_ARG,tx->vouts[j].value,tx->vouts[j].pk_script,tx->vouts[j].pk_scriptlen,tx->txid,j,-1,bp,rmd160); } ramchain->H.spendind += tx->tx_in; + ramchain->H.txidind++; } //printf("scriptoffset.%d after %d txids\n",ramchain->H.scriptoffset,txn_count); ramchain->H.txidind = ramchain->H.spendind = rdata->firsti; - for (i=0; iH.txidind++) + for (i=0; itx_in; j++) { iguana_ramchain_addspend256(coin,addr,RAMCHAIN_ARG,tx->vins[j].prev_hash,tx->vins[j].prev_vout,tx->vins[j].vinscript,tx->vins[j].scriptlen,tx->vins[j].sequence,bp);//,bp->hdrsi,bundlei); } + ramchain->H.txidind++; } rdata->prevhash2 = origtxdata->zblock.RO.prev_block; rdata->scriptspace = scriptspace = ramchain->H.scriptoffset; @@ -2189,6 +2205,8 @@ void iguana_bundlemapfree(struct iguana_info *coin,struct OS_memspace *mem,struc { for (j=starti; j<=endi; j++) { + R[j].fileptr = 0; + R[j].filesize = 0; iguana_ramchain_free(coin,&R[j],1); } myfree(R,n * sizeof(*R)); @@ -2477,13 +2495,17 @@ int32_t iguana_mapchaininit(char *fname,struct iguana_info *coin,struct iguana_r int32_t iguana_bundlesaveHT(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,uint32_t starttime) // helper thread { static int depth; - RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; + RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; static struct iguana_blockRO *_destB; void **ptrs; long *filesizes; uint32_t *ipbits; char fname[1024]; struct iguana_ramchain *R,*mapchain,*dest,newchain; uint32_t fpipbits; bits256 prevhash2; int32_t i,starti,endi,bp_n,numtxids,valid,sigspace,pubkeyspace,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_block *block; long fpos; struct OS_memspace HASHMEM; int32_t err,j,num,bundlei,firsti= 1,retval = -1; memset(&HASHMEM,0,sizeof(HASHMEM)); starti = 0, endi = bp->n - 1; + if ( _destB == 0 ) + _destB = malloc(sizeof(*_destB) * 2000); + destB = _destB; + memset(destB,0,sizeof(*destB) * bp->n); //B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; R = mycalloc('s',bp->n,sizeof(*R)); ptrs = mycalloc('w',bp->n,sizeof(*ptrs)); diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index 19d546676..d79aefe24 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -759,7 +759,7 @@ char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,ch //printf("add params[%d] of %d <- (%s) %p.(%p %p)\n",i,n,jprint(params[i],0),params[i],params[i]->next,params[i]->prev); } } - retstr = iguana_bitcoinrpc(myinfo,IGUANA_RPCPORT,coin,method,params,n,json,remoteaddr,array); + retstr = iguana_bitcoinrpc(myinfo,myinfo->rpcport,coin,method,params,n,json,remoteaddr,array); if ( n > 0 ) for (i=0; i>>>>>>>>> iguana_rpcloop 127.0.0.1:%d bind sock.%d iguana API enabled <<<<<<<<<\n",port,bindsock); + fflush(stdout); space = calloc(1,size); while ( bindsock >= 0 ) { diff --git a/iguana/iguana_secp.c b/iguana/iguana_secp.c index 614f970e4..c53170908 100755 --- a/iguana/iguana_secp.c +++ b/iguana/iguana_secp.c @@ -451,95 +451,6 @@ int32_t bitcoin_rangeproof(void *ctx,uint8_t *proof,uint8_t *commit,bits256 blin return(retval); } -/* - * The intended procedure for creating a multiparty signature is: - * - Each signer S[i] with private key x[i] and public key Q[i] runs - * secp256k1_schnorr_generate_nonce_pair to produce a pair (k[i],R[i]) of private/public nonces. - * - All signers communicate their public nonces to each other (revealing your - * private nonce can lead to discovery of your private key, so it should be considered secret). - * - All signers combine all the public nonces they received (excluding their - * own) using secp256k1_ec_pubkey_combine to obtain an Rall[i] = sum(R[0..i-1,i+1..n]). - * - All signers produce a partial signature using - * secp256k1_schnorr_partial_sign, passing in their own private key x[i], - * their own private nonce k[i], and the sum of the others' public nonces Rall[i]. - * - All signers communicate their partial signatures to each other. - * - Someone combines all partial signatures using secp256k1_schnorr_partial_combine, to obtain a full signature. - * - The resulting signature is validatable using secp256k1_schnorr_verify, with - * public key equal to the result of secp256k1_ec_pubkey_combine of the signers' public keys (sum(Q[0..n])). - * - * Note that secp256k1_schnorr_partial_combine and secp256k1_ec_pubkey_combine - * function take their arguments in any order, and it is possible to - * pre-combine several inputs already with one call, and add more inputs later - * by calling the function again (they are commutative and associative). - */ - -#ifdef test_schnorr -#include "secp256k1/src/util.h" -#include "secp256k1/src/hash_impl.h" -#include "secp256k1/src/testrand_impl.h" - -void test_schnorr_threshold(void *ctx) { - unsigned char msg[32]; - unsigned char sec[5][32]; - secp256k1_pubkey pub[5]; - unsigned char nonce[5][32]; - secp256k1_pubkey pubnonce[5]; - unsigned char sig[5][64]; - const unsigned char* sigs[5]; - unsigned char allsig[64]; - const secp256k1_pubkey* pubs[5]; - secp256k1_pubkey allpub; - int n, i; - int damage; - int ret = 0; - - damage = secp256k1_rand_bits(1) ? (1 + secp256k1_rand_int(4)) : 0; - secp256k1_rand256_test(msg); - n = 2 + secp256k1_rand_int(4); - for (i = 0; i < n; i++) { - do { - secp256k1_rand256_test(sec[i]); - } while (!secp256k1_ec_seckey_verify(ctx, sec[i])); - CHECK(secp256k1_ec_pubkey_create(ctx, &pub[i], sec[i])); - CHECK(secp256k1_schnorr_generate_nonce_pair(ctx, &pubnonce[i], nonce[i], msg, sec[i], NULL, NULL)); - pubs[i] = &pub[i]; - } - if (damage == 1) { - nonce[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } else if (damage == 2) { - sec[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } - for (i = 0; i < n; i++) { - secp256k1_pubkey allpubnonce; - const secp256k1_pubkey *pubnonces[4]; - int j; - for (j = 0; j < i; j++) { - pubnonces[j] = &pubnonce[j]; - } - for (j = i + 1; j < n; j++) { - pubnonces[j - 1] = &pubnonce[j]; - } - CHECK(secp256k1_ec_pubkey_combine(ctx, &allpubnonce, pubnonces, n - 1)); - ret |= (secp256k1_schnorr_partial_sign(ctx, sig[i], msg, sec[i], &allpubnonce, nonce[i]) != 1) * 1; - sigs[i] = sig[i]; - } - if (damage == 3) { - sig[secp256k1_rand_int(n)][secp256k1_rand_bits(6)] ^= 1 + secp256k1_rand_int(255); - } - ret |= (secp256k1_ec_pubkey_combine(ctx, &allpub, pubs, n) != 1) * 2; - if ((ret & 1) == 0) { - ret |= (secp256k1_schnorr_partial_combine(ctx, allsig, sigs, n) != 1) * 4; - } - if (damage == 4) { - allsig[secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } - if ((ret & 7) == 0) { - ret |= (secp256k1_schnorr_verify(ctx, allsig, msg, &allpub) != 1) * 8; - } - CHECK((ret == 0) == (damage == 0)); -} -#endif - int32_t iguana_pederson_test(void *ctx) { uint8_t commits[100][33],*commitptrs[100],proofs[100][5138]; uint16_t vouts[100]; int64_t min_value,values[100],totalpos,totalneg; bits256 txids[100],nonces[100],blinds[100],*blindptrs[100],blindsum; int32_t prooflens[100],i,r,pos,neg,numpos,exponent,min_bits,n,N = 100; diff --git a/iguana/iguana_sign.c b/iguana/iguana_sign.c index 97b0b2006..b1fee7f0e 100755 --- a/iguana/iguana_sign.c +++ b/iguana/iguana_sign.c @@ -568,14 +568,15 @@ void iguana_vinobjset(struct iguana_msgvin *vin,cJSON *item,uint8_t *spendscript } } -int32_t iguana_vinarray_check(cJSON *vinarray,bits256 txid) +int32_t iguana_vinarray_check(cJSON *vinarray,bits256 txid,int32_t vout) { - bits256 array_txid; cJSON *item; int32_t i,n = cJSON_GetArraySize(vinarray); + bits256 array_txid; cJSON *item; int32_t array_vout,i,n = cJSON_GetArraySize(vinarray); for (i=0; ivins[i],jitem(vins,i),spendscript,sizeof(spendscript)); sigtxid = bitcoin_sigtxid(coin,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,SIGHASH_ALL,vpnstr,suppress_pubkeys); //printf("after vini.%d vinscript.%p spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].vinscript,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0)); - if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash) < 0 ) + if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 ) jaddi(vinarray,iguana_vinjson(coin,&msg->vins[i],sigtxid)); if ( msg->vins[i].spendscript == spendscript ) msg->vins[i].spendscript = 0; - } else if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash) < 0 ) + } else if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 ) jaddi(vinarray,iguana_vinjson(coin,&msg->vins[i],sigtxid)); } free(sigser); @@ -975,7 +976,7 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxlen,struct vin_info *V,uint32_t sighash,int32_t signtx,int32_t suppress_pubkeys) { - bits256 sigtxid; uint8_t *sig,*script; struct vin_info *vp; char vpnstr[64]; int32_t scriptlen,complete=0,plen,j,vini=0,flag=0,siglen,numvouts,numsigs; + bits256 sigtxid; uint8_t *sig,*script; struct vin_info *vp; char vpnstr[64]; int32_t scriptlen,complete=0,j,vini=0,flag=0,siglen,numvouts,numsigs; numvouts = msgtx->tx_out; vpnstr[0] = 0; *signedtx = 0; @@ -1005,7 +1006,7 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *sign if ( signtx != 0 && bits256_nonz(vp->signers[j].privkey) != 0 ) { siglen = bitcoin_sign(coin->ctx,coin->symbol,sig,sigtxid,vp->signers[j].privkey,0); - if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) <= 0 ) + //if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) <= 0 ) bitcoin_pubkey33(coin->ctx,vp->signers[j].pubkey,vp->signers[j].privkey); sig[siglen++] = sighash; vp->signers[j].siglen = siglen; @@ -1275,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); @@ -1378,7 +1379,7 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf extraspace = malloc(extralen); memset(msgtx,0,sizeof(*msgtx)); decode_hex(serialized,len,rawtx); - //printf("call hex2json.(%s) vins.(%s)\n",rawtx,jprint(vins,0)); + // printf("call hex2json.(%s) vins.(%s)\n",rawtx,jprint(vins,0)); if ( (txobj= bitcoin_hex2json(coin,height,&txid,msgtx,rawtx,extraspace,extralen,serialized4,vins,V->suppress_pubkeys)) != 0 ) { //printf("back from bitcoin_hex2json (%s)\n",jprint(vins,0)); @@ -1476,12 +1477,12 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf //printf("finalized.%d\n",finalized); if ( (complete= bitcoin_verifyvins(coin,height,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys)) > 0 && signedtx != 0 ) { - int32_t tmp; char str[65]; + int32_t tmp; //char str[65]; if ( (tmp= iguana_interpreter(coin,0,iguana_lockval(finalized,jint(txobj,"locktime")),V,numinputs)) < 0 ) { printf("iguana_interpreter %d error.(%s)\n",tmp,signedtx); complete = 0; - } else printf("%s signed\n",bits256_str(str,*signedtxidp)); + } //else printf("%s signed\n",bits256_str(str,*signedtxidp)); } else printf("complete.%d\n",complete); } else printf("rwmsgtx error\n"); } else fprintf(stderr,"no inputs in vins.(%s)\n",vins!=0?jprint(vins,0):"null"); diff --git a/iguana/iguana_tx.c b/iguana/iguana_tx.c index e096ab1bb..ac6346fc8 100755 --- a/iguana/iguana_tx.c +++ b/iguana/iguana_tx.c @@ -27,7 +27,7 @@ int32_t iguana_scriptdata(struct iguana_info *coin,uint8_t *scriptspace,uint64_t int32_t iguana_scriptdata(struct iguana_info *coin, uint8_t *scriptspace, long fileptr[2], char *fname, uint64_t scriptpos, int32_t scriptlen) #endif { - FILE *fp; long err; int32_t retval = scriptlen; + FILE *fp; long err; uint8_t *ptr; int32_t i,retval = scriptlen; #ifndef __PNACL__ if ( scriptpos < 0xffffffff ) { @@ -41,7 +41,10 @@ int32_t iguana_scriptdata(struct iguana_info *coin, uint8_t *scriptspace, long f { if ( (scriptpos + scriptlen) <= fileptr[1] ) { - memcpy(scriptspace,(void *)(fileptr[0] + (uint32_t)scriptpos),scriptlen); + ptr = (void *)(fileptr[0] + (uint32_t)scriptpos); + //memcpy(scriptspace,ptr,scriptlen); + for (i=0; ihdrsi,bundlei,bits256_str(str,checktxid),bits256_str(str2,T.txid)); } diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 6534c2431..2974c300f 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -1896,7 +1896,10 @@ INT_ARRAY_STRING(iguana,dividends,height,vals,symbol) { sprintf(buf,"%s %s %.8f %s",prefix,field,dstr(val),suffix); if ( execflag != 0 ) - system(buf); + { + if ( system(buf) != 0 ) + printf("error system.(%s)\n",buf); + } else printf("%s\n",buf); emit += val; } else dustsum += val; diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index c73259f29..e125aea2a 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -910,6 +910,9 @@ void iguana_walletlock(struct supernet_info *myinfo,struct iguana_info *coin) memset(&myinfo->persistent_priv,0,sizeof(myinfo->persistent_priv)); memset(&myinfo->persistent_pubkey33,0,sizeof(myinfo->persistent_pubkey33)); memset(myinfo->secret,0,sizeof(myinfo->secret)); + memset(myinfo->jumblr_passphrase,0,sizeof(myinfo->jumblr_passphrase)); + memset(&myinfo->jumblr_depositkey,0,sizeof(myinfo->jumblr_depositkey)); + memset(&myinfo->jumblr_pubkey,0,sizeof(myinfo->jumblr_pubkey)); memset(myinfo->permanentfile,0,sizeof(myinfo->permanentfile)); if ( myinfo->decryptstr != 0 ) scrubfree(myinfo->decryptstr), myinfo->decryptstr = 0; @@ -1355,6 +1358,8 @@ TWOSTRINGS_AND_INT(bitcoinrpc,walletpassphrase,password,permanentfile,timeout) strcpy(myinfo->password,password); if ( permanentfile != 0 ) strcpy(myinfo->permanentfile,permanentfile); + if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password)) != 0 ) + free(retstr); retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password); myinfo->expiration = (uint32_t)time(NULL) + timeout; iguana_walletinitcheck(myinfo,coin); @@ -1369,9 +1374,16 @@ TWOSTRINGS_AND_INT(bitcoinrpc,walletpassphrase,password,permanentfile,timeout) } } if ( bits256_nonz(myinfo->persistent_priv) != 0 ) - smartaddress_add(myinfo,myinfo->persistent_priv,"",""); - - //basilisk_unspents_update(myinfo,coin); + { + char *jumblrstr,jumblr_passphrase[1024],coinaddr[64],KMDaddr[64]; bits256 privkey; + sprintf(jumblr_passphrase,"jumblr %s",password); + if ( (jumblrstr= jumblr_setpassphrase(myinfo,0,0,0,jumblr_passphrase)) != 0 ) + free(jumblrstr); + privkey = jumblr_privkey(myinfo,coinaddr,0,KMDaddr,"kmd "); + smartaddress_add(myinfo,privkey,"kmd","BTC",0.,0.); + privkey = jumblr_privkey(myinfo,coinaddr,0,KMDaddr,"btc "); + smartaddress_add(myinfo,privkey,"btc","KMD",0.,0.); + } return(retstr); } @@ -1419,6 +1431,13 @@ THREE_STRINGS(bitcoinrpc,encryptwallet,passphrase,password,permanentfile) bitcoin_priv2wif(wifstr,waddr.privkey,coin->chain->wiftype); jaddstr(retjson,"KMDwif",wifstr); } + if ( (coin= iguana_coinfind("LTC")) != 0 ) + { + bitcoin_priv2wif(wifstr,waddr.privkey,coin->chain->wiftype); + jaddstr(retjson,"LTCwif",wifstr); + bitcoin_priv2wiflong(wifstr,waddr.privkey,coin->chain->wiftype); + jaddstr(retjson,"LTCwiflong",wifstr); + } if ( need_BTC != 0 ) { bitcoin_priv2wif(wifstr,waddr.privkey,128); diff --git a/iguana/kmd_lookup.h b/iguana/kmd_lookup.h index f3abf52d2..61f7f60b0 100755 --- a/iguana/kmd_lookup.h +++ b/iguana/kmd_lookup.h @@ -16,7 +16,7 @@ #ifndef INCLUDE_KMDLOOKUP_H #define INCLUDE_KMDLOOKUP_H -#define KMD_EXPLORER_LAG 3 +#define KMD_EXPLORER_LAG 6 struct kmd_voutinfo { @@ -117,7 +117,7 @@ int32_t kmd_transactionvin(struct iguana_info *coin,bits256 spendtxid,int32_t vi } return(0); } - char str[65]; printf("vin error %s vout.%d of %d vs ptr %p [%d] spent.%p\n",bits256_str(str,txid),vout,ptr!=0?ptr->numvouts:-1,ptr,ptr!=0?ptr->numvouts:-1,spendptr); + char str[65]; printf("%s.vin error %s vout.%d of %d vs ptr %p [%d] spent.%p\n",coin->symbol,bits256_str(str,txid),vout,ptr!=0?ptr->numvouts:-1,ptr,ptr!=0?ptr->numvouts:-1,spendptr); return(-1); } @@ -309,6 +309,7 @@ cJSON *kmd_unspentjson(struct supernet_info *myinfo,struct iguana_info *coin,int { char *script; cJSON *sobj,*txout,*item = cJSON_CreateObject(); jaddstr(item,"type","received"); + jaddnum(item,"confirmations",height - tx->height); jaddnum(item,"height",tx->height); jaddnum(item,"timestamp",tx->timestamp); jaddbits256(item,"txid",tx->txid); @@ -637,7 +638,10 @@ int32_t _kmd_bitcoinscan(struct iguana_info *coin) } height = kmd_height(coin); loadheight = coin->kmd_height+1; - lag = (strcmp(coin->symbol,"KMD") == 0 ? KMD_EXPLORER_LAG : 1); + //if ( strcmp(coin->symbol,"LTC") == 0 ) + // lag = 3; + //else + lag = (strcmp(coin->symbol,"KMD") == 0 ? KMD_EXPLORER_LAG : 2); while ( loadheight < height-lag ) { flag = 0; @@ -694,13 +698,16 @@ int32_t _kmd_bitcoinscan(struct iguana_info *coin) { bitcoin_addr2rmd160(&type_rmd160[0],&type_rmd160[1],jstri(addresses,0)); kmd_transactionvout(coin,ptr,j,jdouble(vout,"value")*SATOSHIDEN,type_rmd160,zero,-1); + //fprintf(stderr,"%.8f ",jdouble(vout,"value")); } // else printf("missing sobj.%p or addresses.%p (%s)\n",sobj,addresses,jprint(vout,0)); //likely OP_RETURN sobj = addresses = 0; } + //fprintf(stderr,"numvouts.%d ht.%d %s\n",numvouts,height,coin->symbol); if ( coin->kmd_txidfp != 0 ) { ptr->fpos = ftell(coin->kmd_txidfp); fwrite(tx,1,sizeof(*tx) + tx->numvouts*sizeof(*tx->vouts),coin->kmd_txidfp); + fflush(coin->kmd_txidfp); } } else @@ -709,6 +716,7 @@ int32_t _kmd_bitcoinscan(struct iguana_info *coin) { fwrite(&txid,1,sizeof(txid),coin->kmd_spendfp); fwrite(&numvins,1,sizeof(numvins),coin->kmd_spendfp); + fflush(coin->kmd_spendfp); } for (j=0; jkmd_spendfp); fwrite(&spentvout,1,sizeof(spentvout),coin->kmd_spendfp); + fflush(coin->kmd_spendfp); } } } @@ -741,7 +750,7 @@ int32_t _kmd_bitcoinscan(struct iguana_info *coin) } free_json(blockjson); } - if ( flag != 0 || num > 500 ) + if ( flag != 0 || num > 100 ) break; coin->kmd_height = loadheight++; } @@ -763,7 +772,7 @@ void kmd_bitcoinscan() { //if ( strcmp("KMD",coin->symbol) == 0 ) _kmd_bitcoinscan(coin); - usleep(250000); + sleep(1); } } } diff --git a/iguana/m_LP b/iguana/m_LP index d09ee9373..0e1135b48 100755 --- a/iguana/m_LP +++ b/iguana/m_LP @@ -4,6 +4,6 @@ rm -f ../agents/iguana *.o git pull cd secp256k1; ./m_unix; cd .. cd ../crypto777; ./m_LP; cd ../iguana -clang -g -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c -clang -g -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c -clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a /usr/local/lib/libnanomsg.so -lcurl -lssl -lcrypto -lpthread -lz -lm +gcc -g -Wno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +gcc -g -Wno-aggressive-loop-optimizations -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a /usr/local/lib/libnanomsg.so -lcurl -lssl -lcrypto -lpthread -lz -lm 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_LP_win_cross b/iguana/m_LP_win_cross new file mode 100755 index 000000000..725726fb8 --- /dev/null +++ b/iguana/m_LP_win_cross @@ -0,0 +1,9 @@ +#!/bin/bash +#./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery +rm -f ../agents/iguana *.o +git pull +cd secp256k1; ./m_win_cross; cd .. +cd ../crypto777; ./m_LP_win_cross; cd ../iguana +i686-w64-mingw32-gcc -w -static-libgcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c -L../win_lib/lib -I../win_lib/include -lcurl -lws2_32 +i686-w64-mingw32-gcc -w -static-libgcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c -L../win_lib/lib -I../win_lib/include -lcurl -lws2_32 +i686-w64-mingw32-gcc -w -DWIN32 -static-libgcc -g -o ../agents/iguana.exe *.o ../agents/libcrypto777.a secp256k1.a -static-libgcc -DPTW32_STATIC_LIB -lm -DCURL_STATICLIB -lpthread -L../win_lib/lib -I../win_lib/include -lcurl -I../nanomsg/include -L../nanomsg/lib -lnanomsg -I../iguana -I../includes -I../crypto777 -lws2_32 -lsetupapi diff --git a/iguana/m_mm b/iguana/m_mm index 539000f40..b5ba405ca 100755 --- a/iguana/m_mm +++ b/iguana/m_mm @@ -1 +1,3 @@ -gcc -o marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c ../agents/libcrypto777.a -lcurl -lpthread -lm +cd secp256k1; ./m_unix; cd .. +cd ../crypto777; ./m_LP; cd ../iguana +gcc -g -o marketmaker -I../crypto777 exchanges/mm.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm diff --git a/iguana/m_mm_StaticNanoMsg b/iguana/m_mm_StaticNanoMsg new file mode 100755 index 000000000..cab8ae51b --- /dev/null +++ b/iguana/m_mm_StaticNanoMsg @@ -0,0 +1,28 @@ +# makefile for marketmaker uses static nanomsg +# author: fadedreamz@SuperNet.org +# date: Aug, 2017 + +LIB_ARCH=$(uname -m) + +.PHONY: clean all + +err: + @echo "no rule specified, use {clean,all}" + exit 1 + +clean: + - rm -f ../agents/iguana *.o + - rm ../agents/marketmaker + +all: + @echo "Add -j(core count + 1) to speed up build - e,g make -j5 -f m_mm_StaticNanoMsg; on a quad core cpu" + +$(MAKE) -C secp256k1 -f m_unix_Makefile all + +$(MAKE) -C ../crypto777 -f m_LP_StaticNanoMsg all + +$(MAKE) -C ../crypto777 -f m_LP_StaticNanoMsg clean + $(CC) -o ../agents/marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a ../OSlibs/linux/$(shell uname -m)/libnanomsg-static.a -lcurl -lpthread -lm -lanl + @echo "===========================" + @echo " marketmaker -> `pwd`/../agents/marketmaker" + @echo "===========================" + + + diff --git a/iguana/m_mm_win_cross b/iguana/m_mm_win_cross new file mode 100755 index 000000000..fd645c0aa --- /dev/null +++ b/iguana/m_mm_win_cross @@ -0,0 +1,3 @@ +cd secp256k1; ./m_win_cross; cd .. +i686-w64-mingw32-gcc -w -DWIN32 -static-libgcc -g -o marketmaker.exe -I../crypto777 exchanges/mm.c mini-gmp.c secp256k1.a ../agents/libcrypto777.a -static-libgcc -DPTW32_STATIC_LIB -lm -DCURL_STATICLIB -lpthread -L../win_lib/lib -I../win_lib/include -lcurl -I../nanomsg/include -L../nanomsg/lib -lnanomsg -I../iguana -I../includes -I../crypto777 -lws2_32 -lsetupapi + diff --git a/iguana/m_notary b/iguana/m_notary index a1df17e7e..d2c82c7c0 100755 --- a/iguana/m_notary +++ b/iguana/m_notary @@ -1,5 +1,5 @@ #!/bin/bash -pkill iguana +pkill -15 iguana rm -f ../agents/iguana *.o git pull cd secp256k1; ./m_unix; cd .. @@ -20,6 +20,7 @@ curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"SuperNET\",\"method\":\" sleep 3 tests/addnotarys_7776 coins/btc_7776 +coins/ltc_7776 coins/kmd_7776 ./wp_7776 @@ -34,8 +35,9 @@ coins/jumblr_7776 coins/crypto_7776 coins/pangea_7776 coins/mgw_7776 -coins/mvp_7776 -coins/wireless_7776 +#coins/mvp_7776 +coins/coqui_7776 +coins/wlc_7776 coins/kv_7776 coins/ceal_7776 coins/mesh_7776 diff --git a/iguana/m_osx b/iguana/m_osx index 500053d38..b7a296285 100755 --- a/iguana/m_osx +++ b/iguana/m_osx @@ -3,6 +3,7 @@ rm ../agents/iguana *.o git pull cd secp256k1; ./m_unix; cd .. +cd ../crypto777; ./m_unix; cd ../iguana gcc -g -Wno-address-of-packed-member -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c -gcc -g -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +gcc -g -Wno-address-of-packed-member -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm diff --git a/iguana/m_osx_release b/iguana/m_osx_release index 19c94d74b..5f74885e7 100755 --- a/iguana/m_osx_release +++ b/iguana/m_osx_release @@ -3,6 +3,6 @@ rm ../agents/iguana *.o git pull cd secp256k1; ./m_osx_release; cd .. -gcc -g -mmacosx-version-min=10.6 -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c -gcc -g -mmacosx-version-min=10.6 -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c -gcc -g -mmacosx-version-min=10.6 /usr/local/lib/libnanomsg.5.0.0.dylib -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lz -lm +clang -g -mmacosx-version-min=10.6 -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +clang -g -mmacosx-version-min=10.6 -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +clang -g -mmacosx-version-min=10.6 /usr/local/lib/libnanomsg.5.0.0.dylib -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lz -lm diff --git a/iguana/m_splitfund b/iguana/m_splitfund new file mode 100755 index 000000000..dbaf4cb51 --- /dev/null +++ b/iguana/m_splitfund @@ -0,0 +1,58 @@ +#!/bin/bash + +set -x + +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BTC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KMD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" + +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"REVS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SUPERNET\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DEX\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PANGEA\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JUMBLR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BET\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CRYPTO\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HODL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SHARK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BOTS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MGW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MVP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"COQUI\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"WLC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KV\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CEAL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MESH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" + +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"USD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"EUR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" + +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JPY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"GBP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"AUD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CAD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CHF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NZD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CNY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RUB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MXN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BRL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"INR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HKD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"TRY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ZAR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PLN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NOK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SEK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DKK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CZK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HUF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ILS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KRW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MYR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PHP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RON\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SGD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"THB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BGN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"IDR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HRK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" diff --git a/iguana/m_stats b/iguana/m_stats new file mode 100755 index 000000000..9fface988 --- /dev/null +++ b/iguana/m_stats @@ -0,0 +1 @@ +gcc -g -o DEXstats -I../crypto777 exchanges/stats.c ../crypto777/cJSON.c ../agents/libcrypto777.a -lcurl -lpthread -lm diff --git a/iguana/m_test b/iguana/m_test index 702cbb33e..8bf7b041b 100755 --- a/iguana/m_test +++ b/iguana/m_test @@ -1,28 +1,10 @@ #!/bin/bash -pkill iguana +TESTIPADDR=\"78.47.196.146\" +#./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery rm -f ../agents/iguana *.o git pull cd secp256k1; ./m_unix; cd .. cd ../crypto777; ./m_LP; cd ../iguana -gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c -gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c -gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm - -../agents/iguana notary & #> iguana.log 2> error.log & - -myip=`curl -s4 checkip.amazonaws.com` -source pubkey.txt - -coins/kmd_7776 -coins/revs_7776 -sleep 4 -curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"$myip\"}" -sleep 3 - -curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"$myip\"}" -curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"78.47.196.146\"}" -#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"5.9.102.210\"}" -#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"89.248.160.237\"}" -#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"89.248.160.238\"}" -./wp_7776 -curl --url "http://127.0.0.1:7776" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"REVS\",\"pubkey\":\"$pubkey\"}" +gcc -DNOTARY_TESTMODE=$TESTIPADDR -g -Wno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +gcc -DNOTARY_TESTMODE=$TESTIPADDR -g -Wno-aggressive-loop-optimizations -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a /usr/local/lib/libnanomsg.so -lcurl -lssl -lcrypto -lpthread -lz -lm diff --git a/iguana/main.c b/iguana/main.c index 984f2c27a..335d68baa 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -290,7 +290,7 @@ char *SuperNET_processJSON(struct supernet_info *myinfo,struct iguana_info *coin }*/ jsonstr = jprint(json,0); //printf("RPC? (%s)\n",jsonstr); - if ( (immedmillis= juint(json,"immediate")) != 0 || ((remoteaddr == 0 || remoteaddr[0] == 0) && port == IGUANA_RPCPORT) ) + if ( (immedmillis= juint(json,"immediate")) != 0 || ((remoteaddr == 0 || remoteaddr[0] == 0) && port == myinfo->rpcport) ) { if ( coin != 0 ) { @@ -749,22 +749,26 @@ void iguana_urlinit(struct supernet_info *myinfo,int32_t ismainnet,int32_t usess void jumblr_loop(void *ptr) { - struct iguana_info *coin; char BTCaddr[64],KMDaddr[64]; bits256 privkey; uint32_t t; struct supernet_info *myinfo = ptr; int32_t mult = 10; + struct iguana_info *coin; uint32_t t,n=0; struct supernet_info *myinfo = ptr; int32_t mult = 10; printf("JUMBLR loop\n"); - while ( 1 ) + while ( myinfo->IAMNOTARY == 0 ) { - if ( (coin= iguana_coinfind("KMD")) != 0 && coin->FULLNODE < 0 ) + if ( (coin= iguana_coinfind("KMD")) != 0 ) { - privkey = jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); - // if BTC has arrived in deposit address, invoke DEX -> KMD - // if BTC has arrived in destination address, invoke DEX -> BTC - jumblr_DEXcheck(myinfo,coin,BTCaddr,KMDaddr,privkey); - t = (uint32_t)time(NULL); - if ( myinfo->jumblr_passphrase[0] != 0 && (t % (120 * mult)) < 60 ) + n++; + if ( (n % 3) == 0 ) + smartaddress_update(myinfo,(n/3) & 1); + if ( myinfo->jumblr_passphrase[0] != 0 && coin->FULLNODE < 0 ) { - jumblr_iteration(myinfo,coin,(t % (360 * mult)) / (120 * mult),t % (120 * mult)); + // if BTC has arrived in destination address, invoke DEX -> BTC + t = (uint32_t)time(NULL); + if ( (t % (120 * mult)) < 60 ) + { + // if BTC has arrived in deposit address, invoke DEX -> KMD + jumblr_iteration(myinfo,coin,(t % (360 * mult)) / (120 * mult),t % (120 * mult)); + } + //printf("t.%u %p.%d %s\n",t,coin,coin!=0?coin->FULLNODE:0,myinfo->jumblr_passphrase); } - //printf("t.%u %p.%d %s\n",t,coin,coin!=0?coin->FULLNODE:0,myinfo->jumblr_passphrase); } sleep(55); } @@ -1812,14 +1816,14 @@ STRING_ARG(SuperNET,wif2priv,wif) return(jprint(retjson,1)); } -STRING_ARG(SuperNET,priv2wif,priv) +STRING_AND_INT(SuperNET,priv2wif,priv,wiftype) { - bits256 privkey; char wifstr[65]; uint8_t wiftype; cJSON *retjson = cJSON_CreateObject(); + bits256 privkey; char wifstr[65]; cJSON *retjson = cJSON_CreateObject(); if ( is_hexstr(priv,0) == sizeof(bits256)*2 ) { - wiftype = coin != 0 ? coin->chain->wiftype : 0x80; + //wiftype = coin != 0 ? coin->chain->wiftype : 0x80; decode_hex(privkey.bytes,sizeof(privkey),priv); - if ( bitcoin_priv2wif(wifstr,privkey,wiftype) > 0 ) + if ( bitcoin_priv2wif(wifstr,privkey,wiftype&0xff) > 0 ) { jaddstr(retjson,"result","success"); jaddstr(retjson,"privkey",priv); @@ -1909,10 +1913,10 @@ ZERO_ARGS(SuperNET,activehandle) } else jaddstr(retjson,"status","locked"); if ( myinfo->jumblr_passphrase[0] != 0 ) { - jumblr_privkey(myinfo,BTCaddr,KMDaddr,JUMBLR_DEPOSITPREFIX); + jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,JUMBLR_DEPOSITPREFIX); jaddstr(retjson,"BTCdeposit","notyet"); jaddstr(retjson,"KMDdeposit",KMDaddr); - jumblr_privkey(myinfo,BTCaddr,KMDaddr,""); + jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,""); jaddstr(retjson,"BTCjumblr","notyet"); jaddstr(retjson,"KMDjumblr",KMDaddr); } @@ -2051,7 +2055,9 @@ FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase) void komodo_ICO_batch(cJSON *array,int32_t batchid) { - int32_t i,n,iter; cJSON *item; uint64_t kmdamount,revsamount; char *coinaddr,cmd[512]; double totalKMD,totalREVS; + int32_t i,n,iter; cJSON *item; uint64_t kmdamount,revsamount; char *coinaddr,cmd[512]; double totalKMD,totalREVS; struct supernet_info *myinfo = SuperNET_MYINFO(0); + if ( myinfo->rpcport == 0 ) + myinfo->rpcport = 7778; if ( (n= cJSON_GetArraySize(array)) > 0 ) { totalKMD = totalREVS = 0; @@ -2070,7 +2076,7 @@ void komodo_ICO_batch(cJSON *array,int32_t batchid) { if ( dstr(revsamount) >= 1. && (iter & 1) == 0 ) { - printf("curl --url \"http://127.0.0.1:7778\" --data \"{\\\"agent\\\":\\\"dex\\\",\\\"method\\\":\\\"importaddress\\\",\\\"address\\\":\\\"%s\\\",\\\"symbol\\\":\\\"REVS\\\"}\" # %.8f\n",coinaddr,dstr(revsamount)); + printf("curl --url \"http://127.0.0.1:%u\" --data \"{\\\"agent\\\":\\\"dex\\\",\\\"method\\\":\\\"importaddress\\\",\\\"address\\\":\\\"%s\\\",\\\"symbol\\\":\\\"REVS\\\"}\" # %.8f\n",myinfo->rpcport,coinaddr,dstr(revsamount)); printf("sleep 3\n"); } else printf("sleep 1\n"); if ( (iter & 1) != 0 ) @@ -2093,9 +2099,9 @@ void komodo_ICO_batch(cJSON *array,int32_t batchid) { if ( (0) ) { - printf("curl --url \"http://127.0.0.1:7778\" --data \"{\\\"agent\\\":\\\"dex\\\",\\\"method\\\":\\\"importaddress\\\",\\\"address\\\":\\\"%s\\\",\\\"symbol\\\":\\\"KMD\\\"}\" # %.8f\n",coinaddr,dstr(kmdamount)); + printf("curl --url \"http://127.0.0.1:%u\" --data \"{\\\"agent\\\":\\\"dex\\\",\\\"method\\\":\\\"importaddress\\\",\\\"address\\\":\\\"%s\\\",\\\"symbol\\\":\\\"KMD\\\"}\" # %.8f\n",myinfo->rpcport,coinaddr,dstr(kmdamount)); printf("sleep 3\n"); - } else printf("curl --url \"http://127.0.0.1:7778\" --data \"{\\\"agent\\\":\\\"dex\\\",\\\"method\\\":\\\"listunspent\\\",\\\"address\\\":\\\"%s\\\",\\\"symbol\\\":\\\"KMD\\\"}\"\n",coinaddr); + } else printf("curl --url \"http://127.0.0.1:%u\" --data \"{\\\"agent\\\":\\\"dex\\\",\\\"method\\\":\\\"listunspent\\\",\\\"address\\\":\\\"%s\\\",\\\"symbol\\\":\\\"KMD\\\"}\"\n",myinfo->rpcport,coinaddr); } else { @@ -2114,7 +2120,7 @@ void komodo_ICO_batch(cJSON *array,int32_t batchid) void komodo_REVS_merge(char *str,char *str2) { - char line[1024],line2[1024],*coinaddr; int32_t i,n=0,m=0,k=0; + char line[1024],line2[1024],*coinaddr; int32_t i,n=0,m=0,k=0; struct supernet_info *myinfo = SuperNET_MYINFO(0); while ( 1 ) { if ( str[n] == 0 || str2[m] == 0 ) @@ -2136,7 +2142,7 @@ void komodo_REVS_merge(char *str,char *str2) coinaddr[i] = 0; if ( atof(&coinaddr[i+1]) > 1 ) { - printf("curl --url \"http://127.0.0.1:7778\" --data \"{\\\"agent\\\":\\\"dex\\\",\\\"method\\\":\\\"importaddress\\\",\\\"address\\\":\\\"%s\\\",\\\"symbol\\\":\\\"REVS\\\"}\" # %.8f\n",coinaddr,atof(coinaddr+i+1)); + printf("curl --url \"http://127.0.0.1:%u\" --data \"{\\\"agent\\\":\\\"dex\\\",\\\"method\\\":\\\"importaddress\\\",\\\"address\\\":\\\"%s\\\",\\\"symbol\\\":\\\"REVS\\\"}\" # %.8f\n",myinfo->rpcport,coinaddr,atof(coinaddr+i+1)); printf("sleep 3\n"); } k++; @@ -2155,7 +2161,7 @@ void iguana_main(void *arg) else printf("ENDIAN ERROR\n"); mycalloc(0,0,0); #ifdef __APPLE__ - char *batchstr,*batchstr2; cJSON *batchjson; long batchsize; char fname[512],fname2[512]; int32_t batchid = 14; + char *batchstr,*batchstr2; cJSON *batchjson; long batchsize; char fname[512],fname2[512]; int32_t batchid = 18; sprintf(fname,"REVS.raw"), sprintf(fname2,"REVS.rawtxids"); if ( (0) && (batchstr= OS_filestr(&batchsize,fname)) != 0 && (batchstr2= OS_filestr(&batchsize,fname2)) != 0 ) { @@ -2172,13 +2178,13 @@ void iguana_main(void *arg) free(batchstr); } #endif + myinfo = SuperNET_MYINFO(0); + myinfo->rpcport = IGUANA_RPCPORT; decode_hex(CRYPTO777_RMD160,20,CRYPTO777_RMD160STR); decode_hex(CRYPTO777_PUBSECP33,33,CRYPTO777_PUBSECPSTR); iguana_ensuredirs(); iguana_Qinit(); - myinfo = SuperNET_MYINFO(0); libgfshare_init(myinfo,myinfo->logs,myinfo->exps); - myinfo->rpcport = IGUANA_RPCPORT; myinfo->dpowsock = myinfo->dexsock = myinfo->pubsock = myinfo->subsock = myinfo->reqsock = myinfo->repsock = -1; dex_init(myinfo); myinfo->psockport = 30000; @@ -2192,6 +2198,11 @@ void iguana_main(void *arg) myinfo->IAMNOTARY = 1; myinfo->DEXEXPLORER = 1; } + else if ( strncmp((char *)arg,"-port=",6) == 0 ) + { + myinfo->rpcport = atoi(&((char *)arg)[6]); + printf("OVERRIDE IGUANA port <- %u\n",myinfo->rpcport); + } } #ifdef IGUANA_OSTESTS do_OStests = 1; diff --git a/iguana/mini-gmp.c b/iguana/mini-gmp.c index ef9e235df..c2c975f12 100644 --- a/iguana/mini-gmp.c +++ b/iguana/mini-gmp.c @@ -4394,7 +4394,7 @@ int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr) //memset(data,0,be_sz); //for (i=0; i lastdayupdate + 60000*60 ) { lastdayupdate = milliseconds(); + printf("call ecb_matrix.(%s)\n",dp->edate); if ( (datenum= ecb_matrix(dp->ecbmatrix,dp->edate)) > 0 ) { dp->ecbdatenum = datenum; diff --git a/iguana/pangea777.h b/iguana/pangea777.h index 731531f84..1ff471e3a 100755 --- a/iguana/pangea777.h +++ b/iguana/pangea777.h @@ -128,7 +128,7 @@ struct pangea_msghdr char cmd[8]; int8_t turni,cardi,destplayer,myind; // ALL DATA MUST BE SERIALIZED!!! uint8_t serialized[]; -} PACKED; +};// PACKED; #define PANGEA_ARGS struct supernet_info *myinfo,struct table_info *tp,cJSON *json #define PANGEA_CALLARGS myinfo,tp,json diff --git a/iguana/secp256k1/m_unix_Makefile b/iguana/secp256k1/m_unix_Makefile new file mode 100644 index 000000000..9457ed849 --- /dev/null +++ b/iguana/secp256k1/m_unix_Makefile @@ -0,0 +1,7 @@ +# author: fadedreamz@SuperNet.org +# date: August, 2017 + +all: + gcc -c -o ../secp256k1.o -I. -I./src -I./include -I./src -O3 -W -std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden -DHAVE_CONFIG_H src/secp256k1.c + +.PHONY: all diff --git a/iguana/secp256k1/m_win_cross b/iguana/secp256k1/m_win_cross new file mode 100755 index 000000000..faa4d340b --- /dev/null +++ b/iguana/secp256k1/m_win_cross @@ -0,0 +1 @@ +i686-w64-mingw32-gcc -c -o ../secp256k1.a -I. -I./src -I./include -I./src -O3 -W -std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden -DHAVE_CONFIG_H src/secp256k1.c diff --git a/iguana/tests/DEXratio b/iguana/tests/DEXratio new file mode 100755 index 000000000..09365cc85 --- /dev/null +++ b/iguana/tests/DEXratio @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"ratio\":0.97,\"agent\":\"InstantDEX\",\"method\":\"DEXratio\"}" diff --git a/iguana/tests/KMD.batch13 b/iguana/tests/KMD.batch13 index f2764fafe..0d9373fc4 100755 --- a/iguana/tests/KMD.batch13 +++ b/iguana/tests/KMD.batch13 @@ -1,3 +1,4 @@ +sleep 999999 # RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 KMD 341.29719958 ./komodo-cli sendtoaddress RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 341.29719958 sleep 3 diff --git a/iguana/tests/KMD.batch14 b/iguana/tests/KMD.batch14 new file mode 100755 index 000000000..5b3f4d6fa --- /dev/null +++ b/iguana/tests/KMD.batch14 @@ -0,0 +1,146 @@ +sleep 999999 +# RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj KMD 283716.36806687 +./komodo-cli sendtoaddress RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj 283716.36806687 +sleep 3 +echo "283716.36806687 <- expected amount RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 232.80643392 +./komodo-cli sendtoaddress RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ 232.80643392 +sleep 3 +echo "232.80643392 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 2247.65412987 +./komodo-cli sendtoaddress RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni 2247.65412987 +sleep 3 +echo "2247.65412987 <- expected amount RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 202518.10752377 +./komodo-cli sendtoaddress RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB 202518.10752377 +sleep 3 +echo "202518.10752377 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RBQyRBW6RFhcAmoK6UhoqrTgjH3Gz1xdCc KMD 9837.11461840 +./komodo-cli sendtoaddress RBQyRBW6RFhcAmoK6UhoqrTgjH3Gz1xdCc 9837.11461840 +sleep 3 +echo "9837.11461840 <- expected amount RBQyRBW6RFhcAmoK6UhoqrTgjH3Gz1xdCc" + +# RDeUhHeM6kaaMg9bNJQDjXrqimqZSeVTqb KMD 6.87037888 +./komodo-cli sendtoaddress RDeUhHeM6kaaMg9bNJQDjXrqimqZSeVTqb 6.87037888 +sleep 3 +echo "6.87037888 <- expected amount RDeUhHeM6kaaMg9bNJQDjXrqimqZSeVTqb" + +# RY43geE3zoc88VbhnExje4J1wCNvX8fvfi KMD 601.90475901 +./komodo-cli sendtoaddress RY43geE3zoc88VbhnExje4J1wCNvX8fvfi 601.90475901 +sleep 3 +echo "601.90475901 <- expected amount RY43geE3zoc88VbhnExje4J1wCNvX8fvfi" + +# RJ5qNTw5sm9AiHX2129dqBQSFETkP9sYFF KMD 40171.99122689 +./komodo-cli sendtoaddress RJ5qNTw5sm9AiHX2129dqBQSFETkP9sYFF 40171.99122689 +sleep 3 +echo "40171.99122689 <- expected amount RJ5qNTw5sm9AiHX2129dqBQSFETkP9sYFF" + +# RKbr67Hs4exDXg92LQhVYY4MSuqwbJJN7z KMD 1465.10673247 +./komodo-cli sendtoaddress RKbr67Hs4exDXg92LQhVYY4MSuqwbJJN7z 1465.10673247 +sleep 3 +echo "1465.10673247 <- expected amount RKbr67Hs4exDXg92LQhVYY4MSuqwbJJN7z" + +# RBjZCbMHCtsqpcQfaQquiNi4s8GTr6uLRZ KMD 20449.88848416 +./komodo-cli sendtoaddress RBjZCbMHCtsqpcQfaQquiNi4s8GTr6uLRZ 20449.88848416 +sleep 3 +echo "20449.88848416 <- expected amount RBjZCbMHCtsqpcQfaQquiNi4s8GTr6uLRZ" + +# RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH KMD 497.55272329 +./komodo-cli sendtoaddress RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH 497.55272329 +sleep 3 +echo "497.55272329 <- expected amount RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 26.76069242 +./komodo-cli sendtoaddress RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 26.76069242 +sleep 3 +echo "26.76069242 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc KMD 2105.68422851, REVS 41.78542648 +# RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc KMD 2105.68422851 +./komodo-cli sendtoaddress RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc 2105.68422851 +sleep 3 +echo "2105.68422851 <- expected amount RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc" + +# RC3h8Y3o5Ak7gdiCJ9GPY7EkB3DKd5hqtG KMD 37.03715216 +./komodo-cli sendtoaddress RC3h8Y3o5Ak7gdiCJ9GPY7EkB3DKd5hqtG 37.03715216 +sleep 3 +echo "37.03715216 <- expected amount RC3h8Y3o5Ak7gdiCJ9GPY7EkB3DKd5hqtG" + +# RPpsBduDnnpgEZnEYKRKv5j1Ubx32c37jW KMD 9295.82639400 +./komodo-cli sendtoaddress RPpsBduDnnpgEZnEYKRKv5j1Ubx32c37jW 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RPpsBduDnnpgEZnEYKRKv5j1Ubx32c37jW" + +# RKWNm893ZmBoTDHZ287LhHfigdMbg1i5pe KMD 56299.80756714 +./komodo-cli sendtoaddress RKWNm893ZmBoTDHZ287LhHfigdMbg1i5pe 56299.80756714 +sleep 3 +echo "56299.80756714 <- expected amount RKWNm893ZmBoTDHZ287LhHfigdMbg1i5pe" + +# RVCsfNnKexhZfyWzYnVnyYqQ181xNaK83r KMD 46479.13197000 +./komodo-cli sendtoaddress RVCsfNnKexhZfyWzYnVnyYqQ181xNaK83r 46479.13197000 +sleep 3 +echo "46479.13197000 <- expected amount RVCsfNnKexhZfyWzYnVnyYqQ181xNaK83r" + +# RGry1cqvb2DpJ8KVJ8UUx2fe3TxLmmPohY KMD 21522.57690952 +./komodo-cli sendtoaddress RGry1cqvb2DpJ8KVJ8UUx2fe3TxLmmPohY 21522.57690952 +sleep 3 +echo "21522.57690952 <- expected amount RGry1cqvb2DpJ8KVJ8UUx2fe3TxLmmPohY" + +# RJaBNff51EwkwTq6BpmLikW3Wx3XFJ4CZR KMD 5510.79545709 +./komodo-cli sendtoaddress RJaBNff51EwkwTq6BpmLikW3Wx3XFJ4CZR 5510.79545709 +sleep 3 +echo "5510.79545709 <- expected amount RJaBNff51EwkwTq6BpmLikW3Wx3XFJ4CZR" + +# RSGZVs6APV5K96tEtuRoMwtc3P7h1SfzQY KMD 38732.60997500 +./komodo-cli sendtoaddress RSGZVs6APV5K96tEtuRoMwtc3P7h1SfzQY 38732.60997500 +sleep 3 +echo "38732.60997500 <- expected amount RSGZVs6APV5K96tEtuRoMwtc3P7h1SfzQY" + +# RGQm8kgDPFCnhB6y6smATMBG8Bq7NPkeKk KMD 1524.15725197 +./komodo-cli sendtoaddress RGQm8kgDPFCnhB6y6smATMBG8Bq7NPkeKk 1524.15725197 +sleep 3 +echo "1524.15725197 <- expected amount RGQm8kgDPFCnhB6y6smATMBG8Bq7NPkeKk" + +# RH6ZPNWW8XS9cm5xsEyngQuARXNtUzGFKw KMD 21460.18988274 +./komodo-cli sendtoaddress RH6ZPNWW8XS9cm5xsEyngQuARXNtUzGFKw 21460.18988274 +sleep 3 +echo "21460.18988274 <- expected amount RH6ZPNWW8XS9cm5xsEyngQuARXNtUzGFKw" + +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 4938.88955074 +./komodo-cli sendtoaddress RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW 4938.88955074 +sleep 3 +echo "4938.88955074 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW" + +# RXoWchjAaJatpRYGoD7A2tEuYN1jhdrRv3 KMD 37183.30557600 +./komodo-cli sendtoaddress RXoWchjAaJatpRYGoD7A2tEuYN1jhdrRv3 37183.30557600 +sleep 3 +echo "37183.30557600 <- expected amount RXoWchjAaJatpRYGoD7A2tEuYN1jhdrRv3" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# R9Kpd7dQ5udE7bUBWvQ5sEiTL3hSr5R2Ck KMD 29783.79369585 +./komodo-cli sendtoaddress R9Kpd7dQ5udE7bUBWvQ5sEiTL3hSr5R2Ck 29783.79369585 +sleep 3 +echo "29783.79369585 <- expected amount R9Kpd7dQ5udE7bUBWvQ5sEiTL3hSr5R2Ck" + +# RHh3vqCrFmZsLUKPxnx4yCcAqZ8RSZ2NW3 KMD 9683.15249375 +./komodo-cli sendtoaddress RHh3vqCrFmZsLUKPxnx4yCcAqZ8RSZ2NW3 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RHh3vqCrFmZsLUKPxnx4yCcAqZ8RSZ2NW3" + +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 4040.77614254 +./komodo-cli sendtoaddress RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK 4040.77614254 +sleep 3 +echo "4040.77614254 <- expected amount RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK" + +# RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 KMD 47536.89479581 +./komodo-cli sendtoaddress RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 47536.89479581 +sleep 3 +echo "47536.89479581 <- expected amount RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9" diff --git a/iguana/tests/KMD.batch14.listunspent b/iguana/tests/KMD.batch14.listunspent new file mode 100755 index 000000000..f64301ab8 --- /dev/null +++ b/iguana/tests/KMD.batch14.listunspent @@ -0,0 +1,117 @@ +# RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj KMD 283716.36806687 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj\",\"symbol\":\"KMD\"}" +echo "283716.36806687 <- expected amount RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 232.80643392 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" +echo "232.80643392 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 2247.65412987 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni\",\"symbol\":\"KMD\"}" +echo "2247.65412987 <- expected amount RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 202518.10752377 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB\",\"symbol\":\"KMD\"}" +echo "202518.10752377 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RBQyRBW6RFhcAmoK6UhoqrTgjH3Gz1xdCc KMD 9837.11461840 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBQyRBW6RFhcAmoK6UhoqrTgjH3Gz1xdCc\",\"symbol\":\"KMD\"}" +echo "9837.11461840 <- expected amount RBQyRBW6RFhcAmoK6UhoqrTgjH3Gz1xdCc" + +# RDeUhHeM6kaaMg9bNJQDjXrqimqZSeVTqb KMD 6.87037888 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDeUhHeM6kaaMg9bNJQDjXrqimqZSeVTqb\",\"symbol\":\"KMD\"}" +echo "6.87037888 <- expected amount RDeUhHeM6kaaMg9bNJQDjXrqimqZSeVTqb" + +# RY43geE3zoc88VbhnExje4J1wCNvX8fvfi KMD 601.90475901 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RY43geE3zoc88VbhnExje4J1wCNvX8fvfi\",\"symbol\":\"KMD\"}" +echo "601.90475901 <- expected amount RY43geE3zoc88VbhnExje4J1wCNvX8fvfi" + +# RJ5qNTw5sm9AiHX2129dqBQSFETkP9sYFF KMD 40171.99122689 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJ5qNTw5sm9AiHX2129dqBQSFETkP9sYFF\",\"symbol\":\"KMD\"}" +echo "40171.99122689 <- expected amount RJ5qNTw5sm9AiHX2129dqBQSFETkP9sYFF" + +# RKbr67Hs4exDXg92LQhVYY4MSuqwbJJN7z KMD 1465.10673247 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKbr67Hs4exDXg92LQhVYY4MSuqwbJJN7z\",\"symbol\":\"KMD\"}" +echo "1465.10673247 <- expected amount RKbr67Hs4exDXg92LQhVYY4MSuqwbJJN7z" + +# RBjZCbMHCtsqpcQfaQquiNi4s8GTr6uLRZ KMD 20449.88848416 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBjZCbMHCtsqpcQfaQquiNi4s8GTr6uLRZ\",\"symbol\":\"KMD\"}" +echo "20449.88848416 <- expected amount RBjZCbMHCtsqpcQfaQquiNi4s8GTr6uLRZ" + +# RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH KMD 497.55272329 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH\",\"symbol\":\"KMD\"}" +echo "497.55272329 <- expected amount RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 26.76069242 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3\",\"symbol\":\"KMD\"}" +echo "26.76069242 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc KMD 2105.68422851, REVS 41.78542648 +# RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc KMD 2105.68422851 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc\",\"symbol\":\"KMD\"}" +echo "2105.68422851 <- expected amount RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc" + +# RC3h8Y3o5Ak7gdiCJ9GPY7EkB3DKd5hqtG KMD 37.03715216 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC3h8Y3o5Ak7gdiCJ9GPY7EkB3DKd5hqtG\",\"symbol\":\"KMD\"}" +echo "37.03715216 <- expected amount RC3h8Y3o5Ak7gdiCJ9GPY7EkB3DKd5hqtG" + +# RPpsBduDnnpgEZnEYKRKv5j1Ubx32c37jW KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPpsBduDnnpgEZnEYKRKv5j1Ubx32c37jW\",\"symbol\":\"KMD\"}" +echo "9295.82639400 <- expected amount RPpsBduDnnpgEZnEYKRKv5j1Ubx32c37jW" + +# RKWNm893ZmBoTDHZ287LhHfigdMbg1i5pe KMD 56299.80756714 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKWNm893ZmBoTDHZ287LhHfigdMbg1i5pe\",\"symbol\":\"KMD\"}" +echo "56299.80756714 <- expected amount RKWNm893ZmBoTDHZ287LhHfigdMbg1i5pe" + +# RVCsfNnKexhZfyWzYnVnyYqQ181xNaK83r KMD 46479.13197000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVCsfNnKexhZfyWzYnVnyYqQ181xNaK83r\",\"symbol\":\"KMD\"}" +echo "46479.13197000 <- expected amount RVCsfNnKexhZfyWzYnVnyYqQ181xNaK83r" + +# RGry1cqvb2DpJ8KVJ8UUx2fe3TxLmmPohY KMD 21522.57690952 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGry1cqvb2DpJ8KVJ8UUx2fe3TxLmmPohY\",\"symbol\":\"KMD\"}" +echo "21522.57690952 <- expected amount RGry1cqvb2DpJ8KVJ8UUx2fe3TxLmmPohY" + +# RJaBNff51EwkwTq6BpmLikW3Wx3XFJ4CZR KMD 5510.79545709 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJaBNff51EwkwTq6BpmLikW3Wx3XFJ4CZR\",\"symbol\":\"KMD\"}" +echo "5510.79545709 <- expected amount RJaBNff51EwkwTq6BpmLikW3Wx3XFJ4CZR" + +# RSGZVs6APV5K96tEtuRoMwtc3P7h1SfzQY KMD 38732.60997500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSGZVs6APV5K96tEtuRoMwtc3P7h1SfzQY\",\"symbol\":\"KMD\"}" +echo "38732.60997500 <- expected amount RSGZVs6APV5K96tEtuRoMwtc3P7h1SfzQY" + +# RGQm8kgDPFCnhB6y6smATMBG8Bq7NPkeKk KMD 1524.15725197 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGQm8kgDPFCnhB6y6smATMBG8Bq7NPkeKk\",\"symbol\":\"KMD\"}" +echo "1524.15725197 <- expected amount RGQm8kgDPFCnhB6y6smATMBG8Bq7NPkeKk" + +# RH6ZPNWW8XS9cm5xsEyngQuARXNtUzGFKw KMD 21460.18988274 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH6ZPNWW8XS9cm5xsEyngQuARXNtUzGFKw\",\"symbol\":\"KMD\"}" +echo "21460.18988274 <- expected amount RH6ZPNWW8XS9cm5xsEyngQuARXNtUzGFKw" + +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 4938.88955074 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW\",\"symbol\":\"KMD\"}" +echo "4938.88955074 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW" + +# RXoWchjAaJatpRYGoD7A2tEuYN1jhdrRv3 KMD 37183.30557600 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXoWchjAaJatpRYGoD7A2tEuYN1jhdrRv3\",\"symbol\":\"KMD\"}" +echo "37183.30557600 <- expected amount RXoWchjAaJatpRYGoD7A2tEuYN1jhdrRv3" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# R9Kpd7dQ5udE7bUBWvQ5sEiTL3hSr5R2Ck KMD 29783.79369585 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9Kpd7dQ5udE7bUBWvQ5sEiTL3hSr5R2Ck\",\"symbol\":\"KMD\"}" +echo "29783.79369585 <- expected amount R9Kpd7dQ5udE7bUBWvQ5sEiTL3hSr5R2Ck" + +# RHh3vqCrFmZsLUKPxnx4yCcAqZ8RSZ2NW3 KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHh3vqCrFmZsLUKPxnx4yCcAqZ8RSZ2NW3\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RHh3vqCrFmZsLUKPxnx4yCcAqZ8RSZ2NW3" + +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 4040.77614254 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK\",\"symbol\":\"KMD\"}" +echo "4040.77614254 <- expected amount RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK" + +# RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 KMD 47536.89479581 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9\",\"symbol\":\"KMD\"}" +echo "47536.89479581 <- expected amount RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9" + diff --git a/iguana/tests/KMD.batch15 b/iguana/tests/KMD.batch15 new file mode 100755 index 000000000..236157660 --- /dev/null +++ b/iguana/tests/KMD.batch15 @@ -0,0 +1,383 @@ +sleep 999999 +# RBzPz4Sd2Jt3jKVsXKwC4vwGkYG6hSekge KMD 108355.00859530 +./komodo-cli sendtoaddress RBzPz4Sd2Jt3jKVsXKwC4vwGkYG6hSekge 108355.00859530 +sleep 3 +echo "108355.00859530 <- expected amount RBzPz4Sd2Jt3jKVsXKwC4vwGkYG6hSekge" + +# RSN2ceQxBUKUynBf5BGbZU6er7uqAGUXzw KMD 23072.44878134 +./komodo-cli sendtoaddress RSN2ceQxBUKUynBf5BGbZU6er7uqAGUXzw 23072.44878134 +sleep 3 +echo "23072.44878134 <- expected amount RSN2ceQxBUKUynBf5BGbZU6er7uqAGUXzw" + +# RVMGcrxJMHST3dPZJJNNxZWJKidFYBmpTE KMD 26923.62561943 +./komodo-cli sendtoaddress RVMGcrxJMHST3dPZJJNNxZWJKidFYBmpTE 26923.62561943 +sleep 3 +echo "26923.62561943 <- expected amount RVMGcrxJMHST3dPZJJNNxZWJKidFYBmpTE" + +# RJJKtJqfC8Ytrjq9RqiYLH85qbHNkqXb43 KMD 890.85002942 +./komodo-cli sendtoaddress RJJKtJqfC8Ytrjq9RqiYLH85qbHNkqXb43 890.85002942 +sleep 3 +echo "890.85002942 <- expected amount RJJKtJqfC8Ytrjq9RqiYLH85qbHNkqXb43" + +# RWEGPuUx2U8V28VpxAKpuKfwcs6TN4GpKV KMD 6196.32806186 +./komodo-cli sendtoaddress RWEGPuUx2U8V28VpxAKpuKfwcs6TN4GpKV 6196.32806186 +sleep 3 +echo "6196.32806186 <- expected amount RWEGPuUx2U8V28VpxAKpuKfwcs6TN4GpKV" + +# RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX KMD 123341.77894864 +./komodo-cli sendtoaddress RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX 123341.77894864 +sleep 3 +echo "123341.77894864 <- expected amount RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX" + +# RKRtuN5f76BjSxPPTVbmtBSSdz938UjiJx KMD 1267.52466143 +./komodo-cli sendtoaddress RKRtuN5f76BjSxPPTVbmtBSSdz938UjiJx 1267.52466143 +sleep 3 +echo "1267.52466143 <- expected amount RKRtuN5f76BjSxPPTVbmtBSSdz938UjiJx" + +# RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9 KMD 9575.27247343 +./komodo-cli sendtoaddress RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9 9575.27247343 +sleep 3 +echo "9575.27247343 <- expected amount RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9" + +# RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9 KMD 8123.81358037 +./komodo-cli sendtoaddress RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9 8123.81358037 +sleep 3 +echo "8123.81358037 <- expected amount RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9" + +# REZbCCvVVNdvg8eVkwz4SDk4sVvBfSXrE8 KMD 4989.67320242 +./komodo-cli sendtoaddress REZbCCvVVNdvg8eVkwz4SDk4sVvBfSXrE8 4989.67320242 +sleep 3 +echo "4989.67320242 <- expected amount REZbCCvVVNdvg8eVkwz4SDk4sVvBfSXrE8" + +# RUcSLDX7nWM1oe5ftLYj3m6RE3gSsEXcGD KMD 752.38094876 +./komodo-cli sendtoaddress RUcSLDX7nWM1oe5ftLYj3m6RE3gSsEXcGD 752.38094876 +sleep 3 +echo "752.38094876 <- expected amount RUcSLDX7nWM1oe5ftLYj3m6RE3gSsEXcGD" + +# RSs2rBgjQcZjdPLuUhEFEDNVqoUutKAqMz KMD 142854.50921654 +./komodo-cli sendtoaddress RSs2rBgjQcZjdPLuUhEFEDNVqoUutKAqMz 142854.50921654 +sleep 3 +echo "142854.50921654 <- expected amount RSs2rBgjQcZjdPLuUhEFEDNVqoUutKAqMz" + +# RRZw29LKHAMTfw673BQHBjf1H6krpKruEV KMD 700273.96662837 +./komodo-cli sendtoaddress RRZw29LKHAMTfw673BQHBjf1H6krpKruEV 700273.96662837 +sleep 3 +echo "700273.96662837 <- expected amount RRZw29LKHAMTfw673BQHBjf1H6krpKruEV" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 22785.43547500 +./komodo-cli sendtoaddress RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ 22785.43547500 +sleep 3 +echo "22785.43547500 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RFxv7eb5F4hYum2pfJoWDJSBLesdzEothC KMD 49.81951692 +./komodo-cli sendtoaddress RFxv7eb5F4hYum2pfJoWDJSBLesdzEothC 49.81951692 +sleep 3 +echo "49.81951692 <- expected amount RFxv7eb5F4hYum2pfJoWDJSBLesdzEothC" + +# RJD2LGt2KYdmcuLMkrwnXA18o9U5xhLXbG KMD 9768.98395745 +./komodo-cli sendtoaddress RJD2LGt2KYdmcuLMkrwnXA18o9U5xhLXbG 9768.98395745 +sleep 3 +echo "9768.98395745 <- expected amount RJD2LGt2KYdmcuLMkrwnXA18o9U5xhLXbG" + +# RCuyPLaBmudGiTm7chbnWdBATqEvcLWbNc KMD 17899.04337446 +./komodo-cli sendtoaddress RCuyPLaBmudGiTm7chbnWdBATqEvcLWbNc 17899.04337446 +sleep 3 +echo "17899.04337446 <- expected amount RCuyPLaBmudGiTm7chbnWdBATqEvcLWbNc" + +# RWtBYTabQZcJku6Z7X2u9NUyhzGUyMcba7 KMD 14691.11993791 +./komodo-cli sendtoaddress RWtBYTabQZcJku6Z7X2u9NUyhzGUyMcba7 14691.11993791 +sleep 3 +echo "14691.11993791 <- expected amount RWtBYTabQZcJku6Z7X2u9NUyhzGUyMcba7" + +# RJdKjpM8pm3E5Y93p5xy4XE8zQTQP5cfaY KMD 1161.97829925 +./komodo-cli sendtoaddress RJdKjpM8pm3E5Y93p5xy4XE8zQTQP5cfaY 1161.97829925 +sleep 3 +echo "1161.97829925 <- expected amount RJdKjpM8pm3E5Y93p5xy4XE8zQTQP5cfaY" + +# RA8iFVS6B99VfGAThL21NuBFQ1wCeqVkYW KMD 1172.24498253 +./komodo-cli sendtoaddress RA8iFVS6B99VfGAThL21NuBFQ1wCeqVkYW 1172.24498253 +sleep 3 +echo "1172.24498253 <- expected amount RA8iFVS6B99VfGAThL21NuBFQ1wCeqVkYW" + +# RTjshGhD5Nf6ZrWLxd6Kh65LrZRQzUesbx KMD 9007.57601472 +./komodo-cli sendtoaddress RTjshGhD5Nf6ZrWLxd6Kh65LrZRQzUesbx 9007.57601472 +sleep 3 +echo "9007.57601472 <- expected amount RTjshGhD5Nf6ZrWLxd6Kh65LrZRQzUesbx" + +# RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ KMD 5844.47004626, REVS 115.97829823 +# RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ KMD 5844.47004626 +./komodo-cli sendtoaddress RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ 5844.47004626 +sleep 3 +echo "5844.47004626 <- expected amount RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ" + +# RUWP4WNfz1axrYbhLnK1mL1mYQigS9rheg KMD 5008.45159128 +./komodo-cli sendtoaddress RUWP4WNfz1axrYbhLnK1mL1mYQigS9rheg 5008.45159128 +sleep 3 +echo "5008.45159128 <- expected amount RUWP4WNfz1axrYbhLnK1mL1mYQigS9rheg" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 7646.82608478 +./komodo-cli sendtoaddress RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ 7646.82608478 +sleep 3 +echo "7646.82608478 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RKGh71nXHPkXZUwoKtEnwfdLsxcTKwdfbf KMD 3630.85647725 +./komodo-cli sendtoaddress RKGh71nXHPkXZUwoKtEnwfdLsxcTKwdfbf 3630.85647725 +sleep 3 +echo "3630.85647725 <- expected amount RKGh71nXHPkXZUwoKtEnwfdLsxcTKwdfbf" + +# RYaL2xQsvSCaWVF5p4AUFLiM8TZsm2pVuj KMD 26.57494393 +./komodo-cli sendtoaddress RYaL2xQsvSCaWVF5p4AUFLiM8TZsm2pVuj 26.57494393 +sleep 3 +echo "26.57494393 <- expected amount RYaL2xQsvSCaWVF5p4AUFLiM8TZsm2pVuj" + +# R9UwkeRo4HWP14LXKxvii7PQkyrkk8zybU KMD 0.36801433 +./komodo-cli sendtoaddress R9UwkeRo4HWP14LXKxvii7PQkyrkk8zybU 0.36801433 +sleep 3 +echo "0.36801433 <- expected amount R9UwkeRo4HWP14LXKxvii7PQkyrkk8zybU" + +# RE9wMd3wq3SwYYq9y7iv8r2cb7ndFc7V43 KMD 8249.37604889 +./komodo-cli sendtoaddress RE9wMd3wq3SwYYq9y7iv8r2cb7ndFc7V43 8249.37604889 +sleep 3 +echo "8249.37604889 <- expected amount RE9wMd3wq3SwYYq9y7iv8r2cb7ndFc7V43" + +# RXZvRrVc5JhmJ3dpgFNqjPQog2RHJwSTRN KMD 2701.34236284 +./komodo-cli sendtoaddress RXZvRrVc5JhmJ3dpgFNqjPQog2RHJwSTRN 2701.34236284 +sleep 3 +echo "2701.34236284 <- expected amount RXZvRrVc5JhmJ3dpgFNqjPQog2RHJwSTRN" + +# RD7gYAZVD9yN5uUNyGd3TZNVXJA234pWDk KMD 9799.35032367 +./komodo-cli sendtoaddress RD7gYAZVD9yN5uUNyGd3TZNVXJA234pWDk 9799.35032367 +sleep 3 +echo "9799.35032367 <- expected amount RD7gYAZVD9yN5uUNyGd3TZNVXJA234pWDk" + +# RNsNi3L3QWXx4Sa1CyZYfCd2q6TjJcrK4L KMD 2180.13581547 +./komodo-cli sendtoaddress RNsNi3L3QWXx4Sa1CyZYfCd2q6TjJcrK4L 2180.13581547 +sleep 3 +echo "2180.13581547 <- expected amount RNsNi3L3QWXx4Sa1CyZYfCd2q6TjJcrK4L" + +# RRsb2PKKvZQuGCxEJZFEHxydq4aktjQKnV KMD 3028.34071670 +./komodo-cli sendtoaddress RRsb2PKKvZQuGCxEJZFEHxydq4aktjQKnV 3028.34071670 +sleep 3 +echo "3028.34071670 <- expected amount RRsb2PKKvZQuGCxEJZFEHxydq4aktjQKnV" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 6100.04389549 +./komodo-cli sendtoaddress RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz 6100.04389549 +sleep 3 +echo "6100.04389549 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RBBaR5v41Bew2qeybeutzN8YcFV9z2BTXZ KMD 737.35656935 +./komodo-cli sendtoaddress RBBaR5v41Bew2qeybeutzN8YcFV9z2BTXZ 737.35656935 +sleep 3 +echo "737.35656935 <- expected amount RBBaR5v41Bew2qeybeutzN8YcFV9z2BTXZ" + +# RHfFfCbb32Ld5SYjqA7yL5tohX5U1nc919 KMD 929.58263940 +./komodo-cli sendtoaddress RHfFfCbb32Ld5SYjqA7yL5tohX5U1nc919 929.58263940 +sleep 3 +echo "929.58263940 <- expected amount RHfFfCbb32Ld5SYjqA7yL5tohX5U1nc919" + +# RT4DVxxerQye2rPf89Tfdxq6XmMuYMMDWy KMD 34677.50699205 +./komodo-cli sendtoaddress RT4DVxxerQye2rPf89Tfdxq6XmMuYMMDWy 34677.50699205 +sleep 3 +echo "34677.50699205 <- expected amount RT4DVxxerQye2rPf89Tfdxq6XmMuYMMDWy" + +# REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa KMD 26142.50314066, REVS 20.00000000 +# REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa KMD 26142.50314066 +./komodo-cli sendtoaddress REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa 26142.50314066 +sleep 3 +echo "26142.50314066 <- expected amount REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa" + +# RX2gT4WZR7VDiufaYGGCYoxRD3kNZmEN2V KMD 4802.84363690 +./komodo-cli sendtoaddress RX2gT4WZR7VDiufaYGGCYoxRD3kNZmEN2V 4802.84363690 +sleep 3 +echo "4802.84363690 <- expected amount RX2gT4WZR7VDiufaYGGCYoxRD3kNZmEN2V" + +# RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft KMD 1005.97291406, REVS 19.95990000 +# RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft KMD 1005.97291406 +./komodo-cli sendtoaddress RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft 1005.97291406 +sleep 3 +echo "1005.97291406 <- expected amount RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft" + +# RD486qQaD85849AdDPH3Xy3iyppuvxDZYf KMD 112218.69529965 +./komodo-cli sendtoaddress RD486qQaD85849AdDPH3Xy3iyppuvxDZYf 112218.69529965 +sleep 3 +echo "112218.69529965 <- expected amount RD486qQaD85849AdDPH3Xy3iyppuvxDZYf" + +# RFPpBZpjgA1wT5mHBLRfUu4X8xr4DrLP4e KMD 3479.75699272 +./komodo-cli sendtoaddress RFPpBZpjgA1wT5mHBLRfUu4X8xr4DrLP4e 3479.75699272 +sleep 3 +echo "3479.75699272 <- expected amount RFPpBZpjgA1wT5mHBLRfUu4X8xr4DrLP4e" + +# RRv9LoJVCtaQYkKm92MVb2ZZWH3cthWpGN KMD 175.51057343 +./komodo-cli sendtoaddress RRv9LoJVCtaQYkKm92MVb2ZZWH3cthWpGN 175.51057343 +sleep 3 +echo "175.51057343 <- expected amount RRv9LoJVCtaQYkKm92MVb2ZZWH3cthWpGN" + +# RWM6u3En5J8afndTjSyAK6bw7EThdTK3a8 KMD 7477.64792521 +./komodo-cli sendtoaddress RWM6u3En5J8afndTjSyAK6bw7EThdTK3a8 7477.64792521 +sleep 3 +echo "7477.64792521 <- expected amount RWM6u3En5J8afndTjSyAK6bw7EThdTK3a8" + +# RVbyHqZRqL7QnjZdg5JPRCic5vnehjuTgn KMD 54859.12298759 +./komodo-cli sendtoaddress RVbyHqZRqL7QnjZdg5JPRCic5vnehjuTgn 54859.12298759 +sleep 3 +echo "54859.12298759 <- expected amount RVbyHqZRqL7QnjZdg5JPRCic5vnehjuTgn" + +# RHXnTT4jKiS8PGR6RrUobdVC7SxJ5gUXMo KMD 79.56270943 +./komodo-cli sendtoaddress RHXnTT4jKiS8PGR6RrUobdVC7SxJ5gUXMo 79.56270943 +sleep 3 +echo "79.56270943 <- expected amount RHXnTT4jKiS8PGR6RrUobdVC7SxJ5gUXMo" + +# RLgtZmLckAP74eH5DZyG2V44mX1KMCAwCb KMD 349.07505686 +./komodo-cli sendtoaddress RLgtZmLckAP74eH5DZyG2V44mX1KMCAwCb 349.07505686 +sleep 3 +echo "349.07505686 <- expected amount RLgtZmLckAP74eH5DZyG2V44mX1KMCAwCb" + +# RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH KMD 248.34196903 +./komodo-cli sendtoaddress RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH 248.34196903 +sleep 3 +echo "248.34196903 <- expected amount RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH" + +# RDVsguQRewZQxA4CYuFaU6P1ZfzXy15m9R KMD 904.34185995 +./komodo-cli sendtoaddress RDVsguQRewZQxA4CYuFaU6P1ZfzXy15m9R 904.34185995 +sleep 3 +echo "904.34185995 <- expected amount RDVsguQRewZQxA4CYuFaU6P1ZfzXy15m9R" + +# REhB64k55HNsga6tbJxqwioRHg7pD7mTpQ KMD 49.36918661 +./komodo-cli sendtoaddress REhB64k55HNsga6tbJxqwioRHg7pD7mTpQ 49.36918661 +sleep 3 +echo "49.36918661 <- expected amount REhB64k55HNsga6tbJxqwioRHg7pD7mTpQ" + +# RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC KMD 159023.63042654 +./komodo-cli sendtoaddress RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC 159023.63042654 +sleep 3 +echo "159023.63042654 <- expected amount RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC" + +# RC2c6CMiCrTceYdbkYzjXmavR45pwPJczo KMD 18870.52757981 +./komodo-cli sendtoaddress RC2c6CMiCrTceYdbkYzjXmavR45pwPJczo 18870.52757981 +sleep 3 +echo "18870.52757981 <- expected amount RC2c6CMiCrTceYdbkYzjXmavR45pwPJczo" + +# R9WDH8NDcEewJTYGPgqMkvQ7ztbtBfV8zJ KMD 3523.48691215 +./komodo-cli sendtoaddress R9WDH8NDcEewJTYGPgqMkvQ7ztbtBfV8zJ 3523.48691215 +sleep 3 +echo "3523.48691215 <- expected amount R9WDH8NDcEewJTYGPgqMkvQ7ztbtBfV8zJ" + +# RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 KMD 2607.14186398 +./komodo-cli sendtoaddress RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 2607.14186398 +sleep 3 +echo "2607.14186398 <- expected amount RWc6GouJggQDsBCeW1DYck629FPrDJCTP9" + +# RYU6iDdo1AfrBg6zUcCPEX8BnSL1YsxrMk KMD 3098.60879800 +./komodo-cli sendtoaddress RYU6iDdo1AfrBg6zUcCPEX8BnSL1YsxrMk 3098.60879800 +sleep 3 +echo "3098.60879800 <- expected amount RYU6iDdo1AfrBg6zUcCPEX8BnSL1YsxrMk" + +# RTYpGd8VFGtiDb9bJSZasTWjRRHVqYABtT KMD 3647.68227700 +./komodo-cli sendtoaddress RTYpGd8VFGtiDb9bJSZasTWjRRHVqYABtT 3647.68227700 +sleep 3 +echo "3647.68227700 <- expected amount RTYpGd8VFGtiDb9bJSZasTWjRRHVqYABtT" + +# RYUgPBd2MvnSEAADUmAXMSV6bBhRTA9dBH KMD 468.24354647 +./komodo-cli sendtoaddress RYUgPBd2MvnSEAADUmAXMSV6bBhRTA9dBH 468.24354647 +sleep 3 +echo "468.24354647 <- expected amount RYUgPBd2MvnSEAADUmAXMSV6bBhRTA9dBH" + +# RX3EPj8UoJJbQ4LnkQGqLnRSapbneckaKi KMD 2418.85149293 +./komodo-cli sendtoaddress RX3EPj8UoJJbQ4LnkQGqLnRSapbneckaKi 2418.85149293 +sleep 3 +echo "2418.85149293 <- expected amount RX3EPj8UoJJbQ4LnkQGqLnRSapbneckaKi" + +# REJYC31D8z48AJAC8CmhgKgSuVc4WwFPWh KMD 9295.82639400 +./komodo-cli sendtoaddress REJYC31D8z48AJAC8CmhgKgSuVc4WwFPWh 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount REJYC31D8z48AJAC8CmhgKgSuVc4WwFPWh" + +# RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz KMD 55321.57248841 +./komodo-cli sendtoaddress RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz 55321.57248841 +sleep 3 +echo "55321.57248841 <- expected amount RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz" + +# RWXHBrpGt1dwa1rBuQj6QgQdWBdAtLwVAp KMD 367572.46866275 +./komodo-cli sendtoaddress RWXHBrpGt1dwa1rBuQj6QgQdWBdAtLwVAp 367572.46866275 +sleep 3 +echo "367572.46866275 <- expected amount RWXHBrpGt1dwa1rBuQj6QgQdWBdAtLwVAp" + +# REpJJwmxrSetdhNp4uKUTwyyTrSpNxjM2s KMD 4.48872950 +./komodo-cli sendtoaddress REpJJwmxrSetdhNp4uKUTwyyTrSpNxjM2s 4.48872950 +sleep 3 +echo "4.48872950 <- expected amount REpJJwmxrSetdhNp4uKUTwyyTrSpNxjM2s" + +# RKmwwn2n1DaAqZdDXiZkobgQSKiVcUD2RP KMD 4260.58709725 +./komodo-cli sendtoaddress RKmwwn2n1DaAqZdDXiZkobgQSKiVcUD2RP 4260.58709725 +sleep 3 +echo "4260.58709725 <- expected amount RKmwwn2n1DaAqZdDXiZkobgQSKiVcUD2RP" + +# RL8XNqYnfkstJPuNHPYfsPQSzccTHcqFkf KMD 2953.97870652 +./komodo-cli sendtoaddress RL8XNqYnfkstJPuNHPYfsPQSzccTHcqFkf 2953.97870652 +sleep 3 +echo "2953.97870652 <- expected amount RL8XNqYnfkstJPuNHPYfsPQSzccTHcqFkf" + +# RECqqp55ZLUccEgEwd3VTYC2awx9aVXEHi KMD 75258.40704108 +./komodo-cli sendtoaddress RECqqp55ZLUccEgEwd3VTYC2awx9aVXEHi 75258.40704108 +sleep 3 +echo "75258.40704108 <- expected amount RECqqp55ZLUccEgEwd3VTYC2awx9aVXEHi" + +# RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 KMD 125611.30316493, REVS 1564.97178647 +# RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 KMD 125611.30316493 +./komodo-cli sendtoaddress RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 125611.30316493 +sleep 3 +echo "125611.30316493 <- expected amount RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk KMD 4535.36019149, REVS 90.00018012 +# RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk KMD 4535.36019149 +./komodo-cli sendtoaddress RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk 4535.36019149 +sleep 3 +echo "4535.36019149 <- expected amount RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk" + +# RMrm1S6pc1AZY7QvqFwmEGNoPMVxq61E7E KMD 11293.49948607 +./komodo-cli sendtoaddress RMrm1S6pc1AZY7QvqFwmEGNoPMVxq61E7E 11293.49948607 +sleep 3 +echo "11293.49948607 <- expected amount RMrm1S6pc1AZY7QvqFwmEGNoPMVxq61E7E" + +# RQPHxw8wwm83ystB1EciD5BFKmSpQnirrE KMD 12200.87564194 +./komodo-cli sendtoaddress RQPHxw8wwm83ystB1EciD5BFKmSpQnirrE 12200.87564194 +sleep 3 +echo "12200.87564194 <- expected amount RQPHxw8wwm83ystB1EciD5BFKmSpQnirrE" + +# RNWxopR8G5sSkEZ8gAPHBJBrais9rT8rqd KMD 1493.46088391 +./komodo-cli sendtoaddress RNWxopR8G5sSkEZ8gAPHBJBrais9rT8rqd 1493.46088391 +sleep 3 +echo "1493.46088391 <- expected amount RNWxopR8G5sSkEZ8gAPHBJBrais9rT8rqd" + +# RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 KMD 46218.10752319 +./komodo-cli sendtoaddress RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 46218.10752319 +sleep 3 +echo "46218.10752319 <- expected amount RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2" + +# RTmG8UyrSZPRy6Et1wZNtawB8EzCnGXzgJ KMD 11952.18753277 +./komodo-cli sendtoaddress RTmG8UyrSZPRy6Et1wZNtawB8EzCnGXzgJ 11952.18753277 +sleep 3 +echo "11952.18753277 <- expected amount RTmG8UyrSZPRy6Et1wZNtawB8EzCnGXzgJ" + +# RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx KMD 815.56545295 +./komodo-cli sendtoaddress RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx 815.56545295 +sleep 3 +echo "815.56545295 <- expected amount RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx" + +# RNUpL2yQjAHawP2C1kt7bTiMg5YSLEfurr KMD 5212.95301692 +./komodo-cli sendtoaddress RNUpL2yQjAHawP2C1kt7bTiMg5YSLEfurr 5212.95301692 +sleep 3 +echo "5212.95301692 <- expected amount RNUpL2yQjAHawP2C1kt7bTiMg5YSLEfurr" + +# RKPiAqCz2qRQFb5db11uCPDRYMBFfjWVTY KMD 3159.92424349 +./komodo-cli sendtoaddress RKPiAqCz2qRQFb5db11uCPDRYMBFfjWVTY 3159.92424349 +sleep 3 +echo "3159.92424349 <- expected amount RKPiAqCz2qRQFb5db11uCPDRYMBFfjWVTY" + + +# total KMD 2467018.52955628 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch15.listunspent b/iguana/tests/KMD.batch15.listunspent new file mode 100755 index 000000000..e24f8dd38 --- /dev/null +++ b/iguana/tests/KMD.batch15.listunspent @@ -0,0 +1,305 @@ +# RBzPz4Sd2Jt3jKVsXKwC4vwGkYG6hSekge KMD 108355.00859530 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBzPz4Sd2Jt3jKVsXKwC4vwGkYG6hSekge\",\"symbol\":\"KMD\"}" +echo "108355.00859530 <- expected amount RBzPz4Sd2Jt3jKVsXKwC4vwGkYG6hSekge" + +# RSN2ceQxBUKUynBf5BGbZU6er7uqAGUXzw KMD 23072.44878134 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSN2ceQxBUKUynBf5BGbZU6er7uqAGUXzw\",\"symbol\":\"KMD\"}" +echo "23072.44878134 <- expected amount RSN2ceQxBUKUynBf5BGbZU6er7uqAGUXzw" + +# RVMGcrxJMHST3dPZJJNNxZWJKidFYBmpTE KMD 26923.62561943 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVMGcrxJMHST3dPZJJNNxZWJKidFYBmpTE\",\"symbol\":\"KMD\"}" +echo "26923.62561943 <- expected amount RVMGcrxJMHST3dPZJJNNxZWJKidFYBmpTE" + +# RJJKtJqfC8Ytrjq9RqiYLH85qbHNkqXb43 KMD 890.85002942 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJJKtJqfC8Ytrjq9RqiYLH85qbHNkqXb43\",\"symbol\":\"KMD\"}" +echo "890.85002942 <- expected amount RJJKtJqfC8Ytrjq9RqiYLH85qbHNkqXb43" + +# RWEGPuUx2U8V28VpxAKpuKfwcs6TN4GpKV KMD 6196.32806186 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWEGPuUx2U8V28VpxAKpuKfwcs6TN4GpKV\",\"symbol\":\"KMD\"}" +echo "6196.32806186 <- expected amount RWEGPuUx2U8V28VpxAKpuKfwcs6TN4GpKV" + +# RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX KMD 123341.77894864 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX\",\"symbol\":\"KMD\"}" +echo "123341.77894864 <- expected amount RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX" + +# RKRtuN5f76BjSxPPTVbmtBSSdz938UjiJx KMD 1267.52466143 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKRtuN5f76BjSxPPTVbmtBSSdz938UjiJx\",\"symbol\":\"KMD\"}" +echo "1267.52466143 <- expected amount RKRtuN5f76BjSxPPTVbmtBSSdz938UjiJx" + +# RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9 KMD 9575.27247343 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9\",\"symbol\":\"KMD\"}" +echo "9575.27247343 <- expected amount RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9" + +# RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9 KMD 8123.81358037 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9\",\"symbol\":\"KMD\"}" +echo "8123.81358037 <- expected amount RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9" + +# REZbCCvVVNdvg8eVkwz4SDk4sVvBfSXrE8 KMD 4989.67320242 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REZbCCvVVNdvg8eVkwz4SDk4sVvBfSXrE8\",\"symbol\":\"KMD\"}" +echo "4989.67320242 <- expected amount REZbCCvVVNdvg8eVkwz4SDk4sVvBfSXrE8" + +# RUcSLDX7nWM1oe5ftLYj3m6RE3gSsEXcGD KMD 752.38094876 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUcSLDX7nWM1oe5ftLYj3m6RE3gSsEXcGD\",\"symbol\":\"KMD\"}" +echo "752.38094876 <- expected amount RUcSLDX7nWM1oe5ftLYj3m6RE3gSsEXcGD" + +# RSs2rBgjQcZjdPLuUhEFEDNVqoUutKAqMz KMD 142854.50921654 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSs2rBgjQcZjdPLuUhEFEDNVqoUutKAqMz\",\"symbol\":\"KMD\"}" +echo "142854.50921654 <- expected amount RSs2rBgjQcZjdPLuUhEFEDNVqoUutKAqMz" + +# RRZw29LKHAMTfw673BQHBjf1H6krpKruEV KMD 700273.96662837 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRZw29LKHAMTfw673BQHBjf1H6krpKruEV\",\"symbol\":\"KMD\"}" +echo "700273.96662837 <- expected amount RRZw29LKHAMTfw673BQHBjf1H6krpKruEV" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 22785.43547500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ\",\"symbol\":\"KMD\"}" +echo "22785.43547500 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RFxv7eb5F4hYum2pfJoWDJSBLesdzEothC KMD 49.81951692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFxv7eb5F4hYum2pfJoWDJSBLesdzEothC\",\"symbol\":\"KMD\"}" +echo "49.81951692 <- expected amount RFxv7eb5F4hYum2pfJoWDJSBLesdzEothC" + +# RJD2LGt2KYdmcuLMkrwnXA18o9U5xhLXbG KMD 9768.98395745 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJD2LGt2KYdmcuLMkrwnXA18o9U5xhLXbG\",\"symbol\":\"KMD\"}" +echo "9768.98395745 <- expected amount RJD2LGt2KYdmcuLMkrwnXA18o9U5xhLXbG" + +# RCuyPLaBmudGiTm7chbnWdBATqEvcLWbNc KMD 17899.04337446 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCuyPLaBmudGiTm7chbnWdBATqEvcLWbNc\",\"symbol\":\"KMD\"}" +echo "17899.04337446 <- expected amount RCuyPLaBmudGiTm7chbnWdBATqEvcLWbNc" + +# RWtBYTabQZcJku6Z7X2u9NUyhzGUyMcba7 KMD 14691.11993791 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWtBYTabQZcJku6Z7X2u9NUyhzGUyMcba7\",\"symbol\":\"KMD\"}" +echo "14691.11993791 <- expected amount RWtBYTabQZcJku6Z7X2u9NUyhzGUyMcba7" + +# RJdKjpM8pm3E5Y93p5xy4XE8zQTQP5cfaY KMD 1161.97829925 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJdKjpM8pm3E5Y93p5xy4XE8zQTQP5cfaY\",\"symbol\":\"KMD\"}" +echo "1161.97829925 <- expected amount RJdKjpM8pm3E5Y93p5xy4XE8zQTQP5cfaY" + +# RA8iFVS6B99VfGAThL21NuBFQ1wCeqVkYW KMD 1172.24498253 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RA8iFVS6B99VfGAThL21NuBFQ1wCeqVkYW\",\"symbol\":\"KMD\"}" +echo "1172.24498253 <- expected amount RA8iFVS6B99VfGAThL21NuBFQ1wCeqVkYW" + +# RTjshGhD5Nf6ZrWLxd6Kh65LrZRQzUesbx KMD 9007.57601472 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTjshGhD5Nf6ZrWLxd6Kh65LrZRQzUesbx\",\"symbol\":\"KMD\"}" +echo "9007.57601472 <- expected amount RTjshGhD5Nf6ZrWLxd6Kh65LrZRQzUesbx" + +# RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ KMD 5844.47004626, REVS 115.97829823 +# RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ KMD 5844.47004626 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ\",\"symbol\":\"KMD\"}" +echo "5844.47004626 <- expected amount RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ" + +# RUWP4WNfz1axrYbhLnK1mL1mYQigS9rheg KMD 5008.45159128 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUWP4WNfz1axrYbhLnK1mL1mYQigS9rheg\",\"symbol\":\"KMD\"}" +echo "5008.45159128 <- expected amount RUWP4WNfz1axrYbhLnK1mL1mYQigS9rheg" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 7646.82608478 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ\",\"symbol\":\"KMD\"}" +echo "7646.82608478 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RKGh71nXHPkXZUwoKtEnwfdLsxcTKwdfbf KMD 3630.85647725 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKGh71nXHPkXZUwoKtEnwfdLsxcTKwdfbf\",\"symbol\":\"KMD\"}" +echo "3630.85647725 <- expected amount RKGh71nXHPkXZUwoKtEnwfdLsxcTKwdfbf" + +# RYaL2xQsvSCaWVF5p4AUFLiM8TZsm2pVuj KMD 26.57494393 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYaL2xQsvSCaWVF5p4AUFLiM8TZsm2pVuj\",\"symbol\":\"KMD\"}" +echo "26.57494393 <- expected amount RYaL2xQsvSCaWVF5p4AUFLiM8TZsm2pVuj" + +# R9UwkeRo4HWP14LXKxvii7PQkyrkk8zybU KMD 0.36801433 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9UwkeRo4HWP14LXKxvii7PQkyrkk8zybU\",\"symbol\":\"KMD\"}" +echo "0.36801433 <- expected amount R9UwkeRo4HWP14LXKxvii7PQkyrkk8zybU" + +# RE9wMd3wq3SwYYq9y7iv8r2cb7ndFc7V43 KMD 8249.37604889 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RE9wMd3wq3SwYYq9y7iv8r2cb7ndFc7V43\",\"symbol\":\"KMD\"}" +echo "8249.37604889 <- expected amount RE9wMd3wq3SwYYq9y7iv8r2cb7ndFc7V43" + +# RXZvRrVc5JhmJ3dpgFNqjPQog2RHJwSTRN KMD 2701.34236284 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXZvRrVc5JhmJ3dpgFNqjPQog2RHJwSTRN\",\"symbol\":\"KMD\"}" +echo "2701.34236284 <- expected amount RXZvRrVc5JhmJ3dpgFNqjPQog2RHJwSTRN" + +# RD7gYAZVD9yN5uUNyGd3TZNVXJA234pWDk KMD 9799.35032367 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RD7gYAZVD9yN5uUNyGd3TZNVXJA234pWDk\",\"symbol\":\"KMD\"}" +echo "9799.35032367 <- expected amount RD7gYAZVD9yN5uUNyGd3TZNVXJA234pWDk" + +# RNsNi3L3QWXx4Sa1CyZYfCd2q6TjJcrK4L KMD 2180.13581547 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNsNi3L3QWXx4Sa1CyZYfCd2q6TjJcrK4L\",\"symbol\":\"KMD\"}" +echo "2180.13581547 <- expected amount RNsNi3L3QWXx4Sa1CyZYfCd2q6TjJcrK4L" + +# RRsb2PKKvZQuGCxEJZFEHxydq4aktjQKnV KMD 3028.34071670 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRsb2PKKvZQuGCxEJZFEHxydq4aktjQKnV\",\"symbol\":\"KMD\"}" +echo "3028.34071670 <- expected amount RRsb2PKKvZQuGCxEJZFEHxydq4aktjQKnV" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 6100.04389549 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" +echo "6100.04389549 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RBBaR5v41Bew2qeybeutzN8YcFV9z2BTXZ KMD 737.35656935 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBBaR5v41Bew2qeybeutzN8YcFV9z2BTXZ\",\"symbol\":\"KMD\"}" +echo "737.35656935 <- expected amount RBBaR5v41Bew2qeybeutzN8YcFV9z2BTXZ" + +# RHfFfCbb32Ld5SYjqA7yL5tohX5U1nc919 KMD 929.58263940 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHfFfCbb32Ld5SYjqA7yL5tohX5U1nc919\",\"symbol\":\"KMD\"}" +echo "929.58263940 <- expected amount RHfFfCbb32Ld5SYjqA7yL5tohX5U1nc919" + +# RT4DVxxerQye2rPf89Tfdxq6XmMuYMMDWy KMD 34677.50699205 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RT4DVxxerQye2rPf89Tfdxq6XmMuYMMDWy\",\"symbol\":\"KMD\"}" +echo "34677.50699205 <- expected amount RT4DVxxerQye2rPf89Tfdxq6XmMuYMMDWy" + +# REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa KMD 26142.50314066, REVS 20.00000000 +# REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa KMD 26142.50314066 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa\",\"symbol\":\"KMD\"}" +echo "26142.50314066 <- expected amount REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa" + +# RX2gT4WZR7VDiufaYGGCYoxRD3kNZmEN2V KMD 4802.84363690 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RX2gT4WZR7VDiufaYGGCYoxRD3kNZmEN2V\",\"symbol\":\"KMD\"}" +echo "4802.84363690 <- expected amount RX2gT4WZR7VDiufaYGGCYoxRD3kNZmEN2V" + +# RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft KMD 1005.97291406, REVS 19.95990000 +# RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft KMD 1005.97291406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft\",\"symbol\":\"KMD\"}" +echo "1005.97291406 <- expected amount RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft" + +# RD486qQaD85849AdDPH3Xy3iyppuvxDZYf KMD 112218.69529965 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RD486qQaD85849AdDPH3Xy3iyppuvxDZYf\",\"symbol\":\"KMD\"}" +echo "112218.69529965 <- expected amount RD486qQaD85849AdDPH3Xy3iyppuvxDZYf" + +# RFPpBZpjgA1wT5mHBLRfUu4X8xr4DrLP4e KMD 3479.75699272 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFPpBZpjgA1wT5mHBLRfUu4X8xr4DrLP4e\",\"symbol\":\"KMD\"}" +echo "3479.75699272 <- expected amount RFPpBZpjgA1wT5mHBLRfUu4X8xr4DrLP4e" + +# RRv9LoJVCtaQYkKm92MVb2ZZWH3cthWpGN KMD 175.51057343 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRv9LoJVCtaQYkKm92MVb2ZZWH3cthWpGN\",\"symbol\":\"KMD\"}" +echo "175.51057343 <- expected amount RRv9LoJVCtaQYkKm92MVb2ZZWH3cthWpGN" + +# RWM6u3En5J8afndTjSyAK6bw7EThdTK3a8 KMD 7477.64792521 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWM6u3En5J8afndTjSyAK6bw7EThdTK3a8\",\"symbol\":\"KMD\"}" +echo "7477.64792521 <- expected amount RWM6u3En5J8afndTjSyAK6bw7EThdTK3a8" + +# RVbyHqZRqL7QnjZdg5JPRCic5vnehjuTgn KMD 54859.12298759 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVbyHqZRqL7QnjZdg5JPRCic5vnehjuTgn\",\"symbol\":\"KMD\"}" +echo "54859.12298759 <- expected amount RVbyHqZRqL7QnjZdg5JPRCic5vnehjuTgn" + +# RHXnTT4jKiS8PGR6RrUobdVC7SxJ5gUXMo KMD 79.56270943 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHXnTT4jKiS8PGR6RrUobdVC7SxJ5gUXMo\",\"symbol\":\"KMD\"}" +echo "79.56270943 <- expected amount RHXnTT4jKiS8PGR6RrUobdVC7SxJ5gUXMo" + +# RLgtZmLckAP74eH5DZyG2V44mX1KMCAwCb KMD 349.07505686 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLgtZmLckAP74eH5DZyG2V44mX1KMCAwCb\",\"symbol\":\"KMD\"}" +echo "349.07505686 <- expected amount RLgtZmLckAP74eH5DZyG2V44mX1KMCAwCb" + +# RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH KMD 248.34196903 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH\",\"symbol\":\"KMD\"}" +echo "248.34196903 <- expected amount RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH" + +# RDVsguQRewZQxA4CYuFaU6P1ZfzXy15m9R KMD 904.34185995 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDVsguQRewZQxA4CYuFaU6P1ZfzXy15m9R\",\"symbol\":\"KMD\"}" +echo "904.34185995 <- expected amount RDVsguQRewZQxA4CYuFaU6P1ZfzXy15m9R" + +# REhB64k55HNsga6tbJxqwioRHg7pD7mTpQ KMD 49.36918661 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REhB64k55HNsga6tbJxqwioRHg7pD7mTpQ\",\"symbol\":\"KMD\"}" +echo "49.36918661 <- expected amount REhB64k55HNsga6tbJxqwioRHg7pD7mTpQ" + +# RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC KMD 159023.63042654 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC\",\"symbol\":\"KMD\"}" +echo "159023.63042654 <- expected amount RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC" + +# RC2c6CMiCrTceYdbkYzjXmavR45pwPJczo KMD 18870.52757981 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC2c6CMiCrTceYdbkYzjXmavR45pwPJczo\",\"symbol\":\"KMD\"}" +echo "18870.52757981 <- expected amount RC2c6CMiCrTceYdbkYzjXmavR45pwPJczo" + +# R9WDH8NDcEewJTYGPgqMkvQ7ztbtBfV8zJ KMD 3523.48691215 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9WDH8NDcEewJTYGPgqMkvQ7ztbtBfV8zJ\",\"symbol\":\"KMD\"}" +echo "3523.48691215 <- expected amount R9WDH8NDcEewJTYGPgqMkvQ7ztbtBfV8zJ" + +# RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 KMD 2607.14186398 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWc6GouJggQDsBCeW1DYck629FPrDJCTP9\",\"symbol\":\"KMD\"}" +echo "2607.14186398 <- expected amount RWc6GouJggQDsBCeW1DYck629FPrDJCTP9" + +# RYU6iDdo1AfrBg6zUcCPEX8BnSL1YsxrMk KMD 3098.60879800 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYU6iDdo1AfrBg6zUcCPEX8BnSL1YsxrMk\",\"symbol\":\"KMD\"}" +echo "3098.60879800 <- expected amount RYU6iDdo1AfrBg6zUcCPEX8BnSL1YsxrMk" + +# RTYpGd8VFGtiDb9bJSZasTWjRRHVqYABtT KMD 3647.68227700 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTYpGd8VFGtiDb9bJSZasTWjRRHVqYABtT\",\"symbol\":\"KMD\"}" +echo "3647.68227700 <- expected amount RTYpGd8VFGtiDb9bJSZasTWjRRHVqYABtT" + +# RYUgPBd2MvnSEAADUmAXMSV6bBhRTA9dBH KMD 468.24354647 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYUgPBd2MvnSEAADUmAXMSV6bBhRTA9dBH\",\"symbol\":\"KMD\"}" +echo "468.24354647 <- expected amount RYUgPBd2MvnSEAADUmAXMSV6bBhRTA9dBH" + +# RX3EPj8UoJJbQ4LnkQGqLnRSapbneckaKi KMD 2418.85149293 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RX3EPj8UoJJbQ4LnkQGqLnRSapbneckaKi\",\"symbol\":\"KMD\"}" +echo "2418.85149293 <- expected amount RX3EPj8UoJJbQ4LnkQGqLnRSapbneckaKi" + +# REJYC31D8z48AJAC8CmhgKgSuVc4WwFPWh KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REJYC31D8z48AJAC8CmhgKgSuVc4WwFPWh\",\"symbol\":\"KMD\"}" +echo "9295.82639400 <- expected amount REJYC31D8z48AJAC8CmhgKgSuVc4WwFPWh" + +# RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz KMD 55321.57248841 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz\",\"symbol\":\"KMD\"}" +echo "55321.57248841 <- expected amount RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz" + +# RWXHBrpGt1dwa1rBuQj6QgQdWBdAtLwVAp KMD 367572.46866275 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWXHBrpGt1dwa1rBuQj6QgQdWBdAtLwVAp\",\"symbol\":\"KMD\"}" +echo "367572.46866275 <- expected amount RWXHBrpGt1dwa1rBuQj6QgQdWBdAtLwVAp" + +# REpJJwmxrSetdhNp4uKUTwyyTrSpNxjM2s KMD 4.48872950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REpJJwmxrSetdhNp4uKUTwyyTrSpNxjM2s\",\"symbol\":\"KMD\"}" +echo "4.48872950 <- expected amount REpJJwmxrSetdhNp4uKUTwyyTrSpNxjM2s" + +# RKmwwn2n1DaAqZdDXiZkobgQSKiVcUD2RP KMD 4260.58709725 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKmwwn2n1DaAqZdDXiZkobgQSKiVcUD2RP\",\"symbol\":\"KMD\"}" +echo "4260.58709725 <- expected amount RKmwwn2n1DaAqZdDXiZkobgQSKiVcUD2RP" + +# RL8XNqYnfkstJPuNHPYfsPQSzccTHcqFkf KMD 2953.97870652 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RL8XNqYnfkstJPuNHPYfsPQSzccTHcqFkf\",\"symbol\":\"KMD\"}" +echo "2953.97870652 <- expected amount RL8XNqYnfkstJPuNHPYfsPQSzccTHcqFkf" + +# RECqqp55ZLUccEgEwd3VTYC2awx9aVXEHi KMD 75258.40704108 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RECqqp55ZLUccEgEwd3VTYC2awx9aVXEHi\",\"symbol\":\"KMD\"}" +echo "75258.40704108 <- expected amount RECqqp55ZLUccEgEwd3VTYC2awx9aVXEHi" + +# RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 KMD 125611.30316493, REVS 1564.97178647 +# RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 KMD 125611.30316493 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3\",\"symbol\":\"KMD\"}" +echo "125611.30316493 <- expected amount RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk KMD 4535.36019149, REVS 90.00018012 +# RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk KMD 4535.36019149 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk\",\"symbol\":\"KMD\"}" +echo "4535.36019149 <- expected amount RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk" + +# RMrm1S6pc1AZY7QvqFwmEGNoPMVxq61E7E KMD 11293.49948607 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMrm1S6pc1AZY7QvqFwmEGNoPMVxq61E7E\",\"symbol\":\"KMD\"}" +echo "11293.49948607 <- expected amount RMrm1S6pc1AZY7QvqFwmEGNoPMVxq61E7E" + +# RQPHxw8wwm83ystB1EciD5BFKmSpQnirrE KMD 12200.87564194 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQPHxw8wwm83ystB1EciD5BFKmSpQnirrE\",\"symbol\":\"KMD\"}" +echo "12200.87564194 <- expected amount RQPHxw8wwm83ystB1EciD5BFKmSpQnirrE" + +# RNWxopR8G5sSkEZ8gAPHBJBrais9rT8rqd KMD 1493.46088391 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNWxopR8G5sSkEZ8gAPHBJBrais9rT8rqd\",\"symbol\":\"KMD\"}" +echo "1493.46088391 <- expected amount RNWxopR8G5sSkEZ8gAPHBJBrais9rT8rqd" + +# RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 KMD 46218.10752319 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2\",\"symbol\":\"KMD\"}" +echo "46218.10752319 <- expected amount RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2" + +# RTmG8UyrSZPRy6Et1wZNtawB8EzCnGXzgJ KMD 11952.18753277 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTmG8UyrSZPRy6Et1wZNtawB8EzCnGXzgJ\",\"symbol\":\"KMD\"}" +echo "11952.18753277 <- expected amount RTmG8UyrSZPRy6Et1wZNtawB8EzCnGXzgJ" + +# RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx KMD 815.56545295 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx\",\"symbol\":\"KMD\"}" +echo "815.56545295 <- expected amount RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx" + +# RNUpL2yQjAHawP2C1kt7bTiMg5YSLEfurr KMD 5212.95301692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNUpL2yQjAHawP2C1kt7bTiMg5YSLEfurr\",\"symbol\":\"KMD\"}" +echo "5212.95301692 <- expected amount RNUpL2yQjAHawP2C1kt7bTiMg5YSLEfurr" + +# RKPiAqCz2qRQFb5db11uCPDRYMBFfjWVTY KMD 3159.92424349 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKPiAqCz2qRQFb5db11uCPDRYMBFfjWVTY\",\"symbol\":\"KMD\"}" +echo "3159.92424349 <- expected amount RKPiAqCz2qRQFb5db11uCPDRYMBFfjWVTY" + diff --git a/iguana/tests/KMD.batch16 b/iguana/tests/KMD.batch16 new file mode 100755 index 000000000..609a56161 --- /dev/null +++ b/iguana/tests/KMD.batch16 @@ -0,0 +1,464 @@ +sleep 999999 +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 29875.03958530 +./komodo-cli sendtoaddress RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ 29875.03958530 +sleep 3 +echo "29875.03958530 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RE7dTo722hnJ5Hm5aLwSk3YrvTCuiaGJGL KMD 2208761.69588058 +./komodo-cli sendtoaddress RE7dTo722hnJ5Hm5aLwSk3YrvTCuiaGJGL 2208761.69588058 +sleep 3 +echo "2208761.69588058 <- expected amount RE7dTo722hnJ5Hm5aLwSk3YrvTCuiaGJGL" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 500.57828265 +./komodo-cli sendtoaddress RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ 500.57828265 +sleep 3 +echo "500.57828265 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RH4ziYsxYKXi6qEe8gR2WftMFDasUmwAN2 KMD 478577.43414711 +./komodo-cli sendtoaddress RH4ziYsxYKXi6qEe8gR2WftMFDasUmwAN2 478577.43414711 +sleep 3 +echo "478577.43414711 <- expected amount RH4ziYsxYKXi6qEe8gR2WftMFDasUmwAN2" + +# RSz39LBAF8G9GLRuQ1BDvBVAcLczH87nqR KMD 14765.68648492 +./komodo-cli sendtoaddress RSz39LBAF8G9GLRuQ1BDvBVAcLczH87nqR 14765.68648492 +sleep 3 +echo "14765.68648492 <- expected amount RSz39LBAF8G9GLRuQ1BDvBVAcLczH87nqR" + +# RPNKYCYh9v7hzH5Cgo7KBjxAVY7sQ681S9 KMD 16568.79001553 +./komodo-cli sendtoaddress RPNKYCYh9v7hzH5Cgo7KBjxAVY7sQ681S9 16568.79001553 +sleep 3 +echo "16568.79001553 <- expected amount RPNKYCYh9v7hzH5Cgo7KBjxAVY7sQ681S9" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 5426.58572255 +./komodo-cli sendtoaddress RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ 5426.58572255 +sleep 3 +echo "5426.58572255 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o KMD 2277.23212693 +./komodo-cli sendtoaddress RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o 2277.23212693 +sleep 3 +echo "2277.23212693 <- expected amount RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o" + +# R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj KMD 345.82113080 +./komodo-cli sendtoaddress R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj 345.82113080 +sleep 3 +echo "345.82113080 <- expected amount R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj" + +# RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH KMD 32573.04574031 +./komodo-cli sendtoaddress RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH 32573.04574031 +sleep 3 +echo "32573.04574031 <- expected amount RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH" + +# RTxYk2J7PQGaNFCKoxFiCJAkgWi1Yf3XWZ KMD 21696.64781873 +./komodo-cli sendtoaddress RTxYk2J7PQGaNFCKoxFiCJAkgWi1Yf3XWZ 21696.64781873 +sleep 3 +echo "21696.64781873 <- expected amount RTxYk2J7PQGaNFCKoxFiCJAkgWi1Yf3XWZ" + +# RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP KMD 4410.81679144 +./komodo-cli sendtoaddress RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP 4410.81679144 +sleep 3 +echo "4410.81679144 <- expected amount RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP" + +# RFLQ2DDR5BjNxnz6hqgVpQ7VpmvgyPyB7Q KMD 701.98982318 +./komodo-cli sendtoaddress RFLQ2DDR5BjNxnz6hqgVpQ7VpmvgyPyB7Q 701.98982318 +sleep 3 +echo "701.98982318 <- expected amount RFLQ2DDR5BjNxnz6hqgVpQ7VpmvgyPyB7Q" + +# RHaYREKsYLwafyk4GZEtWHmJhjzdZymAGK KMD 228081.21691774 +./komodo-cli sendtoaddress RHaYREKsYLwafyk4GZEtWHmJhjzdZymAGK 228081.21691774 +sleep 3 +echo "228081.21691774 <- expected amount RHaYREKsYLwafyk4GZEtWHmJhjzdZymAGK" + +# RHNAivbuzfhneSwLV9VpXSU4PFnEsmNsC4 KMD 620.49641179 +./komodo-cli sendtoaddress RHNAivbuzfhneSwLV9VpXSU4PFnEsmNsC4 620.49641179 +sleep 3 +echo "620.49641179 <- expected amount RHNAivbuzfhneSwLV9VpXSU4PFnEsmNsC4" + +# RRtJ2f2YJztjFSGVQNnyFPpTt3fQ4RH1MH KMD 940.61717265 +./komodo-cli sendtoaddress RRtJ2f2YJztjFSGVQNnyFPpTt3fQ4RH1MH 940.61717265 +sleep 3 +echo "940.61717265 <- expected amount RRtJ2f2YJztjFSGVQNnyFPpTt3fQ4RH1MH" + +# RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP KMD 329.20973464 +./komodo-cli sendtoaddress RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP 329.20973464 +sleep 3 +echo "329.20973464 <- expected amount RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP" + +# RB91pNtAQVu9qfhFkFYX4x4G1QfcEDNe1n KMD 890.85002942 +./komodo-cli sendtoaddress RB91pNtAQVu9qfhFkFYX4x4G1QfcEDNe1n 890.85002942 +sleep 3 +echo "890.85002942 <- expected amount RB91pNtAQVu9qfhFkFYX4x4G1QfcEDNe1n" + +# RRGgzASdJ4yBv7Y9o39r9iwCit1jbXhpX3 KMD 48415.76246875 +./komodo-cli sendtoaddress RRGgzASdJ4yBv7Y9o39r9iwCit1jbXhpX3 48415.76246875 +sleep 3 +echo "48415.76246875 <- expected amount RRGgzASdJ4yBv7Y9o39r9iwCit1jbXhpX3" + +# RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 KMD 258573.82999375 +./komodo-cli sendtoaddress RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 258573.82999375 +sleep 3 +echo "258573.82999375 <- expected amount RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3" + +# RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV KMD 857.10994504, REVS 17.01091436 +# RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV KMD 857.10994504 +./komodo-cli sendtoaddress RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV 857.10994504 +sleep 3 +echo "857.10994504 <- expected amount RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV" + +# RCX7MWLQEwgoo6qAdzbaeUBZ4x6KC5KDyg KMD 2324.11284584 +./komodo-cli sendtoaddress RCX7MWLQEwgoo6qAdzbaeUBZ4x6KC5KDyg 2324.11284584 +sleep 3 +echo "2324.11284584 <- expected amount RCX7MWLQEwgoo6qAdzbaeUBZ4x6KC5KDyg" + +# RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY KMD 10017.77725515 +./komodo-cli sendtoaddress RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY 10017.77725515 +sleep 3 +echo "10017.77725515 <- expected amount RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 6114.70953620 +./komodo-cli sendtoaddress RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz 6114.70953620 +sleep 3 +echo "6114.70953620 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RSCpqqjUyjAzs2XT8ra4VzcgQoQJJL6ygB KMD 1529.93809401 +./komodo-cli sendtoaddress RSCpqqjUyjAzs2XT8ra4VzcgQoQJJL6ygB 1529.93809401 +sleep 3 +echo "1529.93809401 <- expected amount RSCpqqjUyjAzs2XT8ra4VzcgQoQJJL6ygB" + +# RH8ZCNFMWAavi3n5v2buQ5QZVDJnD4BXMj KMD 315.34144784 +./komodo-cli sendtoaddress RH8ZCNFMWAavi3n5v2buQ5QZVDJnD4BXMj 315.34144784 +sleep 3 +echo "315.34144784 <- expected amount RH8ZCNFMWAavi3n5v2buQ5QZVDJnD4BXMj" + +# RHY2jW41xptqKfmxDNvojC9MmC6VSTmYTe KMD 2913.66058536 +./komodo-cli sendtoaddress RHY2jW41xptqKfmxDNvojC9MmC6VSTmYTe 2913.66058536 +sleep 3 +echo "2913.66058536 <- expected amount RHY2jW41xptqKfmxDNvojC9MmC6VSTmYTe" + +# RF6kNo4YBUHn9hHD94fQPx7sBVcDLLLDut KMD 809.20571578 +./komodo-cli sendtoaddress RF6kNo4YBUHn9hHD94fQPx7sBVcDLLLDut 809.20571578 +sleep 3 +echo "809.20571578 <- expected amount RF6kNo4YBUHn9hHD94fQPx7sBVcDLLLDut" + +# REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf KMD 10922.30573649 +./komodo-cli sendtoaddress REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf 10922.30573649 +sleep 3 +echo "10922.30573649 <- expected amount REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf" + +# RKd488zhEwgwbtonvv1jvXxq9CtWx7JdTt KMD 8552.16028247 +./komodo-cli sendtoaddress RKd488zhEwgwbtonvv1jvXxq9CtWx7JdTt 8552.16028247 +sleep 3 +echo "8552.16028247 <- expected amount RKd488zhEwgwbtonvv1jvXxq9CtWx7JdTt" + +# REDLuGEpoo7d3Z2CvCpNu5VFYoToDWVquZ KMD 11.76905135 +./komodo-cli sendtoaddress REDLuGEpoo7d3Z2CvCpNu5VFYoToDWVquZ 11.76905135 +sleep 3 +echo "11.76905135 <- expected amount REDLuGEpoo7d3Z2CvCpNu5VFYoToDWVquZ" + +# RYNFwcLAQoqWuzZxT8eAnDX8qYyyy8X7CH KMD 781.69278094 +./komodo-cli sendtoaddress RYNFwcLAQoqWuzZxT8eAnDX8qYyyy8X7CH 781.69278094 +sleep 3 +echo "781.69278094 <- expected amount RYNFwcLAQoqWuzZxT8eAnDX8qYyyy8X7CH" + +# RPy24KLGQcj2ixf6VpRC8ceNt2TGfaotJc KMD 5055.79050524 +./komodo-cli sendtoaddress RPy24KLGQcj2ixf6VpRC8ceNt2TGfaotJc 5055.79050524 +sleep 3 +echo "5055.79050524 <- expected amount RPy24KLGQcj2ixf6VpRC8ceNt2TGfaotJc" + +# RDS7pdCZNjXNDZRRN9ThhU9vR9wwDjzkRg KMD 15570.39216000 +./komodo-cli sendtoaddress RDS7pdCZNjXNDZRRN9ThhU9vR9wwDjzkRg 15570.39216000 +sleep 3 +echo "15570.39216000 <- expected amount RDS7pdCZNjXNDZRRN9ThhU9vR9wwDjzkRg" + +# RENgBDkBfw4gJCq4C62kUFtB9z75hTeWJu KMD 131.27522160 +./komodo-cli sendtoaddress RENgBDkBfw4gJCq4C62kUFtB9z75hTeWJu 131.27522160 +sleep 3 +echo "131.27522160 <- expected amount RENgBDkBfw4gJCq4C62kUFtB9z75hTeWJu" + +# RJ2mT6TfXDGDpozBfFQH9khUkisvp2s3bR KMD 20678.85680809 +./komodo-cli sendtoaddress RJ2mT6TfXDGDpozBfFQH9khUkisvp2s3bR 20678.85680809 +sleep 3 +echo "20678.85680809 <- expected amount RJ2mT6TfXDGDpozBfFQH9khUkisvp2s3bR" + +# RK1bfZervNSyMuQPDtK7iPX1YUj5EMvmY1 KMD 4841.57624687 +./komodo-cli sendtoaddress RK1bfZervNSyMuQPDtK7iPX1YUj5EMvmY1 4841.57624687 +sleep 3 +echo "4841.57624687 <- expected amount RK1bfZervNSyMuQPDtK7iPX1YUj5EMvmY1" + +# RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU KMD 8.94389143 +./komodo-cli sendtoaddress RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU 8.94389143 +sleep 3 +echo "8.94389143 <- expected amount RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU" + +# RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW KMD 1000.80729416 +./komodo-cli sendtoaddress RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW 1000.80729416 +sleep 3 +echo "1000.80729416 <- expected amount RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW" + +# RSkxA4q8XD4fH6SFXASdbijeEnMpmw9gag KMD 1282.60555481 +./komodo-cli sendtoaddress RSkxA4q8XD4fH6SFXASdbijeEnMpmw9gag 1282.60555481 +sleep 3 +echo "1282.60555481 <- expected amount RSkxA4q8XD4fH6SFXASdbijeEnMpmw9gag" + +# RJFk6N5CeieX3RhSSTBWEL5LwKVaKeQf83 KMD 247.94454562 +./komodo-cli sendtoaddress RJFk6N5CeieX3RhSSTBWEL5LwKVaKeQf83 247.94454562 +sleep 3 +echo "247.94454562 <- expected amount RJFk6N5CeieX3RhSSTBWEL5LwKVaKeQf83" + +# RCG3XokbbH3QEu4hL4gbZwTK34rDoVKg4u KMD 9295.82639400 +./komodo-cli sendtoaddress RCG3XokbbH3QEu4hL4gbZwTK34rDoVKg4u 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RCG3XokbbH3QEu4hL4gbZwTK34rDoVKg4u" + +# RCuECu2yAYZeG3HiAkXiaxCvKa5gduKL9H KMD 3949.77164792 +./komodo-cli sendtoaddress RCuECu2yAYZeG3HiAkXiaxCvKa5gduKL9H 3949.77164792 +sleep 3 +echo "3949.77164792 <- expected amount RCuECu2yAYZeG3HiAkXiaxCvKa5gduKL9H" + +# RXDpDLmaF34iHXc8DJLrZyqj1v2HpXH7CB KMD 8845.81358175 +./komodo-cli sendtoaddress RXDpDLmaF34iHXc8DJLrZyqj1v2HpXH7CB 8845.81358175 +sleep 3 +echo "8845.81358175 <- expected amount RXDpDLmaF34iHXc8DJLrZyqj1v2HpXH7CB" + +# RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv KMD 2300.71703251 +./komodo-cli sendtoaddress RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv 2300.71703251 +sleep 3 +echo "2300.71703251 <- expected amount RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv" + +# RRW5pyLoAc2GAx618xer3ywidtN83a9nZP KMD 52.19445674 +./komodo-cli sendtoaddress RRW5pyLoAc2GAx618xer3ywidtN83a9nZP 52.19445674 +sleep 3 +echo "52.19445674 <- expected amount RRW5pyLoAc2GAx618xer3ywidtN83a9nZP" + +# RGrJ4AGWusVdLTVsvV3xsTBZe6d1qVS16q KMD 36.13200587 +./komodo-cli sendtoaddress RGrJ4AGWusVdLTVsvV3xsTBZe6d1qVS16q 36.13200587 +sleep 3 +echo "36.13200587 <- expected amount RGrJ4AGWusVdLTVsvV3xsTBZe6d1qVS16q" + +# RAsDYD3FWvQ42eDqDnyaJgcpmUZrarA44w KMD 422.85217955 +./komodo-cli sendtoaddress RAsDYD3FWvQ42eDqDnyaJgcpmUZrarA44w 422.85217955 +sleep 3 +echo "422.85217955 <- expected amount RAsDYD3FWvQ42eDqDnyaJgcpmUZrarA44w" + +# RGYvkNa4vTD6QYkUyugw9Dyk285Q5qGo4B KMD 217.54701681 +./komodo-cli sendtoaddress RGYvkNa4vTD6QYkUyugw9Dyk285Q5qGo4B 217.54701681 +sleep 3 +echo "217.54701681 <- expected amount RGYvkNa4vTD6QYkUyugw9Dyk285Q5qGo4B" + +# RGukbCjoDr2PiJSH6NNC4t7UDQWFkx8zQz KMD 4005.10943567 +./komodo-cli sendtoaddress RGukbCjoDr2PiJSH6NNC4t7UDQWFkx8zQz 4005.10943567 +sleep 3 +echo "4005.10943567 <- expected amount RGukbCjoDr2PiJSH6NNC4t7UDQWFkx8zQz" + +# RMusGcGfCfzNT8S8xYz6p6sPCoxtt4zZzt KMD 519.46088391 +./komodo-cli sendtoaddress RMusGcGfCfzNT8S8xYz6p6sPCoxtt4zZzt 519.46088391 +sleep 3 +echo "519.46088391 <- expected amount RMusGcGfCfzNT8S8xYz6p6sPCoxtt4zZzt" + +# RBbtoXBmNDjh8VYi7mogKCniKcQxBgpmeN KMD 2214.30570000 +./komodo-cli sendtoaddress RBbtoXBmNDjh8VYi7mogKCniKcQxBgpmeN 2214.30570000 +sleep 3 +echo "2214.30570000 <- expected amount RBbtoXBmNDjh8VYi7mogKCniKcQxBgpmeN" + +# RH6jGuCBF3avqJxWpkwpbDHHELBfXW2atr KMD 23.86363839 +./komodo-cli sendtoaddress RH6jGuCBF3avqJxWpkwpbDHHELBfXW2atr 23.86363839 +sleep 3 +echo "23.86363839 <- expected amount RH6jGuCBF3avqJxWpkwpbDHHELBfXW2atr" + +# RPvApbnHfsum7vc4i7X5P2Sqi9t7mF3DUA KMD 6483.53169406 +./komodo-cli sendtoaddress RPvApbnHfsum7vc4i7X5P2Sqi9t7mF3DUA 6483.53169406 +sleep 3 +echo "6483.53169406 <- expected amount RPvApbnHfsum7vc4i7X5P2Sqi9t7mF3DUA" + +# RACCAv92Wt4C1aKEuuL5tX9wt1ZZ5ztVCG KMD 49.71591332 +./komodo-cli sendtoaddress RACCAv92Wt4C1aKEuuL5tX9wt1ZZ5ztVCG 49.71591332 +sleep 3 +echo "49.71591332 <- expected amount RACCAv92Wt4C1aKEuuL5tX9wt1ZZ5ztVCG" + +# RXLGVWxutb7KB5cJw8gmyvs83XfvChL2oY KMD 32.31534366 +./komodo-cli sendtoaddress RXLGVWxutb7KB5cJw8gmyvs83XfvChL2oY 32.31534366 +sleep 3 +echo "32.31534366 <- expected amount RXLGVWxutb7KB5cJw8gmyvs83XfvChL2oY" + +# RLdbW5GT6WJSevJYzFqDQaPmFcXrmKyPYh KMD 181.98552204 +./komodo-cli sendtoaddress RLdbW5GT6WJSevJYzFqDQaPmFcXrmKyPYh 181.98552204 +sleep 3 +echo "181.98552204 <- expected amount RLdbW5GT6WJSevJYzFqDQaPmFcXrmKyPYh" + +# RCJtsbUUAtzHCDkyctcUUJMaibtVY5piUt KMD 108.89297630 +./komodo-cli sendtoaddress RCJtsbUUAtzHCDkyctcUUJMaibtVY5piUt 108.89297630 +sleep 3 +echo "108.89297630 <- expected amount RCJtsbUUAtzHCDkyctcUUJMaibtVY5piUt" + +# RL9G3TyhdxiWADkAvJV34brvKgKZVxq78V KMD 619.72175960 +./komodo-cli sendtoaddress RL9G3TyhdxiWADkAvJV34brvKgKZVxq78V 619.72175960 +sleep 3 +echo "619.72175960 <- expected amount RL9G3TyhdxiWADkAvJV34brvKgKZVxq78V" + +# RKy5mhomLVy1SwSros7sowZKGuRuz9ceeM KMD 81083.51536582 +./komodo-cli sendtoaddress RKy5mhomLVy1SwSros7sowZKGuRuz9ceeM 81083.51536582 +sleep 3 +echo "81083.51536582 <- expected amount RKy5mhomLVy1SwSros7sowZKGuRuz9ceeM" + +# RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi KMD 248.64863568 +./komodo-cli sendtoaddress RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi 248.64863568 +sleep 3 +echo "248.64863568 <- expected amount RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi" + +# REf7AHXuzcRBgQmhRFi34XK2VrDf1LRJhn KMD 2033.46202368 +./komodo-cli sendtoaddress REf7AHXuzcRBgQmhRFi34XK2VrDf1LRJhn 2033.46202368 +sleep 3 +echo "2033.46202368 <- expected amount REf7AHXuzcRBgQmhRFi34XK2VrDf1LRJhn" + +# RWPicNFcigzRVGKfMgoL5h45URs8ko3P6K KMD 2700.73139303 +./komodo-cli sendtoaddress RWPicNFcigzRVGKfMgoL5h45URs8ko3P6K 2700.73139303 +sleep 3 +echo "2700.73139303 <- expected amount RWPicNFcigzRVGKfMgoL5h45URs8ko3P6K" + +# RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB KMD 34229.39253089 +./komodo-cli sendtoaddress RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB 34229.39253089 +sleep 3 +echo "34229.39253089 <- expected amount RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB" + +# RHXkqP1beRbwHfGrhHcLkgNBS6qvkDZuR6 KMD 27887.47918200 +./komodo-cli sendtoaddress RHXkqP1beRbwHfGrhHcLkgNBS6qvkDZuR6 27887.47918200 +sleep 3 +echo "27887.47918200 <- expected amount RHXkqP1beRbwHfGrhHcLkgNBS6qvkDZuR6" + +# RHw3gDr5hySCT1d5ZoskMKcbsZ7eC9Ey7R KMD 24.37095068 +./komodo-cli sendtoaddress RHw3gDr5hySCT1d5ZoskMKcbsZ7eC9Ey7R 24.37095068 +sleep 3 +echo "24.37095068 <- expected amount RHw3gDr5hySCT1d5ZoskMKcbsZ7eC9Ey7R" + +# RGV11QdETeFJ6RbnKALGTAmMZbXFDuHnnF KMD 181212.75889505 +./komodo-cli sendtoaddress RGV11QdETeFJ6RbnKALGTAmMZbXFDuHnnF 181212.75889505 +sleep 3 +echo "181212.75889505 <- expected amount RGV11QdETeFJ6RbnKALGTAmMZbXFDuHnnF" + +# RV4gpXyGMURSC9Hop44Ysum4vBvwGDitkN KMD 1273.91554206 +./komodo-cli sendtoaddress RV4gpXyGMURSC9Hop44Ysum4vBvwGDitkN 1273.91554206 +sleep 3 +echo "1273.91554206 <- expected amount RV4gpXyGMURSC9Hop44Ysum4vBvwGDitkN" + +# RBV3vBdH2fCx5Eev4HYZ94SJ6a3JXgXr9H KMD 54049.29806312 +./komodo-cli sendtoaddress RBV3vBdH2fCx5Eev4HYZ94SJ6a3JXgXr9H 54049.29806312 +sleep 3 +echo "54049.29806312 <- expected amount RBV3vBdH2fCx5Eev4HYZ94SJ6a3JXgXr9H" + +# RQ6vQBtDYrT65TtFFXCHfPRjkmbBsVpXhW KMD 9828.35196887 +./komodo-cli sendtoaddress RQ6vQBtDYrT65TtFFXCHfPRjkmbBsVpXhW 9828.35196887 +sleep 3 +echo "9828.35196887 <- expected amount RQ6vQBtDYrT65TtFFXCHfPRjkmbBsVpXhW" + +# RK8H5iDRgFmdPnPaYNLecXbbKood1kKyz2 KMD 3244.24341150 +./komodo-cli sendtoaddress RK8H5iDRgFmdPnPaYNLecXbbKood1kKyz2 3244.24341150 +sleep 3 +echo "3244.24341150 <- expected amount RK8H5iDRgFmdPnPaYNLecXbbKood1kKyz2" + +# RAgL8oHgKqog2Wazp8MtctJP67UfHzDXoy KMD 134001.54651965 +./komodo-cli sendtoaddress RAgL8oHgKqog2Wazp8MtctJP67UfHzDXoy 134001.54651965 +sleep 3 +echo "134001.54651965 <- expected amount RAgL8oHgKqog2Wazp8MtctJP67UfHzDXoy" + +# RRZgQUxBpHUH9PtAE3X9sBu8nGX7VYXWMU KMD 1450.48101086 +./komodo-cli sendtoaddress RRZgQUxBpHUH9PtAE3X9sBu8nGX7VYXWMU 1450.48101086 +sleep 3 +echo "1450.48101086 <- expected amount RRZgQUxBpHUH9PtAE3X9sBu8nGX7VYXWMU" + +# RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH KMD 54818.61192554 +./komodo-cli sendtoaddress RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH 54818.61192554 +sleep 3 +echo "54818.61192554 <- expected amount RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH" + +# RYT2XAMsa7KA1ahpXex5RoTywy2kJXVbu8 KMD 12701.61657288 +./komodo-cli sendtoaddress RYT2XAMsa7KA1ahpXex5RoTywy2kJXVbu8 12701.61657288 +sleep 3 +echo "12701.61657288 <- expected amount RYT2XAMsa7KA1ahpXex5RoTywy2kJXVbu8" + +# RLQZSbhFzEUs8D9JfnJGKhNJmHTiqVY6ZF KMD 968.31524937 +./komodo-cli sendtoaddress RLQZSbhFzEUs8D9JfnJGKhNJmHTiqVY6ZF 968.31524937 +sleep 3 +echo "968.31524937 <- expected amount RLQZSbhFzEUs8D9JfnJGKhNJmHTiqVY6ZF" + +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 2288.11223404, REVS 45.41799774 +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 2288.11223404 +./komodo-cli sendtoaddress REVcoi6A4GRfuchCXTwBTszbakhoh9inLs 2288.11223404 +sleep 3 +echo "2288.11223404 <- expected amount REVcoi6A4GRfuchCXTwBTszbakhoh9inLs" + +# RBbmWzgpLURyiCzhGv3j59sCUdCV1yLsti KMD 2227.12507356 +./komodo-cli sendtoaddress RBbmWzgpLURyiCzhGv3j59sCUdCV1yLsti 2227.12507356 +sleep 3 +echo "2227.12507356 <- expected amount RBbmWzgpLURyiCzhGv3j59sCUdCV1yLsti" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RGna6hhbbVEEVZg7GiM7uCXcbz5LMb4rGW KMD 0.84952973 +./komodo-cli sendtoaddress RGna6hhbbVEEVZg7GiM7uCXcbz5LMb4rGW 0.84952973 +sleep 3 +echo "0.84952973 <- expected amount RGna6hhbbVEEVZg7GiM7uCXcbz5LMb4rGW" + +# RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije KMD 13018.84319757, REVS 151.44412616 +# RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije KMD 13018.84319757 +./komodo-cli sendtoaddress RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije 13018.84319757 +sleep 3 +echo "13018.84319757 <- expected amount RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije" + +# RFJwrDJe1oso2UgtQjvcUoWmuTmEk53gBQ KMD 212.11828501 +./komodo-cli sendtoaddress RFJwrDJe1oso2UgtQjvcUoWmuTmEk53gBQ 212.11828501 +sleep 3 +echo "212.11828501 <- expected amount RFJwrDJe1oso2UgtQjvcUoWmuTmEk53gBQ" + +# RMX6HitSa9q859FtybK2fNZ4Wf3jwtRFWR KMD 3195.44032293 +./komodo-cli sendtoaddress RMX6HitSa9q859FtybK2fNZ4Wf3jwtRFWR 3195.44032293 +sleep 3 +echo "3195.44032293 <- expected amount RMX6HitSa9q859FtybK2fNZ4Wf3jwtRFWR" + +# RC1kGvPaYPdM2LqXhQK1jT48yQoeJJwVxz KMD 18396.05310761 +./komodo-cli sendtoaddress RC1kGvPaYPdM2LqXhQK1jT48yQoeJJwVxz 18396.05310761 +sleep 3 +echo "18396.05310761 <- expected amount RC1kGvPaYPdM2LqXhQK1jT48yQoeJJwVxz" + +# REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo KMD 9102.02231944, REVS 180.67104532 +# REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo KMD 9102.02231944 +./komodo-cli sendtoaddress REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo 9102.02231944 +sleep 3 +echo "9102.02231944 <- expected amount REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo" + +# RNgdaVesPmwbGfXcJQRKvvW44dZ6ABxdr6 KMD 15493.04399000 +./komodo-cli sendtoaddress RNgdaVesPmwbGfXcJQRKvvW44dZ6ABxdr6 15493.04399000 +sleep 3 +echo "15493.04399000 <- expected amount RNgdaVesPmwbGfXcJQRKvvW44dZ6ABxdr6" + +# RWrywGAqokYxD11FVNYhFMrh6jjKv827jY KMD 18591.65278800 +./komodo-cli sendtoaddress RWrywGAqokYxD11FVNYhFMrh6jjKv827jY 18591.65278800 +sleep 3 +echo "18591.65278800 <- expected amount RWrywGAqokYxD11FVNYhFMrh6jjKv827jY" + +# RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 KMD 2489.43684219 +./komodo-cli sendtoaddress RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 2489.43684219 +sleep 3 +echo "2489.43684219 <- expected amount RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63" + +# RNnEto9ShSFcUaEaprjCn3qFDUzXpLm7bM KMD 295334.21442887 +./komodo-cli sendtoaddress RNnEto9ShSFcUaEaprjCn3qFDUzXpLm7bM 295334.21442887 +sleep 3 +echo "295334.21442887 <- expected amount RNnEto9ShSFcUaEaprjCn3qFDUzXpLm7bM" + +# RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH KMD 471.00874744 +./komodo-cli sendtoaddress RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH 471.00874744 +sleep 3 +echo "471.00874744 <- expected amount RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH" + +# RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4 KMD 11055.19532209 +./komodo-cli sendtoaddress RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4 11055.19532209 +sleep 3 +echo "11055.19532209 <- expected amount RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4" + + +# total KMD 4481986.01571721 REVS 0.00000000 + + diff --git a/iguana/tests/KMD.batch16.listunspent b/iguana/tests/KMD.batch16.listunspent new file mode 100755 index 000000000..08e6135c2 --- /dev/null +++ b/iguana/tests/KMD.batch16.listunspent @@ -0,0 +1,370 @@ +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 29875.03958530 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ\",\"symbol\":\"KMD\"}" +echo "29875.03958530 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RE7dTo722hnJ5Hm5aLwSk3YrvTCuiaGJGL KMD 2208761.69588058 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RE7dTo722hnJ5Hm5aLwSk3YrvTCuiaGJGL\",\"symbol\":\"KMD\"}" +echo "2208761.69588058 <- expected amount RE7dTo722hnJ5Hm5aLwSk3YrvTCuiaGJGL" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 500.57828265 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ\",\"symbol\":\"KMD\"}" +echo "500.57828265 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RH4ziYsxYKXi6qEe8gR2WftMFDasUmwAN2 KMD 478577.43414711 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH4ziYsxYKXi6qEe8gR2WftMFDasUmwAN2\",\"symbol\":\"KMD\"}" +echo "478577.43414711 <- expected amount RH4ziYsxYKXi6qEe8gR2WftMFDasUmwAN2" + +# RSz39LBAF8G9GLRuQ1BDvBVAcLczH87nqR KMD 14765.68648492 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSz39LBAF8G9GLRuQ1BDvBVAcLczH87nqR\",\"symbol\":\"KMD\"}" +echo "14765.68648492 <- expected amount RSz39LBAF8G9GLRuQ1BDvBVAcLczH87nqR" + +# RPNKYCYh9v7hzH5Cgo7KBjxAVY7sQ681S9 KMD 16568.79001553 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPNKYCYh9v7hzH5Cgo7KBjxAVY7sQ681S9\",\"symbol\":\"KMD\"}" +echo "16568.79001553 <- expected amount RPNKYCYh9v7hzH5Cgo7KBjxAVY7sQ681S9" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 5426.58572255 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" +echo "5426.58572255 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o KMD 2277.23212693 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o\",\"symbol\":\"KMD\"}" +echo "2277.23212693 <- expected amount RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o" + +# R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj KMD 345.82113080 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj\",\"symbol\":\"KMD\"}" +echo "345.82113080 <- expected amount R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj" + +# RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH KMD 32573.04574031 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH\",\"symbol\":\"KMD\"}" +echo "32573.04574031 <- expected amount RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH" + +# RTxYk2J7PQGaNFCKoxFiCJAkgWi1Yf3XWZ KMD 21696.64781873 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTxYk2J7PQGaNFCKoxFiCJAkgWi1Yf3XWZ\",\"symbol\":\"KMD\"}" +echo "21696.64781873 <- expected amount RTxYk2J7PQGaNFCKoxFiCJAkgWi1Yf3XWZ" + +# RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP KMD 4410.81679144 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP\",\"symbol\":\"KMD\"}" +echo "4410.81679144 <- expected amount RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP" + +# RFLQ2DDR5BjNxnz6hqgVpQ7VpmvgyPyB7Q KMD 701.98982318 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFLQ2DDR5BjNxnz6hqgVpQ7VpmvgyPyB7Q\",\"symbol\":\"KMD\"}" +echo "701.98982318 <- expected amount RFLQ2DDR5BjNxnz6hqgVpQ7VpmvgyPyB7Q" + +# RHaYREKsYLwafyk4GZEtWHmJhjzdZymAGK KMD 228081.21691774 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHaYREKsYLwafyk4GZEtWHmJhjzdZymAGK\",\"symbol\":\"KMD\"}" +echo "228081.21691774 <- expected amount RHaYREKsYLwafyk4GZEtWHmJhjzdZymAGK" + +# RHNAivbuzfhneSwLV9VpXSU4PFnEsmNsC4 KMD 620.49641179 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHNAivbuzfhneSwLV9VpXSU4PFnEsmNsC4\",\"symbol\":\"KMD\"}" +echo "620.49641179 <- expected amount RHNAivbuzfhneSwLV9VpXSU4PFnEsmNsC4" + +# RRtJ2f2YJztjFSGVQNnyFPpTt3fQ4RH1MH KMD 940.61717265 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRtJ2f2YJztjFSGVQNnyFPpTt3fQ4RH1MH\",\"symbol\":\"KMD\"}" +echo "940.61717265 <- expected amount RRtJ2f2YJztjFSGVQNnyFPpTt3fQ4RH1MH" + +# RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP KMD 329.20973464 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP\",\"symbol\":\"KMD\"}" +echo "329.20973464 <- expected amount RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP" + +# RB91pNtAQVu9qfhFkFYX4x4G1QfcEDNe1n KMD 890.85002942 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RB91pNtAQVu9qfhFkFYX4x4G1QfcEDNe1n\",\"symbol\":\"KMD\"}" +echo "890.85002942 <- expected amount RB91pNtAQVu9qfhFkFYX4x4G1QfcEDNe1n" + +# RRGgzASdJ4yBv7Y9o39r9iwCit1jbXhpX3 KMD 48415.76246875 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRGgzASdJ4yBv7Y9o39r9iwCit1jbXhpX3\",\"symbol\":\"KMD\"}" +echo "48415.76246875 <- expected amount RRGgzASdJ4yBv7Y9o39r9iwCit1jbXhpX3" + +# RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 KMD 258573.82999375 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3\",\"symbol\":\"KMD\"}" +echo "258573.82999375 <- expected amount RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3" + +# RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV KMD 857.10994504, REVS 17.01091436 +# RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV KMD 857.10994504 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV\",\"symbol\":\"KMD\"}" +echo "857.10994504 <- expected amount RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV" + +# RCX7MWLQEwgoo6qAdzbaeUBZ4x6KC5KDyg KMD 2324.11284584 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCX7MWLQEwgoo6qAdzbaeUBZ4x6KC5KDyg\",\"symbol\":\"KMD\"}" +echo "2324.11284584 <- expected amount RCX7MWLQEwgoo6qAdzbaeUBZ4x6KC5KDyg" + +# RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY KMD 10017.77725515 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY\",\"symbol\":\"KMD\"}" +echo "10017.77725515 <- expected amount RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 6114.70953620 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" +echo "6114.70953620 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RSCpqqjUyjAzs2XT8ra4VzcgQoQJJL6ygB KMD 1529.93809401 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSCpqqjUyjAzs2XT8ra4VzcgQoQJJL6ygB\",\"symbol\":\"KMD\"}" +echo "1529.93809401 <- expected amount RSCpqqjUyjAzs2XT8ra4VzcgQoQJJL6ygB" + +# RH8ZCNFMWAavi3n5v2buQ5QZVDJnD4BXMj KMD 315.34144784 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH8ZCNFMWAavi3n5v2buQ5QZVDJnD4BXMj\",\"symbol\":\"KMD\"}" +echo "315.34144784 <- expected amount RH8ZCNFMWAavi3n5v2buQ5QZVDJnD4BXMj" + +# RHY2jW41xptqKfmxDNvojC9MmC6VSTmYTe KMD 2913.66058536 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHY2jW41xptqKfmxDNvojC9MmC6VSTmYTe\",\"symbol\":\"KMD\"}" +echo "2913.66058536 <- expected amount RHY2jW41xptqKfmxDNvojC9MmC6VSTmYTe" + +# RF6kNo4YBUHn9hHD94fQPx7sBVcDLLLDut KMD 809.20571578 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RF6kNo4YBUHn9hHD94fQPx7sBVcDLLLDut\",\"symbol\":\"KMD\"}" +echo "809.20571578 <- expected amount RF6kNo4YBUHn9hHD94fQPx7sBVcDLLLDut" + +# REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf KMD 10922.30573649 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf\",\"symbol\":\"KMD\"}" +echo "10922.30573649 <- expected amount REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf" + +# RKd488zhEwgwbtonvv1jvXxq9CtWx7JdTt KMD 8552.16028247 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKd488zhEwgwbtonvv1jvXxq9CtWx7JdTt\",\"symbol\":\"KMD\"}" +echo "8552.16028247 <- expected amount RKd488zhEwgwbtonvv1jvXxq9CtWx7JdTt" + +# REDLuGEpoo7d3Z2CvCpNu5VFYoToDWVquZ KMD 11.76905135 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REDLuGEpoo7d3Z2CvCpNu5VFYoToDWVquZ\",\"symbol\":\"KMD\"}" +echo "11.76905135 <- expected amount REDLuGEpoo7d3Z2CvCpNu5VFYoToDWVquZ" + +# RYNFwcLAQoqWuzZxT8eAnDX8qYyyy8X7CH KMD 781.69278094 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYNFwcLAQoqWuzZxT8eAnDX8qYyyy8X7CH\",\"symbol\":\"KMD\"}" +echo "781.69278094 <- expected amount RYNFwcLAQoqWuzZxT8eAnDX8qYyyy8X7CH" + +# RPy24KLGQcj2ixf6VpRC8ceNt2TGfaotJc KMD 5055.79050524 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPy24KLGQcj2ixf6VpRC8ceNt2TGfaotJc\",\"symbol\":\"KMD\"}" +echo "5055.79050524 <- expected amount RPy24KLGQcj2ixf6VpRC8ceNt2TGfaotJc" + +# RDS7pdCZNjXNDZRRN9ThhU9vR9wwDjzkRg KMD 15570.39216000 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDS7pdCZNjXNDZRRN9ThhU9vR9wwDjzkRg\",\"symbol\":\"KMD\"}" +echo "15570.39216000 <- expected amount RDS7pdCZNjXNDZRRN9ThhU9vR9wwDjzkRg" + +# RENgBDkBfw4gJCq4C62kUFtB9z75hTeWJu KMD 131.27522160 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RENgBDkBfw4gJCq4C62kUFtB9z75hTeWJu\",\"symbol\":\"KMD\"}" +echo "131.27522160 <- expected amount RENgBDkBfw4gJCq4C62kUFtB9z75hTeWJu" + +# RJ2mT6TfXDGDpozBfFQH9khUkisvp2s3bR KMD 20678.85680809 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJ2mT6TfXDGDpozBfFQH9khUkisvp2s3bR\",\"symbol\":\"KMD\"}" +echo "20678.85680809 <- expected amount RJ2mT6TfXDGDpozBfFQH9khUkisvp2s3bR" + +# RK1bfZervNSyMuQPDtK7iPX1YUj5EMvmY1 KMD 4841.57624687 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RK1bfZervNSyMuQPDtK7iPX1YUj5EMvmY1\",\"symbol\":\"KMD\"}" +echo "4841.57624687 <- expected amount RK1bfZervNSyMuQPDtK7iPX1YUj5EMvmY1" + +# RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU KMD 8.94389143 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU\",\"symbol\":\"KMD\"}" +echo "8.94389143 <- expected amount RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU" + +# RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW KMD 1000.80729416 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW\",\"symbol\":\"KMD\"}" +echo "1000.80729416 <- expected amount RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW" + +# RSkxA4q8XD4fH6SFXASdbijeEnMpmw9gag KMD 1282.60555481 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSkxA4q8XD4fH6SFXASdbijeEnMpmw9gag\",\"symbol\":\"KMD\"}" +echo "1282.60555481 <- expected amount RSkxA4q8XD4fH6SFXASdbijeEnMpmw9gag" + +# RJFk6N5CeieX3RhSSTBWEL5LwKVaKeQf83 KMD 247.94454562 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJFk6N5CeieX3RhSSTBWEL5LwKVaKeQf83\",\"symbol\":\"KMD\"}" +echo "247.94454562 <- expected amount RJFk6N5CeieX3RhSSTBWEL5LwKVaKeQf83" + +# RCG3XokbbH3QEu4hL4gbZwTK34rDoVKg4u KMD 9295.82639400 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCG3XokbbH3QEu4hL4gbZwTK34rDoVKg4u\",\"symbol\":\"KMD\"}" +echo "9295.82639400 <- expected amount RCG3XokbbH3QEu4hL4gbZwTK34rDoVKg4u" + +# RCuECu2yAYZeG3HiAkXiaxCvKa5gduKL9H KMD 3949.77164792 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCuECu2yAYZeG3HiAkXiaxCvKa5gduKL9H\",\"symbol\":\"KMD\"}" +echo "3949.77164792 <- expected amount RCuECu2yAYZeG3HiAkXiaxCvKa5gduKL9H" + +# RXDpDLmaF34iHXc8DJLrZyqj1v2HpXH7CB KMD 8845.81358175 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXDpDLmaF34iHXc8DJLrZyqj1v2HpXH7CB\",\"symbol\":\"KMD\"}" +echo "8845.81358175 <- expected amount RXDpDLmaF34iHXc8DJLrZyqj1v2HpXH7CB" + +# RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv KMD 2300.71703251 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv\",\"symbol\":\"KMD\"}" +echo "2300.71703251 <- expected amount RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv" + +# RRW5pyLoAc2GAx618xer3ywidtN83a9nZP KMD 52.19445674 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRW5pyLoAc2GAx618xer3ywidtN83a9nZP\",\"symbol\":\"KMD\"}" +echo "52.19445674 <- expected amount RRW5pyLoAc2GAx618xer3ywidtN83a9nZP" + +# RGrJ4AGWusVdLTVsvV3xsTBZe6d1qVS16q KMD 36.13200587 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGrJ4AGWusVdLTVsvV3xsTBZe6d1qVS16q\",\"symbol\":\"KMD\"}" +echo "36.13200587 <- expected amount RGrJ4AGWusVdLTVsvV3xsTBZe6d1qVS16q" + +# RAsDYD3FWvQ42eDqDnyaJgcpmUZrarA44w KMD 422.85217955 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAsDYD3FWvQ42eDqDnyaJgcpmUZrarA44w\",\"symbol\":\"KMD\"}" +echo "422.85217955 <- expected amount RAsDYD3FWvQ42eDqDnyaJgcpmUZrarA44w" + +# RGYvkNa4vTD6QYkUyugw9Dyk285Q5qGo4B KMD 217.54701681 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGYvkNa4vTD6QYkUyugw9Dyk285Q5qGo4B\",\"symbol\":\"KMD\"}" +echo "217.54701681 <- expected amount RGYvkNa4vTD6QYkUyugw9Dyk285Q5qGo4B" + +# RGukbCjoDr2PiJSH6NNC4t7UDQWFkx8zQz KMD 4005.10943567 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGukbCjoDr2PiJSH6NNC4t7UDQWFkx8zQz\",\"symbol\":\"KMD\"}" +echo "4005.10943567 <- expected amount RGukbCjoDr2PiJSH6NNC4t7UDQWFkx8zQz" + +# RMusGcGfCfzNT8S8xYz6p6sPCoxtt4zZzt KMD 519.46088391 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMusGcGfCfzNT8S8xYz6p6sPCoxtt4zZzt\",\"symbol\":\"KMD\"}" +echo "519.46088391 <- expected amount RMusGcGfCfzNT8S8xYz6p6sPCoxtt4zZzt" + +# RBbtoXBmNDjh8VYi7mogKCniKcQxBgpmeN KMD 2214.30570000 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBbtoXBmNDjh8VYi7mogKCniKcQxBgpmeN\",\"symbol\":\"KMD\"}" +echo "2214.30570000 <- expected amount RBbtoXBmNDjh8VYi7mogKCniKcQxBgpmeN" + +# RH6jGuCBF3avqJxWpkwpbDHHELBfXW2atr KMD 23.86363839 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH6jGuCBF3avqJxWpkwpbDHHELBfXW2atr\",\"symbol\":\"KMD\"}" +echo "23.86363839 <- expected amount RH6jGuCBF3avqJxWpkwpbDHHELBfXW2atr" + +# RPvApbnHfsum7vc4i7X5P2Sqi9t7mF3DUA KMD 6483.53169406 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPvApbnHfsum7vc4i7X5P2Sqi9t7mF3DUA\",\"symbol\":\"KMD\"}" +echo "6483.53169406 <- expected amount RPvApbnHfsum7vc4i7X5P2Sqi9t7mF3DUA" + +# RACCAv92Wt4C1aKEuuL5tX9wt1ZZ5ztVCG KMD 49.71591332 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RACCAv92Wt4C1aKEuuL5tX9wt1ZZ5ztVCG\",\"symbol\":\"KMD\"}" +echo "49.71591332 <- expected amount RACCAv92Wt4C1aKEuuL5tX9wt1ZZ5ztVCG" + +# RXLGVWxutb7KB5cJw8gmyvs83XfvChL2oY KMD 32.31534366 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXLGVWxutb7KB5cJw8gmyvs83XfvChL2oY\",\"symbol\":\"KMD\"}" +echo "32.31534366 <- expected amount RXLGVWxutb7KB5cJw8gmyvs83XfvChL2oY" + +# RLdbW5GT6WJSevJYzFqDQaPmFcXrmKyPYh KMD 181.98552204 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLdbW5GT6WJSevJYzFqDQaPmFcXrmKyPYh\",\"symbol\":\"KMD\"}" +echo "181.98552204 <- expected amount RLdbW5GT6WJSevJYzFqDQaPmFcXrmKyPYh" + +# RCJtsbUUAtzHCDkyctcUUJMaibtVY5piUt KMD 108.89297630 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCJtsbUUAtzHCDkyctcUUJMaibtVY5piUt\",\"symbol\":\"KMD\"}" +echo "108.89297630 <- expected amount RCJtsbUUAtzHCDkyctcUUJMaibtVY5piUt" + +# RL9G3TyhdxiWADkAvJV34brvKgKZVxq78V KMD 619.72175960 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RL9G3TyhdxiWADkAvJV34brvKgKZVxq78V\",\"symbol\":\"KMD\"}" +echo "619.72175960 <- expected amount RL9G3TyhdxiWADkAvJV34brvKgKZVxq78V" + +# RKy5mhomLVy1SwSros7sowZKGuRuz9ceeM KMD 81083.51536582 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKy5mhomLVy1SwSros7sowZKGuRuz9ceeM\",\"symbol\":\"KMD\"}" +echo "81083.51536582 <- expected amount RKy5mhomLVy1SwSros7sowZKGuRuz9ceeM" + +# RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi KMD 248.64863568 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi\",\"symbol\":\"KMD\"}" +echo "248.64863568 <- expected amount RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi" + +# REf7AHXuzcRBgQmhRFi34XK2VrDf1LRJhn KMD 2033.46202368 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REf7AHXuzcRBgQmhRFi34XK2VrDf1LRJhn\",\"symbol\":\"KMD\"}" +echo "2033.46202368 <- expected amount REf7AHXuzcRBgQmhRFi34XK2VrDf1LRJhn" + +# RWPicNFcigzRVGKfMgoL5h45URs8ko3P6K KMD 2700.73139303 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWPicNFcigzRVGKfMgoL5h45URs8ko3P6K\",\"symbol\":\"KMD\"}" +echo "2700.73139303 <- expected amount RWPicNFcigzRVGKfMgoL5h45URs8ko3P6K" + +# RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB KMD 34229.39253089 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB\",\"symbol\":\"KMD\"}" +echo "34229.39253089 <- expected amount RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB" + +# RHXkqP1beRbwHfGrhHcLkgNBS6qvkDZuR6 KMD 27887.47918200 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHXkqP1beRbwHfGrhHcLkgNBS6qvkDZuR6\",\"symbol\":\"KMD\"}" +echo "27887.47918200 <- expected amount RHXkqP1beRbwHfGrhHcLkgNBS6qvkDZuR6" + +# RHw3gDr5hySCT1d5ZoskMKcbsZ7eC9Ey7R KMD 24.37095068 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHw3gDr5hySCT1d5ZoskMKcbsZ7eC9Ey7R\",\"symbol\":\"KMD\"}" +echo "24.37095068 <- expected amount RHw3gDr5hySCT1d5ZoskMKcbsZ7eC9Ey7R" + +# RGV11QdETeFJ6RbnKALGTAmMZbXFDuHnnF KMD 181212.75889505 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGV11QdETeFJ6RbnKALGTAmMZbXFDuHnnF\",\"symbol\":\"KMD\"}" +echo "181212.75889505 <- expected amount RGV11QdETeFJ6RbnKALGTAmMZbXFDuHnnF" + +# RV4gpXyGMURSC9Hop44Ysum4vBvwGDitkN KMD 1273.91554206 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RV4gpXyGMURSC9Hop44Ysum4vBvwGDitkN\",\"symbol\":\"KMD\"}" +echo "1273.91554206 <- expected amount RV4gpXyGMURSC9Hop44Ysum4vBvwGDitkN" + +# RBV3vBdH2fCx5Eev4HYZ94SJ6a3JXgXr9H KMD 54049.29806312 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBV3vBdH2fCx5Eev4HYZ94SJ6a3JXgXr9H\",\"symbol\":\"KMD\"}" +echo "54049.29806312 <- expected amount RBV3vBdH2fCx5Eev4HYZ94SJ6a3JXgXr9H" + +# RQ6vQBtDYrT65TtFFXCHfPRjkmbBsVpXhW KMD 9828.35196887 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQ6vQBtDYrT65TtFFXCHfPRjkmbBsVpXhW\",\"symbol\":\"KMD\"}" +echo "9828.35196887 <- expected amount RQ6vQBtDYrT65TtFFXCHfPRjkmbBsVpXhW" + +# RK8H5iDRgFmdPnPaYNLecXbbKood1kKyz2 KMD 3244.24341150 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RK8H5iDRgFmdPnPaYNLecXbbKood1kKyz2\",\"symbol\":\"KMD\"}" +echo "3244.24341150 <- expected amount RK8H5iDRgFmdPnPaYNLecXbbKood1kKyz2" + +# RAgL8oHgKqog2Wazp8MtctJP67UfHzDXoy KMD 134001.54651965 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAgL8oHgKqog2Wazp8MtctJP67UfHzDXoy\",\"symbol\":\"KMD\"}" +echo "134001.54651965 <- expected amount RAgL8oHgKqog2Wazp8MtctJP67UfHzDXoy" + +# RRZgQUxBpHUH9PtAE3X9sBu8nGX7VYXWMU KMD 1450.48101086 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRZgQUxBpHUH9PtAE3X9sBu8nGX7VYXWMU\",\"symbol\":\"KMD\"}" +echo "1450.48101086 <- expected amount RRZgQUxBpHUH9PtAE3X9sBu8nGX7VYXWMU" + +# RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH KMD 54818.61192554 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH\",\"symbol\":\"KMD\"}" +echo "54818.61192554 <- expected amount RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH" + +# RYT2XAMsa7KA1ahpXex5RoTywy2kJXVbu8 KMD 12701.61657288 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYT2XAMsa7KA1ahpXex5RoTywy2kJXVbu8\",\"symbol\":\"KMD\"}" +echo "12701.61657288 <- expected amount RYT2XAMsa7KA1ahpXex5RoTywy2kJXVbu8" + +# RLQZSbhFzEUs8D9JfnJGKhNJmHTiqVY6ZF KMD 968.31524937 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLQZSbhFzEUs8D9JfnJGKhNJmHTiqVY6ZF\",\"symbol\":\"KMD\"}" +echo "968.31524937 <- expected amount RLQZSbhFzEUs8D9JfnJGKhNJmHTiqVY6ZF" + +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 2288.11223404, REVS 45.41799774 +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 2288.11223404 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REVcoi6A4GRfuchCXTwBTszbakhoh9inLs\",\"symbol\":\"KMD\"}" +echo "2288.11223404 <- expected amount REVcoi6A4GRfuchCXTwBTszbakhoh9inLs" + +# RBbmWzgpLURyiCzhGv3j59sCUdCV1yLsti KMD 2227.12507356 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBbmWzgpLURyiCzhGv3j59sCUdCV1yLsti\",\"symbol\":\"KMD\"}" +echo "2227.12507356 <- expected amount RBbmWzgpLURyiCzhGv3j59sCUdCV1yLsti" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RGna6hhbbVEEVZg7GiM7uCXcbz5LMb4rGW KMD 0.84952973 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGna6hhbbVEEVZg7GiM7uCXcbz5LMb4rGW\",\"symbol\":\"KMD\"}" +echo "0.84952973 <- expected amount RGna6hhbbVEEVZg7GiM7uCXcbz5LMb4rGW" + +# RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije KMD 13018.84319757, REVS 151.44412616 +# RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije KMD 13018.84319757 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije\",\"symbol\":\"KMD\"}" +echo "13018.84319757 <- expected amount RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije" + +# RFJwrDJe1oso2UgtQjvcUoWmuTmEk53gBQ KMD 212.11828501 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFJwrDJe1oso2UgtQjvcUoWmuTmEk53gBQ\",\"symbol\":\"KMD\"}" +echo "212.11828501 <- expected amount RFJwrDJe1oso2UgtQjvcUoWmuTmEk53gBQ" + +# RMX6HitSa9q859FtybK2fNZ4Wf3jwtRFWR KMD 3195.44032293 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMX6HitSa9q859FtybK2fNZ4Wf3jwtRFWR\",\"symbol\":\"KMD\"}" +echo "3195.44032293 <- expected amount RMX6HitSa9q859FtybK2fNZ4Wf3jwtRFWR" + +# RC1kGvPaYPdM2LqXhQK1jT48yQoeJJwVxz KMD 18396.05310761 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC1kGvPaYPdM2LqXhQK1jT48yQoeJJwVxz\",\"symbol\":\"KMD\"}" +echo "18396.05310761 <- expected amount RC1kGvPaYPdM2LqXhQK1jT48yQoeJJwVxz" + +# REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo KMD 9102.02231944, REVS 180.67104532 +# REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo KMD 9102.02231944 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo\",\"symbol\":\"KMD\"}" +echo "9102.02231944 <- expected amount REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo" + +# RNgdaVesPmwbGfXcJQRKvvW44dZ6ABxdr6 KMD 15493.04399000 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNgdaVesPmwbGfXcJQRKvvW44dZ6ABxdr6\",\"symbol\":\"KMD\"}" +echo "15493.04399000 <- expected amount RNgdaVesPmwbGfXcJQRKvvW44dZ6ABxdr6" + +# RWrywGAqokYxD11FVNYhFMrh6jjKv827jY KMD 18591.65278800 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWrywGAqokYxD11FVNYhFMrh6jjKv827jY\",\"symbol\":\"KMD\"}" +echo "18591.65278800 <- expected amount RWrywGAqokYxD11FVNYhFMrh6jjKv827jY" + +# RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 KMD 2489.43684219 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63\",\"symbol\":\"KMD\"}" +echo "2489.43684219 <- expected amount RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63" + +# RNnEto9ShSFcUaEaprjCn3qFDUzXpLm7bM KMD 295334.21442887 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNnEto9ShSFcUaEaprjCn3qFDUzXpLm7bM\",\"symbol\":\"KMD\"}" +echo "295334.21442887 <- expected amount RNnEto9ShSFcUaEaprjCn3qFDUzXpLm7bM" + +# RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH KMD 471.00874744 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH\",\"symbol\":\"KMD\"}" +echo "471.00874744 <- expected amount RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH" + +# RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4 KMD 11055.19532209 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4\",\"symbol\":\"KMD\"}" +echo "11055.19532209 <- expected amount RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4" + + +# total KMD 0.00000000 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch17 b/iguana/tests/KMD.batch17 new file mode 100755 index 000000000..2b5513271 --- /dev/null +++ b/iguana/tests/KMD.batch17 @@ -0,0 +1,434 @@ +sleep 9999999 +# RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 KMD 108998.28313606 +./komodo-cli sendtoaddress RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 108998.28313606 +sleep 3 +echo "108998.28313606 <- expected amount RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 196.34763557 +./komodo-cli sendtoaddress RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ 196.34763557 +sleep 3 +echo "196.34763557 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU KMD 14524.72874062 +./komodo-cli sendtoaddress RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU 14524.72874062 +sleep 3 +echo "14524.72874062 <- expected amount RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU" + +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 16017.97255691 +./komodo-cli sendtoaddress REVcoi6A4GRfuchCXTwBTszbakhoh9inLs 16017.97255691 +sleep 3 +echo "16017.97255691 <- expected amount REVcoi6A4GRfuchCXTwBTszbakhoh9inLs" + +# RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22 KMD 145928.92215821 +./komodo-cli sendtoaddress RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22 145928.92215821 +sleep 3 +echo "145928.92215821 <- expected amount RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22" + +# RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6 KMD 114940.35721379 +./komodo-cli sendtoaddress RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6 114940.35721379 +sleep 3 +echo "114940.35721379 <- expected amount RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6" + +# RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU KMD 28699.34324752 +./komodo-cli sendtoaddress RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU 28699.34324752 +sleep 3 +echo "28699.34324752 <- expected amount RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU" + +# RV25zizocv445ht9My45WaxpGuAC42cxLa KMD 101090.11347764 +./komodo-cli sendtoaddress RV25zizocv445ht9My45WaxpGuAC42cxLa 101090.11347764 +sleep 3 +echo "101090.11347764 <- expected amount RV25zizocv445ht9My45WaxpGuAC42cxLa" + +# RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S KMD 1704.23483890 +./komodo-cli sendtoaddress RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S 1704.23483890 +sleep 3 +echo "1704.23483890 <- expected amount RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S" + +# RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD KMD 96831.52493750 +./komodo-cli sendtoaddress RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD 96831.52493750 +sleep 3 +echo "96831.52493750 <- expected amount RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD" + +# RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve KMD 11.06362104 +./komodo-cli sendtoaddress RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve 11.06362104 +sleep 3 +echo "11.06362104 <- expected amount RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve" + +# RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv KMD 32009.28059927 +./komodo-cli sendtoaddress RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv 32009.28059927 +sleep 3 +echo "32009.28059927 <- expected amount RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv" + +# RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh KMD 305.48459176 +./komodo-cli sendtoaddress RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh 305.48459176 +sleep 3 +echo "305.48459176 <- expected amount RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh" + +# RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 KMD 162977.74808228 +./komodo-cli sendtoaddress RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 162977.74808228 +sleep 3 +echo "162977.74808228 <- expected amount RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3" + +# RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn KMD 9683.15249375 +./komodo-cli sendtoaddress RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn" + +# RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3 KMD 1593.10203942 +./komodo-cli sendtoaddress RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3 1593.10203942 +sleep 3 +echo "1593.10203942 <- expected amount RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3" + +# RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu KMD 4066.11066256 +./komodo-cli sendtoaddress RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu 4066.11066256 +sleep 3 +echo "4066.11066256 <- expected amount RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu" + +# RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc KMD 4014.80536992 +./komodo-cli sendtoaddress RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc 4014.80536992 +sleep 3 +echo "4014.80536992 <- expected amount RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc" + +# RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd KMD 2904.94574812 +./komodo-cli sendtoaddress RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd 2904.94574812 +sleep 3 +echo "2904.94574812 <- expected amount RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd" + +# REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc KMD 38080.08587787 +./komodo-cli sendtoaddress REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc 38080.08587787 +sleep 3 +echo "38080.08587787 <- expected amount REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc" + +# RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7 KMD 875.08198390 +./komodo-cli sendtoaddress RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7 875.08198390 +sleep 3 +echo "875.08198390 <- expected amount RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7" + +# RULousSwdVGhaP6vusva8u9AQWTs8ugjfp KMD 9683.15249375 +./komodo-cli sendtoaddress RULousSwdVGhaP6vusva8u9AQWTs8ugjfp 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RULousSwdVGhaP6vusva8u9AQWTs8ugjfp" + +# RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK KMD 2954.24166783 +./komodo-cli sendtoaddress RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK 2954.24166783 +sleep 3 +echo "2954.24166783 <- expected amount RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK" + +# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193, REVS 708.36533209 +# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193 +./komodo-cli sendtoaddress RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU 35716.07599193 +sleep 3 +echo "35716.07599193 <- expected amount RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU" + +# R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH KMD 1681.36207445 +./komodo-cli sendtoaddress R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH 1681.36207445 +sleep 3 +echo "1681.36207445 <- expected amount R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH" + +# RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ KMD 7119.36644540 +./komodo-cli sendtoaddress RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ 7119.36644540 +sleep 3 +echo "7119.36644540 <- expected amount RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ" + +# RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV KMD 29049.45748125 +./komodo-cli sendtoaddress RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV 29049.45748125 +sleep 3 +echo "29049.45748125 <- expected amount RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV" + +# RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG KMD 216.38341633 +./komodo-cli sendtoaddress RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG 216.38341633 +sleep 3 +echo "216.38341633 <- expected amount RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG" + +# RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 KMD 3239.94057692 +./komodo-cli sendtoaddress RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 3239.94057692 +sleep 3 +echo "3239.94057692 <- expected amount RWc6GouJggQDsBCeW1DYck629FPrDJCTP9" + +# R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY KMD 723.21529345 +./komodo-cli sendtoaddress R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY 723.21529345 +sleep 3 +echo "723.21529345 <- expected amount R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY" + +# RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd KMD 20415.81928042 +./komodo-cli sendtoaddress RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd 20415.81928042 +sleep 3 +echo "20415.81928042 <- expected amount RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd" + +# RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 KMD 4319.48050817 +./komodo-cli sendtoaddress RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 4319.48050817 +sleep 3 +echo "4319.48050817 <- expected amount RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63" + +# RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1 KMD 155.08169171 +./komodo-cli sendtoaddress RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1 155.08169171 +sleep 3 +echo "155.08169171 <- expected amount RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1" + +# RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC KMD 5177.29144163 +./komodo-cli sendtoaddress RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC 5177.29144163 +sleep 3 +echo "5177.29144163 <- expected amount RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC" + +# RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS KMD 2034.11335616 +./komodo-cli sendtoaddress RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS 2034.11335616 +sleep 3 +echo "2034.11335616 <- expected amount RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS" + +# RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk KMD 8034.62340879 +./komodo-cli sendtoaddress RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk 8034.62340879 +sleep 3 +echo "8034.62340879 <- expected amount RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk" + +# RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW KMD 987.78018920 +./komodo-cli sendtoaddress RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW 987.78018920 +sleep 3 +echo "987.78018920 <- expected amount RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW" + +# RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM KMD 98.35737149 +./komodo-cli sendtoaddress RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM 98.35737149 +sleep 3 +echo "98.35737149 <- expected amount RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 8442.69675032 +./komodo-cli sendtoaddress RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz 8442.69675032 +sleep 3 +echo "8442.69675032 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU KMD 35.32468867 +./komodo-cli sendtoaddress RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU 35.32468867 +sleep 3 +echo "35.32468867 <- expected amount RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU" + +# RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww KMD 2418.19228276 +./komodo-cli sendtoaddress RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww 2418.19228276 +sleep 3 +echo "2418.19228276 <- expected amount RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww" + +# RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb KMD 34.72735411 +./komodo-cli sendtoaddress RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb 34.72735411 +sleep 3 +echo "34.72735411 <- expected amount RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb" + +# RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ KMD 49.50870613 +./komodo-cli sendtoaddress RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ 49.50870613 +sleep 3 +echo "49.50870613 <- expected amount RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ" + +# RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ KMD 9683.15249375 +./komodo-cli sendtoaddress RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ" + +# RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u KMD 56.66050704 +./komodo-cli sendtoaddress RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u 56.66050704 +sleep 3 +echo "56.66050704 <- expected amount RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u" + +# RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74 KMD 722.28571081 +./komodo-cli sendtoaddress RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74 722.28571081 +sleep 3 +echo "722.28571081 <- expected amount RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74" + +# RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68 KMD 226.29998024 +./komodo-cli sendtoaddress RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68 226.29998024 +sleep 3 +echo "226.29998024 <- expected amount RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68" + +# RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P KMD 1160.04166875 +./komodo-cli sendtoaddress RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P 1160.04166875 +sleep 3 +echo "1160.04166875 <- expected amount RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P" + +# REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3 KMD 5365.78339027 +./komodo-cli sendtoaddress REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3 5365.78339027 +sleep 3 +echo "5365.78339027 <- expected amount REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3" + +# RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab KMD 9683.15249375 +./komodo-cli sendtoaddress RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab" + +# RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv KMD 2475.13554655 +./komodo-cli sendtoaddress RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv 2475.13554655 +sleep 3 +echo "2475.13554655 <- expected amount RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv" + +# RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp KMD 6778.20674562 +./komodo-cli sendtoaddress RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp 6778.20674562 +sleep 3 +echo "6778.20674562 <- expected amount RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp" + +# RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh KMD 3898.73512521 +./komodo-cli sendtoaddress RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh 3898.73512521 +sleep 3 +echo "3898.73512521 <- expected amount RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh" + +# R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ KMD 18775.43011383 +./komodo-cli sendtoaddress R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ 18775.43011383 +sleep 3 +echo "18775.43011383 <- expected amount R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ" + +# RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL KMD 49.27663407 +./komodo-cli sendtoaddress RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL 49.27663407 +sleep 3 +echo "49.27663407 <- expected amount RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL" + +# RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3 KMD 1177.96870224 +./komodo-cli sendtoaddress RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3 1177.96870224 +sleep 3 +echo "1177.96870224 <- expected amount RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3" + +# RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW KMD 3692.18604586 +./komodo-cli sendtoaddress RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW 3692.18604586 +sleep 3 +echo "3692.18604586 <- expected amount RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW" + +# RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S KMD 422.98413624 +./komodo-cli sendtoaddress RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S 422.98413624 +sleep 3 +echo "422.98413624 <- expected amount RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S" + +# RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk KMD 428171.85680159 +./komodo-cli sendtoaddress RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk 428171.85680159 +sleep 3 +echo "428171.85680159 <- expected amount RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk" + +# RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB KMD 27228.79164783 +./komodo-cli sendtoaddress RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB 27228.79164783 +sleep 3 +echo "27228.79164783 <- expected amount RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB" + +# RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU KMD 6109.56883640 +./komodo-cli sendtoaddress RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU 6109.56883640 +sleep 3 +echo "6109.56883640 <- expected amount RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU" + +# RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN KMD 316058.09739600 +./komodo-cli sendtoaddress RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN 316058.09739600 +sleep 3 +echo "316058.09739600 <- expected amount RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN" + +# RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH KMD 51229.88531218 +./komodo-cli sendtoaddress RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH 51229.88531218 +sleep 3 +echo "51229.88531218 <- expected amount RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH" + +# RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s KMD 110083.51536582 +./komodo-cli sendtoaddress RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s 110083.51536582 +sleep 3 +echo "110083.51536582 <- expected amount RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s" + +# RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX KMD 9295.82639400 +./komodo-cli sendtoaddress RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX" + +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 2611.69343481 +./komodo-cli sendtoaddress RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK 2611.69343481 +sleep 3 +echo "2611.69343481 <- expected amount RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK" + +# RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs KMD 4841.57624687 +./komodo-cli sendtoaddress RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs 4841.57624687 +sleep 3 +echo "4841.57624687 <- expected amount RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs" + +# RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW KMD 813.38480947 +./komodo-cli sendtoaddress RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW 813.38480947 +sleep 3 +echo "813.38480947 <- expected amount RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW" + +# RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH KMD 20170.43419449 +./komodo-cli sendtoaddress RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH 20170.43419449 +sleep 3 +echo "20170.43419449 <- expected amount RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH" + +# RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD KMD 681.69393556 +./komodo-cli sendtoaddress RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD 681.69393556 +sleep 3 +echo "681.69393556 <- expected amount RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD" + +# RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim KMD 1510.02573700 +./komodo-cli sendtoaddress RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim 1510.02573700 +sleep 3 +echo "1510.02573700 <- expected amount RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy KMD 842.93959567 +./komodo-cli sendtoaddress RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy 842.93959567 +sleep 3 +echo "842.93959567 <- expected amount RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy" + +# RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue KMD 1580.29048698 +./komodo-cli sendtoaddress RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue 1580.29048698 +sleep 3 +echo "1580.29048698 <- expected amount RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue" + +# RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN KMD 2904.94574812 +./komodo-cli sendtoaddress RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN 2904.94574812 +sleep 3 +echo "2904.94574812 <- expected amount RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN" + +# RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX KMD 594.35547049 +./komodo-cli sendtoaddress RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX 594.35547049 +sleep 3 +echo "594.35547049 <- expected amount RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX" + +# RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE KMD 929.58263940 +./komodo-cli sendtoaddress RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE 929.58263940 +sleep 3 +echo "929.58263940 <- expected amount RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE" + +# RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP KMD 95491.01211941 +./komodo-cli sendtoaddress RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP 95491.01211941 +sleep 3 +echo "95491.01211941 <- expected amount RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP" + +# RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY KMD 2631.59182505 +./komodo-cli sendtoaddress RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY 2631.59182505 +sleep 3 +echo "2631.59182505 <- expected amount RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY" + +# RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn KMD 5701.16057828 +./komodo-cli sendtoaddress RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn 5701.16057828 +sleep 3 +echo "5701.16057828 <- expected amount RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn" + +# RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a KMD 49.10934879 +./komodo-cli sendtoaddress RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a 49.10934879 +sleep 3 +echo "49.10934879 <- expected amount RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a" + +# RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR KMD 911.94644914 +./komodo-cli sendtoaddress RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR 911.94644914 +sleep 3 +echo "911.94644914 <- expected amount RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR" + +# RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH KMD 2169.54630422 +./komodo-cli sendtoaddress RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH 2169.54630422 +sleep 3 +echo "2169.54630422 <- expected amount RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH" + +# RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi KMD 12470.86256471 +./komodo-cli sendtoaddress RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi 12470.86256471 +sleep 3 +echo "12470.86256471 <- expected amount RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi" + +# R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj KMD 3365.89754092 +./komodo-cli sendtoaddress R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj 3365.89754092 +sleep 3 +echo "3365.89754092 <- expected amount R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj" + +# RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv KMD 511.26690948 +./komodo-cli sendtoaddress RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv 511.26690948 +sleep 3 +echo "511.26690948 <- expected amount RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv" + + +# total KMD 2201860.11979328 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch17.listunspent b/iguana/tests/KMD.batch17.listunspent new file mode 100755 index 000000000..bffaab46a --- /dev/null +++ b/iguana/tests/KMD.batch17.listunspent @@ -0,0 +1,346 @@ +sleep 999999 +# RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 KMD 108998.28313606 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8\",\"symbol\":\"KMD\"}" +echo "108998.28313606 <- expected amount RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 196.34763557 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" +echo "196.34763557 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU KMD 14524.72874062 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU\",\"symbol\":\"KMD\"}" +echo "14524.72874062 <- expected amount RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU" + +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 16017.97255691 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REVcoi6A4GRfuchCXTwBTszbakhoh9inLs\",\"symbol\":\"KMD\"}" +echo "16017.97255691 <- expected amount REVcoi6A4GRfuchCXTwBTszbakhoh9inLs" + +# RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22 KMD 145928.92215821 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22\",\"symbol\":\"KMD\"}" +echo "145928.92215821 <- expected amount RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22" + +# RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6 KMD 114940.35721379 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6\",\"symbol\":\"KMD\"}" +echo "114940.35721379 <- expected amount RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6" + +# RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU KMD 28699.34324752 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU\",\"symbol\":\"KMD\"}" +echo "28699.34324752 <- expected amount RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU" + +# RV25zizocv445ht9My45WaxpGuAC42cxLa KMD 101090.11347764 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RV25zizocv445ht9My45WaxpGuAC42cxLa\",\"symbol\":\"KMD\"}" +echo "101090.11347764 <- expected amount RV25zizocv445ht9My45WaxpGuAC42cxLa" + +# RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S KMD 1704.23483890 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S\",\"symbol\":\"KMD\"}" +echo "1704.23483890 <- expected amount RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S" + +# RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD KMD 96831.52493750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD\",\"symbol\":\"KMD\"}" +echo "96831.52493750 <- expected amount RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD" + +# RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve KMD 11.06362104 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve\",\"symbol\":\"KMD\"}" +echo "11.06362104 <- expected amount RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve" + +# RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv KMD 32009.28059927 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv\",\"symbol\":\"KMD\"}" +echo "32009.28059927 <- expected amount RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv" + +# RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh KMD 305.48459176 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh\",\"symbol\":\"KMD\"}" +echo "305.48459176 <- expected amount RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh" + +# RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 KMD 162977.74808228 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3\",\"symbol\":\"KMD\"}" +echo "162977.74808228 <- expected amount RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3" + +# RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn" + +# RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3 KMD 1593.10203942 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3\",\"symbol\":\"KMD\"}" +echo "1593.10203942 <- expected amount RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3" + +# RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu KMD 4066.11066256 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu\",\"symbol\":\"KMD\"}" +echo "4066.11066256 <- expected amount RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu" + +# RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc KMD 4014.80536992 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc\",\"symbol\":\"KMD\"}" +echo "4014.80536992 <- expected amount RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc" + +# RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd KMD 2904.94574812 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd\",\"symbol\":\"KMD\"}" +echo "2904.94574812 <- expected amount RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd" + +# REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc KMD 38080.08587787 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc\",\"symbol\":\"KMD\"}" +echo "38080.08587787 <- expected amount REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc" + +# RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7 KMD 875.08198390 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7\",\"symbol\":\"KMD\"}" +echo "875.08198390 <- expected amount RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7" + +# RULousSwdVGhaP6vusva8u9AQWTs8ugjfp KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RULousSwdVGhaP6vusva8u9AQWTs8ugjfp\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RULousSwdVGhaP6vusva8u9AQWTs8ugjfp" + +# RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK KMD 2954.24166783 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK\",\"symbol\":\"KMD\"}" +echo "2954.24166783 <- expected amount RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK" + +# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193, REVS 708.36533209 +# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU\",\"symbol\":\"KMD\"}" +echo "35716.07599193 <- expected amount RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU" + +# R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH KMD 1681.36207445 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH\",\"symbol\":\"KMD\"}" +echo "1681.36207445 <- expected amount R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH" + +# RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ KMD 7119.36644540 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ\",\"symbol\":\"KMD\"}" +echo "7119.36644540 <- expected amount RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ" + +# RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV KMD 29049.45748125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV\",\"symbol\":\"KMD\"}" +echo "29049.45748125 <- expected amount RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV" + +# RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG KMD 216.38341633 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG\",\"symbol\":\"KMD\"}" +echo "216.38341633 <- expected amount RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG" + +# RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 KMD 3239.94057692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWc6GouJggQDsBCeW1DYck629FPrDJCTP9\",\"symbol\":\"KMD\"}" +echo "3239.94057692 <- expected amount RWc6GouJggQDsBCeW1DYck629FPrDJCTP9" + +# R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY KMD 723.21529345 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY\",\"symbol\":\"KMD\"}" +echo "723.21529345 <- expected amount R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY" + +# RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd KMD 20415.81928042 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd\",\"symbol\":\"KMD\"}" +echo "20415.81928042 <- expected amount RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd" + +# RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 KMD 4319.48050817 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63\",\"symbol\":\"KMD\"}" +echo "4319.48050817 <- expected amount RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63" + +# RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1 KMD 155.08169171 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1\",\"symbol\":\"KMD\"}" +echo "155.08169171 <- expected amount RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1" + +# RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC KMD 5177.29144163 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC\",\"symbol\":\"KMD\"}" +echo "5177.29144163 <- expected amount RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC" + +# RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS KMD 2034.11335616 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS\",\"symbol\":\"KMD\"}" +echo "2034.11335616 <- expected amount RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS" + +# RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk KMD 8034.62340879 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk\",\"symbol\":\"KMD\"}" +echo "8034.62340879 <- expected amount RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk" + +# RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW KMD 987.78018920 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW\",\"symbol\":\"KMD\"}" +echo "987.78018920 <- expected amount RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW" + +# RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM KMD 98.35737149 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM\",\"symbol\":\"KMD\"}" +echo "98.35737149 <- expected amount RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 8442.69675032 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" +echo "8442.69675032 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU KMD 35.32468867 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU\",\"symbol\":\"KMD\"}" +echo "35.32468867 <- expected amount RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU" + +# RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww KMD 2418.19228276 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww\",\"symbol\":\"KMD\"}" +echo "2418.19228276 <- expected amount RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww" + +# RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb KMD 34.72735411 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb\",\"symbol\":\"KMD\"}" +echo "34.72735411 <- expected amount RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb" + +# RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ KMD 49.50870613 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ\",\"symbol\":\"KMD\"}" +echo "49.50870613 <- expected amount RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ" + +# RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ" + +# RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u KMD 56.66050704 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u\",\"symbol\":\"KMD\"}" +echo "56.66050704 <- expected amount RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u" + +# RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74 KMD 722.28571081 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74\",\"symbol\":\"KMD\"}" +echo "722.28571081 <- expected amount RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74" + +# RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68 KMD 226.29998024 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68\",\"symbol\":\"KMD\"}" +echo "226.29998024 <- expected amount RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68" + +# RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P KMD 1160.04166875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P\",\"symbol\":\"KMD\"}" +echo "1160.04166875 <- expected amount RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P" + +# REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3 KMD 5365.78339027 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3\",\"symbol\":\"KMD\"}" +echo "5365.78339027 <- expected amount REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3" + +# RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab" + +# RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv KMD 2475.13554655 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv\",\"symbol\":\"KMD\"}" +echo "2475.13554655 <- expected amount RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv" + +# RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp KMD 6778.20674562 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp\",\"symbol\":\"KMD\"}" +echo "6778.20674562 <- expected amount RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp" + +# RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh KMD 3898.73512521 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh\",\"symbol\":\"KMD\"}" +echo "3898.73512521 <- expected amount RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh" + +# R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ KMD 18775.43011383 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ\",\"symbol\":\"KMD\"}" +echo "18775.43011383 <- expected amount R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ" + +# RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL KMD 49.27663407 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL\",\"symbol\":\"KMD\"}" +echo "49.27663407 <- expected amount RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL" + +# RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3 KMD 1177.96870224 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3\",\"symbol\":\"KMD\"}" +echo "1177.96870224 <- expected amount RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3" + +# RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW KMD 3692.18604586 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW\",\"symbol\":\"KMD\"}" +echo "3692.18604586 <- expected amount RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW" + +# RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S KMD 422.98413624 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S\",\"symbol\":\"KMD\"}" +echo "422.98413624 <- expected amount RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S" + +# RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk KMD 428171.85680159 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk\",\"symbol\":\"KMD\"}" +echo "428171.85680159 <- expected amount RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk" + +# RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB KMD 27228.79164783 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB\",\"symbol\":\"KMD\"}" +echo "27228.79164783 <- expected amount RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB" + +# RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU KMD 6109.56883640 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU\",\"symbol\":\"KMD\"}" +echo "6109.56883640 <- expected amount RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU" + +# RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN KMD 316058.09739600 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN\",\"symbol\":\"KMD\"}" +echo "316058.09739600 <- expected amount RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN" + +# RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH KMD 51229.88531218 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH\",\"symbol\":\"KMD\"}" +echo "51229.88531218 <- expected amount RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH" + +# RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s KMD 110083.51536582 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s\",\"symbol\":\"KMD\"}" +echo "110083.51536582 <- expected amount RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s" + +# RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX\",\"symbol\":\"KMD\"}" +echo "9295.82639400 <- expected amount RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX" + +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 2611.69343481 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK\",\"symbol\":\"KMD\"}" +echo "2611.69343481 <- expected amount RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK" + +# RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs KMD 4841.57624687 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs\",\"symbol\":\"KMD\"}" +echo "4841.57624687 <- expected amount RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs" + +# RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW KMD 813.38480947 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW\",\"symbol\":\"KMD\"}" +echo "813.38480947 <- expected amount RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW" + +# RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH KMD 20170.43419449 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH\",\"symbol\":\"KMD\"}" +echo "20170.43419449 <- expected amount RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH" + +# RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD KMD 681.69393556 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD\",\"symbol\":\"KMD\"}" +echo "681.69393556 <- expected amount RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD" + +# RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim KMD 1510.02573700 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim\",\"symbol\":\"KMD\"}" +echo "1510.02573700 <- expected amount RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy KMD 842.93959567 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy\",\"symbol\":\"KMD\"}" +echo "842.93959567 <- expected amount RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy" + +# RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue KMD 1580.29048698 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue\",\"symbol\":\"KMD\"}" +echo "1580.29048698 <- expected amount RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue" + +# RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN KMD 2904.94574812 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN\",\"symbol\":\"KMD\"}" +echo "2904.94574812 <- expected amount RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN" + +# RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX KMD 594.35547049 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX\",\"symbol\":\"KMD\"}" +echo "594.35547049 <- expected amount RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX" + +# RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE KMD 929.58263940 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE\",\"symbol\":\"KMD\"}" +echo "929.58263940 <- expected amount RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE" + +# RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP KMD 95491.01211941 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP\",\"symbol\":\"KMD\"}" +echo "95491.01211941 <- expected amount RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP" + +# RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY KMD 2631.59182505 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY\",\"symbol\":\"KMD\"}" +echo "2631.59182505 <- expected amount RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY" + +# RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn KMD 5701.16057828 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn\",\"symbol\":\"KMD\"}" +echo "5701.16057828 <- expected amount RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn" + +# RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a KMD 49.10934879 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a\",\"symbol\":\"KMD\"}" +echo "49.10934879 <- expected amount RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a" + +# RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR KMD 911.94644914 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR\",\"symbol\":\"KMD\"}" +echo "911.94644914 <- expected amount RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR" + +# RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH KMD 2169.54630422 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH\",\"symbol\":\"KMD\"}" +echo "2169.54630422 <- expected amount RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH" + +# RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi KMD 12470.86256471 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi\",\"symbol\":\"KMD\"}" +echo "12470.86256471 <- expected amount RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi" + +# R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj KMD 3365.89754092 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj\",\"symbol\":\"KMD\"}" +echo "3365.89754092 <- expected amount R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj" + +# RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv KMD 511.26690948 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv\",\"symbol\":\"KMD\"}" +echo "511.26690948 <- expected amount RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv" + diff --git a/iguana/tests/REVS.batch15 b/iguana/tests/REVS.batch15 new file mode 100755 index 000000000..3e64201d3 --- /dev/null +++ b/iguana/tests/REVS.batch15 @@ -0,0 +1,18 @@ +sleep 999999 +# RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ KMD 5844.47004626, REVS 115.97829823 +sleep 1 +fiat/revs sendtoaddress RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ 115.97829823 +# REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa KMD 26142.50314066, REVS 20.00000000 +sleep 1 +fiat/revs sendtoaddress REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa 20.00000000 +# RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft KMD 1005.97291406, REVS 19.95990000 +sleep 1 +fiat/revs sendtoaddress RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft 19.95990000 +# RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 KMD 125611.30316493, REVS 1564.97178647 +sleep 1 +fiat/revs sendtoaddress RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 1564.97178647 +# RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk KMD 4535.36019149, REVS 90.00018012 +sleep 1 +fiat/revs sendtoaddress RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk 90.00018012 + +# total KMD 0.00000000 REVS 1810.91016482 diff --git a/iguana/tests/REVS.batch16 b/iguana/tests/REVS.batch16 new file mode 100755 index 000000000..cd1687ffb --- /dev/null +++ b/iguana/tests/REVS.batch16 @@ -0,0 +1,19 @@ +sleep 99999 +# RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV KMD 857.10994504, REVS 17.01091436 +sleep 1 +fiat/revs sendtoaddress RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV 17.01091436 +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 2288.11223404, REVS 45.41799774 +sleep 1 +fiat/revs sendtoaddress REVcoi6A4GRfuchCXTwBTszbakhoh9inLs 45.41799774 +# RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije KMD 13018.84319757, REVS 151.44412616 +sleep 1 +fiat/revs sendtoaddress RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije 151.44412616 +# REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo KMD 9102.02231944, REVS 180.67104532 +sleep 1 +fiat/revs sendtoaddress REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo 180.67104532 + +1f5038508e4b13c7e9cfc89e2cd3ac187716b7c05506c1432c177757ac2b7b6a +ba117446a8ca5aed03668f6e896e4e993e90007caa5315795db040123a946089 +32f4cec5856b1a0cd0e6de4d1f340cb7f73b52c461cb540e1f6c3bb7b7024dc7 +556402cc20da2e4f162e9212534d8b66239851729b990366a26e5dfe7111ad58 + diff --git a/iguana/tests/REVS.batch17 b/iguana/tests/REVS.batch17 new file mode 100755 index 000000000..fee159901 --- /dev/null +++ b/iguana/tests/REVS.batch17 @@ -0,0 +1,5 @@ +# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193, REVS 708.36533209 +sleep 100000 +fiat/revs sendtoaddress RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU 708.36533209 +2781e7d1a888c22083832e46241aca1cb512605cb4c5492c9a36cc7f2d7829f3 +# total KMD 0.00000000 REVS 708.36533209 diff --git a/iguana/tests/crash b/iguana/tests/crash new file mode 100755 index 000000000..90be8a6d1 --- /dev/null +++ b/iguana/tests/crash @@ -0,0 +1,7 @@ +../coins/basilisk/kmd + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"encryptwallet\",\"passphrase\":\"amount common obey erupt ensure salon shrug digital phone vacant provide word nurse legend shaft ritual strike black fiscal circle dove tone inmate plunge\",\"timeout\":864445678904}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrase\",\"password\":\"amount common obey erupt ensure salon shrug digital phone vacant provide word nurse legend shaft ritual strike black fiscal circle dove tone inmate plunge\",\"timeout\":864445678904}" + +curl --url "http://127.0.0.1:7778" --data "{\"symbol\":\"KMD\",\"agent\":\"basilisk\",\"method\":\"utxorawtx\",\"vals\":{\"timelock\":0,\"changeaddr\":\"RD5Sj6igy53nscMiFS4ECXByfqVeyV9NdG\",\"destaddr\":\"RD5Sj6igy53nscMiFS4ECXByfqVeyV9NdG\",\"txfee\":0,\"amount\":0.0001,\"sendflag\":0},\"utxos\":[{\"bestblock\":\"0000119186ecfaa8d72a7d3c62e78135043db220a6d29a9605f1fbe383bcedfb\",\"confirmations\":65549,\"value\":0.04900000,\"scriptPubKey\":{\"asm\":\"OP_DUP OP_HASH160 29a7bd36e6913b674bb2b5c65e61a6544426ddd7 OP_EQUALVERIFY OP_CHECKSIG\",\"hex\":\"76a91429a7bd36e6913b674bb2b5c65e61a6544426ddd788ac\",\"reqSigs\":1,\"type\":\"pubkeyhash\",\"addresses\":[\"RD5Sj6igy53nscMiFS4ECXByfqVeyV9NdG\"]},\"version\":1,\"coinbase\":false,\"randipbits\":579036043,\"coin\":\"KMD\",\"txid\":\"b32af9977bc8ed0e54631d27f490c79841a03bccce4d6b8181456657b06194ef\",\"vout\":0,\"amount\":0.04900000}, {\"bestblock\":\"0000119186ecfaa8d72a7d3c62e78135043db220a6d29a9605f1fbe383bcedfb\",\"confirmations\":65553,\"value\":1,\"scriptPubKey\":{\"asm\":\"OP_DUP OP_HASH160 29a7bd36e6913b674bb2b5c65e61a6544426ddd7 OP_EQUALVERIFY OP_CHECKSIG\",\"hex\":\"76a91429a7bd36e6913b674bb2b5c65e61a6544426ddd788ac\",\"reqSigs\":1,\"type\":\"pubkeyhash\",\"addresses\":[\"RD5Sj6igy53nscMiFS4ECXByfqVeyV9NdG\"]},\"version\":1,\"coinbase\":false,\"randipbits\":3795805790,\"coin\":\"KMD\",\"txid\":\"84ca2ba7f621c820ab642e358813fcc33171c9999a47bb99dcf3a309dc847419\",\"vout\":1,\"amount\":1}]}" + diff --git a/iguana/tests/dexgetO b/iguana/tests/dexgetO index 6f4290b48..8f3ab668e 100755 --- a/iguana/tests/dexgetO +++ b/iguana/tests/dexgetO @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"gettxout\",\"vout\":1,\"txid\":\"4a1a2026718ac10bd11ccccbdd85f29faa5f0b7c3ab95a57dcf7040c5ca0420c\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"gettxout\",\"vout\":0,\"txid\":\"8661a47003ce3d1712dee5798432475b6b7abb65ba88c4f26eb37446b9038973\",\"symbol\":\"BTC\"}" diff --git a/iguana/tests/dexgetT b/iguana/tests/dexgetT index 7483dbd01..18241a84d 100755 --- a/iguana/tests/dexgetT +++ b/iguana/tests/dexgetT @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"gettransaction\",\"txid\":\"3c00ee16d12c6aae81863d1da485cdd6cd2b73847f8ab93de3663adf6c285e3b\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"gettransaction\",\"txid\":\"88794bbb699f130951c40dc99a27d2c7c7016e12824fd1040cbedf86980de04d\",\"symbol\":\"REVS\"}" diff --git a/iguana/tests/dexgetbalance b/iguana/tests/dexgetbalance index 71efdf9af..f096618ee 100755 --- a/iguana/tests/dexgetbalance +++ b/iguana/tests/dexgetbalance @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"RYZx1e7kVNTuQ6RTrvTkYeZAz5uJobC3pg\",\"symbol\":\"KMD\"}" diff --git a/iguana/tests/dexgetinfo b/iguana/tests/dexgetinfo index d31b736a6..0d89dba21 100755 --- a/iguana/tests/dexgetinfo +++ b/iguana/tests/dexgetinfo @@ -1,2 +1,3 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getinfo\",\"symbol\":\"BTC\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getinfo\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getinfo\",\"symbol\":\"LTC\"}" diff --git a/iguana/tests/dexkvsearch b/iguana/tests/dexkvsearch index 5c2b68524..8391dea10 100755 --- a/iguana/tests/dexkvsearch +++ b/iguana/tests/dexkvsearch @@ -1,4 +1,4 @@ #!/bin/bash #curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvsearch\",\"key\":\"foo\",\"symbol\":\"KMD\"}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvsearch\",\"key\":\"test\",\"symbol\":\"KV\"}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvsearch\",\"key\":\"777\",\"symbol\":\"KV\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvsearch\",\"key\":\"test\",\"symbol\":\"KV\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvsearch\",\"key\":\"ec474661-de713a84\",\"symbol\":\"KV\"}" diff --git a/iguana/tests/dexlisttransactions b/iguana/tests/dexlisttransactions index d53a0ff46..09a94f406 100755 --- a/iguana/tests/dexlisttransactions +++ b/iguana/tests/dexlisttransactions @@ -1,5 +1,5 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listtransactions\",\"address\":\"1Pc27firvEwPoDzPzYdJKZ5hoZK4T1tf6z\",\"count\":100,\"skip\":0,\"symbol\":\"BTC\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listtransactions\",\"address\":\"RWE3NWHT6Fb1zW4mY9LU859MPoWGYvtLfj\",\"count\":100,\"skip\":0,\"symbol\":\"KMD\"}" #curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listtransactions\",\"address\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"count\":100,\"skip\":0,\"symbol\":\"MVP\"}" #curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listtransactions\",\"address\":\"RMGpGoX82M1ZUUbHxZ3JKHacxY9NYVakqr\",\"count\":100,\"skip\":0,\"symbol\":\"USD\"}" #curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listtransactions\",\"address\":\"RMGpGoX82M1ZUUbHxZ3JKHacxY9NYVakqr\",\"count\":100,\"skip\":0,\"symbol\":\"MVP\"}" diff --git a/iguana/tests/dexlistunspent b/iguana/tests/dexlistunspent index 4e353d69b..4e13419d8 100755 --- a/iguana/tests/dexlistunspent +++ b/iguana/tests/dexlistunspent @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\",\"symbol\":\"BTC\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNmvQtThVZAbc1tFEFmKAnJZrc9XqciNog\",\"symbol\":\"KMD\"}" diff --git a/iguana/tests/getinfo b/iguana/tests/getinfo index 35e732fc9..3f0a59664 100755 --- a/iguana/tests/getinfo +++ b/iguana/tests/getinfo @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"SHARK\",\"method\":\"getinfo\",\"params\":[]}" +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"WLC\",\"method\":\"getinfo\",\"params\":[]}" diff --git a/iguana/tests/rawtx2 b/iguana/tests/rawtx2 index 391f42c58..cef4cd52a 100755 --- a/iguana/tests/rawtx2 +++ b/iguana/tests/rawtx2 @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"addresses\":[\"RFMEYcxuBL8S7UPdUbzXunPtS4p82HRcKs\", \"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\", \"RDBjpRUqV1AXzVJCBbbXNskgxGRj711qSc\", \"RL4aMgTBzkM1kX7d8QtE2oYXuAj2ZKabmW\", \"RDE9LBKqMaKgQgnsZM3hFCNeWfoXkHWMLs\", \"RDBjpRUqV1AXzVJCBbbXNskgxGRj711qSc\"],\"timeout\":15000,\"satoshis\":\"128700\",\"spendscript\":\"76a9142b4cf64627268ac24effd9aad5895e8ca862114288ac\",\"txfee\":\"10000\",\"burn\":0.00000000}}" +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"KMD\",\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"addresses\":[\"RFMEYcxuBL8S7UPdUbzXunPtS4p82HRcKs\", \"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\", \"RDBjpRUqV1AXzVJCBbbXNskgxGRj711qSc\", \"RL4aMgTBzkM1kX7d8QtE2oYXuAj2ZKabmW\", \"RDE9LBKqMaKgQgnsZM3hFCNeWfoXkHWMLs\", \"RDBjpRUqV1AXzVJCBbbXNskgxGRj711qSc\"],\"timeout\":15000,\"satoshis\":\"128700\",\"spendscript\":\"76a9142b4cf64627268ac24effd9aad5895e8ca862114288ac\",\"txfee\":\"10000\",\"burn\":0.00000000}}" diff --git a/iguana/tests/sendtoaddress b/iguana/tests/sendtoaddress index e31a3af56..3a1ef1bbc 100755 --- a/iguana/tests/sendtoaddress +++ b/iguana/tests/sendtoaddress @@ -1,3 +1,3 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"KMD\",\"method\":\"sendtoaddress\",\"params\":[\"RVQV5spiARDTqfwBCxstWnMbrT6Q8mhRYz\", 0.15, \"testcomment\", \"sendcomment\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"method\":\"sendtoaddress\",\"params\":[\"1HEQifAU8mcMsTtM4ougjfZemVYfdT1TcJ\", 0.005]}" diff --git a/iguana/tests/smartadd b/iguana/tests/smartadd new file mode 100755 index 000000000..41b844ecc --- /dev/null +++ b/iguana/tests/smartadd @@ -0,0 +1,3 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"smartaddress\",\"type\":\"usd\",\"symbol\":\"USD\"}" # first time +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"smartaddress\",\"type\":\"usd\",\"symbol\":\"REVS\",\"maxbid\":0.20,\"minask\":0.10}" diff --git a/iguana/tests/smartaddresses b/iguana/tests/smartaddresses new file mode 100755 index 000000000..fbcccbf57 --- /dev/null +++ b/iguana/tests/smartaddresses @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"smartaddresses\"}" diff --git a/iguana/tests/splitfunds b/iguana/tests/splitfunds index da05ff6e5..75f93431e 100755 --- a/iguana/tests/splitfunds +++ b/iguana/tests/splitfunds @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"1000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" diff --git a/iguana/tests/statstest b/iguana/tests/statstest new file mode 100755 index 000000000..a91ae778e --- /dev/null +++ b/iguana/tests/statstest @@ -0,0 +1,3 @@ +#!/bin/bash +#curl --url "http://127.0.0.1:7779" --data "{\"method\":\"bitmap\",\"endtimestamp\":0,\"source\":\"KMD\",\"dest\":\"BTC\",\"numdates\":30}" +curl --url "http://78.46.193.199:7779" --data "{\"method\":\"bitmap\",\"endtimestamp\":0,\"source\":\"KMD\",\"dest\":\"BTC\",\"numdates\":30}" diff --git a/iguana/tests/test b/iguana/tests/test deleted file mode 100755 index 495928084..000000000 --- a/iguana/tests/test +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -echo "{\"field\":\"requiredvalue\"}" > /tmp/foo -./jsoncmp /tmp/foo {\"fields\":[{\"field\":\"requiredvalue\"}]} diff --git a/iguana/tests/utxocombine b/iguana/tests/utxocombine new file mode 100755 index 000000000..8f7ab3ff9 --- /dev/null +++ b/iguana/tests/utxocombine @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"symbol\":\"BTC\",\"agent\":\"basilisk\",\"method\":\"utxocombine\",\"vals\":{\"coinaddr\":\"1E2ac2gxeFR2ir1H3vqETTperWkiXkwy99\",\"maxamount\":0.0001,\"sendflag\":0}}" diff --git a/iguana/tests/utxorawtx b/iguana/tests/utxorawtx index 57d252129..7fc804c2f 100755 --- a/iguana/tests/utxorawtx +++ b/iguana/tests/utxorawtx @@ -1,2 +1 @@ -#!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"symbol\":\"BTC\",\"agent\":\"basilisk\",\"method\":\"utxorawtx\",\"vals\":{\"timelock\":0,\"changeaddr\":\"1P3rU1Nk1pmc2BiWC8dEy9bZa1ZbMp5jfg\",\"destaddr\":\"1P3rU1Nk1pmc2BiWC8dEy9bZa1ZbMp5jfg\",\"txfee\":0,\"amount\":0.0001,\"sendflag\":0},\"utxos\":[{\"value\":0.00100000,\"address\":\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\",\"scriptPubKey\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\",\"confirmations\":23351,\"spendable\":true}]}" +#!/bin/bashcurl --url "http://127.0.0.1:7778" --data "{\"symbol\":\"BTC\",\"agent\":\"basilisk\",\"method\":\"utxorawtx\",\"vals\":{\"timelock\":0,\"changeaddr\":\"1P3rU1Nk1pmc2BiWC8dEy9bZa1ZbMp5jfg\",\"destaddr\":\"1P3rU1Nk1pmc2BiWC8dEy9bZa1ZbMp5jfg\",\"txfee\":0,\"amount\":0.0001,\"sendflag\":0},\"utxos\":[{\"value\":0.00100000,\"address\":\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\",\"scriptPubKey\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\",\"confirmations\":23351,\"spendable\":true}]}" diff --git a/includes/cJSON.h b/includes/cJSON.h index b75e73bf1..77e0752e6 100755 --- a/includes/cJSON.h +++ b/includes/cJSON.h @@ -211,7 +211,7 @@ extern "C" char *get_cJSON_fieldname(cJSON *obj); void ensure_jsonitem(cJSON *json,char *field,char *value); int32_t in_jsonarray(cJSON *array,char *value); - char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params); + char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout); uint64_t calc_nxt64bits(const char *str); int32_t expand_nxt64bits(char *str,uint64_t nxt64bits); char *nxt64str(uint64_t nxt64bits); diff --git a/includes/curl/.gitignore b/includes/curl/.gitignore new file mode 100644 index 000000000..228a961fb --- /dev/null +++ b/includes/curl/.gitignore @@ -0,0 +1,4 @@ +curlbuild.h +curlver.h.dist +stamp-h2 +stamp-h3 diff --git a/includes/curl/Makefile.am b/includes/curl/Makefile.am new file mode 100644 index 000000000..7c924fcb5 --- /dev/null +++ b/includes/curl/Makefile.am @@ -0,0 +1,53 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### +pkginclude_HEADERS = \ + curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \ + typecheck-gcc.h curlbuild.h curlrules.h + +pkgincludedir= $(includedir)/curl + +# curlbuild.h does not exist in the git tree. When the original libcurl +# source code distribution archive file is created, curlbuild.h.dist is +# renamed to curlbuild.h and included in the tarball so that it can be +# used directly on non-configure systems. +# +# The distributed curlbuild.h will be overwritten on configure systems +# when the configure script runs, with one that is suitable and specific +# to the library being configured and built. +# +# curlbuild.h.in is the distributed template file from which the configure +# script creates curlbuild.h at library configuration time, overwiting the +# one included in the distribution archive. +# +# curlbuild.h.dist is not included in the source code distribution archive. + +EXTRA_DIST = curlbuild.h.in + +DISTCLEANFILES = curlbuild.h + +checksrc: + @@PERL@ $(top_srcdir)/lib/checksrc.pl -Wcurlbuild.h -D$(top_srcdir)/include/curl $(pkginclude_HEADERS) $(EXTRA_DIST) + +if CURLDEBUG +# for debug builds, we scan the sources on all regular make invokes +all-local: checksrc +endif diff --git a/includes/curl/curl.h b/includes/curl/curl.h new file mode 100644 index 000000000..7c7d28d6a --- /dev/null +++ b/includes/curl/curl.h @@ -0,0 +1,2551 @@ +#ifndef __CURL_CURL_H +#define __CURL_CURL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * If you have libcurl problems, all docs and details are found here: + * https://curl.haxx.se/libcurl/ + * + * curl-library mailing list subscription and unsubscription web interface: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + */ + +#ifdef CURL_NO_OLDIES +#define CURL_STRICTER +#endif + +#include "curlver.h" /* libcurl version defines */ +#include "curlbuild.h" /* libcurl build definitions */ +#include "curlrules.h" /* libcurl rules enforcement */ + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && \ + !defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#include +#include + +#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) +/* Needed for __FreeBSD_version symbol definition */ +#include +#endif + +/* The include stuff here below is mainly for time_t! */ +#include +#include + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ + defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +#include +#include +#endif +#endif + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on systems that are known to + require it! */ +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ + defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ + defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ + (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) +#include +#endif + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif + +#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) +#include +#endif + +#ifdef __BEOS__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_easy CURL; +typedef struct Curl_share CURLSH; +#else +typedef void CURL; +typedef void CURLSH; +#endif + +/* + * libcurl external API function linkage decorations. + */ + +#ifdef CURL_STATICLIB +# define CURL_EXTERN +#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) +# if defined(BUILDING_LIBCURL) +# define CURL_EXTERN __declspec(dllexport) +# else +# define CURL_EXTERN __declspec(dllimport) +# endif +#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) +# define CURL_EXTERN CURL_EXTERN_SYMBOL +#else +# define CURL_EXTERN +#endif + +#ifndef curl_socket_typedef +/* socket typedef */ +#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) +typedef SOCKET curl_socket_t; +#define CURL_SOCKET_BAD INVALID_SOCKET +#else +typedef int curl_socket_t; +#define CURL_SOCKET_BAD -1 +#endif +#define curl_socket_typedef +#endif /* curl_socket_typedef */ + +struct curl_httppost { + struct curl_httppost *next; /* next entry in the list */ + char *name; /* pointer to allocated name */ + long namelength; /* length of name length */ + char *contents; /* pointer to allocated data contents */ + long contentslength; /* length of contents field, see also + CURL_HTTPPOST_LARGE */ + char *buffer; /* pointer to allocated buffer contents */ + long bufferlength; /* length of buffer field */ + char *contenttype; /* Content-Type */ + struct curl_slist *contentheader; /* list of extra headers for this form */ + struct curl_httppost *more; /* if one field name has more than one + file, this link should link to following + files */ + long flags; /* as defined below */ + +/* specified content is a file name */ +#define CURL_HTTPPOST_FILENAME (1<<0) +/* specified content is a file name */ +#define CURL_HTTPPOST_READFILE (1<<1) +/* name is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRNAME (1<<2) +/* contents is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRCONTENTS (1<<3) +/* upload file from buffer */ +#define CURL_HTTPPOST_BUFFER (1<<4) +/* upload file from pointer contents */ +#define CURL_HTTPPOST_PTRBUFFER (1<<5) +/* upload file contents by using the regular read callback to get the data and + pass the given pointer as custom pointer */ +#define CURL_HTTPPOST_CALLBACK (1<<6) +/* use size in 'contentlen', added in 7.46.0 */ +#define CURL_HTTPPOST_LARGE (1<<7) + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ + void *userp; /* custom pointer used for + HTTPPOST_CALLBACK posts */ + curl_off_t contentlen; /* alternative length of contents + field. Used if CURL_HTTPPOST_LARGE is + set. Added in 7.46.0 */ +}; + +/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered + deprecated but was the only choice up until 7.31.0 */ +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + +/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in + 7.32.0, it avoids floating point and provides more detailed information. */ +typedef int (*curl_xferinfo_callback)(void *clientp, + curl_off_t dltotal, + curl_off_t dlnow, + curl_off_t ultotal, + curl_off_t ulnow); + +#ifndef CURL_MAX_READ_SIZE + /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */ +#define CURL_MAX_READ_SIZE 524288 +#endif + +#ifndef CURL_MAX_WRITE_SIZE + /* Tests have proven that 20K is a very bad buffer size for uploads on + Windows, while 16K for some odd reason performed a lot better. + We do the ifndef check to allow this value to easier be changed at build + time for those who feel adventurous. The practical minimum is about + 400 bytes since libcurl uses a buffer of this size as a scratch area + (unrelated to network send operations). */ +#define CURL_MAX_WRITE_SIZE 16384 +#endif + +#ifndef CURL_MAX_HTTP_HEADER +/* The only reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a never-ending header that will cause reallocs + infinitely */ +#define CURL_MAX_HTTP_HEADER (100*1024) +#endif + +/* This is a magic return code for the write callback that, when returned, + will signal libcurl to pause receiving on the current transfer. */ +#define CURL_WRITEFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + + + +/* enumeration of file types */ +typedef enum { + CURLFILETYPE_FILE = 0, + CURLFILETYPE_DIRECTORY, + CURLFILETYPE_SYMLINK, + CURLFILETYPE_DEVICE_BLOCK, + CURLFILETYPE_DEVICE_CHAR, + CURLFILETYPE_NAMEDPIPE, + CURLFILETYPE_SOCKET, + CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ + + CURLFILETYPE_UNKNOWN /* should never occur */ +} curlfiletype; + +#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) +#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) +#define CURLFINFOFLAG_KNOWN_TIME (1<<2) +#define CURLFINFOFLAG_KNOWN_PERM (1<<3) +#define CURLFINFOFLAG_KNOWN_UID (1<<4) +#define CURLFINFOFLAG_KNOWN_GID (1<<5) +#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) +#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) + +/* Content of this structure depends on information which is known and is + achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man + page for callbacks returning this structure -- some fields are mandatory, + some others are optional. The FLAG field has special meaning. */ +struct curl_fileinfo { + char *filename; + curlfiletype filetype; + time_t time; + unsigned int perm; + int uid; + int gid; + curl_off_t size; + long int hardlinks; + + struct { + /* If some of these fields is not NULL, it is a pointer to b_data. */ + char *time; + char *perm; + char *user; + char *group; + char *target; /* pointer to the target filename of a symlink */ + } strings; + + unsigned int flags; + + /* used internally */ + char *b_data; + size_t b_size; + size_t b_used; +}; + +/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ +#define CURL_CHUNK_BGN_FUNC_OK 0 +#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ +#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ + +/* if splitting of data transfer is enabled, this callback is called before + download of an individual chunk started. Note that parameter "remains" works + only for FTP wildcard downloading (for now), otherwise is not used */ +typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, + void *ptr, + int remains); + +/* return codes for CURLOPT_CHUNK_END_FUNCTION */ +#define CURL_CHUNK_END_FUNC_OK 0 +#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ + +/* If splitting of data transfer is enabled this callback is called after + download of an individual chunk finished. + Note! After this callback was set then it have to be called FOR ALL chunks. + Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. + This is the reason why we don't need "transfer_info" parameter in this + callback and we are not interested in "remains" parameter too. */ +typedef long (*curl_chunk_end_callback)(void *ptr); + +/* return codes for FNMATCHFUNCTION */ +#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ +#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ +#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ + +/* callback type for wildcard downloading pattern matching. If the + string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ +typedef int (*curl_fnmatch_callback)(void *ptr, + const char *pattern, + const char *string); + +/* These are the return codes for the seek callbacks */ +#define CURL_SEEKFUNC_OK 0 +#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ +#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so + libcurl might try other means instead */ +typedef int (*curl_seek_callback)(void *instream, + curl_off_t offset, + int origin); /* 'whence' */ + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +/* This is a return code for the read callback that, when returned, will + signal libcurl to pause sending data on the current transfer. */ +#define CURL_READFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ + CURLSOCKTYPE_LAST /* never use */ +} curlsocktype; + +/* The return code from the sockopt_callback can signal information back + to libcurl: */ +#define CURL_SOCKOPT_OK 0 +#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return + CURLE_ABORTED_BY_CALLBACK */ +#define CURL_SOCKOPT_ALREADY_CONNECTED 2 + +typedef int (*curl_sockopt_callback)(void *clientp, + curl_socket_t curlfd, + curlsocktype purpose); + +struct curl_sockaddr { + int family; + int socktype; + int protocol; + unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it + turned really ugly and painful on the systems that + lack this type */ + struct sockaddr addr; +}; + +typedef curl_socket_t +(*curl_opensocket_callback)(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address); + +typedef int +(*curl_closesocket_callback)(void *clientp, curl_socket_t item); + +typedef enum { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} curlioerr; + +typedef enum { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} curliocmd; + +typedef curlioerr (*curl_ioctl_callback)(CURL *handle, + int cmd, + void *clientp); + +#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS +/* + * The following typedef's are signatures of malloc, free, realloc, strdup and + * calloc respectively. Function pointers of these types can be passed to the + * curl_global_init_mem() function to set user defined memory management + * callback routines. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); + +#define CURL_DID_MEMORY_FUNC_TYPEDEFS +#endif + +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userptr); /* whatever the user please */ + +/* All possible error codes from all sorts of curl functions. Future versions + may return other values, stay prepared. + + Always add new return codes last. Never *EVER* remove any. The return + codes must remain the same! + */ + +typedef enum { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for + 7.17.0, reused in April 2011 for 7.21.5] */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for + 7.15.4, reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server + [was obsoleted in August 2007 for 7.17.0, + reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. + [was obsoleted in August 2007 for 7.17.0, + reused in July 2014 for 7.38.0] */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ + CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint + wasn't verified fine */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ + CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURLE_AGAIN, /* 81 - socket is not ready for send/recv, + wait till it's ready and try again (Added + in 7.18.2) */ + CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or + wrong format (Added in 7.19.0) */ + CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in + 7.19.0) */ + CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ + CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ + CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ + CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ + CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ + CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the + session will be queued */ + CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not + match */ + CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ + CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer + */ + CURL_LAST /* never use! */ +} CURLcode; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Previously obsolete error code re-used in 7.38.0 */ +#define CURLE_OBSOLETE16 CURLE_HTTP2 + +/* Previously obsolete error codes re-used in 7.24.0 */ +#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED +#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT + +/* compatibility with older names */ +#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING +#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY + +/* The following were added in 7.21.5, April 2011 */ +#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION + +/* The following were added in 7.17.1 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.17.0 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 +#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN + +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED + +/* The following were added earlier */ + +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT + +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED + +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME + +/* This was the error code 50 in 7.7.3 and a few earlier versions, this + is no longer used by libcurl but is instead #defined here only to not + make programs break */ +#define CURLE_ALREADY_COMPLETE 99999 + +/* Provide defines for really old option names */ +#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ +#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ +#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA + +/* Since long deprecated options with no code in the lib that does anything + with them. */ +#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 +#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 + +#endif /*!CURL_NO_OLDIES*/ + +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ + void *ssl_ctx, /* actually an + OpenSSL SSL_CTX */ + void *userptr); + +typedef enum { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_HTTPS = 2, /* added in 7.52.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already + in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} curl_proxytype; /* this enum was added in 7.10 */ + +/* + * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: + * + * CURLAUTH_NONE - No HTTP authentication + * CURLAUTH_BASIC - HTTP Basic authentication (default) + * CURLAUTH_DIGEST - HTTP Digest authentication + * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication + * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) + * CURLAUTH_NTLM - HTTP NTLM authentication + * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour + * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper + * CURLAUTH_ONLY - Use together with a single other type to force no + * authentication or just that single type + * CURLAUTH_ANY - All fine types set + * CURLAUTH_ANYSAFE - All fine types except Basic + */ + +#define CURLAUTH_NONE ((unsigned long)0) +#define CURLAUTH_BASIC (((unsigned long)1)<<0) +#define CURLAUTH_DIGEST (((unsigned long)1)<<1) +#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) +/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ +#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE +#define CURLAUTH_NTLM (((unsigned long)1)<<3) +#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) +#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) +#define CURLAUTH_ONLY (((unsigned long)1)<<31) +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ +#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ +#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ + +#define CURL_ERROR_SIZE 256 + +enum curl_khtype { + CURLKHTYPE_UNKNOWN, + CURLKHTYPE_RSA1, + CURLKHTYPE_RSA, + CURLKHTYPE_DSS +}; + +struct curl_khkey { + const char *key; /* points to a zero-terminated string encoded with base64 + if len is zero, otherwise to the "raw" data */ + size_t len; + enum curl_khtype keytype; +}; + +/* this is the set of return values expected from the curl_sshkeycallback + callback */ +enum curl_khstat { + CURLKHSTAT_FINE_ADD_TO_FILE, + CURLKHSTAT_FINE, + CURLKHSTAT_REJECT, /* reject the connection, return an error */ + CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so + this causes a CURLE_DEFER error but otherwise the + connection will be left intact etc */ + CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ +}; + +/* this is the set of status codes pass in to the callback */ +enum curl_khmatch { + CURLKHMATCH_OK, /* match */ + CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ + CURLKHMATCH_MISSING, /* no matching host/key found */ + CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ +}; + +typedef int + (*curl_sshkeycallback) (CURL *easy, /* easy handle */ + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch, /* libcurl's view on the keys */ + void *clientp); /* custom pointer passed from app */ + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ + +/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the + name of improving interoperability with older servers. Some SSL libraries + have introduced work-arounds for this flaw but those work-arounds sometimes + make the SSL communication fail. To regain functionality with those broken + servers, a user can this way allow the vulnerability back. */ +#define CURLSSLOPT_ALLOW_BEAST (1<<0) + +/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those + SSL backends where such behavior is present. */ +#define CURLSSLOPT_NO_REVOKE (1<<1) + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +#define CURLFTPSSL_NONE CURLUSESSL_NONE +#define CURLFTPSSL_TRY CURLUSESSL_TRY +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL +#define CURLFTPSSL_ALL CURLUSESSL_ALL +#define CURLFTPSSL_LAST CURLUSESSL_LAST +#define curl_ftpssl curl_usessl +#endif /*!CURL_NO_OLDIES*/ + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +typedef enum { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} curl_ftpccc; + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +typedef enum { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} curl_ftpauth; + +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +typedef enum { + CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ + CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD + again if MKD succeeded, for SFTP this does + similar magic */ + CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD + again even if MKD failed! */ + CURLFTP_CREATE_DIR_LAST /* not an option, never use */ +} curl_ftpcreatedir; + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +typedef enum { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} curl_ftpmethod; + +/* bitmask defines for CURLOPT_HEADEROPT */ +#define CURLHEADER_UNIFIED 0 +#define CURLHEADER_SEPARATE (1<<0) + +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +#define CURLPROTO_HTTP (1<<0) +#define CURLPROTO_HTTPS (1<<1) +#define CURLPROTO_FTP (1<<2) +#define CURLPROTO_FTPS (1<<3) +#define CURLPROTO_SCP (1<<4) +#define CURLPROTO_SFTP (1<<5) +#define CURLPROTO_TELNET (1<<6) +#define CURLPROTO_LDAP (1<<7) +#define CURLPROTO_LDAPS (1<<8) +#define CURLPROTO_DICT (1<<9) +#define CURLPROTO_FILE (1<<10) +#define CURLPROTO_TFTP (1<<11) +#define CURLPROTO_IMAP (1<<12) +#define CURLPROTO_IMAPS (1<<13) +#define CURLPROTO_POP3 (1<<14) +#define CURLPROTO_POP3S (1<<15) +#define CURLPROTO_SMTP (1<<16) +#define CURLPROTO_SMTPS (1<<17) +#define CURLPROTO_RTSP (1<<18) +#define CURLPROTO_RTMP (1<<19) +#define CURLPROTO_RTMPT (1<<20) +#define CURLPROTO_RTMPE (1<<21) +#define CURLPROTO_RTMPTE (1<<22) +#define CURLPROTO_RTMPS (1<<23) +#define CURLPROTO_RTMPTS (1<<24) +#define CURLPROTO_GOPHER (1<<25) +#define CURLPROTO_SMB (1<<26) +#define CURLPROTO_SMBS (1<<27) +#define CURLPROTO_ALL (~0) /* enable everything */ + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_STRINGPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the + string options from the header file */ + +/* name is uppercase CURLOPT_, + type is one of the defined CURLOPTTYPE_ + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif + +#ifdef CURL_ISOCPP +#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define STRINGPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLOPT_/**/name = type + number +#endif + +/* + * This macro-mania below setups the CURLOPT_[what] enum, to be used with + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] + * word. + */ + +typedef enum { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(WRITEDATA, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, STRINGPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, STRINGPOINT, 4), + + /* "user:password;options" to use when fetching. */ + CINIT(USERPWD, STRINGPOINT, 5), + + /* "user:password" to use with proxy. */ + CINIT(PROXYUSERPWD, STRINGPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, STRINGPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(READDATA, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. If this is not used, error messages go to stderr instead: */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was successful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referrer page (needed by some CGIs) */ + CINIT(REFERER, STRINGPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, STRINGPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, STRINGPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, STRINGPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind. This + list is also used for RTSP (in spite of its name) */ + CINIT(HTTPHEADER, OBJECTPOINT, 23), + + /* This points to a linked list of post entries, struct curl_httppost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, STRINGPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, STRINGPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, OBJECTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(HEADERDATA, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, STRINGPOINT, 31), + + /* What version to specifically try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, STRINGPOINT, 36), + + /* FILE handle to use instead of stderr */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, OBJECTPOINT, 39), + + CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */ + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* DEPRECATED + * Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION + callbacks */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), +#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA + + /* We want the referrer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, STRINGPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, STRINGPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, STRINGPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */ + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, STRINGPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, STRINGPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects are + OK within this time, then fine... This only aborts the connect phase. */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, STRINGPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specifically switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, STRINGPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, STRINGPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, STRINGPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, STRINGPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands */ + CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, STRINGPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and + CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. Before 7.21.6, this was known as + CURLOPT_ENCODING */ + CINIT(ACCEPT_ENCODING, STRINGPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentially send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specifically switch on or off the FTP engine's use of the EPRT command ( + it also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx + in second argument. The function must be matching the + curl_ssl_ctx_callback proto. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server. + In 7.19.4 we introduced the convenience enums for this option using the + CURLFTP_CREATE_DIR prefix. + */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), +#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, STRINGPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLUSESSL_TRY - try using SSL, proceed anyway otherwise + CURLUSESSL_CONTROL - SSL for the control connection or fail + CURLUSESSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, STRINGPOINT, 134), + + /* feed cookie into cookie engine */ + CINIT(COOKIELIST, STRINGPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the application even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Set the behaviour of POST when redirecting. Values must be set to one + of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ + CINIT(POSTREDIR, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ + CINIT(PROXY_TRANSFER_MODE, LONG, 166), + + /* Callback function for seeking in the input stream */ + CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), + CINIT(SEEKDATA, OBJECTPOINT, 168), + + /* CRL file */ + CINIT(CRLFILE, STRINGPOINT, 169), + + /* Issuer certificate */ + CINIT(ISSUERCERT, STRINGPOINT, 170), + + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + + /* Collect certificate chain info and allow it to get retrievable with + CURLINFO_CERTINFO after the transfer is complete. */ + CINIT(CERTINFO, LONG, 172), + + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, STRINGPOINT, 173), + CINIT(PASSWORD, STRINGPOINT, 174), + + /* "name" and "pwd" to use with Proxy when fetching. */ + CINIT(PROXYUSERNAME, STRINGPOINT, 175), + CINIT(PROXYPASSWORD, STRINGPOINT, 176), + + /* Comma separated list of hostnames defining no-proxy zones. These should + match both hostnames directly, and hostnames within a domain. For + example, local.com will match local.com and www.local.com, but NOT + notlocal.com or www.notlocal.com. For compatibility with other + implementations of this, .local.com will be considered to be the same as + local.com. A single * is the only valid wildcard, and effectively + disables the use of proxy. */ + CINIT(NOPROXY, STRINGPOINT, 177), + + /* block size for TFTP transfers */ + CINIT(TFTP_BLKSIZE, LONG, 178), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */ + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + CINIT(PROTOCOLS, LONG, 181), + + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. Defaults + to all protocols except FILE and SCP. */ + CINIT(REDIR_PROTOCOLS, LONG, 182), + + /* set the SSH knownhost file name to use */ + CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183), + + /* set the SSH host key callback, must point to a curl_sshkeycallback + function */ + CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + + /* set the SSH host key callback custom pointer */ + CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + + /* set the SMTP mail originator */ + CINIT(MAIL_FROM, STRINGPOINT, 186), + + /* set the list of SMTP mail receiver(s) */ + CINIT(MAIL_RCPT, OBJECTPOINT, 187), + + /* FTP: send PRET before PASV */ + CINIT(FTP_USE_PRET, LONG, 188), + + /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ + CINIT(RTSP_REQUEST, LONG, 189), + + /* The RTSP session identifier */ + CINIT(RTSP_SESSION_ID, STRINGPOINT, 190), + + /* The RTSP stream URI */ + CINIT(RTSP_STREAM_URI, STRINGPOINT, 191), + + /* The Transport: header to use in RTSP requests */ + CINIT(RTSP_TRANSPORT, STRINGPOINT, 192), + + /* Manually initialize the client RTSP CSeq for this handle */ + CINIT(RTSP_CLIENT_CSEQ, LONG, 193), + + /* Manually initialize the server RTSP CSeq for this handle */ + CINIT(RTSP_SERVER_CSEQ, LONG, 194), + + /* The stream to pass to INTERLEAVEFUNCTION. */ + CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), + + /* Let the application define a custom write method for RTP data */ + CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), + + /* Turn on wildcard matching */ + CINIT(WILDCARDMATCH, LONG, 197), + + /* Directory matching callback called before downloading of an + individual file (chunk) started */ + CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), + + /* Directory matching callback called after the file (chunk) + was downloaded, or skipped */ + CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), + + /* Change match (fnmatch-like) callback for wildcard matching */ + CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), + + /* Let the application define custom chunk data pointer */ + CINIT(CHUNK_DATA, OBJECTPOINT, 201), + + /* FNMATCH_FUNCTION user pointer */ + CINIT(FNMATCH_DATA, OBJECTPOINT, 202), + + /* send linked-list of name:port:address sets */ + CINIT(RESOLVE, OBJECTPOINT, 203), + + /* Set a username for authenticated TLS */ + CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204), + + /* Set a password for authenticated TLS */ + CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205), + + /* Set authentication type for authenticated TLS */ + CINIT(TLSAUTH_TYPE, STRINGPOINT, 206), + + /* Set to 1 to enable the "TE:" header in HTTP requests to ask for + compressed transfer-encoded responses. Set to 0 to disable the use of TE: + in outgoing requests. The current default is 0, but it might change in a + future libcurl release. + + libcurl will ask for the compressed methods it knows of, and if that + isn't any, it will not ask for transfer-encoding at all even if this + option is set to 1. + + */ + CINIT(TRANSFER_ENCODING, LONG, 207), + + /* Callback function for closing socket (instead of close(2)). The callback + should have type curl_closesocket_callback */ + CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), + CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), + + /* allow GSSAPI credential delegation */ + CINIT(GSSAPI_DELEGATION, LONG, 210), + + /* Set the name servers to use for DNS resolution */ + CINIT(DNS_SERVERS, STRINGPOINT, 211), + + /* Time-out accept operations (currently for FTP only) after this amount + of miliseconds. */ + CINIT(ACCEPTTIMEOUT_MS, LONG, 212), + + /* Set TCP keepalive */ + CINIT(TCP_KEEPALIVE, LONG, 213), + + /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ + CINIT(TCP_KEEPIDLE, LONG, 214), + CINIT(TCP_KEEPINTVL, LONG, 215), + + /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ + CINIT(SSL_OPTIONS, LONG, 216), + + /* Set the SMTP auth originator */ + CINIT(MAIL_AUTH, STRINGPOINT, 217), + + /* Enable/disable SASL initial response */ + CINIT(SASL_IR, LONG, 218), + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_xferinfo_callback + * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ + CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219), + + /* The XOAUTH2 bearer token */ + CINIT(XOAUTH2_BEARER, STRINGPOINT, 220), + + /* Set the interface string to use as outgoing network + * interface for DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_INTERFACE, STRINGPOINT, 221), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223), + + /* Set authentication options directly */ + CINIT(LOGIN_OPTIONS, STRINGPOINT, 224), + + /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_NPN, LONG, 225), + + /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_ALPN, LONG, 226), + + /* Time to wait for a response to a HTTP request containing an + * Expect: 100-continue header before sending the data anyway. */ + CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227), + + /* This points to a linked list of headers used for proxy requests only, + struct curl_slist kind */ + CINIT(PROXYHEADER, OBJECTPOINT, 228), + + /* Pass in a bitmask of "header options" */ + CINIT(HEADEROPT, LONG, 229), + + /* The public key in DER form used to validate the peer public key + this option is used only if SSL_VERIFYPEER is true */ + CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230), + + /* Path to Unix domain socket */ + CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231), + + /* Set if we should verify the certificate status. */ + CINIT(SSL_VERIFYSTATUS, LONG, 232), + + /* Set if we should enable TLS false start. */ + CINIT(SSL_FALSESTART, LONG, 233), + + /* Do not squash dot-dot sequences */ + CINIT(PATH_AS_IS, LONG, 234), + + /* Proxy Service Name */ + CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235), + + /* Service Name */ + CINIT(SERVICE_NAME, STRINGPOINT, 236), + + /* Wait/don't wait for pipe/mutex to clarify */ + CINIT(PIPEWAIT, LONG, 237), + + /* Set the protocol used when curl is given a URL without a protocol */ + CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238), + + /* Set stream weight, 1 - 256 (default is 16) */ + CINIT(STREAM_WEIGHT, LONG, 239), + + /* Set stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS, OBJECTPOINT, 240), + + /* Set E-xclusive stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241), + + /* Do not send any tftp option requests to the server */ + CINIT(TFTP_NO_OPTIONS, LONG, 242), + + /* Linked-list of host:port:connect-to-host:connect-to-port, + overrides the URL's host:port (only for the network layer) */ + CINIT(CONNECT_TO, OBJECTPOINT, 243), + + /* Set TCP Fast Open */ + CINIT(TCP_FASTOPEN, LONG, 244), + + /* Continue to send data if the server responds early with an + * HTTP status code >= 300 */ + CINIT(KEEP_SENDING_ON_ERROR, LONG, 245), + + /* The CApath or CAfile used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_CAINFO, STRINGPOINT, 246), + + /* The CApath directory used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_CAPATH, STRINGPOINT, 247), + + /* Set if we should verify the proxy in ssl handshake, + set 1 to verify. */ + CINIT(PROXY_SSL_VERIFYPEER, LONG, 248), + + /* Set if we should verify the Common name from the proxy certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches + * the provided hostname. */ + CINIT(PROXY_SSL_VERIFYHOST, LONG, 249), + + /* What version to specifically try to use for proxy. + See CURL_SSLVERSION defines below. */ + CINIT(PROXY_SSLVERSION, LONG, 250), + + /* Set a username for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251), + + /* Set a password for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252), + + /* Set authentication type for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253), + + /* name of the file keeping your private SSL-certificate for proxy */ + CINIT(PROXY_SSLCERT, STRINGPOINT, 254), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for + proxy */ + CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255), + + /* name of the file keeping your private SSL-key for proxy */ + CINIT(PROXY_SSLKEY, STRINGPOINT, 256), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for + proxy */ + CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257), + + /* password for the SSL private key for proxy */ + CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258), + + /* Specify which SSL ciphers to use for proxy */ + CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259), + + /* CRL file for proxy */ + CINIT(PROXY_CRLFILE, STRINGPOINT, 260), + + /* Enable/disable specific SSL features with a bitmask for proxy, see + CURLSSLOPT_* */ + CINIT(PROXY_SSL_OPTIONS, LONG, 261), + + /* Name of pre proxy to use. */ + CINIT(PRE_PROXY, STRINGPOINT, 262), + + /* The public key in DER form used to validate the proxy public key + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263), + + /* Path to an abstract Unix domain socket */ + CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264), + + /* Suppress proxy CONNECT response headers from user callbacks */ + CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265), + + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2011 */ + +/* This was added in version 7.19.1 */ +#define CURLOPT_POST301 CURLOPT_POSTREDIR + +/* These are scheduled to disappear by 2009 */ + +/* The following were added in 7.17.0 */ +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_FTPAPPEND CURLOPT_APPEND +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL + +/* The following were added earlier */ + +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ + + /* three convenient "aliases" that follow the name scheme better */ +#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ + CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ + CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 + Upgrade */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +}; + +/* Convenience definition simple because the name of the version is HTTP/2 and + not 2.0. The 2_0 version of the enum name was set while the version was + still planned to be 2.0 and we stick to it for compatibility. */ +#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 + +/* + * Public API enums for RTSP requests + */ +enum { + CURL_RTSPREQ_NONE, /* first in list */ + CURL_RTSPREQ_OPTIONS, + CURL_RTSPREQ_DESCRIBE, + CURL_RTSPREQ_ANNOUNCE, + CURL_RTSPREQ_SETUP, + CURL_RTSPREQ_PLAY, + CURL_RTSPREQ_PAUSE, + CURL_RTSPREQ_TEARDOWN, + CURL_RTSPREQ_GET_PARAMETER, + CURL_RTSPREQ_SET_PARAMETER, + CURL_RTSPREQ_RECORD, + CURL_RTSPREQ_RECEIVE, + CURL_RTSPREQ_LAST /* last in list */ +}; + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +}; + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, /* TLS 1.x */ + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + CURL_SSLVERSION_TLSv1_0, + CURL_SSLVERSION_TLSv1_1, + CURL_SSLVERSION_TLSv1_2, + CURL_SSLVERSION_TLSv1_3, + + CURL_SSLVERSION_LAST /* never use, keep last */ +}; + +enum { + CURL_SSLVERSION_MAX_NONE = 0, + CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16), + CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16), + CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16), + CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16), + CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16), + + /* never use, keep last */ + CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16) +}; + +enum CURL_TLSAUTH { + CURL_TLSAUTH_NONE, + CURL_TLSAUTH_SRP, + CURL_TLSAUTH_LAST /* never use, keep last */ +}; + +/* symbols to use with CURLOPT_POSTREDIR. + CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 + can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 + | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ + +#define CURL_REDIR_GET_ALL 0 +#define CURL_REDIR_POST_301 1 +#define CURL_REDIR_POST_302 2 +#define CURL_REDIR_POST_303 4 +#define CURL_REDIR_POST_ALL \ + (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + + +/* curl_strequal() and curl_strnequal() are subject for removal in a future + libcurl, see lib/README.curlx for details + + !checksrc! disable SPACEBEFOREPAREN 2 +*/ +CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); +CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); + +/* name is uppercase CURLFORM_ */ +#ifdef CFINIT +#undef CFINIT +#endif + +#ifdef CURL_ISOCPP +#define CFINIT(name) CURLFORM_ ## name +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define CFINIT(name) CURLFORM_/**/name +#endif + +typedef enum { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CFINIT(STREAM), + CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */ + + CURLFORM_LASTENTRY /* the last unused */ +} CURLformoption; + +#undef CFINIT /* done */ + +/* structure to be used as parameter for CURLFORM_ARRAY */ +struct curl_forms { + CURLformoption option; + const char *value; +}; + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +typedef enum { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} CURLFORMcode; + +/* + * NAME curl_formadd() + * + * DESCRIPTION + * + * Pretty advanced function for building multi-part formposts. Each invoke + * adds one part that together construct a full post. Then use + * CURLOPT_HTTPPOST to send it off to libcurl. + */ +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...); + +/* + * callback function for curl_formget() + * The void *arg pointer will be the one passed as second argument to + * curl_formget(). + * The character buffer passed to it must not be freed. + * Should return the buffer length passed to it as the argument "len" on + * success. + */ +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, + size_t len); + +/* + * NAME curl_formget() + * + * DESCRIPTION + * + * Serialize a curl_httppost struct built with curl_formadd(). + * Accepts a void pointer as second argument which will be passed to + * the curl_formget_callback function. + * Returns 0 on success. + */ +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append); +/* + * NAME curl_formfree() + * + * DESCRIPTION + * + * Free a multipart formpost previously built with curl_formadd(). + */ +CURL_EXTERN void curl_formfree(struct curl_httppost *form); + +/* + * NAME curl_getenv() + * + * DESCRIPTION + * + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is + * complete. DEPRECATED - see lib/README.curlx + */ +CURL_EXTERN char *curl_getenv(const char *variable); + +/* + * NAME curl_version() + * + * DESCRIPTION + * + * Returns a static ascii string of the libcurl version. + */ +CURL_EXTERN char *curl_version(void); + +/* + * NAME curl_easy_escape() + * + * DESCRIPTION + * + * Escapes URL strings (converts all letters consider illegal in URLs to their + * %XX versions). This function returns a new allocated string or NULL if an + * error occurred. + */ +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + + +/* + * NAME curl_easy_unescape() + * + * DESCRIPTION + * + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit + * versions). This function returns a new allocated string or NULL if an error + * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. + */ +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); + +/* + * NAME curl_free() + * + * DESCRIPTION + * + * Provided for de-allocation in the same translation unit that did the + * allocation. Added in libcurl 7.10 + */ +CURL_EXTERN void curl_free(void *p); + +/* + * NAME curl_global_init() + * + * DESCRIPTION + * + * curl_global_init() should be invoked exactly once for each application that + * uses libcurl and before any call of other libcurl functions. + * + * This function is not thread-safe! + */ +CURL_EXTERN CURLcode curl_global_init(long flags); + +/* + * NAME curl_global_init_mem() + * + * DESCRIPTION + * + * curl_global_init() or curl_global_init_mem() should be invoked exactly once + * for each application that uses libcurl. This function can be used to + * initialize libcurl and set user defined memory management callback + * functions. Users can implement memory management routines to check for + * memory leaks, check for mis-use of the curl library etc. User registered + * callback routines with be invoked by this library instead of the system + * memory management routines like malloc, free etc. + */ +CURL_EXTERN CURLcode curl_global_init_mem(long flags, + curl_malloc_callback m, + curl_free_callback f, + curl_realloc_callback r, + curl_strdup_callback s, + curl_calloc_callback c); + +/* + * NAME curl_global_cleanup() + * + * DESCRIPTION + * + * curl_global_cleanup() should be invoked exactly once for each application + * that uses libcurl + */ +CURL_EXTERN void curl_global_cleanup(void); + +/* linked-list structure for the CURLOPT_QUOTE option (and other) */ +struct curl_slist { + char *data; + struct curl_slist *next; +}; + +/* + * NAME curl_slist_append() + * + * DESCRIPTION + * + * Appends a string to a linked list. If no list exists, it will be created + * first. Returns the new list, after appending. + */ +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, + const char *); + +/* + * NAME curl_slist_free_all() + * + * DESCRIPTION + * + * free a previously built curl_slist. + */ +CURL_EXTERN void curl_slist_free_all(struct curl_slist *); + +/* + * NAME curl_getdate() + * + * DESCRIPTION + * + * Returns the time, in seconds since 1 Jan 1970 of the time string given in + * the first argument. The time argument in the second parameter is unused + * and should be set to NULL. + */ +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); + +/* info about the certificate chain, only for OpenSSL builds. Asked + for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ +struct curl_certinfo { + int num_of_certs; /* number of certificates with information */ + struct curl_slist **certinfo; /* for each index in this array, there's a + linked list with textual information in the + format "name: value" */ +}; + +/* enum for the different supported SSL backends */ +typedef enum { + CURLSSLBACKEND_NONE = 0, + CURLSSLBACKEND_OPENSSL = 1, + CURLSSLBACKEND_GNUTLS = 2, + CURLSSLBACKEND_NSS = 3, + CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ + CURLSSLBACKEND_GSKIT = 5, + CURLSSLBACKEND_POLARSSL = 6, + CURLSSLBACKEND_CYASSL = 7, + CURLSSLBACKEND_SCHANNEL = 8, + CURLSSLBACKEND_DARWINSSL = 9, + CURLSSLBACKEND_AXTLS = 10, + CURLSSLBACKEND_MBEDTLS = 11 +} curl_sslbackend; + +/* aliases for library clones and renames */ +#define CURLSSLBACKEND_LIBRESSL 1 +#define CURLSSLBACKEND_BORINGSSL 1 +#define CURLSSLBACKEND_WOLFSSL 6 + +/* Information about the SSL library used and the respective internal SSL + handle, which can be used to obtain further information regarding the + connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ +struct curl_tlssessioninfo { + curl_sslbackend backend; + void *internals; +}; + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_SOCKET 0x500000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_SLIST + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43, + CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, + CURLINFO_TLS_SSL_PTR = CURLINFO_SLIST + 45, + CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, + CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, + CURLINFO_PROTOCOL = CURLINFO_LONG + 48, + CURLINFO_SCHEME = CURLINFO_STRING + 49, + /* Fill in new entries below here! */ + + CURLINFO_LASTONE = 49 +} CURLINFO; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_WIN32 (1<<1) +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_NOTHING 0 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL +#define CURL_GLOBAL_ACK_EINTR (1<<2) + + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different data locks for a single share */ +typedef enum { + CURL_LOCK_DATA_NONE = 0, + /* CURL_LOCK_DATA_SHARE is used internally to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_LAST +} curl_lock_data; + +/* Different lock access types */ +typedef enum { + CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ + CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ + CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ + CURL_LOCK_ACCESS_LAST /* never use */ +} curl_lock_access; + +typedef void (*curl_lock_function)(CURL *handle, + curl_lock_data data, + curl_lock_access locktype, + void *userptr); +typedef void (*curl_unlock_function)(CURL *handle, + curl_lock_data data, + void *userptr); + + +typedef enum { + CURLSHE_OK, /* all is fine */ + CURLSHE_BAD_OPTION, /* 1 */ + CURLSHE_IN_USE, /* 2 */ + CURLSHE_INVALID, /* 3 */ + CURLSHE_NOMEM, /* 4 out of memory */ + CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ + CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ + CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ + CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock + callback functions */ + CURLSHOPT_LAST /* never use */ +} CURLSHoption; + +CURL_EXTERN CURLSH *curl_share_init(void); +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); + +/**************************************************************************** + * Structures for querying information about the curl library at runtime. + */ + +typedef enum { + CURLVERSION_FIRST, + CURLVERSION_SECOND, + CURLVERSION_THIRD, + CURLVERSION_FOURTH, + CURLVERSION_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basically all programs ever that want to get version information. It is + meant to be a built-in version number for what kind of struct the caller + expects. If the struct ever changes, we redefine the NOW to another enum + from above. */ +#define CURLVERSION_NOW CURLVERSION_FOURTH + +typedef struct { + CURLversion age; /* age of the returned struct */ + const char *version; /* LIBCURL_VERSION */ + unsigned int version_num; /* LIBCURL_VERSION_NUM */ + const char *host; /* OS/host/cpu/machine when configured */ + int features; /* bitmask, see defines below */ + const char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used anymore, always 0 */ + const char *libz_version; /* human readable string */ + /* protocols is terminated by an entry with a NULL protoname */ + const char * const *protocols; + + /* The fields below this were added in CURLVERSION_SECOND */ + const char *ares; + int ares_num; + + /* This field was added in CURLVERSION_THIRD */ + const char *libidn; + + /* These field were added in CURLVERSION_FOURTH */ + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; + + const char *libssh_version; /* human readable string */ + +} curl_version_info_data; + +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported + (deprecated) */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported + (deprecated) */ +#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ +#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are + supported */ +#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ +#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ +#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ +#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ +#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper + is suported */ +#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ +#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ +#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ +#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ +#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used + for cookie domain verification */ +#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */ + + /* + * NAME curl_version_info() + * + * DESCRIPTION + * + * This function returns a pointer to a static copy of the version info + * struct. See above. + */ +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); + +/* + * NAME curl_easy_strerror() + * + * DESCRIPTION + * + * The curl_easy_strerror function may be used to turn a CURLcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_easy_strerror(CURLcode); + +/* + * NAME curl_share_strerror() + * + * DESCRIPTION + * + * The curl_share_strerror function may be used to turn a CURLSHcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_share_strerror(CURLSHcode); + +/* + * NAME curl_easy_pause() + * + * DESCRIPTION + * + * The curl_easy_pause function pauses or unpauses transfers. Select the new + * state by setting the bitmask, use the convenience defines below. + * + */ +CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); + +#define CURLPAUSE_RECV (1<<0) +#define CURLPAUSE_RECV_CONT (0) + +#define CURLPAUSE_SEND (1<<2) +#define CURLPAUSE_SEND_CONT (0) + +#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) +#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) + +#ifdef __cplusplus +} +#endif + +/* unfortunately, the easy.h and multi.h include files need options and info + stuff before they can be included! */ +#include "easy.h" /* nothing in curl is fun without the easy stuff */ +#include "multi.h" + +/* the typechecker doesn't work in C++ (yet) */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ + !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) +#include "typecheck-gcc.h" +#else +#if defined(__STDC__) && (__STDC__ >= 1) +/* This preprocessor magic that replaces a call with the exact same call is + only done to make sure application authors pass exactly three arguments + to these functions. */ +#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) +#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) +#endif /* __STDC__ >= 1 */ +#endif /* gcc >= 4.3 && !__cplusplus */ + +#endif /* __CURL_CURL_H */ diff --git a/includes/curl/curlbuild.h b/includes/curl/curlbuild.h new file mode 100644 index 000000000..ae95095fa --- /dev/null +++ b/includes/curl/curlbuild.h @@ -0,0 +1,586 @@ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * See file include/curl/curlbuild.h.in, run configure, and forget + * that this file exists it is only used for non-configure systems. + * But you can keep reading if you want ;-) + * + */ + +/* ================================================================ */ +/* NOTES FOR NON-CONFIGURE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * Try to keep one section per platform, compiler and architecture, + * otherwise, if an existing section is reused for a different one and + * later on the original is adjusted, probably the piggybacking one can + * be adversely changed. + * + * In order to differentiate between platforms/compilers/architectures + * use only compiler built in predefined preprocessor symbols. + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * For any given platform/compiler curl_off_t must be typedef'ed to a + * 64-bit wide signed integral data type. The width of this data type + * must remain constant and independent of any possible large file + * support settings. + * + * As an exception to the above, curl_off_t shall be typedef'ed to a + * 32-bit wide signed integral data type if there is no 64-bit type. + * + * As a general rule, curl_off_t shall not be mapped to off_t. This + * rule shall only be violated if off_t is the only 64-bit data type + * available and the size of off_t is independent of large file support + * settings. Keep your build on the safe side avoiding an off_t gating. + * If you have a 64-bit off_t then take for sure that another 64-bit + * data type exists, dig deeper and you will find it. + * + * NOTE 3: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.dist or + * at file include/curl/curlbuild.h, this is due to the following reason: + * file include/curl/curlbuild.h.dist is renamed to include/curl/curlbuild.h + * when the libcurl source code distribution archive file is created. + * + * File include/curl/curlbuild.h.dist is not included in the distribution + * archive. File include/curl/curlbuild.h is not present in the git tree. + * + * The distributed include/curl/curlbuild.h file is only intended to be used + * on systems which can not run the also distributed configure script. + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + * If you check out from git on a non-configure platform, you must run the + * appropriate buildconf* script to set up curlbuild.h and other local files. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR NON-CONFIGURE SYSTEMS ONLY */ +/* ================================================================ */ + +#if defined(__DJGPP__) || defined(__GO32__) +# if defined(__DJGPP__) && (__DJGPP__ > 1) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__SALFORDC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__BORLANDC__) +# if (__BORLANDC__ < 0x520) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__TURBOC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__WATCOMC__) +# if defined(__386__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__POCC__) +# if (__POCC__ < 280) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# elif defined(_MSC_VER) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__LCC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__SYMBIAN32__) +# if defined(__EABI__) /* Treat all ARM compilers equally */ +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__CW32__) +# pragma longlong on +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__VC32__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__MWERKS__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(_WIN32_WCE) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__MINGW32__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__VMS) +# if defined(__VAX) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__OS400__) +# if defined(__ILEC400__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__MVS__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# define CURL_SIZEOF_LONG 4 +# elif defined(_LP64) +# define CURL_SIZEOF_LONG 8 +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__370__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# define CURL_SIZEOF_LONG 4 +# elif defined(_LP64) +# define CURL_SIZEOF_LONG 8 +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(TPF) +# define CURL_SIZEOF_LONG 8 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* ===================================== */ +/* KEEP MSVC THE PENULTIMATE ENTRY */ +/* ===================================== */ + +#elif defined(_MSC_VER) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* ===================================== */ +/* KEEP GENERIC GCC THE LAST ENTRY */ +/* ===================================== */ + +#elif defined(__GNUC__) +# if !defined(__LP64__) && (defined(__ILP32__) || \ + defined(__i386__) || defined(__ppc__) || defined(__arm__) || \ + defined(__sparc__) || defined(__mips__) || defined(__sh__)) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__LP64__) || \ + defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) +# define CURL_SIZEOF_LONG 8 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +#else +# error "Unknown non-configure build target!" + Error Compilation_aborted_Unknown_non_configure_build_target +#endif + +/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */ +/* sys/types.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */ +/* sys/socket.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Data type definition of curl_socklen_t. */ + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T + typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; +#endif + +/* Data type definition of curl_off_t. */ + +#ifdef CURL_TYPEOF_CURL_OFF_T + typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; +#endif + +#endif /* __CURL_CURLBUILD_H */ diff --git a/includes/curl/curlbuild.h.cmake b/includes/curl/curlbuild.h.cmake new file mode 100644 index 000000000..bbb31a940 --- /dev/null +++ b/includes/curl/curlbuild.h.cmake @@ -0,0 +1,197 @@ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.in or + * at file include/curl/curlbuild.h, this is due to the following reason: + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file ws2tcpip.h must be included by the external interface. */ +#cmakedefine CURL_PULL_WS2TCPIP_H +#ifdef CURL_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# include +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +#cmakedefine CURL_PULL_SYS_TYPES_H +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file stdint.h must be included by the external interface. */ +#cmakedefine CURL_PULL_STDINT_H +#ifdef CURL_PULL_STDINT_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file inttypes.h must be included by the external interface. */ +#cmakedefine CURL_PULL_INTTYPES_H +#ifdef CURL_PULL_INTTYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/socket.h must be included by the external interface. */ +#cmakedefine CURL_PULL_SYS_SOCKET_H +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/poll.h must be included by the external interface. */ +#cmakedefine CURL_PULL_SYS_POLL_H +#ifdef CURL_PULL_SYS_POLL_H +# include +#endif + +/* The size of `long', as computed by sizeof. */ +#define CURL_SIZEOF_LONG ${CURL_SIZEOF_LONG} + +/* Integral data type used for curl_socklen_t. */ +#define CURL_TYPEOF_CURL_SOCKLEN_T ${CURL_TYPEOF_CURL_SOCKLEN_T} + +/* The size of `curl_socklen_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_SOCKLEN_T ${CURL_SIZEOF_CURL_SOCKLEN_T} + +/* Data type definition of curl_socklen_t. */ +typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; + +/* Signed integral data type used for curl_off_t. */ +#define CURL_TYPEOF_CURL_OFF_T ${CURL_TYPEOF_CURL_OFF_T} + +/* Data type definition of curl_off_t. */ +typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; + +/* curl_off_t formatting string directive without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_T "${CURL_FORMAT_CURL_OFF_T}" + +/* unsigned curl_off_t formatting string without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_TU "${CURL_FORMAT_CURL_OFF_TU}" + +/* curl_off_t formatting string directive with "%" conversion specifier. */ +#define CURL_FORMAT_OFF_T "${CURL_FORMAT_OFF_T}" + +/* The size of `curl_off_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_OFF_T ${CURL_SIZEOF_CURL_OFF_T} + +/* curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_T ${CURL_SUFFIX_CURL_OFF_T} + +/* unsigned curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_TU ${CURL_SUFFIX_CURL_OFF_TU} + +#endif /* __CURL_CURLBUILD_H */ diff --git a/includes/curl/curlbuild.h.dist b/includes/curl/curlbuild.h.dist new file mode 100644 index 000000000..ae95095fa --- /dev/null +++ b/includes/curl/curlbuild.h.dist @@ -0,0 +1,586 @@ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * See file include/curl/curlbuild.h.in, run configure, and forget + * that this file exists it is only used for non-configure systems. + * But you can keep reading if you want ;-) + * + */ + +/* ================================================================ */ +/* NOTES FOR NON-CONFIGURE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * Try to keep one section per platform, compiler and architecture, + * otherwise, if an existing section is reused for a different one and + * later on the original is adjusted, probably the piggybacking one can + * be adversely changed. + * + * In order to differentiate between platforms/compilers/architectures + * use only compiler built in predefined preprocessor symbols. + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * For any given platform/compiler curl_off_t must be typedef'ed to a + * 64-bit wide signed integral data type. The width of this data type + * must remain constant and independent of any possible large file + * support settings. + * + * As an exception to the above, curl_off_t shall be typedef'ed to a + * 32-bit wide signed integral data type if there is no 64-bit type. + * + * As a general rule, curl_off_t shall not be mapped to off_t. This + * rule shall only be violated if off_t is the only 64-bit data type + * available and the size of off_t is independent of large file support + * settings. Keep your build on the safe side avoiding an off_t gating. + * If you have a 64-bit off_t then take for sure that another 64-bit + * data type exists, dig deeper and you will find it. + * + * NOTE 3: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.dist or + * at file include/curl/curlbuild.h, this is due to the following reason: + * file include/curl/curlbuild.h.dist is renamed to include/curl/curlbuild.h + * when the libcurl source code distribution archive file is created. + * + * File include/curl/curlbuild.h.dist is not included in the distribution + * archive. File include/curl/curlbuild.h is not present in the git tree. + * + * The distributed include/curl/curlbuild.h file is only intended to be used + * on systems which can not run the also distributed configure script. + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + * If you check out from git on a non-configure platform, you must run the + * appropriate buildconf* script to set up curlbuild.h and other local files. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR NON-CONFIGURE SYSTEMS ONLY */ +/* ================================================================ */ + +#if defined(__DJGPP__) || defined(__GO32__) +# if defined(__DJGPP__) && (__DJGPP__ > 1) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__SALFORDC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__BORLANDC__) +# if (__BORLANDC__ < 0x520) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__TURBOC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__WATCOMC__) +# if defined(__386__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__POCC__) +# if (__POCC__ < 280) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# elif defined(_MSC_VER) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__LCC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__SYMBIAN32__) +# if defined(__EABI__) /* Treat all ARM compilers equally */ +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__CW32__) +# pragma longlong on +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__VC32__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__MWERKS__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(_WIN32_WCE) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__MINGW32__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__VMS) +# if defined(__VAX) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__OS400__) +# if defined(__ILEC400__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__MVS__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# define CURL_SIZEOF_LONG 4 +# elif defined(_LP64) +# define CURL_SIZEOF_LONG 8 +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__370__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# define CURL_SIZEOF_LONG 4 +# elif defined(_LP64) +# define CURL_SIZEOF_LONG 8 +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(TPF) +# define CURL_SIZEOF_LONG 8 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* ===================================== */ +/* KEEP MSVC THE PENULTIMATE ENTRY */ +/* ===================================== */ + +#elif defined(_MSC_VER) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* ===================================== */ +/* KEEP GENERIC GCC THE LAST ENTRY */ +/* ===================================== */ + +#elif defined(__GNUC__) +# if !defined(__LP64__) && (defined(__ILP32__) || \ + defined(__i386__) || defined(__ppc__) || defined(__arm__) || \ + defined(__sparc__) || defined(__mips__) || defined(__sh__)) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__LP64__) || \ + defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) +# define CURL_SIZEOF_LONG 8 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +#else +# error "Unknown non-configure build target!" + Error Compilation_aborted_Unknown_non_configure_build_target +#endif + +/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */ +/* sys/types.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */ +/* sys/socket.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Data type definition of curl_socklen_t. */ + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T + typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; +#endif + +/* Data type definition of curl_off_t. */ + +#ifdef CURL_TYPEOF_CURL_OFF_T + typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; +#endif + +#endif /* __CURL_CURLBUILD_H */ diff --git a/includes/curl/curlbuild.h.in b/includes/curl/curlbuild.h.in new file mode 100644 index 000000000..ffab35670 --- /dev/null +++ b/includes/curl/curlbuild.h.in @@ -0,0 +1,197 @@ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.in or + * at file include/curl/curlbuild.h, this is due to the following reason: + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file ws2tcpip.h must be included by the external interface. */ +#undef CURL_PULL_WS2TCPIP_H +#ifdef CURL_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# include +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +#undef CURL_PULL_SYS_TYPES_H +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file stdint.h must be included by the external interface. */ +#undef CURL_PULL_STDINT_H +#ifdef CURL_PULL_STDINT_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file inttypes.h must be included by the external interface. */ +#undef CURL_PULL_INTTYPES_H +#ifdef CURL_PULL_INTTYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/socket.h must be included by the external interface. */ +#undef CURL_PULL_SYS_SOCKET_H +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/poll.h must be included by the external interface. */ +#undef CURL_PULL_SYS_POLL_H +#ifdef CURL_PULL_SYS_POLL_H +# include +#endif + +/* The size of `long', as computed by sizeof. */ +#undef CURL_SIZEOF_LONG + +/* Integral data type used for curl_socklen_t. */ +#undef CURL_TYPEOF_CURL_SOCKLEN_T + +/* The size of `curl_socklen_t', as computed by sizeof. */ +#undef CURL_SIZEOF_CURL_SOCKLEN_T + +/* Data type definition of curl_socklen_t. */ +typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; + +/* Signed integral data type used for curl_off_t. */ +#undef CURL_TYPEOF_CURL_OFF_T + +/* Data type definition of curl_off_t. */ +typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; + +/* curl_off_t formatting string directive without "%" conversion specifier. */ +#undef CURL_FORMAT_CURL_OFF_T + +/* unsigned curl_off_t formatting string without "%" conversion specifier. */ +#undef CURL_FORMAT_CURL_OFF_TU + +/* curl_off_t formatting string directive with "%" conversion specifier. */ +#undef CURL_FORMAT_OFF_T + +/* The size of `curl_off_t', as computed by sizeof. */ +#undef CURL_SIZEOF_CURL_OFF_T + +/* curl_off_t constant suffix. */ +#undef CURL_SUFFIX_CURL_OFF_T + +/* unsigned curl_off_t constant suffix. */ +#undef CURL_SUFFIX_CURL_OFF_TU + +#endif /* __CURL_CURLBUILD_H */ diff --git a/includes/curl/curlrules.h b/includes/curl/curlrules.h new file mode 100644 index 000000000..55d21f68f --- /dev/null +++ b/includes/curl/curlrules.h @@ -0,0 +1,262 @@ +#ifndef __CURL_CURLRULES_H +#define __CURL_CURLRULES_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* COMPILE TIME SANITY CHECKS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * All checks done in this file are intentionally placed in a public + * header file which is pulled by curl/curl.h when an application is + * being built using an already built libcurl library. Additionally + * this file is also included and used when building the library. + * + * If compilation fails on this file it is certainly sure that the + * problem is elsewhere. It could be a problem in the curlbuild.h + * header file, or simply that you are using different compilation + * settings than those used to build the library. + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * Do not deactivate any check, these are done to make sure that the + * library is properly built and used. + * + * You can find further help on the libcurl development mailing list: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * NOTE 2 + * ------ + * + * Some of the following compile time checks are based on the fact + * that the dimension of a constant array can not be a negative one. + * In this way if the compile time verification fails, the compilation + * will fail issuing an error. The error description wording is compiler + * dependent but it will be quite similar to one of the following: + * + * "negative subscript or subscript is too large" + * "array must have at least one element" + * "-1 is an illegal array size" + * "size of array is negative" + * + * If you are building an application which tries to use an already + * built libcurl library and you are getting this kind of errors on + * this file, it is a clear indication that there is a mismatch between + * how the library was built and how you are trying to use it for your + * application. Your already compiled or binary library provider is the + * only one who can give you the details you need to properly use it. + */ + +/* + * Verify that some macros are actually defined. + */ + +#ifndef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing +#endif + +#ifndef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing +#endif + +/* + * Macros private to this header file. + */ + +#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1 + +#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 + +/* + * Verify that the size previously defined and expected for long + * is the same as the one reported by sizeof() at compile time. + */ + +typedef char + __curl_rule_01__ + [CurlchkszEQ(long, CURL_SIZEOF_LONG)]; + +/* + * Verify that the size previously defined and expected for + * curl_off_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_02__ + [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)]; + +/* + * Verify at compile time that the size of curl_off_t as reported + * by sizeof() is greater or equal than the one reported for long + * for the current compilation. + */ + +typedef char + __curl_rule_03__ + [CurlchkszGE(curl_off_t, long)]; + +/* + * Verify that the size previously defined and expected for + * curl_socklen_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_04__ + [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)]; + +/* + * Verify at compile time that the size of curl_socklen_t as reported + * by sizeof() is greater or equal than the one reported for int for + * the current compilation. + */ + +typedef char + __curl_rule_05__ + [CurlchkszGE(curl_socklen_t, int)]; + +/* ================================================================ */ +/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ +/* ================================================================ */ + +/* + * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow + * these to be visible and exported by the external libcurl interface API, + * while also making them visible to the library internals, simply including + * curl_setup.h, without actually needing to include curl.h internally. + * If some day this section would grow big enough, all this should be moved + * to its own header file. + */ + +/* + * Figure out if we can use the ## preprocessor operator, which is supported + * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ + * or __cplusplus so we need to carefully check for them too. + */ + +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ + defined(__ILEC400__) + /* This compiler is believed to have an ISO compatible preprocessor */ +#define CURL_ISOCPP +#else + /* This compiler is believed NOT to have an ISO compatible preprocessor */ +#undef CURL_ISOCPP +#endif + +/* + * Macros for minimum-width signed and unsigned curl_off_t integer constants. + */ + +#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) +# define __CURL_OFF_T_C_HLPR2(x) x +# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) +#else +# ifdef CURL_ISOCPP +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix +# else +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix +# endif +# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) +#endif + +/* + * Get rid of macros private to this header file. + */ + +#undef CurlchkszEQ +#undef CurlchkszGE + +/* + * Get rid of macros not intended to exist beyond this point. + */ + +#undef CURL_PULL_WS2TCPIP_H +#undef CURL_PULL_SYS_TYPES_H +#undef CURL_PULL_SYS_SOCKET_H +#undef CURL_PULL_SYS_POLL_H +#undef CURL_PULL_STDINT_H +#undef CURL_PULL_INTTYPES_H + +#undef CURL_TYPEOF_CURL_SOCKLEN_T +#undef CURL_TYPEOF_CURL_OFF_T + +#ifdef CURL_NO_OLDIES +#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */ +#endif + +#endif /* __CURL_CURLRULES_H */ diff --git a/includes/curl/curlver.h b/includes/curl/curlver.h new file mode 100644 index 000000000..7beda3fa7 --- /dev/null +++ b/includes/curl/curlver.h @@ -0,0 +1,77 @@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This header file contains nothing but libcurl version info, generated by + a script at release-time. This was made its own header file in 7.11.2 */ + +/* This is the global package copyright */ +#define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, ." + +/* This is the version number of the libcurl package from which this header + file origins: */ +#define LIBCURL_VERSION "7.54.0-DEV" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 +#define LIBCURL_VERSION_MINOR 54 +#define LIBCURL_VERSION_PATCH 0 + +/* This is the numeric version of the libcurl version number, meant for easier + parsing and comparions by programs. The LIBCURL_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. + + Note: This define is the full hex number and _does not_ use the + CURL_VERSION_BITS() macro since curl's own configure script greps for it + and needs it to contain the full number. +*/ +#define LIBCURL_VERSION_NUM 0x073600 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in git, as the timestamp is properly set in the + * tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + */ +#define LIBCURL_TIMESTAMP "DEV" + +#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) +#define CURL_AT_LEAST_VERSION(x,y,z) \ + (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) + +#endif /* __CURL_CURLVER_H */ diff --git a/includes/curl/easy.h b/includes/curl/easy.h new file mode 100644 index 000000000..752c5049f --- /dev/null +++ b/includes/curl/easy.h @@ -0,0 +1,102 @@ +#ifndef __CURL_EASY_H +#define __CURL_EASY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN CURL *curl_easy_init(void); +CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); +CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); +CURL_EXTERN void curl_easy_cleanup(CURL *curl); + +/* + * NAME curl_easy_getinfo() + * + * DESCRIPTION + * + * Request internal information from the curl session with this function. The + * third argument MUST be a pointer to a long, a pointer to a char * or a + * pointer to a double (as the documentation describes elsewhere). The data + * pointed to will be filled in accordingly and can be relied upon only if the + * function returns CURLE_OK. This function is intended to get used *AFTER* a + * performed transfer, all results from this function are undefined until the + * transfer is completed. + */ +CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); + + +/* + * NAME curl_easy_duphandle() + * + * DESCRIPTION + * + * Creates a new curl session handle with the same options set for the handle + * passed in. Duplicating a handle could only be a matter of cloning data and + * options, internal state info and things like persistent connections cannot + * be transferred. It is useful in multithreaded applications when you can run + * curl_easy_duphandle() for each new thread to avoid a series of identical + * curl_easy_setopt() invokes in every thread. + */ +CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); + +/* + * NAME curl_easy_reset() + * + * DESCRIPTION + * + * Re-initializes a CURL handle to the default values. This puts back the + * handle to the same state as it was in when it was just created. + * + * It does keep: live connections, the Session ID cache, the DNS cache and the + * cookies. + */ +CURL_EXTERN void curl_easy_reset(CURL *curl); + +/* + * NAME curl_easy_recv() + * + * DESCRIPTION + * + * Receives data from the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, + size_t *n); + +/* + * NAME curl_easy_send() + * + * DESCRIPTION + * + * Sends data over the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, + size_t buflen, size_t *n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/includes/curl/mprintf.h b/includes/curl/mprintf.h new file mode 100644 index 000000000..e20f546e1 --- /dev/null +++ b/includes/curl/mprintf.h @@ -0,0 +1,50 @@ +#ifndef __CURL_MPRINTF_H +#define __CURL_MPRINTF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include +#include /* needed for FILE */ +#include "curl.h" /* for CURL_EXTERN */ + +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN int curl_mprintf(const char *format, ...); +CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); +CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); +CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, + const char *format, ...); +CURL_EXTERN int curl_mvprintf(const char *format, va_list args); +CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); +CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); +CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, + const char *format, va_list args); +CURL_EXTERN char *curl_maprintf(const char *format, ...); +CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); + +#ifdef __cplusplus +} +#endif + +#endif /* __CURL_MPRINTF_H */ diff --git a/includes/curl/multi.h b/includes/curl/multi.h new file mode 100644 index 000000000..d1e00cc5d --- /dev/null +++ b/includes/curl/multi.h @@ -0,0 +1,439 @@ +#ifndef __CURL_MULTI_H +#define __CURL_MULTI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + This is an "external" header file. Don't give away any internals here! + + GOALS + + o Enable a "pull" interface. The application that uses libcurl decides where + and when to ask libcurl to get/send data. + + o Enable multiple simultaneous transfers in the same thread without making it + complicated for the application. + + o Enable the application to select() on its own file descriptors and curl's + file descriptors simultaneous easily. + +*/ + +/* + * This header file should not really need to include "curl.h" since curl.h + * itself includes this file and we expect user applications to do #include + * without the need for especially including multi.h. + * + * For some reason we added this include here at one point, and rather than to + * break existing (wrongly written) libcurl applications, we leave it as-is + * but with this warning attached. + */ +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_multi CURLM; +#else +typedef void CURLM; +#endif + +typedef enum { + CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or + curl_multi_socket*() soon */ + CURLM_OK, + CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ + CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ + CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ + CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ + CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ + CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ + CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was + attempted to get added - again */ + CURLM_LAST +} CURLMcode; + +/* just to make code nicer when using curl_multi_socket() you can now check + for CURLM_CALL_MULTI_SOCKET too in the same style it works for + curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ +#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM + +/* bitmask bits for CURLMOPT_PIPELINING */ +#define CURLPIPE_NOTHING 0L +#define CURLPIPE_HTTP1 1L +#define CURLPIPE_MULTIPLEX 2L + +typedef enum { + CURLMSG_NONE, /* first, not used */ + CURLMSG_DONE, /* This easy handle has completed. 'result' contains + the CURLcode of the transfer */ + CURLMSG_LAST /* last, not used */ +} CURLMSG; + +struct CURLMsg { + CURLMSG msg; /* what this message means */ + CURL *easy_handle; /* the handle it concerns */ + union { + void *whatever; /* message-specific data */ + CURLcode result; /* return code for transfer */ + } data; +}; +typedef struct CURLMsg CURLMsg; + +/* Based on poll(2) structure and values. + * We don't use pollfd and POLL* constants explicitly + * to cover platforms without poll(). */ +#define CURL_WAIT_POLLIN 0x0001 +#define CURL_WAIT_POLLPRI 0x0002 +#define CURL_WAIT_POLLOUT 0x0004 + +struct curl_waitfd { + curl_socket_t fd; + short events; + short revents; /* not supported yet */ +}; + +/* + * Name: curl_multi_init() + * + * Desc: inititalize multi-style curl usage + * + * Returns: a new CURLM handle to use in all 'curl_multi' functions. + */ +CURL_EXTERN CURLM *curl_multi_init(void); + +/* + * Name: curl_multi_add_handle() + * + * Desc: add a standard curl handle to the multi stack + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_remove_handle() + * + * Desc: removes a curl handle from the multi stack again + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_fdset() + * + * Desc: Ask curl for its fd_set sets. The app can use these to select() or + * poll() on. We want curl_multi_perform() called as soon as one of + * them are ready. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); + +/* + * Name: curl_multi_wait() + * + * Desc: Poll on all fds within a CURLM set as well as any + * additional fds passed to the function. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret); + + /* + * Name: curl_multi_perform() + * + * Desc: When the app thinks there's data available for curl it calls this + * function to read/write whatever there is right now. This returns + * as soon as the reads and writes are done. This function does not + * require that there actually is data available for reading or that + * data can be written, it can be called just in case. It returns + * the number of handles that still transfer data in the second + * argument's integer-pointer. + * + * Returns: CURLMcode type, general multi error code. *NOTE* that this only + * returns errors etc regarding the whole multi stack. There might + * still have occurred problems on invidual transfers even when this + * returns OK. + */ +CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, + int *running_handles); + + /* + * Name: curl_multi_cleanup() + * + * Desc: Cleans up and removes a whole multi stack. It does not free or + * touch any individual easy handles in any way. We need to define + * in what state those handles will be if this function is called + * in the middle of a transfer. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); + +/* + * Name: curl_multi_info_read() + * + * Desc: Ask the multi handle if there's any messages/informationals from + * the individual transfers. Messages include informationals such as + * error code from the transfer or just the fact that a transfer is + * completed. More details on these should be written down as well. + * + * Repeated calls to this function will return a new struct each + * time, until a special "end of msgs" struct is returned as a signal + * that there is no more to get at this point. + * + * The data the returned pointer points to will not survive calling + * curl_multi_cleanup(). + * + * The 'CURLMsg' struct is meant to be very simple and only contain + * very basic informations. If more involved information is wanted, + * we will provide the particular "transfer handle" in that struct + * and that should/could/would be used in subsequent + * curl_easy_getinfo() calls (or similar). The point being that we + * must never expose complex structs to applications, as then we'll + * undoubtably get backwards compatibility problems in the future. + * + * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out + * of structs. It also writes the number of messages left in the + * queue (after this read) in the integer the second argument points + * to. + */ +CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, + int *msgs_in_queue); + +/* + * Name: curl_multi_strerror() + * + * Desc: The curl_multi_strerror function may be used to turn a CURLMcode + * value into the equivalent human readable error string. This is + * useful for printing meaningful error messages. + * + * Returns: A pointer to a zero-terminated error message. + */ +CURL_EXTERN const char *curl_multi_strerror(CURLMcode); + +/* + * Name: curl_multi_socket() and + * curl_multi_socket_all() + * + * Desc: An alternative version of curl_multi_perform() that allows the + * application to pass in one of the file descriptors that have been + * detected to have "action" on them and let libcurl perform. + * See man page for details. + */ +#define CURL_POLL_NONE 0 +#define CURL_POLL_IN 1 +#define CURL_POLL_OUT 2 +#define CURL_POLL_INOUT 3 +#define CURL_POLL_REMOVE 4 + +#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD + +#define CURL_CSELECT_IN 0x01 +#define CURL_CSELECT_OUT 0x02 +#define CURL_CSELECT_ERR 0x04 + +typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* see above */ + void *userp, /* private callback + pointer */ + void *socketp); /* private socket + pointer */ +/* + * Name: curl_multi_timer_callback + * + * Desc: Called by libcurl whenever the library detects a change in the + * maximum number of milliseconds the app is allowed to wait before + * curl_multi_socket() or curl_multi_perform() must be called + * (to allow libcurl's timed events to take place). + * + * Returns: The callback should return zero. + */ +typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp); /* private callback + pointer */ + +CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, + curl_socket_t s, + int ev_bitmask, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); + +#ifndef CURL_ALLOW_OLD_MULTI_SOCKET +/* This macro below was added in 7.16.3 to push users who recompile to use + the new curl_multi_socket_action() instead of the old curl_multi_socket() +*/ +#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) +#endif + +/* + * Name: curl_multi_timeout() + * + * Desc: Returns the maximum number of milliseconds the app is allowed to + * wait before curl_multi_socket() or curl_multi_perform() must be + * called (to allow libcurl's timed events to take place). + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, + long *milliseconds); + +#undef CINIT /* re-using the same name as in curl.h */ + +#ifdef CURL_ISOCPP +#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLMOPT_/**/name = type + number +#endif + +typedef enum { + /* This is the socket callback function pointer */ + CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), + + /* This is the argument passed to the socket callback */ + CINIT(SOCKETDATA, OBJECTPOINT, 2), + + /* set to 1 to enable pipelining for this multi handle */ + CINIT(PIPELINING, LONG, 3), + + /* This is the timer callback function pointer */ + CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), + + /* This is the argument passed to the timer callback */ + CINIT(TIMERDATA, OBJECTPOINT, 5), + + /* maximum number of entries in the connection cache */ + CINIT(MAXCONNECTS, LONG, 6), + + /* maximum number of (pipelining) connections to one host */ + CINIT(MAX_HOST_CONNECTIONS, LONG, 7), + + /* maximum number of requests in a pipeline */ + CINIT(MAX_PIPELINE_LENGTH, LONG, 8), + + /* a connection with a content-length longer than this + will not be considered for pipelining */ + CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9), + + /* a connection with a chunk length longer than this + will not be considered for pipelining */ + CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10), + + /* a list of site names(+port) that are blacklisted from + pipelining */ + CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11), + + /* a list of server types that are blacklisted from + pipelining */ + CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12), + + /* maximum number of open connections in total */ + CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13), + + /* This is the server push callback function pointer */ + CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14), + + /* This is the argument passed to the server push callback */ + CINIT(PUSHDATA, OBJECTPOINT, 15), + + CURLMOPT_LASTENTRY /* the last unused */ +} CURLMoption; + + +/* + * Name: curl_multi_setopt() + * + * Desc: Sets options for the multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, + CURLMoption option, ...); + + +/* + * Name: curl_multi_assign() + * + * Desc: This function sets an association in the multi handle between the + * given socket and a private pointer of the application. This is + * (only) useful for curl_multi_socket uses. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, + curl_socket_t sockfd, void *sockp); + + +/* + * Name: curl_push_callback + * + * Desc: This callback gets called when a new stream is being pushed by the + * server. It approves or denies the new stream. + * + * Returns: CURL_PUSH_OK or CURL_PUSH_DENY. + */ +#define CURL_PUSH_OK 0 +#define CURL_PUSH_DENY 1 + +struct curl_pushheaders; /* forward declaration only */ + +CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, + size_t num); +CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, + const char *name); + +typedef int (*curl_push_callback)(CURL *parent, + CURL *easy, + size_t num_headers, + struct curl_pushheaders *headers, + void *userp); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/includes/curl/stdcheaders.h b/includes/curl/stdcheaders.h new file mode 100644 index 000000000..027b6f421 --- /dev/null +++ b/includes/curl/stdcheaders.h @@ -0,0 +1,33 @@ +#ifndef __STDC_HEADERS_H +#define __STDC_HEADERS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include + +size_t fread(void *, size_t, size_t, FILE *); +size_t fwrite(const void *, size_t, size_t, FILE *); + +int strcasecmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); + +#endif /* __STDC_HEADERS_H */ diff --git a/includes/curl/typecheck-gcc.h b/includes/curl/typecheck-gcc.h new file mode 100644 index 000000000..3d683152b --- /dev/null +++ b/includes/curl/typecheck-gcc.h @@ -0,0 +1,624 @@ +#ifndef __CURL_TYPECHECK_GCC_H +#define __CURL_TYPECHECK_GCC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* wraps curl_easy_setopt() with typechecking */ + +/* To add a new kind of warning, add an + * if(_curl_is_sometype_option(_curl_opt)) + * if(!_curl_is_sometype(value)) + * _curl_easy_setopt_err_sometype(); + * block and define _curl_is_sometype_option, _curl_is_sometype and + * _curl_easy_setopt_err_sometype below + * + * NOTE: We use two nested 'if' statements here instead of the && operator, in + * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x + * when compiling with -Wlogical-op. + * + * To add an option that uses the same type as an existing option, you'll just + * need to extend the appropriate _curl_*_option macro + */ +#define curl_easy_setopt(handle, option, value) \ +__extension__ ({ \ + __typeof__(option) _curl_opt = option; \ + if(__builtin_constant_p(_curl_opt)) { \ + if(_curl_is_long_option(_curl_opt)) \ + if(!_curl_is_long(value)) \ + _curl_easy_setopt_err_long(); \ + if(_curl_is_off_t_option(_curl_opt)) \ + if(!_curl_is_off_t(value)) \ + _curl_easy_setopt_err_curl_off_t(); \ + if(_curl_is_string_option(_curl_opt)) \ + if(!_curl_is_string(value)) \ + _curl_easy_setopt_err_string(); \ + if(_curl_is_write_cb_option(_curl_opt)) \ + if(!_curl_is_write_cb(value)) \ + _curl_easy_setopt_err_write_callback(); \ + if((_curl_opt) == CURLOPT_READFUNCTION) \ + if(!_curl_is_read_cb(value)) \ + _curl_easy_setopt_err_read_cb(); \ + if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ + if(!_curl_is_ioctl_cb(value)) \ + _curl_easy_setopt_err_ioctl_cb(); \ + if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ + if(!_curl_is_sockopt_cb(value)) \ + _curl_easy_setopt_err_sockopt_cb(); \ + if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ + if(!_curl_is_opensocket_cb(value)) \ + _curl_easy_setopt_err_opensocket_cb(); \ + if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ + if(!_curl_is_progress_cb(value)) \ + _curl_easy_setopt_err_progress_cb(); \ + if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ + if(!_curl_is_debug_cb(value)) \ + _curl_easy_setopt_err_debug_cb(); \ + if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ + if(!_curl_is_ssl_ctx_cb(value)) \ + _curl_easy_setopt_err_ssl_ctx_cb(); \ + if(_curl_is_conv_cb_option(_curl_opt)) \ + if(!_curl_is_conv_cb(value)) \ + _curl_easy_setopt_err_conv_cb(); \ + if((_curl_opt) == CURLOPT_SEEKFUNCTION) \ + if(!_curl_is_seek_cb(value)) \ + _curl_easy_setopt_err_seek_cb(); \ + if(_curl_is_cb_data_option(_curl_opt)) \ + if(!_curl_is_cb_data(value)) \ + _curl_easy_setopt_err_cb_data(); \ + if((_curl_opt) == CURLOPT_ERRORBUFFER) \ + if(!_curl_is_error_buffer(value)) \ + _curl_easy_setopt_err_error_buffer(); \ + if((_curl_opt) == CURLOPT_STDERR) \ + if(!_curl_is_FILE(value)) \ + _curl_easy_setopt_err_FILE(); \ + if(_curl_is_postfields_option(_curl_opt)) \ + if(!_curl_is_postfields(value)) \ + _curl_easy_setopt_err_postfields(); \ + if((_curl_opt) == CURLOPT_HTTPPOST) \ + if(!_curl_is_arr((value), struct curl_httppost)) \ + _curl_easy_setopt_err_curl_httpost(); \ + if(_curl_is_slist_option(_curl_opt)) \ + if(!_curl_is_arr((value), struct curl_slist)) \ + _curl_easy_setopt_err_curl_slist(); \ + if((_curl_opt) == CURLOPT_SHARE) \ + if(!_curl_is_ptr((value), CURLSH)) \ + _curl_easy_setopt_err_CURLSH(); \ + } \ + curl_easy_setopt(handle, _curl_opt, value); \ +}) + +/* wraps curl_easy_getinfo() with typechecking */ +/* FIXME: don't allow const pointers */ +#define curl_easy_getinfo(handle, info, arg) \ +__extension__ ({ \ + __typeof__(info) _curl_info = info; \ + if(__builtin_constant_p(_curl_info)) { \ + if(_curl_is_string_info(_curl_info)) \ + if(!_curl_is_arr((arg), char *)) \ + _curl_easy_getinfo_err_string(); \ + if(_curl_is_long_info(_curl_info)) \ + if(!_curl_is_arr((arg), long)) \ + _curl_easy_getinfo_err_long(); \ + if(_curl_is_double_info(_curl_info)) \ + if(!_curl_is_arr((arg), double)) \ + _curl_easy_getinfo_err_double(); \ + if(_curl_is_slist_info(_curl_info)) \ + if(!_curl_is_arr((arg), struct curl_slist *)) \ + _curl_easy_getinfo_err_curl_slist(); \ + } \ + curl_easy_getinfo(handle, _curl_info, arg); \ +}) + +/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), + * for now just make sure that the functions are called with three + * arguments + */ +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) + + +/* the actual warnings, triggered by calling the _curl_easy_setopt_err* + * functions */ + +/* To define a new warning, use _CURL_WARNING(identifier, "message") */ +#define _CURL_WARNING(id, message) \ + static void __attribute__((__warning__(message))) \ + __attribute__((__unused__)) __attribute__((__noinline__)) \ + id(void) { __asm__(""); } + +_CURL_WARNING(_curl_easy_setopt_err_long, + "curl_easy_setopt expects a long argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, + "curl_easy_setopt expects a curl_off_t argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_string, + "curl_easy_setopt expects a " + "string ('char *' or char[]) argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_write_callback, + "curl_easy_setopt expects a curl_write_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_read_cb, + "curl_easy_setopt expects a curl_read_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, + "curl_easy_setopt expects a curl_ioctl_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, + "curl_easy_setopt expects a curl_sockopt_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, + "curl_easy_setopt expects a " + "curl_opensocket_callback argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_progress_cb, + "curl_easy_setopt expects a curl_progress_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_debug_cb, + "curl_easy_setopt expects a curl_debug_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, + "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_conv_cb, + "curl_easy_setopt expects a curl_conv_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_seek_cb, + "curl_easy_setopt expects a curl_seek_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_cb_data, + "curl_easy_setopt expects a " + "private data pointer as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_error_buffer, + "curl_easy_setopt expects a " + "char buffer of CURL_ERROR_SIZE as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_FILE, + "curl_easy_setopt expects a 'FILE *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_postfields, + "curl_easy_setopt expects a 'void *' or 'char *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, + "curl_easy_setopt expects a 'struct curl_httppost *' " + "argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_slist, + "curl_easy_setopt expects a 'struct curl_slist *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_CURLSH, + "curl_easy_setopt expects a CURLSH* argument for this option") + +_CURL_WARNING(_curl_easy_getinfo_err_string, + "curl_easy_getinfo expects a pointer to 'char *' for this info") +_CURL_WARNING(_curl_easy_getinfo_err_long, + "curl_easy_getinfo expects a pointer to long for this info") +_CURL_WARNING(_curl_easy_getinfo_err_double, + "curl_easy_getinfo expects a pointer to double for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, + "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info") + +/* groups of curl_easy_setops options that take the same type of argument */ + +/* To add a new option to one of the groups, just add + * (option) == CURLOPT_SOMETHING + * to the or-expression. If the option takes a long or curl_off_t, you don't + * have to do anything + */ + +/* evaluates to true if option takes a long argument */ +#define _curl_is_long_option(option) \ + (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) + +#define _curl_is_off_t_option(option) \ + ((option) > CURLOPTTYPE_OFF_T) + +/* evaluates to true if option takes a char* argument */ +#define _curl_is_string_option(option) \ + ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \ + (option) == CURLOPT_ACCEPT_ENCODING || \ + (option) == CURLOPT_CAINFO || \ + (option) == CURLOPT_CAPATH || \ + (option) == CURLOPT_COOKIE || \ + (option) == CURLOPT_COOKIEFILE || \ + (option) == CURLOPT_COOKIEJAR || \ + (option) == CURLOPT_COOKIELIST || \ + (option) == CURLOPT_CRLFILE || \ + (option) == CURLOPT_CUSTOMREQUEST || \ + (option) == CURLOPT_DEFAULT_PROTOCOL || \ + (option) == CURLOPT_DNS_INTERFACE || \ + (option) == CURLOPT_DNS_LOCAL_IP4 || \ + (option) == CURLOPT_DNS_LOCAL_IP6 || \ + (option) == CURLOPT_DNS_SERVERS || \ + (option) == CURLOPT_EGDSOCKET || \ + (option) == CURLOPT_FTPPORT || \ + (option) == CURLOPT_FTP_ACCOUNT || \ + (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ + (option) == CURLOPT_INTERFACE || \ + (option) == CURLOPT_ISSUERCERT || \ + (option) == CURLOPT_KEYPASSWD || \ + (option) == CURLOPT_KRBLEVEL || \ + (option) == CURLOPT_LOGIN_OPTIONS || \ + (option) == CURLOPT_MAIL_AUTH || \ + (option) == CURLOPT_MAIL_FROM || \ + (option) == CURLOPT_NETRC_FILE || \ + (option) == CURLOPT_NOPROXY || \ + (option) == CURLOPT_PASSWORD || \ + (option) == CURLOPT_PINNEDPUBLICKEY || \ + (option) == CURLOPT_PROXY || \ + (option) == CURLOPT_PROXYPASSWORD || \ + (option) == CURLOPT_PROXYUSERNAME || \ + (option) == CURLOPT_PROXYUSERPWD || \ + (option) == CURLOPT_PROXY_SERVICE_NAME || \ + (option) == CURLOPT_RANDOM_FILE || \ + (option) == CURLOPT_RANGE || \ + (option) == CURLOPT_REFERER || \ + (option) == CURLOPT_RTSP_SESSION_ID || \ + (option) == CURLOPT_RTSP_STREAM_URI || \ + (option) == CURLOPT_RTSP_TRANSPORT || \ + (option) == CURLOPT_SERVICE_NAME || \ + (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ + (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ + (option) == CURLOPT_SSH_KNOWNHOSTS || \ + (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ + (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ + (option) == CURLOPT_SSLCERT || \ + (option) == CURLOPT_SSLCERTTYPE || \ + (option) == CURLOPT_SSLENGINE || \ + (option) == CURLOPT_SSLKEY || \ + (option) == CURLOPT_SSLKEYTYPE || \ + (option) == CURLOPT_SSL_CIPHER_LIST || \ + (option) == CURLOPT_TLSAUTH_PASSWORD || \ + (option) == CURLOPT_TLSAUTH_TYPE || \ + (option) == CURLOPT_TLSAUTH_USERNAME || \ + (option) == CURLOPT_UNIX_SOCKET_PATH || \ + (option) == CURLOPT_URL || \ + (option) == CURLOPT_USERAGENT || \ + (option) == CURLOPT_USERNAME || \ + (option) == CURLOPT_USERPWD || \ + (option) == CURLOPT_XOAUTH2_BEARER || \ + 0) + +/* evaluates to true if option takes a curl_write_callback argument */ +#define _curl_is_write_cb_option(option) \ + ((option) == CURLOPT_HEADERFUNCTION || \ + (option) == CURLOPT_WRITEFUNCTION) + +/* evaluates to true if option takes a curl_conv_callback argument */ +#define _curl_is_conv_cb_option(option) \ + ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) + +/* evaluates to true if option takes a data argument to pass to a callback */ +#define _curl_is_cb_data_option(option) \ + ((option) == CURLOPT_CHUNK_DATA || \ + (option) == CURLOPT_CLOSESOCKETDATA || \ + (option) == CURLOPT_DEBUGDATA || \ + (option) == CURLOPT_FNMATCH_DATA || \ + (option) == CURLOPT_HEADERDATA || \ + (option) == CURLOPT_INTERLEAVEDATA || \ + (option) == CURLOPT_IOCTLDATA || \ + (option) == CURLOPT_OPENSOCKETDATA || \ + (option) == CURLOPT_PRIVATE || \ + (option) == CURLOPT_PROGRESSDATA || \ + (option) == CURLOPT_READDATA || \ + (option) == CURLOPT_SEEKDATA || \ + (option) == CURLOPT_SOCKOPTDATA || \ + (option) == CURLOPT_SSH_KEYDATA || \ + (option) == CURLOPT_SSL_CTX_DATA || \ + (option) == CURLOPT_WRITEDATA || \ + 0) + +/* evaluates to true if option takes a POST data argument (void* or char*) */ +#define _curl_is_postfields_option(option) \ + ((option) == CURLOPT_POSTFIELDS || \ + (option) == CURLOPT_COPYPOSTFIELDS || \ + 0) + +/* evaluates to true if option takes a struct curl_slist * argument */ +#define _curl_is_slist_option(option) \ + ((option) == CURLOPT_HTTP200ALIASES || \ + (option) == CURLOPT_HTTPHEADER || \ + (option) == CURLOPT_MAIL_RCPT || \ + (option) == CURLOPT_POSTQUOTE || \ + (option) == CURLOPT_PREQUOTE || \ + (option) == CURLOPT_PROXYHEADER || \ + (option) == CURLOPT_QUOTE || \ + (option) == CURLOPT_RESOLVE || \ + (option) == CURLOPT_TELNETOPTIONS || \ + 0) + +/* groups of curl_easy_getinfo infos that take the same type of argument */ + +/* evaluates to true if info expects a pointer to char * argument */ +#define _curl_is_string_info(info) \ + (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) + +/* evaluates to true if info expects a pointer to long argument */ +#define _curl_is_long_info(info) \ + (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) + +/* evaluates to true if info expects a pointer to double argument */ +#define _curl_is_double_info(info) \ + (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) + +/* true if info expects a pointer to struct curl_slist * argument */ +#define _curl_is_slist_info(info) \ + (CURLINFO_SLIST < (info)) + + +/* typecheck helpers -- check whether given expression has requested type*/ + +/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, + * otherwise define a new macro. Search for __builtin_types_compatible_p + * in the GCC manual. + * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is + * the actual expression passed to the curl_easy_setopt macro. This + * means that you can only apply the sizeof and __typeof__ operators, no + * == or whatsoever. + */ + +/* XXX: should evaluate to true iff expr is a pointer */ +#define _curl_is_any_ptr(expr) \ + (sizeof(expr) == sizeof(void *)) + +/* evaluates to true if expr is NULL */ +/* XXX: must not evaluate expr, so this check is not accurate */ +#define _curl_is_NULL(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) + +/* evaluates to true if expr is type*, const type* or NULL */ +#define _curl_is_ptr(expr, type) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), type *) || \ + __builtin_types_compatible_p(__typeof__(expr), const type *)) + +/* evaluates to true if expr is one of type[], type*, NULL or const type* */ +#define _curl_is_arr(expr, type) \ + (_curl_is_ptr((expr), type) || \ + __builtin_types_compatible_p(__typeof__(expr), type [])) + +/* evaluates to true if expr is a string */ +#define _curl_is_string(expr) \ + (_curl_is_arr((expr), char) || \ + _curl_is_arr((expr), signed char) || \ + _curl_is_arr((expr), unsigned char)) + +/* evaluates to true if expr is a long (no matter the signedness) + * XXX: for now, int is also accepted (and therefore short and char, which + * are promoted to int when passed to a variadic function) */ +#define _curl_is_long(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), long) || \ + __builtin_types_compatible_p(__typeof__(expr), signed long) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ + __builtin_types_compatible_p(__typeof__(expr), int) || \ + __builtin_types_compatible_p(__typeof__(expr), signed int) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ + __builtin_types_compatible_p(__typeof__(expr), short) || \ + __builtin_types_compatible_p(__typeof__(expr), signed short) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ + __builtin_types_compatible_p(__typeof__(expr), char) || \ + __builtin_types_compatible_p(__typeof__(expr), signed char) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned char)) + +/* evaluates to true if expr is of type curl_off_t */ +#define _curl_is_off_t(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) + +/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ +/* XXX: also check size of an char[] array? */ +#define _curl_is_error_buffer(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), char *) || \ + __builtin_types_compatible_p(__typeof__(expr), char[])) + +/* evaluates to true if expr is of type (const) void* or (const) FILE* */ +#if 0 +#define _curl_is_cb_data(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_ptr((expr), FILE)) +#else /* be less strict */ +#define _curl_is_cb_data(expr) \ + _curl_is_any_ptr(expr) +#endif + +/* evaluates to true if expr is of type FILE* */ +#define _curl_is_FILE(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), FILE *)) + +/* evaluates to true if expr can be passed as POST data (void* or char*) */ +#define _curl_is_postfields(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_arr((expr), char)) + +/* FIXME: the whole callback checking is messy... + * The idea is to tolerate char vs. void and const vs. not const + * pointers in arguments at least + */ +/* helper: __builtin_types_compatible_p distinguishes between functions and + * function pointers, hide it */ +#define _curl_callback_compatible(func, type) \ + (__builtin_types_compatible_p(__typeof__(func), type) || \ + __builtin_types_compatible_p(__typeof__(func), type*)) + +/* evaluates to true if expr is of type curl_read_callback or "similar" */ +#define _curl_is_read_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \ + _curl_callback_compatible((expr), _curl_read_callback1) || \ + _curl_callback_compatible((expr), _curl_read_callback2) || \ + _curl_callback_compatible((expr), _curl_read_callback3) || \ + _curl_callback_compatible((expr), _curl_read_callback4) || \ + _curl_callback_compatible((expr), _curl_read_callback5) || \ + _curl_callback_compatible((expr), _curl_read_callback6)) +typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void *); +typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void *); +typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE *); +typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void *); +typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void *); +typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE *); + +/* evaluates to true if expr is of type curl_write_callback or "similar" */ +#define _curl_is_write_cb(expr) \ + (_curl_is_read_cb(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \ + _curl_callback_compatible((expr), _curl_write_callback1) || \ + _curl_callback_compatible((expr), _curl_write_callback2) || \ + _curl_callback_compatible((expr), _curl_write_callback3) || \ + _curl_callback_compatible((expr), _curl_write_callback4) || \ + _curl_callback_compatible((expr), _curl_write_callback5) || \ + _curl_callback_compatible((expr), _curl_write_callback6)) +typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void *); +typedef size_t (_curl_write_callback2)(const char *, size_t, size_t, + const void *); +typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE *); +typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void *); +typedef size_t (_curl_write_callback5)(const void *, size_t, size_t, + const void *); +typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE *); + +/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ +#define _curl_is_ioctl_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback4)) +typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void *); +typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void *); +typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void *); +typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void *); + +/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ +#define _curl_is_sockopt_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback2)) +typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); +typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t, + curlsocktype); + +/* evaluates to true if expr is of type curl_opensocket_callback or + "similar" */ +#define _curl_is_opensocket_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\ + _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback4)) +typedef curl_socket_t (_curl_opensocket_callback1) + (void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback2) + (void *, curlsocktype, const struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback3) + (const void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback4) + (const void *, curlsocktype, const struct curl_sockaddr *); + +/* evaluates to true if expr is of type curl_progress_callback or "similar" */ +#define _curl_is_progress_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \ + _curl_callback_compatible((expr), _curl_progress_callback1) || \ + _curl_callback_compatible((expr), _curl_progress_callback2)) +typedef int (_curl_progress_callback1)(void *, + double, double, double, double); +typedef int (_curl_progress_callback2)(const void *, + double, double, double, double); + +/* evaluates to true if expr is of type curl_debug_callback or "similar" */ +#define _curl_is_debug_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \ + _curl_callback_compatible((expr), _curl_debug_callback1) || \ + _curl_callback_compatible((expr), _curl_debug_callback2) || \ + _curl_callback_compatible((expr), _curl_debug_callback3) || \ + _curl_callback_compatible((expr), _curl_debug_callback4) || \ + _curl_callback_compatible((expr), _curl_debug_callback5) || \ + _curl_callback_compatible((expr), _curl_debug_callback6) || \ + _curl_callback_compatible((expr), _curl_debug_callback7) || \ + _curl_callback_compatible((expr), _curl_debug_callback8)) +typedef int (_curl_debug_callback1) (CURL *, + curl_infotype, char *, size_t, void *); +typedef int (_curl_debug_callback2) (CURL *, + curl_infotype, char *, size_t, const void *); +typedef int (_curl_debug_callback3) (CURL *, + curl_infotype, const char *, size_t, void *); +typedef int (_curl_debug_callback4) (CURL *, + curl_infotype, const char *, size_t, const void *); +typedef int (_curl_debug_callback5) (CURL *, + curl_infotype, unsigned char *, size_t, void *); +typedef int (_curl_debug_callback6) (CURL *, + curl_infotype, unsigned char *, size_t, const void *); +typedef int (_curl_debug_callback7) (CURL *, + curl_infotype, const unsigned char *, size_t, void *); +typedef int (_curl_debug_callback8) (CURL *, + curl_infotype, const unsigned char *, size_t, const void *); + +/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ +/* this is getting even messier... */ +#define _curl_is_ssl_ctx_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) +typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *); +typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *); +#ifdef HEADER_SSL_H +/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX + * this will of course break if we're included before OpenSSL headers... + */ +typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); +typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, + const void *); +#else +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; +#endif + +/* evaluates to true if expr is of type curl_conv_callback or "similar" */ +#define _curl_is_conv_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \ + _curl_callback_compatible((expr), _curl_conv_callback1) || \ + _curl_callback_compatible((expr), _curl_conv_callback2) || \ + _curl_callback_compatible((expr), _curl_conv_callback3) || \ + _curl_callback_compatible((expr), _curl_conv_callback4)) +typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); +typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); +typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); +typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); + +/* evaluates to true if expr is of type curl_seek_callback or "similar" */ +#define _curl_is_seek_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \ + _curl_callback_compatible((expr), _curl_seek_callback1) || \ + _curl_callback_compatible((expr), _curl_seek_callback2)) +typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); +typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); + + +#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index 861e71444..48d39e417 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -67,6 +67,7 @@ HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr); TWO_STRINGS(basilisk,refresh,symbol,address); ZERO_ARGS(basilisk,cancelrefresh); STRING_ARRAY_OBJ_STRING(basilisk,utxorawtx,symbol,utxos,vals,ignore); +HASH_ARRAY_STRING(basilisk,utxocombine,ignore,vals,symbol); HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr); @@ -197,6 +198,8 @@ STRING_ARG(iguana,stakers,activecoin); STRING_ARG(jumblr,setpassphrase,passphrase); ZERO_ARGS(jumblr,status); +ZERO_ARGS(jumblr,runsilent); +ZERO_ARGS(jumblr,totransparent); ZERO_ARGS(InstantDEX,allcoins); STRING_ARG(InstantDEX,available,source); @@ -225,6 +228,9 @@ STRING_ARG(InstantDEX,allpairs,exchange); THREE_STRINGS(InstantDEX,supports,exchange,base,rel); ZERO_ARGS(InstantDEX,init); ZERO_ARGS(InstantDEX,getswaplist); +ZERO_ARGS(InstantDEX,smartaddresses); +TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,smartaddress,type,symbol,maxbid,minask); +DOUBLE_ARG(InstantDEX,DEXratio,ratio); //THREE_STRINGS(atomic,approve,myorderid,otherid,txname); //THREE_STRINGS(atomic,claim,myorderid,otherid,txname); @@ -298,7 +304,7 @@ THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey); ZERO_ARGS(SuperNET,keypair); HASH_AND_INT(SuperNET,priv2pub,privkey,addrtype); STRING_ARG(SuperNET,wif2priv,wif); -STRING_ARG(SuperNET,priv2wif,priv); +STRING_AND_INT(SuperNET,priv2wif,priv,wiftype); STRING_ARG(SuperNET,addr2rmd160,address); STRING_ARG(SuperNET,rmd160conv,rmd160); diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index ac4487c49..ceb086e22 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -287,6 +287,7 @@ int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,s int32_t category_peer(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 category,bits256 subhash); int32_t bitcoin_wif2priv(uint8_t *addrtypep,bits256 *privkeyp,char *wifstr); int32_t bitcoin_priv2wif(char *wifstr,bits256 privkey,uint8_t addrtype); +int32_t bitcoin_priv2wiflong(char *wifstr,bits256 privkey,uint8_t addrtype); bits256 iguana_chaingenesis(struct supernet_info *myinfo,char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root); int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr); cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height,struct vin_info *V); @@ -528,7 +529,7 @@ char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coi int32_t iguana_markedunspents_find(struct iguana_info *coin,int32_t *firstslotp,bits256 txid,int32_t vout); void jumblr_opidsupdate(struct supernet_info *myinfo,struct iguana_info *coin); -char *iguana_signrawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkey,struct vin_info *V); +char *iguana_signrawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkeys,struct vin_info *V); bits256 scrypt_blockhash(const void *input); bits256 iguana_calcblockhash(char *symbol,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),uint8_t *serialized,int32_t len); struct bitcoin_eventitem *instantdex_event(char *cmdstr,cJSON *argjson,cJSON *newjson,uint8_t *serdata,int32_t serdatalen); @@ -604,12 +605,12 @@ int32_t iguana_scriptdata(struct iguana_info *coin,uint8_t *scriptspace,long fil void basilisk_ensurerelay(struct supernet_info *myinfo,struct iguana_info *notaries,uint32_t ipbits); void dpow_nanomsginit(struct supernet_info *myinfo,char *ipaddr); int32_t iguana_datachain_scan(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t rmd160[20]); -void basilisk_requests_poll(struct supernet_info *myinfo); +int32_t basilisk_requests_poll(struct supernet_info *myinfo); void dpow_psockloop(void *_ptr); -int32_t smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *BTCaddr,char *KMDaddr); -int32_t smartaddress(struct supernet_info *myinfo,bits256 *privkeyp,char *coinaddr); -int32_t smartaddress_pubkey(struct supernet_info *myinfo,bits256 *privkeyp,bits256 pubkey); -int32_t smartaddress_pubkey33(struct supernet_info *myinfo,bits256 *privkeyp,uint8_t *pubkey33); +int32_t smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *typestr,char *symbol,double maxbid,double minask); +int32_t smartaddress(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,char *coinaddr); +int32_t smartaddress_pubkey(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,bits256 pubkey); +int32_t smartaddress_pubkey33(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,uint8_t *pubkey33); void iguana_RTreset(struct iguana_info *coin); void iguana_RTpurge(struct iguana_info *coin,int32_t lastheight); @@ -629,10 +630,11 @@ int32_t iguana_staker_sort(struct iguana_info *coin,bits256 *hash2p,uint8_t *ref bits256 mpz_div64(bits256 hash,uint64_t divval); void iguana_walletinitcheck(struct supernet_info *myinfo,struct iguana_info *coin); void jumblr_iteration(struct supernet_info *myinfo,struct iguana_info *coin,int32_t selector,int32_t modval); -void jumblr_DEXcheck(struct supernet_info *myinfo,struct iguana_info *coinkmd,char *BTCaddr,char *KMDaddr,bits256 privkey); -bits256 jumblr_privkey(struct supernet_info *myinfo,char *BTCaddr,char *KMDaddr,char *prefix); +void smartaddress_update(struct supernet_info *myinfo,int32_t selector); +bits256 jumblr_privkey(struct supernet_info *myinfo,char *BTCaddr,uint8_t pubtype,char *KMDaddr,char *prefix); char *jumblr_importprivkey(struct supernet_info *myinfo,struct iguana_info *coin,char *wifstr); int64_t iguana_esttxfee(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx,char *signedtx,int32_t numvins); +int64_t jumblr_balance(struct supernet_info *myinfo,struct iguana_info *coin,char *addr); // ------------------------------------------------------[ Preparation ]---- // Initialise a gfshare context for producing shares @@ -659,7 +661,7 @@ void iguana_schnorr(struct supernet_info *myinfo); void iguana_fixsecp(struct supernet_info *myinfo); int32_t bitcoin_timelockspend(uint8_t *script,int32_t n,uint8_t rmd160[20],uint32_t timestamp); -char *iguana_calcutxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,cJSON *txobj,int64_t satoshis,char *changeaddr,int64_t txfee,cJSON *utxos,char *remoteaddr,struct vin_info *V,int32_t maxmode); +char *iguana_calcutxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,cJSON *txobj,int64_t *satoshis,int32_t numoutputs,char *changeaddr,int64_t txfee,cJSON *utxos,char *remoteaddr,struct vin_info *V,int32_t maxmode); uint64_t _iguana_interest(uint32_t now,int32_t height,uint32_t txlocktime,uint64_t value); #include "../includes/iguana_api.h" diff --git a/includes/iguana_structs.h b/includes/iguana_structs.h index 813bd77a7..3becc3b26 100755 --- a/includes/iguana_structs.h +++ b/includes/iguana_structs.h @@ -141,7 +141,7 @@ struct iguana_msgmerkle uint32_t branch_length; bits256 branch_hash[4096]; uint32_t branch_side_mask; -}PACKEDSTRUCT; +}; //PACKEDSTRUCT; struct iguana_msgblock { @@ -155,9 +155,9 @@ struct iguana_msgzblock uint32_t txn_count; } PACKEDSTRUCT; -struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; }PACKEDSTRUCT; +struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; }; //PACKEDSTRUCT; -struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; }PACKEDSTRUCT; +struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; }; //PACKEDSTRUCT; struct iguana_msgtx { @@ -168,7 +168,7 @@ struct iguana_msgtx int32_t allocsize,timestamp,numinputs,numoutputs; int64_t inputsum,outputsum,txfee; uint8_t *serialized; -} PACKEDSTRUCT; +};// PACKEDSTRUCT; struct iguana_msgjoinsplit { @@ -466,10 +466,22 @@ struct iguana_RTtxid struct hashstr_item { UT_hash_handle hh; char address[40]; }; +struct jumblr_pending { bits256 splittxid,txid; int32_t vout,ind; }; + +struct DEXcoin_info +{ + bits256 deposit_privkey,jumblr_privkey; + struct iguana_info *coin; + double btcprice,BTC2KMD,kmdprice,USD_average,DEXpending,maxbid,minask,avail,jumblravail; + uint32_t lasttime,counter; int32_t numpending; + char CMCname[32],symbol[16],depositaddr[64],KMDdepositaddr[64],KMDjumblraddr[64],jumblraddr[64]; + struct jumblr_pending *pending; +}; + struct iguana_info { UT_hash_handle hh; - char name[64],symbol[64],protocol,statusstr[512],scriptsfname[2][512]; + char CMCname[64],name[64],symbol[64],protocol,statusstr[512],scriptsfname[2][512]; struct iguana_peers *peers; struct iguana_peer internaladdr; //basilisk_func basilisk_rawtx,basilisk_balances,basilisk_value; //basilisk_metricfunc basilisk_rawtxmetric,basilisk_balancesmetric,basilisk_valuemetric; @@ -534,6 +546,7 @@ struct iguana_info uint64_t estimatedfee; char seedipaddr[64]; uint32_t lastbesthashtime; bits256 lastbesthash; int32_t lastbestheight; + struct DEXcoin_info DEXinfo; struct iguana_block *RTblocks[65536]; uint8_t *RTrawdata[65536]; int32_t RTrecvlens[65536],RTnumtx[65536]; struct iguana_RTtxid *RTdataset; struct iguana_RTaddr *RTaddrs; struct hashstr_item *alladdresses; @@ -591,7 +604,7 @@ struct basilisk_request char src[8],dest[8]; //char volatile_start,message[43]; uint64_t destamount; - int32_t optionhours,profitmargin; + int32_t optionhours,profitmargin;//,DEXselector,extraspace; } PACKEDSTRUCT; struct basilisk_relaystatus diff --git a/makeRelease.sh b/makeRelease.sh new file mode 100644 index 000000000..89f5c8a88 --- /dev/null +++ b/makeRelease.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +binaries=("iguana") + +for binary in "${binaries[@]}"; +do + # find the dylibs to copy for komodod + DYLIBS=`otool -L agents/$binary | grep "/usr/local" | awk -F' ' '{ print $1 }'` + echo "copying $DYLIBS to agents" + # copy the dylibs to the agents-dir + for dylib in $DYLIBS; do cp -rf $dylib agents/; done + + # modify komodod to point to dylibs + echo "modifying $binary to use local libraries" + for dylib in $DYLIBS; do install_name_tool -change $dylib @executable_path/`basename $dylib` agents/$binary; done; + chmod +x agents/$binary +done diff --git a/nanomsg/bin/libnanomsg.dll b/nanomsg/bin/libnanomsg.dll new file mode 100755 index 000000000..4a7fe2768 Binary files /dev/null and b/nanomsg/bin/libnanomsg.dll differ diff --git a/nanomsg/bin/nanocat.exe b/nanomsg/bin/nanocat.exe new file mode 100755 index 000000000..b34b8984e Binary files /dev/null and b/nanomsg/bin/nanocat.exe differ diff --git a/nanomsg/include/nanomsg/bus.h b/nanomsg/include/nanomsg/bus.h new file mode 100644 index 000000000..7572903ed --- /dev/null +++ b/nanomsg/include/nanomsg/bus.h @@ -0,0 +1,39 @@ +/* + Copyright (c) 2013 Martin Sustrik All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef BUS_H_INCLUDED +#define BUS_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define NN_PROTO_BUS 7 + +#define NN_BUS (NN_PROTO_BUS * 16 + 0) + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nanomsg/include/nanomsg/inproc.h b/nanomsg/include/nanomsg/inproc.h new file mode 100644 index 000000000..ed3879908 --- /dev/null +++ b/nanomsg/include/nanomsg/inproc.h @@ -0,0 +1,37 @@ +/* + Copyright (c) 2012 Martin Sustrik All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef INPROC_H_INCLUDED +#define INPROC_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define NN_INPROC -1 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nanomsg/include/nanomsg/ipc.h b/nanomsg/include/nanomsg/ipc.h new file mode 100644 index 000000000..a78bfb833 --- /dev/null +++ b/nanomsg/include/nanomsg/ipc.h @@ -0,0 +1,42 @@ +/* + Copyright (c) 2012 Martin Sustrik All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef IPC_H_INCLUDED +#define IPC_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define NN_IPC -2 + +/* The object set here must be valid as long as you are using the socket */ +#define NN_IPC_SEC_ATTR 1 +#define NN_IPC_OUTBUFSZ 2 +#define NN_IPC_INBUFSZ 3 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nanomsg/include/nanomsg/nn.h b/nanomsg/include/nanomsg/nn.h new file mode 100644 index 000000000..ce5efe33b --- /dev/null +++ b/nanomsg/include/nanomsg/nn.h @@ -0,0 +1,412 @@ +/* + Copyright (c) 2012-2014 Martin Sustrik All rights reserved. + Copyright (c) 2013 GoPivotal, Inc. All rights reserved. + Copyright 2016 Garrett D'Amore + Copyright (c) 2015-2016 Jack R. Dunaway. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef NN_H_INCLUDED +#define NN_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* Handle DSO symbol visibility. */ +#if !defined(NN_EXPORT) +# if defined(_WIN32) && !defined(NN_STATIC_LIB) +# if defined NN_SHARED_LIB +# define NN_EXPORT __declspec(dllexport) +# else +# define NN_EXPORT __declspec(dllimport) +# endif +# else +# define NN_EXPORT extern +# endif +#endif + +/******************************************************************************/ +/* ABI versioning support. */ +/******************************************************************************/ + +/* Don't change this unless you know exactly what you're doing and have */ +/* read and understand the following documents: */ +/* www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html */ +/* www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html */ + +/* The current interface version. */ +#define NN_VERSION_CURRENT 5 + +/* The latest revision of the current interface. */ +#define NN_VERSION_REVISION 0 + +/* How many past interface versions are still supported. */ +#define NN_VERSION_AGE 0 + +/******************************************************************************/ +/* Errors. */ +/******************************************************************************/ + +/* A number random enough not to collide with different errno ranges on */ +/* different OSes. The assumption is that error_t is at least 32-bit type. */ +#define NN_HAUSNUMERO 156384712 + +/* On some platforms some standard POSIX errnos are not defined. */ +#ifndef ENOTSUP +#define ENOTSUP (NN_HAUSNUMERO + 1) +#endif +#ifndef EPROTONOSUPPORT +#define EPROTONOSUPPORT (NN_HAUSNUMERO + 2) +#endif +#ifndef ENOBUFS +#define ENOBUFS (NN_HAUSNUMERO + 3) +#endif +#ifndef ENETDOWN +#define ENETDOWN (NN_HAUSNUMERO + 4) +#endif +#ifndef EADDRINUSE +#define EADDRINUSE (NN_HAUSNUMERO + 5) +#endif +#ifndef EADDRNOTAVAIL +#define EADDRNOTAVAIL (NN_HAUSNUMERO + 6) +#endif +#ifndef ECONNREFUSED +#define ECONNREFUSED (NN_HAUSNUMERO + 7) +#endif +#ifndef EINPROGRESS +#define EINPROGRESS (NN_HAUSNUMERO + 8) +#endif +#ifndef ENOTSOCK +#define ENOTSOCK (NN_HAUSNUMERO + 9) +#endif +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT (NN_HAUSNUMERO + 10) +#endif +#ifndef EPROTO +#define EPROTO (NN_HAUSNUMERO + 11) +#endif +#ifndef EAGAIN +#define EAGAIN (NN_HAUSNUMERO + 12) +#endif +#ifndef EBADF +#define EBADF (NN_HAUSNUMERO + 13) +#endif +#ifndef EINVAL +#define EINVAL (NN_HAUSNUMERO + 14) +#endif +#ifndef EMFILE +#define EMFILE (NN_HAUSNUMERO + 15) +#endif +#ifndef EFAULT +#define EFAULT (NN_HAUSNUMERO + 16) +#endif +#ifndef EACCES +#define EACCES (NN_HAUSNUMERO + 17) +#endif +#ifndef EACCESS +#define EACCESS (EACCES) +#endif +#ifndef ENETRESET +#define ENETRESET (NN_HAUSNUMERO + 18) +#endif +#ifndef ENETUNREACH +#define ENETUNREACH (NN_HAUSNUMERO + 19) +#endif +#ifndef EHOSTUNREACH +#define EHOSTUNREACH (NN_HAUSNUMERO + 20) +#endif +#ifndef ENOTCONN +#define ENOTCONN (NN_HAUSNUMERO + 21) +#endif +#ifndef EMSGSIZE +#define EMSGSIZE (NN_HAUSNUMERO + 22) +#endif +#ifndef ETIMEDOUT +#define ETIMEDOUT (NN_HAUSNUMERO + 23) +#endif +#ifndef ECONNABORTED +#define ECONNABORTED (NN_HAUSNUMERO + 24) +#endif +#ifndef ECONNRESET +#define ECONNRESET (NN_HAUSNUMERO + 25) +#endif +#ifndef ENOPROTOOPT +#define ENOPROTOOPT (NN_HAUSNUMERO + 26) +#endif +#ifndef EISCONN +#define EISCONN (NN_HAUSNUMERO + 27) +#define NN_EISCONN_DEFINED +#endif +#ifndef ESOCKTNOSUPPORT +#define ESOCKTNOSUPPORT (NN_HAUSNUMERO + 28) +#endif + +/* Native nanomsg error codes. */ +#ifndef ETERM +#define ETERM (NN_HAUSNUMERO + 53) +#endif +#ifndef EFSM +#define EFSM (NN_HAUSNUMERO + 54) +#endif + +/* This function retrieves the errno as it is known to the library. */ +/* The goal of this function is to make the code 100% portable, including */ +/* where the library is compiled with certain CRT library (on Windows) and */ +/* linked to an application that uses different CRT library. */ +NN_EXPORT int nn_errno (void); + +/* Resolves system errors and native errors to human-readable string. */ +NN_EXPORT const char *nn_strerror (int errnum); + + +/* Returns the symbol name (e.g. "NN_REQ") and value at a specified index. */ +/* If the index is out-of-range, returns NULL and sets errno to EINVAL */ +/* General usage is to start at i=0 and iterate until NULL is returned. */ +NN_EXPORT const char *nn_symbol (int i, int *value); + +/* Constants that are returned in `ns` member of nn_symbol_properties */ +#define NN_NS_NAMESPACE 0 +#define NN_NS_VERSION 1 +#define NN_NS_DOMAIN 2 +#define NN_NS_TRANSPORT 3 +#define NN_NS_PROTOCOL 4 +#define NN_NS_OPTION_LEVEL 5 +#define NN_NS_SOCKET_OPTION 6 +#define NN_NS_TRANSPORT_OPTION 7 +#define NN_NS_OPTION_TYPE 8 +#define NN_NS_OPTION_UNIT 9 +#define NN_NS_FLAG 10 +#define NN_NS_ERROR 11 +#define NN_NS_LIMIT 12 +#define NN_NS_EVENT 13 +#define NN_NS_STATISTIC 14 + +/* Constants that are returned in `type` member of nn_symbol_properties */ +#define NN_TYPE_NONE 0 +#define NN_TYPE_INT 1 +#define NN_TYPE_STR 2 + +/* Constants that are returned in the `unit` member of nn_symbol_properties */ +#define NN_UNIT_NONE 0 +#define NN_UNIT_BYTES 1 +#define NN_UNIT_MILLISECONDS 2 +#define NN_UNIT_PRIORITY 3 +#define NN_UNIT_BOOLEAN 4 +#define NN_UNIT_MESSAGES 5 +#define NN_UNIT_COUNTER 6 + +/* Structure that is returned from nn_symbol */ +struct nn_symbol_properties { + + /* The constant value */ + int value; + + /* The constant name */ + const char* name; + + /* The constant namespace, or zero for namespaces themselves */ + int ns; + + /* The option type for socket option constants */ + int type; + + /* The unit for the option value for socket option constants */ + int unit; +}; + +/* Fills in nn_symbol_properties structure and returns it's length */ +/* If the index is out-of-range, returns 0 */ +/* General usage is to start at i=0 and iterate until zero is returned. */ +NN_EXPORT int nn_symbol_info (int i, + struct nn_symbol_properties *buf, int buflen); + +/******************************************************************************/ +/* Helper function for shutting down multi-threaded applications. */ +/******************************************************************************/ + +NN_EXPORT void nn_term (void); + +/******************************************************************************/ +/* Zero-copy support. */ +/******************************************************************************/ + +#define NN_MSG ((size_t) -1) + +NN_EXPORT void *nn_allocmsg (size_t size, int type); +NN_EXPORT void *nn_reallocmsg (void *msg, size_t size); +NN_EXPORT int nn_freemsg (void *msg); + +/******************************************************************************/ +/* Socket definition. */ +/******************************************************************************/ + +struct nn_iovec { + void *iov_base; + size_t iov_len; +}; + +struct nn_msghdr { + struct nn_iovec *msg_iov; + int msg_iovlen; + void *msg_control; + size_t msg_controllen; +}; + +struct nn_cmsghdr { + size_t cmsg_len; + int cmsg_level; + int cmsg_type; +}; + +/* Internal stuff. Not to be used directly. */ +NN_EXPORT struct nn_cmsghdr *nn_cmsg_nxthdr_ ( + const struct nn_msghdr *mhdr, + const struct nn_cmsghdr *cmsg); +#define NN_CMSG_ALIGN_(len) \ + (((len) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)) + +/* POSIX-defined msghdr manipulation. */ + +#define NN_CMSG_FIRSTHDR(mhdr) \ + nn_cmsg_nxthdr_ ((struct nn_msghdr*) (mhdr), NULL) + +#define NN_CMSG_NXTHDR(mhdr, cmsg) \ + nn_cmsg_nxthdr_ ((struct nn_msghdr*) (mhdr), (struct nn_cmsghdr*) (cmsg)) + +#define NN_CMSG_DATA(cmsg) \ + ((unsigned char*) (((struct nn_cmsghdr*) (cmsg)) + 1)) + +/* Extensions to POSIX defined by RFC 3542. */ + +#define NN_CMSG_SPACE(len) \ + (NN_CMSG_ALIGN_ (len) + NN_CMSG_ALIGN_ (sizeof (struct nn_cmsghdr))) + +#define NN_CMSG_LEN(len) \ + (NN_CMSG_ALIGN_ (sizeof (struct nn_cmsghdr)) + (len)) + +/* SP address families. */ +#define AF_SP 1 +#define AF_SP_RAW 2 + +/* Max size of an SP address. */ +#define NN_SOCKADDR_MAX 128 + +/* Socket option levels: Negative numbers are reserved for transports, + positive for socket types. */ +#define NN_SOL_SOCKET 0 + +/* Generic socket options (NN_SOL_SOCKET level). */ +#define NN_LINGER 1 +#define NN_SNDBUF 2 +#define NN_RCVBUF 3 +#define NN_SNDTIMEO 4 +#define NN_RCVTIMEO 5 +#define NN_RECONNECT_IVL 6 +#define NN_RECONNECT_IVL_MAX 7 +#define NN_SNDPRIO 8 +#define NN_RCVPRIO 9 +#define NN_SNDFD 10 +#define NN_RCVFD 11 +#define NN_DOMAIN 12 +#define NN_PROTOCOL 13 +#define NN_IPV4ONLY 14 +#define NN_SOCKET_NAME 15 +#define NN_RCVMAXSIZE 16 +#define NN_MAXTTL 17 + +/* Send/recv options. */ +#define NN_DONTWAIT 1 + +/* Ancillary data. */ +#define PROTO_SP 1 +#define SP_HDR 1 + +NN_EXPORT int nn_socket (int domain, int protocol); +NN_EXPORT int nn_close (int s); +NN_EXPORT int nn_setsockopt (int s, int level, int option, const void *optval, + size_t optvallen); +NN_EXPORT int nn_getsockopt (int s, int level, int option, void *optval, + size_t *optvallen); +NN_EXPORT int nn_bind (int s, const char *addr); +NN_EXPORT int nn_connect (int s, const char *addr); +NN_EXPORT int nn_shutdown (int s, int how); +NN_EXPORT int nn_send (int s, const void *buf, size_t len, int flags); +NN_EXPORT int nn_recv (int s, void *buf, size_t len, int flags); +NN_EXPORT int nn_sendmsg (int s, const struct nn_msghdr *msghdr, int flags); +NN_EXPORT int nn_recvmsg (int s, struct nn_msghdr *msghdr, int flags); + +/******************************************************************************/ +/* Socket mutliplexing support. */ +/******************************************************************************/ + +#define NN_POLLIN 1 +#define NN_POLLOUT 2 + +struct nn_pollfd { + int fd; + short events; + short revents; +}; + +NN_EXPORT int nn_poll (struct nn_pollfd *fds, int nfds, int timeout); + +/******************************************************************************/ +/* Built-in support for devices. */ +/******************************************************************************/ + +NN_EXPORT int nn_device (int s1, int s2); + +/******************************************************************************/ +/* Statistics. */ +/******************************************************************************/ + +/* Transport statistics */ +#define NN_STAT_ESTABLISHED_CONNECTIONS 101 +#define NN_STAT_ACCEPTED_CONNECTIONS 102 +#define NN_STAT_DROPPED_CONNECTIONS 103 +#define NN_STAT_BROKEN_CONNECTIONS 104 +#define NN_STAT_CONNECT_ERRORS 105 +#define NN_STAT_BIND_ERRORS 106 +#define NN_STAT_ACCEPT_ERRORS 107 + +#define NN_STAT_CURRENT_CONNECTIONS 201 +#define NN_STAT_INPROGRESS_CONNECTIONS 202 +#define NN_STAT_CURRENT_EP_ERRORS 203 + +/* The socket-internal statistics */ +#define NN_STAT_MESSAGES_SENT 301 +#define NN_STAT_MESSAGES_RECEIVED 302 +#define NN_STAT_BYTES_SENT 303 +#define NN_STAT_BYTES_RECEIVED 304 +/* Protocol statistics */ +#define NN_STAT_CURRENT_SND_PRIORITY 401 + +NN_EXPORT uint64_t nn_get_statistic (int s, int stat); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/nanomsg/include/nanomsg/pair.h b/nanomsg/include/nanomsg/pair.h new file mode 100644 index 000000000..3409418f2 --- /dev/null +++ b/nanomsg/include/nanomsg/pair.h @@ -0,0 +1,39 @@ +/* + Copyright (c) 2012 Martin Sustrik All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef PAIR_H_INCLUDED +#define PAIR_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define NN_PROTO_PAIR 1 + +#define NN_PAIR (NN_PROTO_PAIR * 16 + 0) + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nanomsg/include/nanomsg/pipeline.h b/nanomsg/include/nanomsg/pipeline.h new file mode 100644 index 000000000..db9b7d729 --- /dev/null +++ b/nanomsg/include/nanomsg/pipeline.h @@ -0,0 +1,41 @@ +/* + Copyright (c) 2012 Martin Sustrik All rights reserved. + Copyright (c) 2013 GoPivotal, Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef PIPELINE_H_INCLUDED +#define PIPELINE_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define NN_PROTO_PIPELINE 5 + +#define NN_PUSH (NN_PROTO_PIPELINE * 16 + 0) +#define NN_PULL (NN_PROTO_PIPELINE * 16 + 1) + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nanomsg/include/nanomsg/pubsub.h b/nanomsg/include/nanomsg/pubsub.h new file mode 100644 index 000000000..04abb4f1f --- /dev/null +++ b/nanomsg/include/nanomsg/pubsub.h @@ -0,0 +1,43 @@ +/* + Copyright (c) 2012 Martin Sustrik All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef PUBSUB_H_INCLUDED +#define PUBSUB_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define NN_PROTO_PUBSUB 2 + +#define NN_PUB (NN_PROTO_PUBSUB * 16 + 0) +#define NN_SUB (NN_PROTO_PUBSUB * 16 + 1) + +#define NN_SUB_SUBSCRIBE 1 +#define NN_SUB_UNSUBSCRIBE 2 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nanomsg/include/nanomsg/reqrep.h b/nanomsg/include/nanomsg/reqrep.h new file mode 100644 index 000000000..fea7a7eb2 --- /dev/null +++ b/nanomsg/include/nanomsg/reqrep.h @@ -0,0 +1,50 @@ +/* + Copyright (c) 2012 Martin Sustrik All rights reserved. + Copyright 2016 Garrett D'Amore + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef REQREP_H_INCLUDED +#define REQREP_H_INCLUDED + +#include "nn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NN_PROTO_REQREP 3 + +#define NN_REQ (NN_PROTO_REQREP * 16 + 0) +#define NN_REP (NN_PROTO_REQREP * 16 + 1) + +#define NN_REQ_RESEND_IVL 1 + +typedef union nn_req_handle { + int i; + void *ptr; +} nn_req_handle; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nanomsg/include/nanomsg/survey.h b/nanomsg/include/nanomsg/survey.h new file mode 100644 index 000000000..ad594aa66 --- /dev/null +++ b/nanomsg/include/nanomsg/survey.h @@ -0,0 +1,46 @@ +/* + Copyright (c) 2012 Martin Sustrik All rights reserved. + Copyright 2015 Garrett D'Amore + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef SURVEY_H_INCLUDED +#define SURVEY_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define NN_PROTO_SURVEY 6 + +/* NB: Version 0 used 16 + 0/1. That version lacked backtraces, and so + is wire-incompatible with this version. */ + +#define NN_SURVEYOR (NN_PROTO_SURVEY * 16 + 2) +#define NN_RESPONDENT (NN_PROTO_SURVEY * 16 + 3) + +#define NN_SURVEYOR_DEADLINE 1 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nanomsg/include/nanomsg/tcp.h b/nanomsg/include/nanomsg/tcp.h new file mode 100644 index 000000000..1d9077655 --- /dev/null +++ b/nanomsg/include/nanomsg/tcp.h @@ -0,0 +1,39 @@ +/* + Copyright (c) 2012 Martin Sustrik All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef TCP_H_INCLUDED +#define TCP_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#define NN_TCP -3 + +#define NN_TCP_NODELAY 1 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nanomsg/include/nanomsg/ws.h b/nanomsg/include/nanomsg/ws.h new file mode 100644 index 000000000..b7f66b4b3 --- /dev/null +++ b/nanomsg/include/nanomsg/ws.h @@ -0,0 +1,49 @@ +/* + Copyright (c) 2012 250bpm s.r.o. All rights reserved. + Copyright (c) 2014 Wirebird Labs LLC. All rights reserved. + Copyright 2015 Garrett D'Amore + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef WS_H_INCLUDED +#define WS_H_INCLUDED + +#include "nn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NN_WS -4 + +/* NN_WS level socket/cmsg options. Note that only NN_WSMG_TYPE_TEXT and + NN_WS_MSG_TYPE_BINARY messages are supported fully by this implementation. + Attempting to set other message types is undefined. */ +#define NN_WS_MSG_TYPE 1 + +/* WebSocket opcode constants as per RFC 6455 5.2 */ +#define NN_WS_MSG_TYPE_TEXT 0x01 +#define NN_WS_MSG_TYPE_BINARY 0x02 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/nanomsg/lib/libnanomsg.dll b/nanomsg/lib/libnanomsg.dll new file mode 100644 index 000000000..8ffe03686 Binary files /dev/null and b/nanomsg/lib/libnanomsg.dll differ diff --git a/nanomsg/lib/libnanomsg.dll.a b/nanomsg/lib/libnanomsg.dll.a new file mode 100644 index 000000000..8ffe03686 Binary files /dev/null and b/nanomsg/lib/libnanomsg.dll.a differ diff --git a/nanomsg/lib/pkgconfig/nanomsg.pc b/nanomsg/lib/pkgconfig/nanomsg.pc new file mode 100644 index 000000000..57459dd0b --- /dev/null +++ b/nanomsg/lib/pkgconfig/nanomsg.pc @@ -0,0 +1,13 @@ +prefix=/home/ca/Schreibtisch/supernet/iguana/nanomsg +exec_prefix=${prefix} +includedir=${prefix}/include +libdir=${prefix}/lib + +Name: nanomsg +Description: High-Performance Scalability Protocols +URL: http://nanomsg.org/ +Version: 1.0.0 +Requires: +Libs: -L${libdir} -lnanomsg +Libs.private: -lws2_32 -lmswsock -ladvapi32 +Cflags: -I${includedir} 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 }'` diff --git a/win_lib/bin/curl-config b/win_lib/bin/curl-config new file mode 100755 index 000000000..9fbbf0b50 --- /dev/null +++ b/win_lib/bin/curl-config @@ -0,0 +1,178 @@ +#! /bin/sh +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 2001 - 2012, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### + +prefix=/home/ca/Schreibtisch/supernet/crypto777/curl-7.52.1/win_lib +exec_prefix=${prefix} +includedir=${prefix}/include +cppflag_curl_staticlib=-DCURL_STATICLIB + +usage() +{ + cat <&2 + exit 1 + fi + ;; + + --configure) + echo " '--enable-mingw' '--enable-static' '--disable-shared' '--prefix=/home/ca/Schreibtisch/supernet/crypto777/curl-7.52.1/win_lib' '--host=i686-w64-mingw32' '--with-ssl=openssl_lib/' 'host_alias=i686-w64-mingw32' 'CC=i686-w64-mingw32-gcc'" + ;; + + *) + echo "unknown option: $1" + usage 1 + ;; + esac + shift +done + +exit 0 diff --git a/win_lib/bin/curl.exe b/win_lib/bin/curl.exe new file mode 100755 index 000000000..65de807ec Binary files /dev/null and b/win_lib/bin/curl.exe differ diff --git a/win_lib/bin/libcurl-4.dll b/win_lib/bin/libcurl-4.dll new file mode 100755 index 000000000..6a73485a6 Binary files /dev/null and b/win_lib/bin/libcurl-4.dll differ diff --git a/win_lib/include/curl/curl.h b/win_lib/include/curl/curl.h new file mode 100644 index 000000000..5b4ae469e --- /dev/null +++ b/win_lib/include/curl/curl.h @@ -0,0 +1,2528 @@ +#ifndef __CURL_CURL_H +#define __CURL_CURL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * If you have libcurl problems, all docs and details are found here: + * https://curl.haxx.se/libcurl/ + * + * curl-library mailing list subscription and unsubscription web interface: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + */ + +#ifdef CURL_NO_OLDIES +#define CURL_STRICTER +#endif + +#include "curlver.h" /* libcurl version defines */ +#include "curlbuild.h" /* libcurl build definitions */ +#include "curlrules.h" /* libcurl rules enforcement */ + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && \ + !defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#include +#include + +#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) +/* Needed for __FreeBSD_version symbol definition */ +#include +#endif + +/* The include stuff here below is mainly for time_t! */ +#include +#include + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ + defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +#include +#include +#endif +#endif + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on systems that are known to + require it! */ +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ + defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ + defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ + (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) +#include +#endif + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif + +#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) +#include +#endif + +#ifdef __BEOS__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_easy CURL; +typedef struct Curl_share CURLSH; +#else +typedef void CURL; +typedef void CURLSH; +#endif + +/* + * libcurl external API function linkage decorations. + */ + +#ifdef CURL_STATICLIB +# define CURL_EXTERN +#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) +# if defined(BUILDING_LIBCURL) +# define CURL_EXTERN __declspec(dllexport) +# else +# define CURL_EXTERN __declspec(dllimport) +# endif +#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) +# define CURL_EXTERN CURL_EXTERN_SYMBOL +#else +# define CURL_EXTERN +#endif + +#ifndef curl_socket_typedef +/* socket typedef */ +#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) +typedef SOCKET curl_socket_t; +#define CURL_SOCKET_BAD INVALID_SOCKET +#else +typedef int curl_socket_t; +#define CURL_SOCKET_BAD -1 +#endif +#define curl_socket_typedef +#endif /* curl_socket_typedef */ + +struct curl_httppost { + struct curl_httppost *next; /* next entry in the list */ + char *name; /* pointer to allocated name */ + long namelength; /* length of name length */ + char *contents; /* pointer to allocated data contents */ + long contentslength; /* length of contents field, see also + CURL_HTTPPOST_LARGE */ + char *buffer; /* pointer to allocated buffer contents */ + long bufferlength; /* length of buffer field */ + char *contenttype; /* Content-Type */ + struct curl_slist *contentheader; /* list of extra headers for this form */ + struct curl_httppost *more; /* if one field name has more than one + file, this link should link to following + files */ + long flags; /* as defined below */ + +/* specified content is a file name */ +#define CURL_HTTPPOST_FILENAME (1<<0) +/* specified content is a file name */ +#define CURL_HTTPPOST_READFILE (1<<1) +/* name is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRNAME (1<<2) +/* contents is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRCONTENTS (1<<3) +/* upload file from buffer */ +#define CURL_HTTPPOST_BUFFER (1<<4) +/* upload file from pointer contents */ +#define CURL_HTTPPOST_PTRBUFFER (1<<5) +/* upload file contents by using the regular read callback to get the data and + pass the given pointer as custom pointer */ +#define CURL_HTTPPOST_CALLBACK (1<<6) +/* use size in 'contentlen', added in 7.46.0 */ +#define CURL_HTTPPOST_LARGE (1<<7) + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ + void *userp; /* custom pointer used for + HTTPPOST_CALLBACK posts */ + curl_off_t contentlen; /* alternative length of contents + field. Used if CURL_HTTPPOST_LARGE is + set. Added in 7.46.0 */ +}; + +/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered + deprecated but was the only choice up until 7.31.0 */ +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + +/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in + 7.32.0, it avoids floating point and provides more detailed information. */ +typedef int (*curl_xferinfo_callback)(void *clientp, + curl_off_t dltotal, + curl_off_t dlnow, + curl_off_t ultotal, + curl_off_t ulnow); + +#ifndef CURL_MAX_WRITE_SIZE + /* Tests have proven that 20K is a very bad buffer size for uploads on + Windows, while 16K for some odd reason performed a lot better. + We do the ifndef check to allow this value to easier be changed at build + time for those who feel adventurous. The practical minimum is about + 400 bytes since libcurl uses a buffer of this size as a scratch area + (unrelated to network send operations). */ +#define CURL_MAX_WRITE_SIZE 16384 +#endif + +#ifndef CURL_MAX_HTTP_HEADER +/* The only reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a never-ending header that will cause reallocs + infinitely */ +#define CURL_MAX_HTTP_HEADER (100*1024) +#endif + +/* This is a magic return code for the write callback that, when returned, + will signal libcurl to pause receiving on the current transfer. */ +#define CURL_WRITEFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + + + +/* enumeration of file types */ +typedef enum { + CURLFILETYPE_FILE = 0, + CURLFILETYPE_DIRECTORY, + CURLFILETYPE_SYMLINK, + CURLFILETYPE_DEVICE_BLOCK, + CURLFILETYPE_DEVICE_CHAR, + CURLFILETYPE_NAMEDPIPE, + CURLFILETYPE_SOCKET, + CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ + + CURLFILETYPE_UNKNOWN /* should never occur */ +} curlfiletype; + +#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) +#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) +#define CURLFINFOFLAG_KNOWN_TIME (1<<2) +#define CURLFINFOFLAG_KNOWN_PERM (1<<3) +#define CURLFINFOFLAG_KNOWN_UID (1<<4) +#define CURLFINFOFLAG_KNOWN_GID (1<<5) +#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) +#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) + +/* Content of this structure depends on information which is known and is + achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man + page for callbacks returning this structure -- some fields are mandatory, + some others are optional. The FLAG field has special meaning. */ +struct curl_fileinfo { + char *filename; + curlfiletype filetype; + time_t time; + unsigned int perm; + int uid; + int gid; + curl_off_t size; + long int hardlinks; + + struct { + /* If some of these fields is not NULL, it is a pointer to b_data. */ + char *time; + char *perm; + char *user; + char *group; + char *target; /* pointer to the target filename of a symlink */ + } strings; + + unsigned int flags; + + /* used internally */ + char *b_data; + size_t b_size; + size_t b_used; +}; + +/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ +#define CURL_CHUNK_BGN_FUNC_OK 0 +#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ +#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ + +/* if splitting of data transfer is enabled, this callback is called before + download of an individual chunk started. Note that parameter "remains" works + only for FTP wildcard downloading (for now), otherwise is not used */ +typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, + void *ptr, + int remains); + +/* return codes for CURLOPT_CHUNK_END_FUNCTION */ +#define CURL_CHUNK_END_FUNC_OK 0 +#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ + +/* If splitting of data transfer is enabled this callback is called after + download of an individual chunk finished. + Note! After this callback was set then it have to be called FOR ALL chunks. + Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. + This is the reason why we don't need "transfer_info" parameter in this + callback and we are not interested in "remains" parameter too. */ +typedef long (*curl_chunk_end_callback)(void *ptr); + +/* return codes for FNMATCHFUNCTION */ +#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ +#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ +#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ + +/* callback type for wildcard downloading pattern matching. If the + string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ +typedef int (*curl_fnmatch_callback)(void *ptr, + const char *pattern, + const char *string); + +/* These are the return codes for the seek callbacks */ +#define CURL_SEEKFUNC_OK 0 +#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ +#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so + libcurl might try other means instead */ +typedef int (*curl_seek_callback)(void *instream, + curl_off_t offset, + int origin); /* 'whence' */ + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +/* This is a return code for the read callback that, when returned, will + signal libcurl to pause sending data on the current transfer. */ +#define CURL_READFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ + CURLSOCKTYPE_LAST /* never use */ +} curlsocktype; + +/* The return code from the sockopt_callback can signal information back + to libcurl: */ +#define CURL_SOCKOPT_OK 0 +#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return + CURLE_ABORTED_BY_CALLBACK */ +#define CURL_SOCKOPT_ALREADY_CONNECTED 2 + +typedef int (*curl_sockopt_callback)(void *clientp, + curl_socket_t curlfd, + curlsocktype purpose); + +struct curl_sockaddr { + int family; + int socktype; + int protocol; + unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it + turned really ugly and painful on the systems that + lack this type */ + struct sockaddr addr; +}; + +typedef curl_socket_t +(*curl_opensocket_callback)(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address); + +typedef int +(*curl_closesocket_callback)(void *clientp, curl_socket_t item); + +typedef enum { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} curlioerr; + +typedef enum { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} curliocmd; + +typedef curlioerr (*curl_ioctl_callback)(CURL *handle, + int cmd, + void *clientp); + +#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS +/* + * The following typedef's are signatures of malloc, free, realloc, strdup and + * calloc respectively. Function pointers of these types can be passed to the + * curl_global_init_mem() function to set user defined memory management + * callback routines. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); + +#define CURL_DID_MEMORY_FUNC_TYPEDEFS +#endif + +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userptr); /* whatever the user please */ + +/* All possible error codes from all sorts of curl functions. Future versions + may return other values, stay prepared. + + Always add new return codes last. Never *EVER* remove any. The return + codes must remain the same! + */ + +typedef enum { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for + 7.17.0, reused in April 2011 for 7.21.5] */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for + 7.15.4, reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server + [was obsoleted in August 2007 for 7.17.0, + reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. + [was obsoleted in August 2007 for 7.17.0, + reused in July 2014 for 7.38.0] */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ + CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint + wasn't verified fine */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ + CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURLE_AGAIN, /* 81 - socket is not ready for send/recv, + wait till it's ready and try again (Added + in 7.18.2) */ + CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or + wrong format (Added in 7.19.0) */ + CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in + 7.19.0) */ + CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ + CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ + CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ + CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ + CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ + CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the + session will be queued */ + CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not + match */ + CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ + CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer + */ + CURL_LAST /* never use! */ +} CURLcode; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Previously obsolete error code re-used in 7.38.0 */ +#define CURLE_OBSOLETE16 CURLE_HTTP2 + +/* Previously obsolete error codes re-used in 7.24.0 */ +#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED +#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT + +/* compatibility with older names */ +#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING +#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY + +/* The following were added in 7.21.5, April 2011 */ +#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION + +/* The following were added in 7.17.1 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.17.0 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 +#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN + +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED + +/* The following were added earlier */ + +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT + +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED + +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME + +/* This was the error code 50 in 7.7.3 and a few earlier versions, this + is no longer used by libcurl but is instead #defined here only to not + make programs break */ +#define CURLE_ALREADY_COMPLETE 99999 + +/* Provide defines for really old option names */ +#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ +#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ +#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA + +/* Since long deprecated options with no code in the lib that does anything + with them. */ +#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 +#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 + +#endif /*!CURL_NO_OLDIES*/ + +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ + void *ssl_ctx, /* actually an + OpenSSL SSL_CTX */ + void *userptr); + +typedef enum { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_HTTPS = 2, /* added in 7.52.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already + in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} curl_proxytype; /* this enum was added in 7.10 */ + +/* + * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: + * + * CURLAUTH_NONE - No HTTP authentication + * CURLAUTH_BASIC - HTTP Basic authentication (default) + * CURLAUTH_DIGEST - HTTP Digest authentication + * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication + * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) + * CURLAUTH_NTLM - HTTP NTLM authentication + * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour + * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper + * CURLAUTH_ONLY - Use together with a single other type to force no + * authentication or just that single type + * CURLAUTH_ANY - All fine types set + * CURLAUTH_ANYSAFE - All fine types except Basic + */ + +#define CURLAUTH_NONE ((unsigned long)0) +#define CURLAUTH_BASIC (((unsigned long)1)<<0) +#define CURLAUTH_DIGEST (((unsigned long)1)<<1) +#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) +/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ +#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE +#define CURLAUTH_NTLM (((unsigned long)1)<<3) +#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) +#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) +#define CURLAUTH_ONLY (((unsigned long)1)<<31) +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ +#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ +#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ + +#define CURL_ERROR_SIZE 256 + +enum curl_khtype { + CURLKHTYPE_UNKNOWN, + CURLKHTYPE_RSA1, + CURLKHTYPE_RSA, + CURLKHTYPE_DSS +}; + +struct curl_khkey { + const char *key; /* points to a zero-terminated string encoded with base64 + if len is zero, otherwise to the "raw" data */ + size_t len; + enum curl_khtype keytype; +}; + +/* this is the set of return values expected from the curl_sshkeycallback + callback */ +enum curl_khstat { + CURLKHSTAT_FINE_ADD_TO_FILE, + CURLKHSTAT_FINE, + CURLKHSTAT_REJECT, /* reject the connection, return an error */ + CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so + this causes a CURLE_DEFER error but otherwise the + connection will be left intact etc */ + CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ +}; + +/* this is the set of status codes pass in to the callback */ +enum curl_khmatch { + CURLKHMATCH_OK, /* match */ + CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ + CURLKHMATCH_MISSING, /* no matching host/key found */ + CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ +}; + +typedef int + (*curl_sshkeycallback) (CURL *easy, /* easy handle */ + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch, /* libcurl's view on the keys */ + void *clientp); /* custom pointer passed from app */ + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ + +/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the + name of improving interoperability with older servers. Some SSL libraries + have introduced work-arounds for this flaw but those work-arounds sometimes + make the SSL communication fail. To regain functionality with those broken + servers, a user can this way allow the vulnerability back. */ +#define CURLSSLOPT_ALLOW_BEAST (1<<0) + +/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those + SSL backends where such behavior is present. */ +#define CURLSSLOPT_NO_REVOKE (1<<1) + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +#define CURLFTPSSL_NONE CURLUSESSL_NONE +#define CURLFTPSSL_TRY CURLUSESSL_TRY +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL +#define CURLFTPSSL_ALL CURLUSESSL_ALL +#define CURLFTPSSL_LAST CURLUSESSL_LAST +#define curl_ftpssl curl_usessl +#endif /*!CURL_NO_OLDIES*/ + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +typedef enum { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} curl_ftpccc; + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +typedef enum { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} curl_ftpauth; + +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +typedef enum { + CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ + CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD + again if MKD succeeded, for SFTP this does + similar magic */ + CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD + again even if MKD failed! */ + CURLFTP_CREATE_DIR_LAST /* not an option, never use */ +} curl_ftpcreatedir; + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +typedef enum { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} curl_ftpmethod; + +/* bitmask defines for CURLOPT_HEADEROPT */ +#define CURLHEADER_UNIFIED 0 +#define CURLHEADER_SEPARATE (1<<0) + +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +#define CURLPROTO_HTTP (1<<0) +#define CURLPROTO_HTTPS (1<<1) +#define CURLPROTO_FTP (1<<2) +#define CURLPROTO_FTPS (1<<3) +#define CURLPROTO_SCP (1<<4) +#define CURLPROTO_SFTP (1<<5) +#define CURLPROTO_TELNET (1<<6) +#define CURLPROTO_LDAP (1<<7) +#define CURLPROTO_LDAPS (1<<8) +#define CURLPROTO_DICT (1<<9) +#define CURLPROTO_FILE (1<<10) +#define CURLPROTO_TFTP (1<<11) +#define CURLPROTO_IMAP (1<<12) +#define CURLPROTO_IMAPS (1<<13) +#define CURLPROTO_POP3 (1<<14) +#define CURLPROTO_POP3S (1<<15) +#define CURLPROTO_SMTP (1<<16) +#define CURLPROTO_SMTPS (1<<17) +#define CURLPROTO_RTSP (1<<18) +#define CURLPROTO_RTMP (1<<19) +#define CURLPROTO_RTMPT (1<<20) +#define CURLPROTO_RTMPE (1<<21) +#define CURLPROTO_RTMPTE (1<<22) +#define CURLPROTO_RTMPS (1<<23) +#define CURLPROTO_RTMPTS (1<<24) +#define CURLPROTO_GOPHER (1<<25) +#define CURLPROTO_SMB (1<<26) +#define CURLPROTO_SMBS (1<<27) +#define CURLPROTO_ALL (~0) /* enable everything */ + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_STRINGPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the + string options from the header file */ + +/* name is uppercase CURLOPT_, + type is one of the defined CURLOPTTYPE_ + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif + +#ifdef CURL_ISOCPP +#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define STRINGPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLOPT_/**/name = type + number +#endif + +/* + * This macro-mania below setups the CURLOPT_[what] enum, to be used with + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] + * word. + */ + +typedef enum { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(WRITEDATA, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, STRINGPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, STRINGPOINT, 4), + + /* "user:password;options" to use when fetching. */ + CINIT(USERPWD, STRINGPOINT, 5), + + /* "user:password" to use with proxy. */ + CINIT(PROXYUSERPWD, STRINGPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, STRINGPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(READDATA, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. If this is not used, error messages go to stderr instead: */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was successful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referrer page (needed by some CGIs) */ + CINIT(REFERER, STRINGPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, STRINGPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, STRINGPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, STRINGPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind. This + list is also used for RTSP (in spite of its name) */ + CINIT(HTTPHEADER, OBJECTPOINT, 23), + + /* This points to a linked list of post entries, struct curl_httppost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, STRINGPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, STRINGPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, OBJECTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(HEADERDATA, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, STRINGPOINT, 31), + + /* What version to specifically try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, STRINGPOINT, 36), + + /* FILE handle to use instead of stderr */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, OBJECTPOINT, 39), + + CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */ + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* DEPRECATED + * Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION + callbacks */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), +#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA + + /* We want the referrer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, STRINGPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, STRINGPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, STRINGPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */ + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, STRINGPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, STRINGPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects are + OK within this time, then fine... This only aborts the connect phase. */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, STRINGPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specifically switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, STRINGPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, STRINGPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, STRINGPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, STRINGPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands */ + CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, STRINGPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and + CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. Before 7.21.6, this was known as + CURLOPT_ENCODING */ + CINIT(ACCEPT_ENCODING, STRINGPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentially send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specifically switch on or off the FTP engine's use of the EPRT command ( + it also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx + in second argument. The function must be matching the + curl_ssl_ctx_callback proto. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server. + In 7.19.4 we introduced the convenience enums for this option using the + CURLFTP_CREATE_DIR prefix. + */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), +#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, STRINGPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLUSESSL_TRY - try using SSL, proceed anyway otherwise + CURLUSESSL_CONTROL - SSL for the control connection or fail + CURLUSESSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, STRINGPOINT, 134), + + /* feed cookie into cookie engine */ + CINIT(COOKIELIST, STRINGPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the application even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Set the behaviour of POST when redirecting. Values must be set to one + of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ + CINIT(POSTREDIR, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ + CINIT(PROXY_TRANSFER_MODE, LONG, 166), + + /* Callback function for seeking in the input stream */ + CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), + CINIT(SEEKDATA, OBJECTPOINT, 168), + + /* CRL file */ + CINIT(CRLFILE, STRINGPOINT, 169), + + /* Issuer certificate */ + CINIT(ISSUERCERT, STRINGPOINT, 170), + + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + + /* Collect certificate chain info and allow it to get retrievable with + CURLINFO_CERTINFO after the transfer is complete. */ + CINIT(CERTINFO, LONG, 172), + + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, STRINGPOINT, 173), + CINIT(PASSWORD, STRINGPOINT, 174), + + /* "name" and "pwd" to use with Proxy when fetching. */ + CINIT(PROXYUSERNAME, STRINGPOINT, 175), + CINIT(PROXYPASSWORD, STRINGPOINT, 176), + + /* Comma separated list of hostnames defining no-proxy zones. These should + match both hostnames directly, and hostnames within a domain. For + example, local.com will match local.com and www.local.com, but NOT + notlocal.com or www.notlocal.com. For compatibility with other + implementations of this, .local.com will be considered to be the same as + local.com. A single * is the only valid wildcard, and effectively + disables the use of proxy. */ + CINIT(NOPROXY, STRINGPOINT, 177), + + /* block size for TFTP transfers */ + CINIT(TFTP_BLKSIZE, LONG, 178), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */ + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + CINIT(PROTOCOLS, LONG, 181), + + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. Defaults + to all protocols except FILE and SCP. */ + CINIT(REDIR_PROTOCOLS, LONG, 182), + + /* set the SSH knownhost file name to use */ + CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183), + + /* set the SSH host key callback, must point to a curl_sshkeycallback + function */ + CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + + /* set the SSH host key callback custom pointer */ + CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + + /* set the SMTP mail originator */ + CINIT(MAIL_FROM, STRINGPOINT, 186), + + /* set the list of SMTP mail receiver(s) */ + CINIT(MAIL_RCPT, OBJECTPOINT, 187), + + /* FTP: send PRET before PASV */ + CINIT(FTP_USE_PRET, LONG, 188), + + /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ + CINIT(RTSP_REQUEST, LONG, 189), + + /* The RTSP session identifier */ + CINIT(RTSP_SESSION_ID, STRINGPOINT, 190), + + /* The RTSP stream URI */ + CINIT(RTSP_STREAM_URI, STRINGPOINT, 191), + + /* The Transport: header to use in RTSP requests */ + CINIT(RTSP_TRANSPORT, STRINGPOINT, 192), + + /* Manually initialize the client RTSP CSeq for this handle */ + CINIT(RTSP_CLIENT_CSEQ, LONG, 193), + + /* Manually initialize the server RTSP CSeq for this handle */ + CINIT(RTSP_SERVER_CSEQ, LONG, 194), + + /* The stream to pass to INTERLEAVEFUNCTION. */ + CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), + + /* Let the application define a custom write method for RTP data */ + CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), + + /* Turn on wildcard matching */ + CINIT(WILDCARDMATCH, LONG, 197), + + /* Directory matching callback called before downloading of an + individual file (chunk) started */ + CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), + + /* Directory matching callback called after the file (chunk) + was downloaded, or skipped */ + CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), + + /* Change match (fnmatch-like) callback for wildcard matching */ + CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), + + /* Let the application define custom chunk data pointer */ + CINIT(CHUNK_DATA, OBJECTPOINT, 201), + + /* FNMATCH_FUNCTION user pointer */ + CINIT(FNMATCH_DATA, OBJECTPOINT, 202), + + /* send linked-list of name:port:address sets */ + CINIT(RESOLVE, OBJECTPOINT, 203), + + /* Set a username for authenticated TLS */ + CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204), + + /* Set a password for authenticated TLS */ + CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205), + + /* Set authentication type for authenticated TLS */ + CINIT(TLSAUTH_TYPE, STRINGPOINT, 206), + + /* Set to 1 to enable the "TE:" header in HTTP requests to ask for + compressed transfer-encoded responses. Set to 0 to disable the use of TE: + in outgoing requests. The current default is 0, but it might change in a + future libcurl release. + + libcurl will ask for the compressed methods it knows of, and if that + isn't any, it will not ask for transfer-encoding at all even if this + option is set to 1. + + */ + CINIT(TRANSFER_ENCODING, LONG, 207), + + /* Callback function for closing socket (instead of close(2)). The callback + should have type curl_closesocket_callback */ + CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), + CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), + + /* allow GSSAPI credential delegation */ + CINIT(GSSAPI_DELEGATION, LONG, 210), + + /* Set the name servers to use for DNS resolution */ + CINIT(DNS_SERVERS, STRINGPOINT, 211), + + /* Time-out accept operations (currently for FTP only) after this amount + of miliseconds. */ + CINIT(ACCEPTTIMEOUT_MS, LONG, 212), + + /* Set TCP keepalive */ + CINIT(TCP_KEEPALIVE, LONG, 213), + + /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ + CINIT(TCP_KEEPIDLE, LONG, 214), + CINIT(TCP_KEEPINTVL, LONG, 215), + + /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ + CINIT(SSL_OPTIONS, LONG, 216), + + /* Set the SMTP auth originator */ + CINIT(MAIL_AUTH, STRINGPOINT, 217), + + /* Enable/disable SASL initial response */ + CINIT(SASL_IR, LONG, 218), + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_xferinfo_callback + * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ + CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219), + + /* The XOAUTH2 bearer token */ + CINIT(XOAUTH2_BEARER, STRINGPOINT, 220), + + /* Set the interface string to use as outgoing network + * interface for DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_INTERFACE, STRINGPOINT, 221), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223), + + /* Set authentication options directly */ + CINIT(LOGIN_OPTIONS, STRINGPOINT, 224), + + /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_NPN, LONG, 225), + + /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_ALPN, LONG, 226), + + /* Time to wait for a response to a HTTP request containing an + * Expect: 100-continue header before sending the data anyway. */ + CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227), + + /* This points to a linked list of headers used for proxy requests only, + struct curl_slist kind */ + CINIT(PROXYHEADER, OBJECTPOINT, 228), + + /* Pass in a bitmask of "header options" */ + CINIT(HEADEROPT, LONG, 229), + + /* The public key in DER form used to validate the peer public key + this option is used only if SSL_VERIFYPEER is true */ + CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230), + + /* Path to Unix domain socket */ + CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231), + + /* Set if we should verify the certificate status. */ + CINIT(SSL_VERIFYSTATUS, LONG, 232), + + /* Set if we should enable TLS false start. */ + CINIT(SSL_FALSESTART, LONG, 233), + + /* Do not squash dot-dot sequences */ + CINIT(PATH_AS_IS, LONG, 234), + + /* Proxy Service Name */ + CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235), + + /* Service Name */ + CINIT(SERVICE_NAME, STRINGPOINT, 236), + + /* Wait/don't wait for pipe/mutex to clarify */ + CINIT(PIPEWAIT, LONG, 237), + + /* Set the protocol used when curl is given a URL without a protocol */ + CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238), + + /* Set stream weight, 1 - 256 (default is 16) */ + CINIT(STREAM_WEIGHT, LONG, 239), + + /* Set stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS, OBJECTPOINT, 240), + + /* Set E-xclusive stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241), + + /* Do not send any tftp option requests to the server */ + CINIT(TFTP_NO_OPTIONS, LONG, 242), + + /* Linked-list of host:port:connect-to-host:connect-to-port, + overrides the URL's host:port (only for the network layer) */ + CINIT(CONNECT_TO, OBJECTPOINT, 243), + + /* Set TCP Fast Open */ + CINIT(TCP_FASTOPEN, LONG, 244), + + /* Continue to send data if the server responds early with an + * HTTP status code >= 300 */ + CINIT(KEEP_SENDING_ON_ERROR, LONG, 245), + + /* The CApath or CAfile used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_CAINFO, STRINGPOINT, 246), + + /* The CApath directory used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_CAPATH, STRINGPOINT, 247), + + /* Set if we should verify the proxy in ssl handshake, + set 1 to verify. */ + CINIT(PROXY_SSL_VERIFYPEER, LONG, 248), + + /* Set if we should verify the Common name from the proxy certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches + * the provided hostname. */ + CINIT(PROXY_SSL_VERIFYHOST, LONG, 249), + + /* What version to specifically try to use for proxy. + See CURL_SSLVERSION defines below. */ + CINIT(PROXY_SSLVERSION, LONG, 250), + + /* Set a username for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251), + + /* Set a password for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252), + + /* Set authentication type for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253), + + /* name of the file keeping your private SSL-certificate for proxy */ + CINIT(PROXY_SSLCERT, STRINGPOINT, 254), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for + proxy */ + CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255), + + /* name of the file keeping your private SSL-key for proxy */ + CINIT(PROXY_SSLKEY, STRINGPOINT, 256), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for + proxy */ + CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257), + + /* password for the SSL private key for proxy */ + CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258), + + /* Specify which SSL ciphers to use for proxy */ + CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259), + + /* CRL file for proxy */ + CINIT(PROXY_CRLFILE, STRINGPOINT, 260), + + /* Enable/disable specific SSL features with a bitmask for proxy, see + CURLSSLOPT_* */ + CINIT(PROXY_SSL_OPTIONS, LONG, 261), + + /* Name of pre proxy to use. */ + CINIT(PRE_PROXY, STRINGPOINT, 262), + + /* The public key in DER form used to validate the proxy public key + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263), + + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2011 */ + +/* This was added in version 7.19.1 */ +#define CURLOPT_POST301 CURLOPT_POSTREDIR + +/* These are scheduled to disappear by 2009 */ + +/* The following were added in 7.17.0 */ +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_FTPAPPEND CURLOPT_APPEND +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL + +/* The following were added earlier */ + +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ + + /* three convenient "aliases" that follow the name scheme better */ +#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ + CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ + CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 + Upgrade */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +}; + +/* Convenience definition simple because the name of the version is HTTP/2 and + not 2.0. The 2_0 version of the enum name was set while the version was + still planned to be 2.0 and we stick to it for compatibility. */ +#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 + +/* + * Public API enums for RTSP requests + */ +enum { + CURL_RTSPREQ_NONE, /* first in list */ + CURL_RTSPREQ_OPTIONS, + CURL_RTSPREQ_DESCRIBE, + CURL_RTSPREQ_ANNOUNCE, + CURL_RTSPREQ_SETUP, + CURL_RTSPREQ_PLAY, + CURL_RTSPREQ_PAUSE, + CURL_RTSPREQ_TEARDOWN, + CURL_RTSPREQ_GET_PARAMETER, + CURL_RTSPREQ_SET_PARAMETER, + CURL_RTSPREQ_RECORD, + CURL_RTSPREQ_RECEIVE, + CURL_RTSPREQ_LAST /* last in list */ +}; + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +}; + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, /* TLS 1.x */ + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + CURL_SSLVERSION_TLSv1_0, + CURL_SSLVERSION_TLSv1_1, + CURL_SSLVERSION_TLSv1_2, + CURL_SSLVERSION_TLSv1_3, + + CURL_SSLVERSION_LAST /* never use, keep last */ +}; + +enum CURL_TLSAUTH { + CURL_TLSAUTH_NONE, + CURL_TLSAUTH_SRP, + CURL_TLSAUTH_LAST /* never use, keep last */ +}; + +/* symbols to use with CURLOPT_POSTREDIR. + CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 + can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 + | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ + +#define CURL_REDIR_GET_ALL 0 +#define CURL_REDIR_POST_301 1 +#define CURL_REDIR_POST_302 2 +#define CURL_REDIR_POST_303 4 +#define CURL_REDIR_POST_ALL \ + (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + + +/* curl_strequal() and curl_strnequal() are subject for removal in a future + libcurl, see lib/README.curlx for details + + !checksrc! disable SPACEBEFOREPAREN 2 +*/ +CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); +CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); + +/* name is uppercase CURLFORM_ */ +#ifdef CFINIT +#undef CFINIT +#endif + +#ifdef CURL_ISOCPP +#define CFINIT(name) CURLFORM_ ## name +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define CFINIT(name) CURLFORM_/**/name +#endif + +typedef enum { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CFINIT(STREAM), + CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */ + + CURLFORM_LASTENTRY /* the last unused */ +} CURLformoption; + +#undef CFINIT /* done */ + +/* structure to be used as parameter for CURLFORM_ARRAY */ +struct curl_forms { + CURLformoption option; + const char *value; +}; + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +typedef enum { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} CURLFORMcode; + +/* + * NAME curl_formadd() + * + * DESCRIPTION + * + * Pretty advanced function for building multi-part formposts. Each invoke + * adds one part that together construct a full post. Then use + * CURLOPT_HTTPPOST to send it off to libcurl. + */ +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...); + +/* + * callback function for curl_formget() + * The void *arg pointer will be the one passed as second argument to + * curl_formget(). + * The character buffer passed to it must not be freed. + * Should return the buffer length passed to it as the argument "len" on + * success. + */ +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, + size_t len); + +/* + * NAME curl_formget() + * + * DESCRIPTION + * + * Serialize a curl_httppost struct built with curl_formadd(). + * Accepts a void pointer as second argument which will be passed to + * the curl_formget_callback function. + * Returns 0 on success. + */ +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append); +/* + * NAME curl_formfree() + * + * DESCRIPTION + * + * Free a multipart formpost previously built with curl_formadd(). + */ +CURL_EXTERN void curl_formfree(struct curl_httppost *form); + +/* + * NAME curl_getenv() + * + * DESCRIPTION + * + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is + * complete. DEPRECATED - see lib/README.curlx + */ +CURL_EXTERN char *curl_getenv(const char *variable); + +/* + * NAME curl_version() + * + * DESCRIPTION + * + * Returns a static ascii string of the libcurl version. + */ +CURL_EXTERN char *curl_version(void); + +/* + * NAME curl_easy_escape() + * + * DESCRIPTION + * + * Escapes URL strings (converts all letters consider illegal in URLs to their + * %XX versions). This function returns a new allocated string or NULL if an + * error occurred. + */ +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + + +/* + * NAME curl_easy_unescape() + * + * DESCRIPTION + * + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit + * versions). This function returns a new allocated string or NULL if an error + * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. + */ +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); + +/* + * NAME curl_free() + * + * DESCRIPTION + * + * Provided for de-allocation in the same translation unit that did the + * allocation. Added in libcurl 7.10 + */ +CURL_EXTERN void curl_free(void *p); + +/* + * NAME curl_global_init() + * + * DESCRIPTION + * + * curl_global_init() should be invoked exactly once for each application that + * uses libcurl and before any call of other libcurl functions. + * + * This function is not thread-safe! + */ +CURL_EXTERN CURLcode curl_global_init(long flags); + +/* + * NAME curl_global_init_mem() + * + * DESCRIPTION + * + * curl_global_init() or curl_global_init_mem() should be invoked exactly once + * for each application that uses libcurl. This function can be used to + * initialize libcurl and set user defined memory management callback + * functions. Users can implement memory management routines to check for + * memory leaks, check for mis-use of the curl library etc. User registered + * callback routines with be invoked by this library instead of the system + * memory management routines like malloc, free etc. + */ +CURL_EXTERN CURLcode curl_global_init_mem(long flags, + curl_malloc_callback m, + curl_free_callback f, + curl_realloc_callback r, + curl_strdup_callback s, + curl_calloc_callback c); + +/* + * NAME curl_global_cleanup() + * + * DESCRIPTION + * + * curl_global_cleanup() should be invoked exactly once for each application + * that uses libcurl + */ +CURL_EXTERN void curl_global_cleanup(void); + +/* linked-list structure for the CURLOPT_QUOTE option (and other) */ +struct curl_slist { + char *data; + struct curl_slist *next; +}; + +/* + * NAME curl_slist_append() + * + * DESCRIPTION + * + * Appends a string to a linked list. If no list exists, it will be created + * first. Returns the new list, after appending. + */ +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, + const char *); + +/* + * NAME curl_slist_free_all() + * + * DESCRIPTION + * + * free a previously built curl_slist. + */ +CURL_EXTERN void curl_slist_free_all(struct curl_slist *); + +/* + * NAME curl_getdate() + * + * DESCRIPTION + * + * Returns the time, in seconds since 1 Jan 1970 of the time string given in + * the first argument. The time argument in the second parameter is unused + * and should be set to NULL. + */ +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); + +/* info about the certificate chain, only for OpenSSL builds. Asked + for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ +struct curl_certinfo { + int num_of_certs; /* number of certificates with information */ + struct curl_slist **certinfo; /* for each index in this array, there's a + linked list with textual information in the + format "name: value" */ +}; + +/* enum for the different supported SSL backends */ +typedef enum { + CURLSSLBACKEND_NONE = 0, + CURLSSLBACKEND_OPENSSL = 1, + CURLSSLBACKEND_GNUTLS = 2, + CURLSSLBACKEND_NSS = 3, + CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ + CURLSSLBACKEND_GSKIT = 5, + CURLSSLBACKEND_POLARSSL = 6, + CURLSSLBACKEND_CYASSL = 7, + CURLSSLBACKEND_SCHANNEL = 8, + CURLSSLBACKEND_DARWINSSL = 9, + CURLSSLBACKEND_AXTLS = 10, + CURLSSLBACKEND_MBEDTLS = 11 +} curl_sslbackend; + +/* aliases for library clones and renames */ +#define CURLSSLBACKEND_LIBRESSL 1 +#define CURLSSLBACKEND_BORINGSSL 1 +#define CURLSSLBACKEND_WOLFSSL 6 + +/* Information about the SSL library used and the respective internal SSL + handle, which can be used to obtain further information regarding the + connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ +struct curl_tlssessioninfo { + curl_sslbackend backend; + void *internals; +}; + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_SOCKET 0x500000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_SLIST + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43, + CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, + CURLINFO_TLS_SSL_PTR = CURLINFO_SLIST + 45, + CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, + CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, + CURLINFO_PROTOCOL = CURLINFO_LONG + 48, + CURLINFO_SCHEME = CURLINFO_STRING + 49, + /* Fill in new entries below here! */ + + CURLINFO_LASTONE = 49 +} CURLINFO; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_WIN32 (1<<1) +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_NOTHING 0 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL +#define CURL_GLOBAL_ACK_EINTR (1<<2) + + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different data locks for a single share */ +typedef enum { + CURL_LOCK_DATA_NONE = 0, + /* CURL_LOCK_DATA_SHARE is used internally to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_LAST +} curl_lock_data; + +/* Different lock access types */ +typedef enum { + CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ + CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ + CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ + CURL_LOCK_ACCESS_LAST /* never use */ +} curl_lock_access; + +typedef void (*curl_lock_function)(CURL *handle, + curl_lock_data data, + curl_lock_access locktype, + void *userptr); +typedef void (*curl_unlock_function)(CURL *handle, + curl_lock_data data, + void *userptr); + + +typedef enum { + CURLSHE_OK, /* all is fine */ + CURLSHE_BAD_OPTION, /* 1 */ + CURLSHE_IN_USE, /* 2 */ + CURLSHE_INVALID, /* 3 */ + CURLSHE_NOMEM, /* 4 out of memory */ + CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ + CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ + CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ + CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock + callback functions */ + CURLSHOPT_LAST /* never use */ +} CURLSHoption; + +CURL_EXTERN CURLSH *curl_share_init(void); +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); + +/**************************************************************************** + * Structures for querying information about the curl library at runtime. + */ + +typedef enum { + CURLVERSION_FIRST, + CURLVERSION_SECOND, + CURLVERSION_THIRD, + CURLVERSION_FOURTH, + CURLVERSION_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basically all programs ever that want to get version information. It is + meant to be a built-in version number for what kind of struct the caller + expects. If the struct ever changes, we redefine the NOW to another enum + from above. */ +#define CURLVERSION_NOW CURLVERSION_FOURTH + +typedef struct { + CURLversion age; /* age of the returned struct */ + const char *version; /* LIBCURL_VERSION */ + unsigned int version_num; /* LIBCURL_VERSION_NUM */ + const char *host; /* OS/host/cpu/machine when configured */ + int features; /* bitmask, see defines below */ + const char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used anymore, always 0 */ + const char *libz_version; /* human readable string */ + /* protocols is terminated by an entry with a NULL protoname */ + const char * const *protocols; + + /* The fields below this were added in CURLVERSION_SECOND */ + const char *ares; + int ares_num; + + /* This field was added in CURLVERSION_THIRD */ + const char *libidn; + + /* These field were added in CURLVERSION_FOURTH */ + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; + + const char *libssh_version; /* human readable string */ + +} curl_version_info_data; + +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported + (deprecated) */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported + (deprecated) */ +#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ +#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are + supported */ +#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ +#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ +#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ +#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ +#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper + is suported */ +#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ +#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ +#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ +#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ +#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used + for cookie domain verification */ +#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */ + + /* + * NAME curl_version_info() + * + * DESCRIPTION + * + * This function returns a pointer to a static copy of the version info + * struct. See above. + */ +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); + +/* + * NAME curl_easy_strerror() + * + * DESCRIPTION + * + * The curl_easy_strerror function may be used to turn a CURLcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_easy_strerror(CURLcode); + +/* + * NAME curl_share_strerror() + * + * DESCRIPTION + * + * The curl_share_strerror function may be used to turn a CURLSHcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_share_strerror(CURLSHcode); + +/* + * NAME curl_easy_pause() + * + * DESCRIPTION + * + * The curl_easy_pause function pauses or unpauses transfers. Select the new + * state by setting the bitmask, use the convenience defines below. + * + */ +CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); + +#define CURLPAUSE_RECV (1<<0) +#define CURLPAUSE_RECV_CONT (0) + +#define CURLPAUSE_SEND (1<<2) +#define CURLPAUSE_SEND_CONT (0) + +#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) +#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) + +#ifdef __cplusplus +} +#endif + +/* unfortunately, the easy.h and multi.h include files need options and info + stuff before they can be included! */ +#include "easy.h" /* nothing in curl is fun without the easy stuff */ +#include "multi.h" + +/* the typechecker doesn't work in C++ (yet) */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ + !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) +#include "typecheck-gcc.h" +#else +#if defined(__STDC__) && (__STDC__ >= 1) +/* This preprocessor magic that replaces a call with the exact same call is + only done to make sure application authors pass exactly three arguments + to these functions. */ +#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) +#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) +#endif /* __STDC__ >= 1 */ +#endif /* gcc >= 4.3 && !__cplusplus */ + +#endif /* __CURL_CURL_H */ diff --git a/win_lib/include/curl/curlbuild.h b/win_lib/include/curl/curlbuild.h new file mode 100644 index 000000000..80e4ba7ca --- /dev/null +++ b/win_lib/include/curl/curlbuild.h @@ -0,0 +1,198 @@ +/* include/curl/curlbuild.h. Generated from curlbuild.h.in by configure. */ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.in or + * at file include/curl/curlbuild.h, this is due to the following reason: + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file ws2tcpip.h must be included by the external interface. */ +#define CURL_PULL_WS2TCPIP_H 1 +#ifdef CURL_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +# include +# include +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +#define CURL_PULL_SYS_TYPES_H 1 +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file stdint.h must be included by the external interface. */ +#define CURL_PULL_STDINT_H 1 +#ifdef CURL_PULL_STDINT_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file inttypes.h must be included by the external interface. */ +#define CURL_PULL_INTTYPES_H 1 +#ifdef CURL_PULL_INTTYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/socket.h must be included by the external interface. */ +/* #undef CURL_PULL_SYS_SOCKET_H */ +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/poll.h must be included by the external interface. */ +/* #undef CURL_PULL_SYS_POLL_H */ +#ifdef CURL_PULL_SYS_POLL_H +# include +#endif + +/* The size of `long', as computed by sizeof. */ +#define CURL_SIZEOF_LONG 4 + +/* Integral data type used for curl_socklen_t. */ +#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t + +/* The size of `curl_socklen_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* Data type definition of curl_socklen_t. */ +typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; + +/* Signed integral data type used for curl_off_t. */ +#define CURL_TYPEOF_CURL_OFF_T int64_t + +/* Data type definition of curl_off_t. */ +typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; + +/* curl_off_t formatting string directive without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_T "I64d" + +/* unsigned curl_off_t formatting string without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_TU "I64u" + +/* curl_off_t formatting string directive with "%" conversion specifier. */ +#define CURL_FORMAT_OFF_T "%I64d" + +/* The size of `curl_off_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_OFF_T 8 + +/* curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_T LL + +/* unsigned curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_TU ULL + +#endif /* __CURL_CURLBUILD_H */ diff --git a/win_lib/include/curl/curlrules.h b/win_lib/include/curl/curlrules.h new file mode 100644 index 000000000..55d21f68f --- /dev/null +++ b/win_lib/include/curl/curlrules.h @@ -0,0 +1,262 @@ +#ifndef __CURL_CURLRULES_H +#define __CURL_CURLRULES_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* COMPILE TIME SANITY CHECKS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * All checks done in this file are intentionally placed in a public + * header file which is pulled by curl/curl.h when an application is + * being built using an already built libcurl library. Additionally + * this file is also included and used when building the library. + * + * If compilation fails on this file it is certainly sure that the + * problem is elsewhere. It could be a problem in the curlbuild.h + * header file, or simply that you are using different compilation + * settings than those used to build the library. + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * Do not deactivate any check, these are done to make sure that the + * library is properly built and used. + * + * You can find further help on the libcurl development mailing list: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * NOTE 2 + * ------ + * + * Some of the following compile time checks are based on the fact + * that the dimension of a constant array can not be a negative one. + * In this way if the compile time verification fails, the compilation + * will fail issuing an error. The error description wording is compiler + * dependent but it will be quite similar to one of the following: + * + * "negative subscript or subscript is too large" + * "array must have at least one element" + * "-1 is an illegal array size" + * "size of array is negative" + * + * If you are building an application which tries to use an already + * built libcurl library and you are getting this kind of errors on + * this file, it is a clear indication that there is a mismatch between + * how the library was built and how you are trying to use it for your + * application. Your already compiled or binary library provider is the + * only one who can give you the details you need to properly use it. + */ + +/* + * Verify that some macros are actually defined. + */ + +#ifndef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing +#endif + +#ifndef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing +#endif + +/* + * Macros private to this header file. + */ + +#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1 + +#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 + +/* + * Verify that the size previously defined and expected for long + * is the same as the one reported by sizeof() at compile time. + */ + +typedef char + __curl_rule_01__ + [CurlchkszEQ(long, CURL_SIZEOF_LONG)]; + +/* + * Verify that the size previously defined and expected for + * curl_off_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_02__ + [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)]; + +/* + * Verify at compile time that the size of curl_off_t as reported + * by sizeof() is greater or equal than the one reported for long + * for the current compilation. + */ + +typedef char + __curl_rule_03__ + [CurlchkszGE(curl_off_t, long)]; + +/* + * Verify that the size previously defined and expected for + * curl_socklen_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_04__ + [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)]; + +/* + * Verify at compile time that the size of curl_socklen_t as reported + * by sizeof() is greater or equal than the one reported for int for + * the current compilation. + */ + +typedef char + __curl_rule_05__ + [CurlchkszGE(curl_socklen_t, int)]; + +/* ================================================================ */ +/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ +/* ================================================================ */ + +/* + * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow + * these to be visible and exported by the external libcurl interface API, + * while also making them visible to the library internals, simply including + * curl_setup.h, without actually needing to include curl.h internally. + * If some day this section would grow big enough, all this should be moved + * to its own header file. + */ + +/* + * Figure out if we can use the ## preprocessor operator, which is supported + * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ + * or __cplusplus so we need to carefully check for them too. + */ + +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ + defined(__ILEC400__) + /* This compiler is believed to have an ISO compatible preprocessor */ +#define CURL_ISOCPP +#else + /* This compiler is believed NOT to have an ISO compatible preprocessor */ +#undef CURL_ISOCPP +#endif + +/* + * Macros for minimum-width signed and unsigned curl_off_t integer constants. + */ + +#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) +# define __CURL_OFF_T_C_HLPR2(x) x +# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) +#else +# ifdef CURL_ISOCPP +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix +# else +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix +# endif +# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) +#endif + +/* + * Get rid of macros private to this header file. + */ + +#undef CurlchkszEQ +#undef CurlchkszGE + +/* + * Get rid of macros not intended to exist beyond this point. + */ + +#undef CURL_PULL_WS2TCPIP_H +#undef CURL_PULL_SYS_TYPES_H +#undef CURL_PULL_SYS_SOCKET_H +#undef CURL_PULL_SYS_POLL_H +#undef CURL_PULL_STDINT_H +#undef CURL_PULL_INTTYPES_H + +#undef CURL_TYPEOF_CURL_SOCKLEN_T +#undef CURL_TYPEOF_CURL_OFF_T + +#ifdef CURL_NO_OLDIES +#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */ +#endif + +#endif /* __CURL_CURLRULES_H */ diff --git a/win_lib/include/curl/curlver.h b/win_lib/include/curl/curlver.h new file mode 100644 index 000000000..ae91b0d2b --- /dev/null +++ b/win_lib/include/curl/curlver.h @@ -0,0 +1,77 @@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This header file contains nothing but libcurl version info, generated by + a script at release-time. This was made its own header file in 7.11.2 */ + +/* This is the global package copyright */ +#define LIBCURL_COPYRIGHT "1996 - 2016 Daniel Stenberg, ." + +/* This is the version number of the libcurl package from which this header + file origins: */ +#define LIBCURL_VERSION "7.52.1" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 +#define LIBCURL_VERSION_MINOR 52 +#define LIBCURL_VERSION_PATCH 1 + +/* This is the numeric version of the libcurl version number, meant for easier + parsing and comparions by programs. The LIBCURL_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. + + Note: This define is the full hex number and _does not_ use the + CURL_VERSION_BITS() macro since curl's own configure script greps for it + and needs it to contain the full number. +*/ +#define LIBCURL_VERSION_NUM 0x073401 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in git, as the timestamp is properly set in the + * tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + */ +#define LIBCURL_TIMESTAMP "Fri Dec 23 07:22:31 UTC 2016" + +#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) +#define CURL_AT_LEAST_VERSION(x,y,z) \ + (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) + +#endif /* __CURL_CURLVER_H */ diff --git a/win_lib/include/curl/easy.h b/win_lib/include/curl/easy.h new file mode 100644 index 000000000..752c5049f --- /dev/null +++ b/win_lib/include/curl/easy.h @@ -0,0 +1,102 @@ +#ifndef __CURL_EASY_H +#define __CURL_EASY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN CURL *curl_easy_init(void); +CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); +CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); +CURL_EXTERN void curl_easy_cleanup(CURL *curl); + +/* + * NAME curl_easy_getinfo() + * + * DESCRIPTION + * + * Request internal information from the curl session with this function. The + * third argument MUST be a pointer to a long, a pointer to a char * or a + * pointer to a double (as the documentation describes elsewhere). The data + * pointed to will be filled in accordingly and can be relied upon only if the + * function returns CURLE_OK. This function is intended to get used *AFTER* a + * performed transfer, all results from this function are undefined until the + * transfer is completed. + */ +CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); + + +/* + * NAME curl_easy_duphandle() + * + * DESCRIPTION + * + * Creates a new curl session handle with the same options set for the handle + * passed in. Duplicating a handle could only be a matter of cloning data and + * options, internal state info and things like persistent connections cannot + * be transferred. It is useful in multithreaded applications when you can run + * curl_easy_duphandle() for each new thread to avoid a series of identical + * curl_easy_setopt() invokes in every thread. + */ +CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); + +/* + * NAME curl_easy_reset() + * + * DESCRIPTION + * + * Re-initializes a CURL handle to the default values. This puts back the + * handle to the same state as it was in when it was just created. + * + * It does keep: live connections, the Session ID cache, the DNS cache and the + * cookies. + */ +CURL_EXTERN void curl_easy_reset(CURL *curl); + +/* + * NAME curl_easy_recv() + * + * DESCRIPTION + * + * Receives data from the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, + size_t *n); + +/* + * NAME curl_easy_send() + * + * DESCRIPTION + * + * Sends data over the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, + size_t buflen, size_t *n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/win_lib/include/curl/mprintf.h b/win_lib/include/curl/mprintf.h new file mode 100644 index 000000000..e20f546e1 --- /dev/null +++ b/win_lib/include/curl/mprintf.h @@ -0,0 +1,50 @@ +#ifndef __CURL_MPRINTF_H +#define __CURL_MPRINTF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include +#include /* needed for FILE */ +#include "curl.h" /* for CURL_EXTERN */ + +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN int curl_mprintf(const char *format, ...); +CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); +CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); +CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, + const char *format, ...); +CURL_EXTERN int curl_mvprintf(const char *format, va_list args); +CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); +CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); +CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, + const char *format, va_list args); +CURL_EXTERN char *curl_maprintf(const char *format, ...); +CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); + +#ifdef __cplusplus +} +#endif + +#endif /* __CURL_MPRINTF_H */ diff --git a/win_lib/include/curl/multi.h b/win_lib/include/curl/multi.h new file mode 100644 index 000000000..d1e00cc5d --- /dev/null +++ b/win_lib/include/curl/multi.h @@ -0,0 +1,439 @@ +#ifndef __CURL_MULTI_H +#define __CURL_MULTI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + This is an "external" header file. Don't give away any internals here! + + GOALS + + o Enable a "pull" interface. The application that uses libcurl decides where + and when to ask libcurl to get/send data. + + o Enable multiple simultaneous transfers in the same thread without making it + complicated for the application. + + o Enable the application to select() on its own file descriptors and curl's + file descriptors simultaneous easily. + +*/ + +/* + * This header file should not really need to include "curl.h" since curl.h + * itself includes this file and we expect user applications to do #include + * without the need for especially including multi.h. + * + * For some reason we added this include here at one point, and rather than to + * break existing (wrongly written) libcurl applications, we leave it as-is + * but with this warning attached. + */ +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_multi CURLM; +#else +typedef void CURLM; +#endif + +typedef enum { + CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or + curl_multi_socket*() soon */ + CURLM_OK, + CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ + CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ + CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ + CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ + CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ + CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ + CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was + attempted to get added - again */ + CURLM_LAST +} CURLMcode; + +/* just to make code nicer when using curl_multi_socket() you can now check + for CURLM_CALL_MULTI_SOCKET too in the same style it works for + curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ +#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM + +/* bitmask bits for CURLMOPT_PIPELINING */ +#define CURLPIPE_NOTHING 0L +#define CURLPIPE_HTTP1 1L +#define CURLPIPE_MULTIPLEX 2L + +typedef enum { + CURLMSG_NONE, /* first, not used */ + CURLMSG_DONE, /* This easy handle has completed. 'result' contains + the CURLcode of the transfer */ + CURLMSG_LAST /* last, not used */ +} CURLMSG; + +struct CURLMsg { + CURLMSG msg; /* what this message means */ + CURL *easy_handle; /* the handle it concerns */ + union { + void *whatever; /* message-specific data */ + CURLcode result; /* return code for transfer */ + } data; +}; +typedef struct CURLMsg CURLMsg; + +/* Based on poll(2) structure and values. + * We don't use pollfd and POLL* constants explicitly + * to cover platforms without poll(). */ +#define CURL_WAIT_POLLIN 0x0001 +#define CURL_WAIT_POLLPRI 0x0002 +#define CURL_WAIT_POLLOUT 0x0004 + +struct curl_waitfd { + curl_socket_t fd; + short events; + short revents; /* not supported yet */ +}; + +/* + * Name: curl_multi_init() + * + * Desc: inititalize multi-style curl usage + * + * Returns: a new CURLM handle to use in all 'curl_multi' functions. + */ +CURL_EXTERN CURLM *curl_multi_init(void); + +/* + * Name: curl_multi_add_handle() + * + * Desc: add a standard curl handle to the multi stack + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_remove_handle() + * + * Desc: removes a curl handle from the multi stack again + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_fdset() + * + * Desc: Ask curl for its fd_set sets. The app can use these to select() or + * poll() on. We want curl_multi_perform() called as soon as one of + * them are ready. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); + +/* + * Name: curl_multi_wait() + * + * Desc: Poll on all fds within a CURLM set as well as any + * additional fds passed to the function. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret); + + /* + * Name: curl_multi_perform() + * + * Desc: When the app thinks there's data available for curl it calls this + * function to read/write whatever there is right now. This returns + * as soon as the reads and writes are done. This function does not + * require that there actually is data available for reading or that + * data can be written, it can be called just in case. It returns + * the number of handles that still transfer data in the second + * argument's integer-pointer. + * + * Returns: CURLMcode type, general multi error code. *NOTE* that this only + * returns errors etc regarding the whole multi stack. There might + * still have occurred problems on invidual transfers even when this + * returns OK. + */ +CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, + int *running_handles); + + /* + * Name: curl_multi_cleanup() + * + * Desc: Cleans up and removes a whole multi stack. It does not free or + * touch any individual easy handles in any way. We need to define + * in what state those handles will be if this function is called + * in the middle of a transfer. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); + +/* + * Name: curl_multi_info_read() + * + * Desc: Ask the multi handle if there's any messages/informationals from + * the individual transfers. Messages include informationals such as + * error code from the transfer or just the fact that a transfer is + * completed. More details on these should be written down as well. + * + * Repeated calls to this function will return a new struct each + * time, until a special "end of msgs" struct is returned as a signal + * that there is no more to get at this point. + * + * The data the returned pointer points to will not survive calling + * curl_multi_cleanup(). + * + * The 'CURLMsg' struct is meant to be very simple and only contain + * very basic informations. If more involved information is wanted, + * we will provide the particular "transfer handle" in that struct + * and that should/could/would be used in subsequent + * curl_easy_getinfo() calls (or similar). The point being that we + * must never expose complex structs to applications, as then we'll + * undoubtably get backwards compatibility problems in the future. + * + * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out + * of structs. It also writes the number of messages left in the + * queue (after this read) in the integer the second argument points + * to. + */ +CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, + int *msgs_in_queue); + +/* + * Name: curl_multi_strerror() + * + * Desc: The curl_multi_strerror function may be used to turn a CURLMcode + * value into the equivalent human readable error string. This is + * useful for printing meaningful error messages. + * + * Returns: A pointer to a zero-terminated error message. + */ +CURL_EXTERN const char *curl_multi_strerror(CURLMcode); + +/* + * Name: curl_multi_socket() and + * curl_multi_socket_all() + * + * Desc: An alternative version of curl_multi_perform() that allows the + * application to pass in one of the file descriptors that have been + * detected to have "action" on them and let libcurl perform. + * See man page for details. + */ +#define CURL_POLL_NONE 0 +#define CURL_POLL_IN 1 +#define CURL_POLL_OUT 2 +#define CURL_POLL_INOUT 3 +#define CURL_POLL_REMOVE 4 + +#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD + +#define CURL_CSELECT_IN 0x01 +#define CURL_CSELECT_OUT 0x02 +#define CURL_CSELECT_ERR 0x04 + +typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* see above */ + void *userp, /* private callback + pointer */ + void *socketp); /* private socket + pointer */ +/* + * Name: curl_multi_timer_callback + * + * Desc: Called by libcurl whenever the library detects a change in the + * maximum number of milliseconds the app is allowed to wait before + * curl_multi_socket() or curl_multi_perform() must be called + * (to allow libcurl's timed events to take place). + * + * Returns: The callback should return zero. + */ +typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp); /* private callback + pointer */ + +CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, + curl_socket_t s, + int ev_bitmask, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); + +#ifndef CURL_ALLOW_OLD_MULTI_SOCKET +/* This macro below was added in 7.16.3 to push users who recompile to use + the new curl_multi_socket_action() instead of the old curl_multi_socket() +*/ +#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) +#endif + +/* + * Name: curl_multi_timeout() + * + * Desc: Returns the maximum number of milliseconds the app is allowed to + * wait before curl_multi_socket() or curl_multi_perform() must be + * called (to allow libcurl's timed events to take place). + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, + long *milliseconds); + +#undef CINIT /* re-using the same name as in curl.h */ + +#ifdef CURL_ISOCPP +#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLMOPT_/**/name = type + number +#endif + +typedef enum { + /* This is the socket callback function pointer */ + CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), + + /* This is the argument passed to the socket callback */ + CINIT(SOCKETDATA, OBJECTPOINT, 2), + + /* set to 1 to enable pipelining for this multi handle */ + CINIT(PIPELINING, LONG, 3), + + /* This is the timer callback function pointer */ + CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), + + /* This is the argument passed to the timer callback */ + CINIT(TIMERDATA, OBJECTPOINT, 5), + + /* maximum number of entries in the connection cache */ + CINIT(MAXCONNECTS, LONG, 6), + + /* maximum number of (pipelining) connections to one host */ + CINIT(MAX_HOST_CONNECTIONS, LONG, 7), + + /* maximum number of requests in a pipeline */ + CINIT(MAX_PIPELINE_LENGTH, LONG, 8), + + /* a connection with a content-length longer than this + will not be considered for pipelining */ + CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9), + + /* a connection with a chunk length longer than this + will not be considered for pipelining */ + CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10), + + /* a list of site names(+port) that are blacklisted from + pipelining */ + CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11), + + /* a list of server types that are blacklisted from + pipelining */ + CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12), + + /* maximum number of open connections in total */ + CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13), + + /* This is the server push callback function pointer */ + CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14), + + /* This is the argument passed to the server push callback */ + CINIT(PUSHDATA, OBJECTPOINT, 15), + + CURLMOPT_LASTENTRY /* the last unused */ +} CURLMoption; + + +/* + * Name: curl_multi_setopt() + * + * Desc: Sets options for the multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, + CURLMoption option, ...); + + +/* + * Name: curl_multi_assign() + * + * Desc: This function sets an association in the multi handle between the + * given socket and a private pointer of the application. This is + * (only) useful for curl_multi_socket uses. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, + curl_socket_t sockfd, void *sockp); + + +/* + * Name: curl_push_callback + * + * Desc: This callback gets called when a new stream is being pushed by the + * server. It approves or denies the new stream. + * + * Returns: CURL_PUSH_OK or CURL_PUSH_DENY. + */ +#define CURL_PUSH_OK 0 +#define CURL_PUSH_DENY 1 + +struct curl_pushheaders; /* forward declaration only */ + +CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, + size_t num); +CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, + const char *name); + +typedef int (*curl_push_callback)(CURL *parent, + CURL *easy, + size_t num_headers, + struct curl_pushheaders *headers, + void *userp); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/win_lib/include/curl/stdcheaders.h b/win_lib/include/curl/stdcheaders.h new file mode 100644 index 000000000..027b6f421 --- /dev/null +++ b/win_lib/include/curl/stdcheaders.h @@ -0,0 +1,33 @@ +#ifndef __STDC_HEADERS_H +#define __STDC_HEADERS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include + +size_t fread(void *, size_t, size_t, FILE *); +size_t fwrite(const void *, size_t, size_t, FILE *); + +int strcasecmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); + +#endif /* __STDC_HEADERS_H */ diff --git a/win_lib/include/curl/typecheck-gcc.h b/win_lib/include/curl/typecheck-gcc.h new file mode 100644 index 000000000..4eb896eaa --- /dev/null +++ b/win_lib/include/curl/typecheck-gcc.h @@ -0,0 +1,623 @@ +#ifndef __CURL_TYPECHECK_GCC_H +#define __CURL_TYPECHECK_GCC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* wraps curl_easy_setopt() with typechecking */ + +/* To add a new kind of warning, add an + * if(_curl_is_sometype_option(_curl_opt)) + * if(!_curl_is_sometype(value)) + * _curl_easy_setopt_err_sometype(); + * block and define _curl_is_sometype_option, _curl_is_sometype and + * _curl_easy_setopt_err_sometype below + * + * NOTE: We use two nested 'if' statements here instead of the && operator, in + * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x + * when compiling with -Wlogical-op. + * + * To add an option that uses the same type as an existing option, you'll just + * need to extend the appropriate _curl_*_option macro + */ +#define curl_easy_setopt(handle, option, value) \ +__extension__ ({ \ + __typeof__(option) _curl_opt = option; \ + if(__builtin_constant_p(_curl_opt)) { \ + if(_curl_is_long_option(_curl_opt)) \ + if(!_curl_is_long(value)) \ + _curl_easy_setopt_err_long(); \ + if(_curl_is_off_t_option(_curl_opt)) \ + if(!_curl_is_off_t(value)) \ + _curl_easy_setopt_err_curl_off_t(); \ + if(_curl_is_string_option(_curl_opt)) \ + if(!_curl_is_string(value)) \ + _curl_easy_setopt_err_string(); \ + if(_curl_is_write_cb_option(_curl_opt)) \ + if(!_curl_is_write_cb(value)) \ + _curl_easy_setopt_err_write_callback(); \ + if((_curl_opt) == CURLOPT_READFUNCTION) \ + if(!_curl_is_read_cb(value)) \ + _curl_easy_setopt_err_read_cb(); \ + if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ + if(!_curl_is_ioctl_cb(value)) \ + _curl_easy_setopt_err_ioctl_cb(); \ + if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ + if(!_curl_is_sockopt_cb(value)) \ + _curl_easy_setopt_err_sockopt_cb(); \ + if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ + if(!_curl_is_opensocket_cb(value)) \ + _curl_easy_setopt_err_opensocket_cb(); \ + if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ + if(!_curl_is_progress_cb(value)) \ + _curl_easy_setopt_err_progress_cb(); \ + if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ + if(!_curl_is_debug_cb(value)) \ + _curl_easy_setopt_err_debug_cb(); \ + if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ + if(!_curl_is_ssl_ctx_cb(value)) \ + _curl_easy_setopt_err_ssl_ctx_cb(); \ + if(_curl_is_conv_cb_option(_curl_opt)) \ + if(!_curl_is_conv_cb(value)) \ + _curl_easy_setopt_err_conv_cb(); \ + if((_curl_opt) == CURLOPT_SEEKFUNCTION) \ + if(!_curl_is_seek_cb(value)) \ + _curl_easy_setopt_err_seek_cb(); \ + if(_curl_is_cb_data_option(_curl_opt)) \ + if(!_curl_is_cb_data(value)) \ + _curl_easy_setopt_err_cb_data(); \ + if((_curl_opt) == CURLOPT_ERRORBUFFER) \ + if(!_curl_is_error_buffer(value)) \ + _curl_easy_setopt_err_error_buffer(); \ + if((_curl_opt) == CURLOPT_STDERR) \ + if(!_curl_is_FILE(value)) \ + _curl_easy_setopt_err_FILE(); \ + if(_curl_is_postfields_option(_curl_opt)) \ + if(!_curl_is_postfields(value)) \ + _curl_easy_setopt_err_postfields(); \ + if((_curl_opt) == CURLOPT_HTTPPOST) \ + if(!_curl_is_arr((value), struct curl_httppost)) \ + _curl_easy_setopt_err_curl_httpost(); \ + if(_curl_is_slist_option(_curl_opt)) \ + if(!_curl_is_arr((value), struct curl_slist)) \ + _curl_easy_setopt_err_curl_slist(); \ + if((_curl_opt) == CURLOPT_SHARE) \ + if(!_curl_is_ptr((value), CURLSH)) \ + _curl_easy_setopt_err_CURLSH(); \ + } \ + curl_easy_setopt(handle, _curl_opt, value); \ +}) + +/* wraps curl_easy_getinfo() with typechecking */ +/* FIXME: don't allow const pointers */ +#define curl_easy_getinfo(handle, info, arg) \ +__extension__ ({ \ + __typeof__(info) _curl_info = info; \ + if(__builtin_constant_p(_curl_info)) { \ + if(_curl_is_string_info(_curl_info)) \ + if(!_curl_is_arr((arg), char *)) \ + _curl_easy_getinfo_err_string(); \ + if(_curl_is_long_info(_curl_info)) \ + if(!_curl_is_arr((arg), long)) \ + _curl_easy_getinfo_err_long(); \ + if(_curl_is_double_info(_curl_info)) \ + if(!_curl_is_arr((arg), double)) \ + _curl_easy_getinfo_err_double(); \ + if(_curl_is_slist_info(_curl_info)) \ + if(!_curl_is_arr((arg), struct curl_slist *)) \ + _curl_easy_getinfo_err_curl_slist(); \ + } \ + curl_easy_getinfo(handle, _curl_info, arg); \ +}) + +/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), + * for now just make sure that the functions are called with three + * arguments + */ +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) + + +/* the actual warnings, triggered by calling the _curl_easy_setopt_err* + * functions */ + +/* To define a new warning, use _CURL_WARNING(identifier, "message") */ +#define _CURL_WARNING(id, message) \ + static void __attribute__((__warning__(message))) \ + __attribute__((__unused__)) __attribute__((__noinline__)) \ + id(void) { __asm__(""); } + +_CURL_WARNING(_curl_easy_setopt_err_long, + "curl_easy_setopt expects a long argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, + "curl_easy_setopt expects a curl_off_t argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_string, + "curl_easy_setopt expects a " + "string ('char *' or char[]) argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_write_callback, + "curl_easy_setopt expects a curl_write_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_read_cb, + "curl_easy_setopt expects a curl_read_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, + "curl_easy_setopt expects a curl_ioctl_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, + "curl_easy_setopt expects a curl_sockopt_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, + "curl_easy_setopt expects a " + "curl_opensocket_callback argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_progress_cb, + "curl_easy_setopt expects a curl_progress_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_debug_cb, + "curl_easy_setopt expects a curl_debug_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, + "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_conv_cb, + "curl_easy_setopt expects a curl_conv_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_seek_cb, + "curl_easy_setopt expects a curl_seek_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_cb_data, + "curl_easy_setopt expects a " + "private data pointer as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_error_buffer, + "curl_easy_setopt expects a " + "char buffer of CURL_ERROR_SIZE as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_FILE, + "curl_easy_setopt expects a 'FILE *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_postfields, + "curl_easy_setopt expects a 'void *' or 'char *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, + "curl_easy_setopt expects a 'struct curl_httppost *' " + "argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_slist, + "curl_easy_setopt expects a 'struct curl_slist *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_CURLSH, + "curl_easy_setopt expects a CURLSH* argument for this option") + +_CURL_WARNING(_curl_easy_getinfo_err_string, + "curl_easy_getinfo expects a pointer to 'char *' for this info") +_CURL_WARNING(_curl_easy_getinfo_err_long, + "curl_easy_getinfo expects a pointer to long for this info") +_CURL_WARNING(_curl_easy_getinfo_err_double, + "curl_easy_getinfo expects a pointer to double for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, + "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info") + +/* groups of curl_easy_setops options that take the same type of argument */ + +/* To add a new option to one of the groups, just add + * (option) == CURLOPT_SOMETHING + * to the or-expression. If the option takes a long or curl_off_t, you don't + * have to do anything + */ + +/* evaluates to true if option takes a long argument */ +#define _curl_is_long_option(option) \ + (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) + +#define _curl_is_off_t_option(option) \ + ((option) > CURLOPTTYPE_OFF_T) + +/* evaluates to true if option takes a char* argument */ +#define _curl_is_string_option(option) \ + ((option) == CURLOPT_ACCEPT_ENCODING || \ + (option) == CURLOPT_CAINFO || \ + (option) == CURLOPT_CAPATH || \ + (option) == CURLOPT_COOKIE || \ + (option) == CURLOPT_COOKIEFILE || \ + (option) == CURLOPT_COOKIEJAR || \ + (option) == CURLOPT_COOKIELIST || \ + (option) == CURLOPT_CRLFILE || \ + (option) == CURLOPT_CUSTOMREQUEST || \ + (option) == CURLOPT_DEFAULT_PROTOCOL || \ + (option) == CURLOPT_DNS_INTERFACE || \ + (option) == CURLOPT_DNS_LOCAL_IP4 || \ + (option) == CURLOPT_DNS_LOCAL_IP6 || \ + (option) == CURLOPT_DNS_SERVERS || \ + (option) == CURLOPT_EGDSOCKET || \ + (option) == CURLOPT_FTPPORT || \ + (option) == CURLOPT_FTP_ACCOUNT || \ + (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ + (option) == CURLOPT_INTERFACE || \ + (option) == CURLOPT_ISSUERCERT || \ + (option) == CURLOPT_KEYPASSWD || \ + (option) == CURLOPT_KRBLEVEL || \ + (option) == CURLOPT_LOGIN_OPTIONS || \ + (option) == CURLOPT_MAIL_AUTH || \ + (option) == CURLOPT_MAIL_FROM || \ + (option) == CURLOPT_NETRC_FILE || \ + (option) == CURLOPT_NOPROXY || \ + (option) == CURLOPT_PASSWORD || \ + (option) == CURLOPT_PINNEDPUBLICKEY || \ + (option) == CURLOPT_PROXY || \ + (option) == CURLOPT_PROXYPASSWORD || \ + (option) == CURLOPT_PROXYUSERNAME || \ + (option) == CURLOPT_PROXYUSERPWD || \ + (option) == CURLOPT_PROXY_SERVICE_NAME || \ + (option) == CURLOPT_RANDOM_FILE || \ + (option) == CURLOPT_RANGE || \ + (option) == CURLOPT_REFERER || \ + (option) == CURLOPT_RTSP_SESSION_ID || \ + (option) == CURLOPT_RTSP_STREAM_URI || \ + (option) == CURLOPT_RTSP_TRANSPORT || \ + (option) == CURLOPT_SERVICE_NAME || \ + (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ + (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ + (option) == CURLOPT_SSH_KNOWNHOSTS || \ + (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ + (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ + (option) == CURLOPT_SSLCERT || \ + (option) == CURLOPT_SSLCERTTYPE || \ + (option) == CURLOPT_SSLENGINE || \ + (option) == CURLOPT_SSLKEY || \ + (option) == CURLOPT_SSLKEYTYPE || \ + (option) == CURLOPT_SSL_CIPHER_LIST || \ + (option) == CURLOPT_TLSAUTH_PASSWORD || \ + (option) == CURLOPT_TLSAUTH_TYPE || \ + (option) == CURLOPT_TLSAUTH_USERNAME || \ + (option) == CURLOPT_UNIX_SOCKET_PATH || \ + (option) == CURLOPT_URL || \ + (option) == CURLOPT_USERAGENT || \ + (option) == CURLOPT_USERNAME || \ + (option) == CURLOPT_USERPWD || \ + (option) == CURLOPT_XOAUTH2_BEARER || \ + 0) + +/* evaluates to true if option takes a curl_write_callback argument */ +#define _curl_is_write_cb_option(option) \ + ((option) == CURLOPT_HEADERFUNCTION || \ + (option) == CURLOPT_WRITEFUNCTION) + +/* evaluates to true if option takes a curl_conv_callback argument */ +#define _curl_is_conv_cb_option(option) \ + ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) + +/* evaluates to true if option takes a data argument to pass to a callback */ +#define _curl_is_cb_data_option(option) \ + ((option) == CURLOPT_CHUNK_DATA || \ + (option) == CURLOPT_CLOSESOCKETDATA || \ + (option) == CURLOPT_DEBUGDATA || \ + (option) == CURLOPT_FNMATCH_DATA || \ + (option) == CURLOPT_HEADERDATA || \ + (option) == CURLOPT_INTERLEAVEDATA || \ + (option) == CURLOPT_IOCTLDATA || \ + (option) == CURLOPT_OPENSOCKETDATA || \ + (option) == CURLOPT_PRIVATE || \ + (option) == CURLOPT_PROGRESSDATA || \ + (option) == CURLOPT_READDATA || \ + (option) == CURLOPT_SEEKDATA || \ + (option) == CURLOPT_SOCKOPTDATA || \ + (option) == CURLOPT_SSH_KEYDATA || \ + (option) == CURLOPT_SSL_CTX_DATA || \ + (option) == CURLOPT_WRITEDATA || \ + 0) + +/* evaluates to true if option takes a POST data argument (void* or char*) */ +#define _curl_is_postfields_option(option) \ + ((option) == CURLOPT_POSTFIELDS || \ + (option) == CURLOPT_COPYPOSTFIELDS || \ + 0) + +/* evaluates to true if option takes a struct curl_slist * argument */ +#define _curl_is_slist_option(option) \ + ((option) == CURLOPT_HTTP200ALIASES || \ + (option) == CURLOPT_HTTPHEADER || \ + (option) == CURLOPT_MAIL_RCPT || \ + (option) == CURLOPT_POSTQUOTE || \ + (option) == CURLOPT_PREQUOTE || \ + (option) == CURLOPT_PROXYHEADER || \ + (option) == CURLOPT_QUOTE || \ + (option) == CURLOPT_RESOLVE || \ + (option) == CURLOPT_TELNETOPTIONS || \ + 0) + +/* groups of curl_easy_getinfo infos that take the same type of argument */ + +/* evaluates to true if info expects a pointer to char * argument */ +#define _curl_is_string_info(info) \ + (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) + +/* evaluates to true if info expects a pointer to long argument */ +#define _curl_is_long_info(info) \ + (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) + +/* evaluates to true if info expects a pointer to double argument */ +#define _curl_is_double_info(info) \ + (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) + +/* true if info expects a pointer to struct curl_slist * argument */ +#define _curl_is_slist_info(info) \ + (CURLINFO_SLIST < (info)) + + +/* typecheck helpers -- check whether given expression has requested type*/ + +/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, + * otherwise define a new macro. Search for __builtin_types_compatible_p + * in the GCC manual. + * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is + * the actual expression passed to the curl_easy_setopt macro. This + * means that you can only apply the sizeof and __typeof__ operators, no + * == or whatsoever. + */ + +/* XXX: should evaluate to true iff expr is a pointer */ +#define _curl_is_any_ptr(expr) \ + (sizeof(expr) == sizeof(void *)) + +/* evaluates to true if expr is NULL */ +/* XXX: must not evaluate expr, so this check is not accurate */ +#define _curl_is_NULL(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) + +/* evaluates to true if expr is type*, const type* or NULL */ +#define _curl_is_ptr(expr, type) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), type *) || \ + __builtin_types_compatible_p(__typeof__(expr), const type *)) + +/* evaluates to true if expr is one of type[], type*, NULL or const type* */ +#define _curl_is_arr(expr, type) \ + (_curl_is_ptr((expr), type) || \ + __builtin_types_compatible_p(__typeof__(expr), type [])) + +/* evaluates to true if expr is a string */ +#define _curl_is_string(expr) \ + (_curl_is_arr((expr), char) || \ + _curl_is_arr((expr), signed char) || \ + _curl_is_arr((expr), unsigned char)) + +/* evaluates to true if expr is a long (no matter the signedness) + * XXX: for now, int is also accepted (and therefore short and char, which + * are promoted to int when passed to a variadic function) */ +#define _curl_is_long(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), long) || \ + __builtin_types_compatible_p(__typeof__(expr), signed long) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ + __builtin_types_compatible_p(__typeof__(expr), int) || \ + __builtin_types_compatible_p(__typeof__(expr), signed int) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ + __builtin_types_compatible_p(__typeof__(expr), short) || \ + __builtin_types_compatible_p(__typeof__(expr), signed short) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ + __builtin_types_compatible_p(__typeof__(expr), char) || \ + __builtin_types_compatible_p(__typeof__(expr), signed char) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned char)) + +/* evaluates to true if expr is of type curl_off_t */ +#define _curl_is_off_t(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) + +/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ +/* XXX: also check size of an char[] array? */ +#define _curl_is_error_buffer(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), char *) || \ + __builtin_types_compatible_p(__typeof__(expr), char[])) + +/* evaluates to true if expr is of type (const) void* or (const) FILE* */ +#if 0 +#define _curl_is_cb_data(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_ptr((expr), FILE)) +#else /* be less strict */ +#define _curl_is_cb_data(expr) \ + _curl_is_any_ptr(expr) +#endif + +/* evaluates to true if expr is of type FILE* */ +#define _curl_is_FILE(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), FILE *)) + +/* evaluates to true if expr can be passed as POST data (void* or char*) */ +#define _curl_is_postfields(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_arr((expr), char)) + +/* FIXME: the whole callback checking is messy... + * The idea is to tolerate char vs. void and const vs. not const + * pointers in arguments at least + */ +/* helper: __builtin_types_compatible_p distinguishes between functions and + * function pointers, hide it */ +#define _curl_callback_compatible(func, type) \ + (__builtin_types_compatible_p(__typeof__(func), type) || \ + __builtin_types_compatible_p(__typeof__(func), type*)) + +/* evaluates to true if expr is of type curl_read_callback or "similar" */ +#define _curl_is_read_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \ + _curl_callback_compatible((expr), _curl_read_callback1) || \ + _curl_callback_compatible((expr), _curl_read_callback2) || \ + _curl_callback_compatible((expr), _curl_read_callback3) || \ + _curl_callback_compatible((expr), _curl_read_callback4) || \ + _curl_callback_compatible((expr), _curl_read_callback5) || \ + _curl_callback_compatible((expr), _curl_read_callback6)) +typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void *); +typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void *); +typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE *); +typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void *); +typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void *); +typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE *); + +/* evaluates to true if expr is of type curl_write_callback or "similar" */ +#define _curl_is_write_cb(expr) \ + (_curl_is_read_cb(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \ + _curl_callback_compatible((expr), _curl_write_callback1) || \ + _curl_callback_compatible((expr), _curl_write_callback2) || \ + _curl_callback_compatible((expr), _curl_write_callback3) || \ + _curl_callback_compatible((expr), _curl_write_callback4) || \ + _curl_callback_compatible((expr), _curl_write_callback5) || \ + _curl_callback_compatible((expr), _curl_write_callback6)) +typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void *); +typedef size_t (_curl_write_callback2)(const char *, size_t, size_t, + const void *); +typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE *); +typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void *); +typedef size_t (_curl_write_callback5)(const void *, size_t, size_t, + const void *); +typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE *); + +/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ +#define _curl_is_ioctl_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback4)) +typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void *); +typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void *); +typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void *); +typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void *); + +/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ +#define _curl_is_sockopt_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback2)) +typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); +typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t, + curlsocktype); + +/* evaluates to true if expr is of type curl_opensocket_callback or + "similar" */ +#define _curl_is_opensocket_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\ + _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback4)) +typedef curl_socket_t (_curl_opensocket_callback1) + (void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback2) + (void *, curlsocktype, const struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback3) + (const void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback4) + (const void *, curlsocktype, const struct curl_sockaddr *); + +/* evaluates to true if expr is of type curl_progress_callback or "similar" */ +#define _curl_is_progress_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \ + _curl_callback_compatible((expr), _curl_progress_callback1) || \ + _curl_callback_compatible((expr), _curl_progress_callback2)) +typedef int (_curl_progress_callback1)(void *, + double, double, double, double); +typedef int (_curl_progress_callback2)(const void *, + double, double, double, double); + +/* evaluates to true if expr is of type curl_debug_callback or "similar" */ +#define _curl_is_debug_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \ + _curl_callback_compatible((expr), _curl_debug_callback1) || \ + _curl_callback_compatible((expr), _curl_debug_callback2) || \ + _curl_callback_compatible((expr), _curl_debug_callback3) || \ + _curl_callback_compatible((expr), _curl_debug_callback4) || \ + _curl_callback_compatible((expr), _curl_debug_callback5) || \ + _curl_callback_compatible((expr), _curl_debug_callback6) || \ + _curl_callback_compatible((expr), _curl_debug_callback7) || \ + _curl_callback_compatible((expr), _curl_debug_callback8)) +typedef int (_curl_debug_callback1) (CURL *, + curl_infotype, char *, size_t, void *); +typedef int (_curl_debug_callback2) (CURL *, + curl_infotype, char *, size_t, const void *); +typedef int (_curl_debug_callback3) (CURL *, + curl_infotype, const char *, size_t, void *); +typedef int (_curl_debug_callback4) (CURL *, + curl_infotype, const char *, size_t, const void *); +typedef int (_curl_debug_callback5) (CURL *, + curl_infotype, unsigned char *, size_t, void *); +typedef int (_curl_debug_callback6) (CURL *, + curl_infotype, unsigned char *, size_t, const void *); +typedef int (_curl_debug_callback7) (CURL *, + curl_infotype, const unsigned char *, size_t, void *); +typedef int (_curl_debug_callback8) (CURL *, + curl_infotype, const unsigned char *, size_t, const void *); + +/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ +/* this is getting even messier... */ +#define _curl_is_ssl_ctx_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) +typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *); +typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *); +#ifdef HEADER_SSL_H +/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX + * this will of course break if we're included before OpenSSL headers... + */ +typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); +typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, + const void *); +#else +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; +#endif + +/* evaluates to true if expr is of type curl_conv_callback or "similar" */ +#define _curl_is_conv_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \ + _curl_callback_compatible((expr), _curl_conv_callback1) || \ + _curl_callback_compatible((expr), _curl_conv_callback2) || \ + _curl_callback_compatible((expr), _curl_conv_callback3) || \ + _curl_callback_compatible((expr), _curl_conv_callback4)) +typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); +typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); +typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); +typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); + +/* evaluates to true if expr is of type curl_seek_callback or "similar" */ +#define _curl_is_seek_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \ + _curl_callback_compatible((expr), _curl_seek_callback1) || \ + _curl_callback_compatible((expr), _curl_seek_callback2)) +typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); +typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); + + +#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/win_lib/lib/libcurl.a b/win_lib/lib/libcurl.a new file mode 100644 index 000000000..845b4b26c Binary files /dev/null and b/win_lib/lib/libcurl.a differ diff --git a/win_lib/lib/libcurl.dll.a b/win_lib/lib/libcurl.dll.a new file mode 100755 index 000000000..39c3a7527 Binary files /dev/null and b/win_lib/lib/libcurl.dll.a differ diff --git a/win_lib/lib/libcurl.la b/win_lib/lib/libcurl.la new file mode 100755 index 000000000..f8dd7f3a1 --- /dev/null +++ b/win_lib/lib/libcurl.la @@ -0,0 +1,41 @@ +# libcurl.la - a libtool library file +# Generated by libtool (GNU libtool) 2.4.6 Debian-2.4.6-2 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='' + +# Names of this library. +library_names='' + +# The name of the static archive. +old_library='libcurl.a' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='' + +# Libraries that this one depends upon. +dependency_libs=' -L/home/ca/Schreibtisch/supernet/crypto777/curl-7.52.1/openssl-1.1.0e/dist/lib -lssl -lcrypto -lgdi32 -lwldap32 -lws2_32' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libcurl. +current=8 +age=4 +revision=0 + +# Is this an already installed library? +installed=yes + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/home/ca/Schreibtisch/supernet/crypto777/curl-7.52.1/win_lib/lib' diff --git a/win_lib/lib/pkgconfig/libcurl.pc b/win_lib/lib/pkgconfig/libcurl.pc new file mode 100644 index 000000000..f4f22700c --- /dev/null +++ b/win_lib/lib/pkgconfig/libcurl.pc @@ -0,0 +1,39 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### + +# This should most probably benefit from getting a "Requires:" field added +# dynamically by configure. +# +prefix=/home/ca/Schreibtisch/supernet/crypto777/curl-7.52.1/win_lib +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include +supported_protocols="DICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS LDAP LDAPS POP3 POP3S RTSP SMB SMBS SMTP SMTPS TELNET TFTP" +supported_features="SSL IPv6 NTLM TLS-SRP HTTPS-proxy" + +Name: libcurl +URL: https://curl.haxx.se/ +Description: Library to transfer files with ftp, http, etc. +Version: 7.52.1 +Libs: -L${libdir} -lcurl +Libs.private: -lssl -lcrypto -lssl -lcrypto -lgdi32 -lwldap32 -lws2_32 +Cflags: -I${includedir} -DCURL_STATICLIB diff --git a/win_lib/share/aclocal/libcurl.m4 b/win_lib/share/aclocal/libcurl.m4 new file mode 100644 index 000000000..53d694d0a --- /dev/null +++ b/win_lib/share/aclocal/libcurl.m4 @@ -0,0 +1,272 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 2006, David Shaw +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### +# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION], +# [ACTION-IF-YES], [ACTION-IF-NO]) +# ---------------------------------------------------------- +# David Shaw May-09-2006 +# +# Checks for libcurl. DEFAULT-ACTION is the string yes or no to +# specify whether to default to --with-libcurl or --without-libcurl. +# If not supplied, DEFAULT-ACTION is yes. MINIMUM-VERSION is the +# minimum version of libcurl to accept. Pass the version as a regular +# version number like 7.10.1. If not supplied, any version is +# accepted. ACTION-IF-YES is a list of shell commands to run if +# libcurl was successfully found and passed the various tests. +# ACTION-IF-NO is a list of shell commands that are run otherwise. +# Note that using --without-libcurl does run ACTION-IF-NO. +# +# This macro #defines HAVE_LIBCURL if a working libcurl setup is +# found, and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary +# values. Other useful defines are LIBCURL_FEATURE_xxx where xxx are +# the various features supported by libcurl, and LIBCURL_PROTOCOL_yyy +# where yyy are the various protocols supported by libcurl. Both xxx +# and yyy are capitalized. See the list of AH_TEMPLATEs at the top of +# the macro for the complete list of possible defines. Shell +# variables $libcurl_feature_xxx and $libcurl_protocol_yyy are also +# defined to 'yes' for those features and protocols that were found. +# Note that xxx and yyy keep the same capitalization as in the +# curl-config list (e.g. it's "HTTP" and not "http"). +# +# Users may override the detected values by doing something like: +# LIBCURL="-lcurl" LIBCURL_CPPFLAGS="-I/usr/myinclude" ./configure +# +# For the sake of sanity, this macro assumes that any libcurl that is +# found is after version 7.7.2, the first version that included the +# curl-config script. Note that it is very important for people +# packaging binary versions of libcurl to include this script! +# Without curl-config, we can only guess what protocols are available, +# or use curl_version_info to figure it out at runtime. + +AC_DEFUN([LIBCURL_CHECK_CONFIG], +[ + AH_TEMPLATE([LIBCURL_FEATURE_SSL],[Defined if libcurl supports SSL]) + AH_TEMPLATE([LIBCURL_FEATURE_KRB4],[Defined if libcurl supports KRB4]) + AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6]) + AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz]) + AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS]) + AH_TEMPLATE([LIBCURL_FEATURE_IDN],[Defined if libcurl supports IDN]) + AH_TEMPLATE([LIBCURL_FEATURE_SSPI],[Defined if libcurl supports SSPI]) + AH_TEMPLATE([LIBCURL_FEATURE_NTLM],[Defined if libcurl supports NTLM]) + + AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS]) + AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS]) + AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE]) + AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET]) + AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT]) + AH_TEMPLATE([LIBCURL_PROTOCOL_TFTP],[Defined if libcurl supports TFTP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_RTSP],[Defined if libcurl supports RTSP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_POP3],[Defined if libcurl supports POP3]) + AH_TEMPLATE([LIBCURL_PROTOCOL_IMAP],[Defined if libcurl supports IMAP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_SMTP],[Defined if libcurl supports SMTP]) + + AC_ARG_WITH(libcurl, + AS_HELP_STRING([--with-libcurl=PREFIX],[look for the curl library in PREFIX/lib and headers in PREFIX/include]), + [_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])]) + + if test "$_libcurl_with" != "no" ; then + + AC_PROG_AWK + + _libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'" + + _libcurl_try_link=yes + + if test -d "$_libcurl_with" ; then + LIBCURL_CPPFLAGS="-I$withval/include" + _libcurl_ldflags="-L$withval/lib" + AC_PATH_PROG([_libcurl_config],[curl-config],[], + ["$withval/bin"]) + else + AC_PATH_PROG([_libcurl_config],[curl-config],[],[$PATH]) + fi + + if test x$_libcurl_config != "x" ; then + AC_CACHE_CHECK([for the version of libcurl], + [libcurl_cv_lib_curl_version], + [libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $[]2}'`]) + + _libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse` + _libcurl_wanted=`echo ifelse([$2],,[0],[$2]) | $_libcurl_version_parse` + + if test $_libcurl_wanted -gt 0 ; then + AC_CACHE_CHECK([for libcurl >= version $2], + [libcurl_cv_lib_version_ok], + [ + if test $_libcurl_version -ge $_libcurl_wanted ; then + libcurl_cv_lib_version_ok=yes + else + libcurl_cv_lib_version_ok=no + fi + ]) + fi + + if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then + if test x"$LIBCURL_CPPFLAGS" = "x" ; then + LIBCURL_CPPFLAGS=`$_libcurl_config --cflags` + fi + if test x"$LIBCURL" = "x" ; then + LIBCURL=`$_libcurl_config --libs` + + # This is so silly, but Apple actually has a bug in their + # curl-config script. Fixed in Tiger, but there are still + # lots of Panther installs around. + case "${host}" in + powerpc-apple-darwin7*) + LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'` + ;; + esac + fi + + # All curl-config scripts support --feature + _libcurl_features=`$_libcurl_config --feature` + + # Is it modern enough to have --protocols? (7.12.4) + if test $_libcurl_version -ge 461828 ; then + _libcurl_protocols=`$_libcurl_config --protocols` + fi + else + _libcurl_try_link=no + fi + + unset _libcurl_wanted + fi + + if test $_libcurl_try_link = yes ; then + + # we didn't find curl-config, so let's see if the user-supplied + # link line (or failing that, "-lcurl") is enough. + LIBCURL=${LIBCURL-"$_libcurl_ldflags -lcurl"} + + AC_CACHE_CHECK([whether libcurl is usable], + [libcurl_cv_lib_curl_usable], + [ + _libcurl_save_cppflags=$CPPFLAGS + CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS" + _libcurl_save_libs=$LIBS + LIBS="$LIBCURL $LIBS" + + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]],[[ +/* Try and use a few common options to force a failure if we are + missing symbols or can't link. */ +int x; +curl_easy_setopt(NULL,CURLOPT_URL,NULL); +x=CURL_ERROR_SIZE; +x=CURLOPT_WRITEFUNCTION; +x=CURLOPT_WRITEDATA; +x=CURLOPT_ERRORBUFFER; +x=CURLOPT_STDERR; +x=CURLOPT_VERBOSE; +if (x) {;} +]])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no) + + CPPFLAGS=$_libcurl_save_cppflags + LIBS=$_libcurl_save_libs + unset _libcurl_save_cppflags + unset _libcurl_save_libs + ]) + + if test $libcurl_cv_lib_curl_usable = yes ; then + + # Does curl_free() exist in this version of libcurl? + # If not, fake it with free() + + _libcurl_save_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS" + _libcurl_save_libs=$LIBS + LIBS="$LIBS $LIBCURL" + + AC_CHECK_FUNC(curl_free,, + AC_DEFINE(curl_free,free, + [Define curl_free() as free() if our version of curl lacks curl_free.])) + + CPPFLAGS=$_libcurl_save_cppflags + LIBS=$_libcurl_save_libs + unset _libcurl_save_cppflags + unset _libcurl_save_libs + + AC_DEFINE(HAVE_LIBCURL,1, + [Define to 1 if you have a functional curl library.]) + AC_SUBST(LIBCURL_CPPFLAGS) + AC_SUBST(LIBCURL) + + for _libcurl_feature in $_libcurl_features ; do + AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1]) + eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes + done + + if test "x$_libcurl_protocols" = "x" ; then + + # We don't have --protocols, so just assume that all + # protocols are available + _libcurl_protocols="HTTP FTP FILE TELNET LDAP DICT TFTP" + + if test x$libcurl_feature_SSL = xyes ; then + _libcurl_protocols="$_libcurl_protocols HTTPS" + + # FTPS wasn't standards-compliant until version + # 7.11.0 (0x070b00 == 461568) + if test $_libcurl_version -ge 461568; then + _libcurl_protocols="$_libcurl_protocols FTPS" + fi + fi + + # RTSP, IMAP, POP3 and SMTP were added in + # 7.20.0 (0x071400 == 463872) + if test $_libcurl_version -ge 463872; then + _libcurl_protocols="$_libcurl_protocols RTSP IMAP POP3 SMTP" + fi + fi + + for _libcurl_protocol in $_libcurl_protocols ; do + AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1]) + eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes + done + else + unset LIBCURL + unset LIBCURL_CPPFLAGS + fi + fi + + unset _libcurl_try_link + unset _libcurl_version_parse + unset _libcurl_config + unset _libcurl_feature + unset _libcurl_features + unset _libcurl_protocol + unset _libcurl_protocols + unset _libcurl_version + unset _libcurl_ldflags + fi + + if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then + # This is the IF-NO path + ifelse([$4],,:,[$4]) + else + # This is the IF-YES path + ifelse([$3],,:,[$3]) + fi + + unset _libcurl_with +])dnl diff --git a/win_lib/share/man/man1/curl-config.1 b/win_lib/share/man/man1/curl-config.1 new file mode 100644 index 000000000..4c1e323c6 --- /dev/null +++ b/win_lib/share/man/man1/curl-config.1 @@ -0,0 +1,98 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. +.\" * +.\" * This software is licensed as described in the file COPYING, which +.\" * you should have received as part of this distribution. The terms +.\" * are also available at https://curl.haxx.se/docs/copyright.html. +.\" * +.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell +.\" * copies of the Software, and permit persons to whom the Software is +.\" * furnished to do so, under the terms of the COPYING file. +.\" * +.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +.\" * KIND, either express or implied. +.\" * +.\" ************************************************************************** +.\" +.TH curl-config 1 "25 Oct 2007" "Curl 7.17.1" "curl-config manual" +.SH NAME +curl-config \- Get information about a libcurl installation +.SH SYNOPSIS +.B curl-config [options] +.SH DESCRIPTION +.B curl-config +displays information about the curl and libcurl installation. +.SH OPTIONS +.IP "--ca" +Displays the built-in path to the CA cert bundle this libcurl uses. +.IP "--cc" +Displays the compiler used to build libcurl. +.IP "--cflags" +Set of compiler options (CFLAGS) to use when compiling files that use +libcurl. Currently that is only the include path to the curl include files. +.IP "--checkfor [version]" +Specify the oldest possible libcurl version string you want, and this +script will return 0 if the current installation is new enough or it +returns 1 and outputs a text saying that the current version is not new +enough. (Added in 7.15.4) +.IP "--configure" +Displays the arguments given to configure when building curl. +.IP "--feature" +Lists what particular main features the installed libcurl was built with. At +the time of writing, this list may include SSL, KRB4 or IPv6. Do not assume +any particular order. The keywords will be separated by newlines. There may be +none, one, or several keywords in the list. +.IP "--help" +Displays the available options. +.IP "--libs" +Shows the complete set of libs and other linker options you will need in order +to link your application with libcurl. +.IP "--prefix" +This is the prefix used when libcurl was installed. Libcurl is then installed +in $prefix/lib and its header files are installed in $prefix/include and so +on. The prefix is set with "configure --prefix". +.IP "--protocols" +Lists what particular protocols the installed libcurl was built to support. At +the time of writing, this list may include HTTP, HTTPS, FTP, FTPS, FILE, +TELNET, LDAP, DICT. Do not assume any particular order. The protocols will +be listed using uppercase and are separated by newlines. There may be none, +one, or several protocols in the list. (Added in 7.13.0) +.IP "--static-libs" +Shows the complete set of libs and other linker options you will need in order +to link your application with libcurl statically. (Added in 7.17.1) +.IP "--version" +Outputs version information about the installed libcurl. +.IP "--vernum" +Outputs version information about the installed libcurl, in numerical mode. +This outputs the version number, in hexadecimal, with 8 bits for each part; +major, minor, patch. So that libcurl 7.7.4 would appear as 070704 and libcurl +12.13.14 would appear as 0c0d0e... Note that the initial zero might be +omitted. (This option was broken in the 7.15.0 release.) +.SH "EXAMPLES" +What linker options do I need when I link with libcurl? + + $ curl-config --libs + +What compiler options do I need when I compile using libcurl functions? + + $ curl-config --cflags + +How do I know if libcurl was built with SSL support? + + $ curl-config --feature | grep SSL + +What's the installed libcurl version? + + $ curl-config --version + +How do I build a single file with a one-line command? + + $ `curl-config --cc --cflags` -o example example.c `curl-config --libs` +.SH "SEE ALSO" +.BR curl (1) diff --git a/win_lib/share/man/man1/curl.1 b/win_lib/share/man/man1/curl.1 new file mode 100644 index 000000000..5866ba908 --- /dev/null +++ b/win_lib/share/man/man1/curl.1 @@ -0,0 +1,2668 @@ +.\" ************************************************************************** +.\" * _ _ ____ _ +.\" * Project ___| | | | _ \| | +.\" * / __| | | | |_) | | +.\" * | (__| |_| | _ <| |___ +.\" * \___|\___/|_| \_\_____| +.\" * +.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. +.\" * +.\" * This software is licensed as described in the file COPYING, which +.\" * you should have received as part of this distribution. The terms +.\" * are also available at https://curl.haxx.se/docs/copyright.html. +.\" * +.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell +.\" * copies of the Software, and permit persons to whom the Software is +.\" * furnished to do so, under the terms of the COPYING file. +.\" * +.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +.\" * KIND, either express or implied. +.\" * +.\" ************************************************************************** +.\" +.\" DO NOT EDIT. Generated by the curl project gen.pl man page generator. +.\" +.TH curl 1 "16 Dec 2016" "Curl 7.52.0" "Curl Manual" +.SH NAME +curl \- transfer a URL +.SH SYNOPSIS +.B curl [options] +.I [URL...] +.SH DESCRIPTION +.B curl +is a tool to transfer data from or to a server, using one of the supported +protocols (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, +LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET +and TFTP). The command is designed to work without user interaction. + +curl offers a busload of useful tricks like proxy support, user +authentication, FTP upload, HTTP post, SSL connections, cookies, file transfer +resume, Metalink, and more. As you will see below, the number of features will +make your head spin! + +curl is powered by libcurl for all transfer-related features. See +\fIlibcurl(3)\fP for details. +.SH URL +The URL syntax is protocol-dependent. You'll find a detailed description in +RFC 3986. + +You can specify multiple URLs or parts of URLs by writing part sets within +braces as in: + + http://site.{one,two,three}.com + +or you can get sequences of alphanumeric series by using [] as in: + + ftp://ftp.example.com/file[1-100].txt + + ftp://ftp.example.com/file[001-100].txt (with leading zeros) + + ftp://ftp.example.com/file[a-z].txt + +Nested sequences are not supported, but you can use several ones next to each +other: + + http://example.com/archive[1996-1999]/vol[1-4]/part{a,b,c}.html + +You can specify any amount of URLs on the command line. They will be fetched +in a sequential manner in the specified order. + +You can specify a step counter for the ranges to get every Nth number or +letter: + + http://example.com/file[1-100:10].txt + + http://example.com/file[a-z:2].txt + +When using [] or {} sequences when invoked from a command line prompt, you +probably have to put the full URL within double quotes to avoid the shell from +interfering with it. This also goes for other characters treated special, like +for example '&', '?' and '*'. + +Provide the IPv6 zone index in the URL with an escaped percentage sign and the +interface name. Like in + + http://[fe80::3%25eth0]/ + +If you specify URL without protocol:// prefix, curl will attempt to guess what +protocol you might want. It will then default to HTTP but try other protocols +based on often-used host name prefixes. For example, for host names starting +with "ftp." curl will assume you want to speak FTP. + +curl will do its best to use what you pass to it as a URL. It is not trying to +validate it as a syntactically correct URL by any means but is instead +\fBvery\fP liberal with what it accepts. + +curl will attempt to re-use connections for multiple file transfers, so that +getting many files from the same server will not do multiple connects / +handshakes. This improves speed. Of course this is only done on files +specified on a single command line and cannot be used between separate curl +invokes. +.SH "PROGRESS METER" +curl normally displays a progress meter during operations, indicating the +amount of transferred data, transfer speeds and estimated time left, etc. The +progress meter displays number of bytes and the speeds are in bytes per +second. The suffixes (k, M, G, T, P) are 1024 based. For example 1k is 1024 +bytes. 1M is 1048576 bytes. + +curl displays this data to the terminal by default, so if you invoke curl to +do an operation and it is about to write data to the terminal, it +\fIdisables\fP the progress meter as otherwise it would mess up the output +mixing progress meter and response data. + +If you want a progress meter for HTTP POST or PUT requests, you need to +redirect the response output to a file, using shell redirect (>), -o [file] or +similar. + +It is not the same case for FTP upload as that operation does not spit out +any response data to the terminal. + +If you prefer a progress "bar" instead of the regular meter, \fI-#, --progress-bar\fP is +your friend. +.SH OPTIONS +Options start with one or two dashes. Many of the options require an +additional value next to them. + +The short "single-dash" form of the options, -d for example, may be used with +or without a space between it and its value, although a space is a recommended +separator. The long "double-dash" form, \fI-d, --data\fP for example, requires a space +between it and its value. + +Short version options that don't need any additional values can be used +immediately next to each other, like for example you can specify all the +options -O, -L and -v at once as -OLv. + +In general, all boolean options are enabled with --\fBoption\fP and yet again +disabled with --\fBno-\fPoption. That is, you use the exact same option name +but prefix it with "no-". However, in this list we mostly only list and show +the --option version of them. (This concept with --no options was added in +7.19.0. Previously most options were toggled on/off on repeated use of the +same command line option.) +.IP "--anyauth" +(HTTP) Tells curl to figure out authentication method by itself, and use the most +secure one the remote site claims to support. This is done by first doing a +request and checking the response-headers, thus possibly inducing an extra +network round-trip. This is used instead of setting a specific authentication +method, which you can do with \fI--basic\fP, \fI--digest\fP, \fI--ntlm\fP, and \fI--negotiate\fP. + +Using \fI--anyauth\fP is not recommended if you do uploads from stdin, since it may +require data to be sent twice and then the client must be able to rewind. If +the need should arise when uploading from stdin, the upload operation will +fail. + +Used together with \fI-u, --user\fP. + +See also \fI--proxy-anyauth\fP and \fI--basic\fP and \fI--digest\fP. +.IP "-a, --append" +(FTP SFTP) When used in an upload, this makes curl append to the target file instead of +overwriting it. If the remote file doesn't exist, it will be created. Note +that this flag is ignored by some SFTP servers (including OpenSSH). +.IP "--basic" +(HTTP) Tells curl to use HTTP Basic authentication with the remote host. This is the +default and this option is usually pointless, unless you use it to override a +previously set option that sets a different authentication method (such as +\fI--ntlm\fP, \fI--digest\fP, or \fI--negotiate\fP). + +Used together with \fI-u, --user\fP. + +See also \fI--proxy-basic\fP. +.IP "--cacert " +(TLS) Tells curl to use the specified certificate file to verify the peer. The file +may contain multiple CA certificates. The certificate(s) must be in PEM +format. Normally curl is built to use a default file for this, so this option +is typically used to alter that default file. + +curl recognizes the environment variable named 'CURL_CA_BUNDLE' if it is +set, and uses the given path as a path to a CA cert bundle. This option +overrides that variable. + +The windows version of curl will automatically look for a CA certs file named +\'curl-ca-bundle.crt\', either in the same directory as curl.exe, or in the +Current Working Directory, or in any folder along your PATH. + +If curl is built against the NSS SSL library, the NSS PEM PKCS#11 module +(libnsspem.so) needs to be available for this option to work properly. + +(iOS and macOS only) If curl is built against Secure Transport, then this +option is supported for backward compatibility with other SSL engines, but it +should not be set. If the option is not set, then curl will use the +certificates in the system and user Keychain to verify the peer, which is the +preferred method of verifying the peer's certificate chain. + +If this option is used several times, the last one will be used. +.IP "--capath " +(TLS) Tells curl to use the specified certificate directory to verify the +peer. Multiple paths can be provided by separating them with ":" (e.g. +\&"path1:path2:path3"). The certificates must be in PEM format, and if curl is +built against OpenSSL, the directory must have been processed using the +c_rehash utility supplied with OpenSSL. Using \fI--capath\fP can allow +OpenSSL-powered curl to make SSL-connections much more efficiently than using +\fI--cacert\fP if the --cacert file contains many CA certificates. + +If this option is set, the default capath value will be ignored, and if it is +used several times, the last one will be used. +.IP "--cert-status" +(TLS) Tells curl to verify the status of the server certificate by using the +Certificate Status Request (aka. OCSP stapling) TLS extension. + +If this option is enabled and the server sends an invalid (e.g. expired) +response, if the response suggests that the server certificate has been revoked, +or no response at all is received, the verification fails. + +This is currently only implemented in the OpenSSL, GnuTLS and NSS backends. + +Added in 7.41.0. +.IP "--cert-type " +(TLS) Tells curl what certificate type the provided certificate is in. PEM, DER and +ENG are recognized types. If not specified, PEM is assumed. + +If this option is used several times, the last one will be used. + +See also \fI-E, --cert\fP and \fI--key\fP and \fI--key-type\fP. +.IP "-E, --cert " +(TLS) Tells curl to use the specified client certificate file when getting a file +with HTTPS, FTPS or another SSL-based protocol. The certificate must be in +PKCS#12 format if using Secure Transport, or PEM format if using any other +engine. If the optional password isn't specified, it will be queried for on +the terminal. Note that this option assumes a \&"certificate" file that is the +private key and the client certificate concatenated! See \fI-E, --cert\fP and \fI--key\fP to +specify them independently. + +If curl is built against the NSS SSL library then this option can tell +curl the nickname of the certificate to use within the NSS database defined +by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the +NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be +loaded. If you want to use a file from the current directory, please precede +it with "./" prefix, in order to avoid confusion with a nickname. If the +nickname contains ":", it needs to be preceded by "\\" so that it is not +recognized as password delimiter. If the nickname contains "\\", it needs to +be escaped as "\\\\" so that it is not recognized as an escape character. + +(iOS and macOS only) If curl is built against Secure Transport, then the +certificate string can either be the name of a certificate/private key in the +system or user keychain, or the path to a PKCS#12-encoded certificate and +private key. If you want to use a file from the current directory, please +precede it with "./" prefix, in order to avoid confusion with a nickname. + +If this option is used several times, the last one will be used. + +See also \fI--cert-type\fP and \fI--key\fP and \fI--key-type\fP. +.IP "--ciphers " +(TLS) Specifies which ciphers to use in the connection. The list of ciphers must +specify valid ciphers. Read up on SSL cipher list details on this URL: + + https://www.openssl.org/docs/apps/ciphers.html + +NSS ciphers are done differently than OpenSSL and GnuTLS. The full list of NSS +ciphers is in the NSSCipherSuite entry at this URL: + + https://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html#Directives + +If this option is used several times, the last one will be used. +.IP "--compressed" +(HTTP) Request a compressed response using one of the algorithms curl supports, and +save the uncompressed document. If this option is used and the server sends +an unsupported encoding, curl will report an error. +.IP "-K, --config " +Specify which config file to read curl arguments from. The config file is a +text file in which command line arguments can be written which then will be +used as if they were written on the actual command line. + +Options and their parameters must be specified on the same config file line, +separated by whitespace, colon, or the equals sign. Long option names can +optionally be given in the config file without the initial double dashes and +if so, the colon or equals characters can be used as separators. If the option +is specified with one or two dashes, there can be no colon or equals character +between the option and its parameter. + +If the parameter is to contain whitespace, the parameter must be enclosed +within quotes. Within double quotes, the following escape sequences are +available: \\\\, \\", \\t, \\n, \\r and \\v. A backslash preceding any other +letter is ignored. If the first column of a config line is a '#' character, +the rest of the line will be treated as a comment. Only write one option per +physical line in the config file. + +Specify the filename to \fI-K, --config\fP as '-' to make curl read the file from stdin. + +Note that to be able to specify a URL in the config file, you need to specify +it using the \fI--url\fP option, and not by simply writing the URL on its own +line. So, it could look similar to this: + +url = "https://curl.haxx.se/docs/" + +When curl is invoked, it always (unless \fI-q, --disable\fP is used) checks for a +default config file and uses it if found. The default config file is checked +for in the following places in this order: + +1) curl tries to find the "home dir": It first checks for the CURL_HOME and +then the HOME environment variables. Failing that, it uses getpwuid() on +Unix-like systems (which returns the home dir given the current user in your +system). On Windows, it then checks for the APPDATA variable, or as a last +resort the '%USERPROFILE%\\Application Data'. + +2) On windows, if there is no _curlrc file in the home dir, it checks for one +in the same dir the curl executable is placed. On Unix-like systems, it will +simply try to load .curlrc from the determined home dir. + +.nf +# --- Example file --- +# this is a comment +url = "example.com" +output = "curlhere.html" +user-agent = "superagent/1.0" + +# and fetch another URL too +url = "example.com/docs/manpage.html" +-O +referer = "http://nowhereatall.example.com/" +# --- End of example file --- +.fi + +This option can be used multiple times to load multiple config files. +.IP "--connect-timeout " +Maximum time in seconds that you allow curl's connection to take. This only +limits the connection phase, so if curl connects within the given period it +will continue - if not it will exit. Since version 7.32.0, this option +accepts decimal values. + +If this option is used several times, the last one will be used. + +See also \fI-m, --max-time\fP. +.IP "--connect-to " + +For a request to the given HOST:PORT pair, connect to +CONNECT-TO-HOST:CONNECT-TO-PORT instead. This option is suitable to direct +requests at a specific server, e.g. at a specific cluster node in a cluster of +servers. This option is only used to establish the network connection. It +does NOT affect the hostname/port that is used for TLS/SSL (e.g. SNI, +certificate verification) or for the application protocols. "host" and "port" +may be the empty string, meaning "any host/port". "connect-to-host" and +"connect-to-port" may also be the empty string, meaning "use the request's +original host/port". + +This option can be used many times to add many connect rules. + +See also \fI--resolve\fP and \fI-H, --header\fP. Added in 7.49.0. +.IP "-C, --continue-at " +Continue/Resume a previous file transfer at the given offset. The given offset +is the exact number of bytes that will be skipped, counting from the beginning +of the source file before it is transferred to the destination. If used with +uploads, the FTP server command SIZE will not be used by curl. + +Use "-C -" to tell curl to automatically find out where/how to resume the +transfer. It then uses the given output/input files to figure that out. + +If this option is used several times, the last one will be used. + +See also \fI-r, --range\fP. +.IP "-c, --cookie-jar " +(HTTP) Specify to which file you want curl to write all cookies after a completed +operation. Curl writes all cookies from its in-memory cookie storage to the +given file at the end of operations. If no cookies are known, no data will be +written. The file will be written using the Netscape cookie file format. If +you set the file name to a single dash, "-", the cookies will be written to +stdout. + +This command line option will activate the cookie engine that makes curl +record and use cookies. Another way to activate it is to use the \fI-b, --cookie\fP +option. + +If the cookie jar can't be created or written to, the whole curl operation +won't fail or even report an error clearly. Using \fI-v, --verbose\fP will get a warning +displayed, but that is the only visible feedback you get about this possibly +lethal situation. + +If this option is used several times, the last specified file name will be +used. +.IP "-b, --cookie " +(HTTP) Pass the data to the HTTP server in the Cookie header. It is supposedly +the data previously received from the server in a "Set-Cookie:" line. The +data should be in the format "NAME1=VALUE1; NAME2=VALUE2". + +If no '=' symbol is used in the argument, it is instead treated as a filename +to read previously stored cookie from. This option also activates the cookie +engine which will make curl record incoming cookies, which may be handy if +you're using this in combination with the \fI-L, --location\fP option or do multiple URL +transfers on the same invoke. + +The file format of the file to read cookies from should be plain HTTP headers +(Set-Cookie style) or the Netscape/Mozilla cookie file format. + +The file specified with \fI-b, --cookie\fP is only used as input. No cookies will be +written to the file. To store cookies, use the \fI-c, --cookie-jar\fP option. + +Exercise caution if you are using this option and multiple transfers may +occur. If you use the NAME1=VALUE1; format, or in a file use the Set-Cookie +format and don't specify a domain, then the cookie is sent for any domain +(even after redirects are followed) and cannot be modified by a server-set +cookie. If the cookie engine is enabled and a server sets a cookie of the same +name then both will be sent on a future transfer to that server, likely not +what you intended. To address these issues set a domain in Set-Cookie (doing +that will include sub domains) or use the Netscape format. + +If this option is used several times, the last one will be used. + +Users very often want to both read cookies from a file and write updated +cookies back to a file, so using both \fI-b, --cookie\fP and \fI-c, --cookie-jar\fP in the same +command line is common. +.IP "--create-dirs" +When used in conjunction with the \fI-o, --output\fP option, curl will create the +necessary local directory hierarchy as needed. This option creates the dirs +mentioned with the \fI-o, --output\fP option, nothing else. If the --output file name +uses no dir or if the dirs it mentions already exist, no dir will be created. + +To create remote directories when using FTP or SFTP, try \fI--ftp-create-dirs\fP. +.IP "--crlf" +(FTP SMTP) Convert LF to CRLF in upload. Useful for MVS (OS/390). + +(SMTP added in 7.40.0) +.IP "--crlfile " +(TLS) Provide a file using PEM format with a Certificate Revocation List that may +specify peer certificates that are to be considered revoked. + +If this option is used several times, the last one will be used. + +Added in 7.19.7. +.IP "--data-ascii " +(HTTP) This is just an alias for \fI-d, --data\fP. +.IP "--data-binary " +(HTTP) This posts data exactly as specified with no extra processing whatsoever. + +If you start the data with the letter @, the rest should be a filename. Data +is posted in a similar manner as \fI-d, --data\fP does, except that newlines and +carriage returns are preserved and conversions are never done. + +If this option is used several times, the ones following the first will append +data as described in \fI-d, --data\fP. +.IP "--data-raw " +(HTTP) This posts data similarly to \fI-d, --data\fP but without the special +interpretation of the @ character. + +See also \fI-d, --data\fP. Added in 7.43.0. +.IP "--data-urlencode " +(HTTP) This posts data, similar to the other \fI-d, --data\fP options with the exception +that this performs URL-encoding. + +To be CGI-compliant, the part should begin with a \fIname\fP followed +by a separator and a content specification. The part can be passed to +curl using one of the following syntaxes: +.RS +.IP "content" +This will make curl URL-encode the content and pass that on. Just be careful +so that the content doesn't contain any = or @ symbols, as that will then make +the syntax match one of the other cases below! +.IP "=content" +This will make curl URL-encode the content and pass that on. The preceding = +symbol is not included in the data. +.IP "name=content" +This will make curl URL-encode the content part and pass that on. Note that +the name part is expected to be URL-encoded already. +.IP "@filename" +This will make curl load data from the given file (including any newlines), +URL-encode that data and pass it on in the POST. +.IP "name@filename" +This will make curl load data from the given file (including any newlines), +URL-encode that data and pass it on in the POST. The name part gets an equal +sign appended, resulting in \fIname=urlencoded-file-content\fP. Note that the +name is expected to be URL-encoded already. +.RE + +See also \fI-d, --data\fP and \fI--data-raw\fP. Added in 7.18.0. +.IP "-d, --data " +(HTTP) Sends the specified data in a POST request to the HTTP server, in the same way +that a browser does when a user has filled in an HTML form and presses the +submit button. This will cause curl to pass the data to the server using the +content-type application/x-www-form-urlencoded. Compare to \fI-F, --form\fP. + +\fI--data-raw\fP is almost the same but does not have a special interpretation of +the @ character. To post data purely binary, you should instead use the +\fI--data-binary\fP option. To URL-encode the value of a form field you may use +\fI--data-urlencode\fP. + +If any of these options is used more than once on the same command line, the +data pieces specified will be merged together with a separating +&-symbol. Thus, using '-d name=daniel -d skill=lousy' would generate a post +chunk that looks like \&'name=daniel&skill=lousy'. + +If you start the data with the letter @, the rest should be a file name to +read the data from, or - if you want curl to read the data from +stdin. Multiple files can also be specified. Posting data from a file named +'foobar' would thus be done with \fI-d, --data\fP @foobar. When --data is told to read +from a file like that, carriage returns and newlines will be stripped out. If +you don't want the @ character to have a special interpretation use \fI--data-raw\fP +instead. + +See also \fI--data-binary\fP and \fI--data-urlencode\fP and \fI--data-raw\fP. This option overrides \fI-F, --form\fP and \fI-I, --head\fP and \fI--upload\fP. +.IP "--delegation " +(GSS/kerberos) Set LEVEL to tell the server what it is allowed to delegate when it +comes to user credentials. +.RS +.IP "none" +Don't allow any delegation. +.IP "policy" +Delegates if and only if the OK-AS-DELEGATE flag is set in the Kerberos +service ticket, which is a matter of realm policy. +.IP "always" +Unconditionally allow the server to delegate. +.RE +.IP "--digest" +(HTTP) Enables HTTP Digest authentication. This is an authentication scheme that +prevents the password from being sent over the wire in clear text. Use this in +combination with the normal \fI-u, --user\fP option to set user name and password. + +If this option is used several times, only the first one is used. + +See also \fI-u, --user\fP and \fI--proxy-digest\fP and \fI--anyauth\fP. This option overrides \fI--basic\fP and \fI--ntlm\fP and \fI--negotiate\fP. +.IP "--disable-eprt" +(FTP) Tell curl to disable the use of the EPRT and LPRT commands when doing active +FTP transfers. Curl will normally always first attempt to use EPRT, then LPRT +before using PORT, but with this option, it will use PORT right away. EPRT and +LPRT are extensions to the original FTP protocol, and may not work on all +servers, but they enable more functionality in a better way than the +traditional PORT command. + +--eprt can be used to explicitly enable EPRT again and --no-eprt is an alias +for \fI--disable-eprt\fP. + +If the server is accessed using IPv6, this option will have no effect as EPRT +is necessary then. + +Disabling EPRT only changes the active behavior. If you want to switch to +passive mode you need to not use \fI-P, --ftp-port\fP or force it with \fI--ftp-pasv\fP. +.IP "--disable-epsv" +(FTP) (FTP) Tell curl to disable the use of the EPSV command when doing passive FTP +transfers. Curl will normally always first attempt to use EPSV before PASV, +but with this option, it will not try using EPSV. + +--epsv can be used to explicitly enable EPSV again and --no-epsv is an alias +for \fI--disable-epsv\fP. + +If the server is an IPv6 host, this option will have no effect as EPSV is +necessary then. + +Disabling EPSV only changes the passive behavior. If you want to switch to +active mode you need to use \fI-P, --ftp-port\fP. +.IP "-q, --disable" +If used as the first parameter on the command line, the \fIcurlrc\fP config +file will not be read and used. See the \fI-K, --config\fP for details on the default +config file search path. +.IP "--dns-interface " +(DNS) Tell curl to send outgoing DNS requests through . This option is a +counterpart to \fI--interface\fP (which does not affect DNS). The supplied string +must be an interface name (not an address). + +See also \fI--dns-ipv4-addr\fP and \fI--dns-ipv6-addr\fP. \fI--dns-interface\fP requires that the underlying libcurl was built to support c-ares. Added in 7.33.0. +.IP "--dns-ipv4-addr
" +(DNS) Tell curl to bind to when making IPv4 DNS requests, so that +the DNS requests originate from this address. The argument should be a +single IPv4 address. + +See also \fI--dns-interface\fP and \fI--dns-ipv6-addr\fP. \fI--dns-ipv4-addr\fP requires that the underlying libcurl was built to support c-ares. Added in 7.33.0. +.IP "--dns-ipv6-addr
" +(DNS) Tell curl to bind to when making IPv6 DNS requests, so that +the DNS requests originate from this address. The argument should be a +single IPv6 address. + +See also \fI--dns-interface\fP and \fI--dns-ipv4-addr\fP. \fI--dns-ipv6-addr\fP requires that the underlying libcurl was built to support c-ares. Added in 7.33.0. +.IP "--dns-servers " +Set the list of DNS servers to be used instead of the system default. +The list of IP addresses should be separated with commas. Port numbers +may also optionally be given as \fI:\fP after each IP +address. + +\fI--dns-servers\fP requires that the underlying libcurl was built to support c-ares. Added in 7.33.0. +.IP "-D, --dump-header " +(HTTP FTP) Write the received protocol headers to the specified file. + +This option is handy to use when you want to store the headers that an HTTP +site sends to you. Cookies from the headers could then be read in a second +curl invocation by using the \fI-b, --cookie\fP option! The \fI-c, --cookie-jar\fP option is a +better way to store cookies. + +When used in FTP, the FTP server response lines are considered being "headers" +and thus are saved there. + +If this option is used several times, the last one will be used. + +See also \fI-o, --output\fP. +.IP "--egd-file " +(TLS) Specify the path name to the Entropy Gathering Daemon socket. The socket is +used to seed the random engine for SSL connections. + +See also \fI--random-file\fP. +.IP "--engine " +(TLS) Select the OpenSSL crypto engine to use for cipher operations. Use \fI--engine\fP +list to print a list of build-time supported engines. Note that not all (or +none) of the engines may be available at run-time. +.IP "--environment" +Sets a range of environment variables, using the names the \fI-w, --write-out\fP option +supports, to allow easier extraction of useful information after having run +curl. + +\fI--environment\fP requires that the underlying libcurl was built to support RISC OS. +.IP "--expect100-timeout " +(HTTP) Maximum time in seconds that you allow curl to wait for a 100-continue +response when curl emits an Expects: 100-continue header in its request. By +default curl will wait one second. This option accepts decimal values! When +curl stops waiting, it will continue as if the response has been received. + +See also \fI--connect-timeout\fP. Added in 7.47.0. +.IP "--fail-early" +Fail and exit on first detected error. + +When curl is used to do multiple transfers on the command line, it will +attempt to operate on each given URL, one by one. By default, it will ignore +errors if there are more URLs given and the last URL's success will determine +the error code curl returns. So early failures will be "hidden" by subsequent +successful transfers. + +Using this option, curl will instead return an error on the first transfers +that fails, independent on the amount of more URLs that are given on the +command line. This way, no transfer failures go undetected by scripts and +similar. + +This option will apply for all given URLs even if you use \fI-:, --next\fP. + +Added in 7.52.0. +.IP "-f, --fail" +(HTTP) Fail silently (no output at all) on server errors. This is mostly done to +better enable scripts etc to better deal with failed attempts. In normal cases +when an HTTP server fails to deliver a document, it returns an HTML document +stating so (which often also describes why and more). This flag will prevent +curl from outputting that and return error 22. + +This method is not fail-safe and there are occasions where non-successful +response codes will slip through, especially when authentication is involved +(response codes 401 and 407). +.IP "--false-start" +(TLS) Tells curl to use false start during the TLS handshake. False start is a mode +where a TLS client will start sending application data before verifying the +server's Finished message, thus saving a round trip when performing a full +handshake. + +This is currently only implemented in the NSS and Secure Transport (on iOS 7.0 +or later, or OS X 10.9 or later) backends. + +Added in 7.42.0. +.IP "--form-string " +(HTTP) Similar to \fI-F, --form\fP except that the value string for the named parameter is used +literally. Leading \&'@' and \&'<' characters, and the \&';type=' string in +the value have no special meaning. Use this in preference to \fI-F, --form\fP if +there's any possibility that the string value may accidentally trigger the +\&'@' or \&'<' features of \fI-F, --form\fP. + +See also \fI-F, --form\fP. +.IP "-F, --form " +(HTTP) This lets curl emulate a filled-in form in which a user has pressed the submit +button. This causes curl to POST data using the Content-Type +multipart/form-data according to RFC 2388. This enables uploading of binary +files etc. To force the 'content' part to be a file, prefix the file name with +an @ sign. To just get the content part from a file, prefix the file name with +the symbol <. The difference between @ and < is then that @ makes a file get +attached in the post as a file upload, while the < makes a text field and just +get the contents for that text field from a file. + +Example: to send an image to a server, where \&'profile' is the name of the +form-field to which portrait.jpg will be the input: + + curl -F profile=@portrait.jpg https://example.com/upload.cgi + +To read content from stdin instead of a file, use - as the filename. This goes +for both @ and < constructs. Unfortunately it does not support reading the +file from a named pipe or similar, as it needs the full size before the +transfer starts. + +You can also tell curl what Content-Type to use by using 'type=', in a manner +similar to: + + curl -F "web=@index.html;type=text/html" example.com + +or + + curl -F "name=daniel;type=text/foo" example.com + +You can also explicitly change the name field of a file upload part by setting +filename=, like this: + + curl -F "file=@localfile;filename=nameinpost" example.com + +If filename/path contains ',' or ';', it must be quoted by double-quotes like: + + curl -F "file=@\\"localfile\\";filename=\\"nameinpost\\"" example.com + +or + + curl -F 'file=@"localfile";filename="nameinpost"' example.com + +Note that if a filename/path is quoted by double-quotes, any double-quote +or backslash within the filename must be escaped by backslash. + +See further examples and details in the MANUAL. + +This option can be used multiple times. + +This option overrides \fI-d, --data\fP and \fI-I, --head\fP and \fI--upload\fP. +.IP "--ftp-account " +(FTP) When an FTP server asks for "account data" after user name and password has +been provided, this data is sent off using the ACCT command. + +If this option is used several times, the last one will be used. + +Added in 7.13.0. +.IP "--ftp-alternative-to-user " +(FTP) If authenticating with the USER and PASS commands fails, send this command. +When connecting to Tumbleweed's Secure Transport server over FTPS using a +client certificate, using "SITE AUTH" will tell the server to retrieve the +username from the certificate. + +Added in 7.15.5. +.IP "--ftp-create-dirs" +(FTP SFTP) When an FTP or SFTP URL/operation uses a path that doesn't currently exist on +the server, the standard behavior of curl is to fail. Using this option, curl +will instead attempt to create missing directories. + +See also \fI--create-dirs\fP. +.IP "--ftp-method " +(FTP) Control what method curl should use to reach a file on an FTP(S) +server. The method argument should be one of the following alternatives: +.RS +.IP multicwd +curl does a single CWD operation for each path part in the given URL. For deep +hierarchies this means very many commands. This is how RFC 1738 says it should +be done. This is the default but the slowest behavior. +.IP nocwd +curl does no CWD at all. curl will do SIZE, RETR, STOR etc and give a full +path to the server for all these commands. This is the fastest behavior. +.IP singlecwd +curl does one CWD with the full target directory and then operates on the file +\&"normally" (like in the multicwd case). This is somewhat more standards +compliant than 'nocwd' but without the full penalty of 'multicwd'. +.RE + +Added in 7.15.1. +.IP "--ftp-pasv" +(FTP) Use passive mode for the data connection. Passive is the internal default +behavior, but using this option can be used to override a previous \fI-P, --ftp-port\fP +option. + +If this option is used several times, only the first one is used. Undoing an +enforced passive really isn't doable but you must then instead enforce the +correct \fI-P, --ftp-port\fP again. + +Passive mode means that curl will try the EPSV command first and then PASV, +unless \fI--disable-epsv\fP is used. + +See also \fI--disable-epsv\fP. Added in 7.11.0. +.IP "-P, --ftp-port
" +(FTP) Reverses the default initiator/listener roles when connecting with FTP. This +option makes curl use active mode. curl then tells the server to connect back +to the client's specified address and port, while passive mode asks the server +to setup an IP address and port for it to connect to.
should be one +of: +.RS +.IP interface +i.e "eth0" to specify which interface's IP address you want to use (Unix only) +.IP "IP address" +i.e "192.168.10.1" to specify the exact IP address +.IP "host name" +i.e "my.host.domain" to specify the machine +.IP "-" +make curl pick the same IP address that is already used for the control +connection +.RE + +If this option is used several times, the last one will be used. Disable the +use of PORT with \fI--ftp-pasv\fP. Disable the attempt to use the EPRT command +instead of PORT by using \fI--disable-eprt\fP. EPRT is really PORT++. + +Since 7.19.5, you can append \&":[start]-[end]\&" to the right of the address, +to tell curl what TCP port range to use. That means you specify a port range, +from a lower to a higher number. A single number works as well, but do note +that it increases the risk of failure since the port may not be available. + +See also \fI--ftp-pasv\fP and \fI--disable-eprt\fP. +.IP "--ftp-pret" +(FTP) Tell curl to send a PRET command before PASV (and EPSV). Certain FTP servers, +mainly drftpd, require this non-standard command for directory listings as +well as up and downloads in PASV mode. + +Added in 7.20.0. +.IP "--ftp-skip-pasv-ip" +(FTP) Tell curl to not use the IP address the server suggests in its response +to curl's PASV command when curl connects the data connection. Instead curl +will re-use the same IP address it already uses for the control +connection. + +This option has no effect if PORT, EPRT or EPSV is used instead of PASV. + +See also \fI--ftp-pasv\fP. Added in 7.14.2. +.IP "--ftp-ssl-ccc-mode " +(FTP) Sets the CCC mode. The passive mode will not initiate the shutdown, but +instead wait for the server to do it, and will not reply to the shutdown from +the server. The active mode initiates the shutdown and waits for a reply from +the server. + +See also \fI--ftp-ssl-ccc\fP. Added in 7.16.2. +.IP "--ftp-ssl-ccc" +(FTP) Use CCC (Clear Command Channel) Shuts down the SSL/TLS layer after +authenticating. The rest of the control channel communication will be +unencrypted. This allows NAT routers to follow the FTP transaction. The +default mode is passive. + +See also \fI--ssl\fP and \fI--ftp-ssl-ccc-mode\fP. Added in 7.16.1. +.IP "--ftp-ssl-control" +(FTP) Require SSL/TLS for the FTP login, clear for transfer. Allows secure +authentication, but non-encrypted data transfers for efficiency. Fails the +transfer if the server doesn't support SSL/TLS. + +Added in 7.16.0. +.IP "-G, --get" +When used, this option will make all data specified with \fI-d, --data\fP, \fI--data-binary\fP +or \fI--data-urlencode\fP to be used in an HTTP GET request instead of the POST +request that otherwise would be used. The data will be appended to the URL +with a '?' separator. + +If used in combination with \fI-I, --head\fP, the POST data will instead be appended to +the URL with a HEAD request. + +If this option is used several times, only the first one is used. This is +because undoing a GET doesn't make sense, but you should then instead enforce +the alternative method you prefer. +.IP "-g, --globoff" +This option switches off the "URL globbing parser". When you set this option, +you can specify URLs that contain the letters {}[] without having them being +interpreted by curl itself. Note that these letters are not normal legal URL +contents but they should be encoded according to the URI standard. +.IP "-I, --head" +(HTTP FTP FILE) Fetch the headers only! HTTP-servers feature the command HEAD which this uses +to get nothing but the header of a document. When used on an FTP or FILE file, +curl displays the file size and last modification time only. +.IP "-H, --header
" +(HTTP) +Extra header to include in the request when sending HTTP to a server. You may +specify any number of extra headers. Note that if you should add a custom +header that has the same name as one of the internal ones curl would use, your +externally set header will be used instead of the internal one. This allows +you to make even trickier stuff than curl would normally do. You should not +replace internally set headers without knowing perfectly well what you're +doing. Remove an internal header by giving a replacement without content on +the right side of the colon, as in: -H \&"Host:". If you send the custom +header with no-value then its header must be terminated with a semicolon, such +as \-H \&"X-Custom-Header;" to send "X-Custom-Header:". + +curl will make sure that each header you add/replace is sent with the proper +end-of-line marker, you should thus \fBnot\fP add that as a part of the header +content: do not add newlines or carriage returns, they will only mess things up +for you. + +See also the \fI-A, --user-agent\fP and \fI-e, --referer\fP options. + +Starting in 7.37.0, you need \fI--proxy-header\fP to send custom headers intended +for a proxy. + +Example: + + curl -H "X-First-Name: Joe" http://example.com/ + +\fBWARNING\fP: headers set with this option will be set in all requests - even +after redirects are followed, like when told with \fI-L, --location\fP. This can lead to +the header being sent to other hosts than the original host, so sensitive +headers should be used with caution combined with following redirects. + +This option can be used multiple times to add/replace/remove multiple headers. +.IP "-h, --help" +Usage help. This lists all current command line options with a short +description. +.IP "--hostpubmd5 " +(SFTP SCP) Pass a string containing 32 hexadecimal digits. The string should +be the 128 bit MD5 checksum of the remote host's public key, curl will refuse +the connection with the host unless the md5sums match. + +Added in 7.17.1. +.IP "-0, --http1.0" +(HTTP) Tells curl to use HTTP version 1.0 instead of using its internally preferred +HTTP version. + +This option overrides \fI--http1.1\fP and \fI--http2\fP. +.IP "--http1.1" +(HTTP) Tells curl to use HTTP version 1.1. + +This option overrides \fI-0, --http1.0\fP and \fI--http2\fP. Added in 7.33.0. +.IP "--http2-prior-knowledge" +(HTTP) Tells curl to issue its non-TLS HTTP requests using HTTP/2 without HTTP/1.1 +Upgrade. It requires prior knowledge that the server supports HTTP/2 straight +away. HTTPS requests will still do HTTP/2 the standard way with negotiated +protocol version in the TLS handshake. + +\fI--http2-prior-knowledge\fP requires that the underlying libcurl was built to support HTTP/2. This option overrides \fI--http1.1\fP and \fI-0, --http1.0\fP and \fI--http2\fP. Added in 7.49.0. +.IP "--http2" +(HTTP) Tells curl to use HTTP version 2. + +See also \fI--no-alpn\fP. \fI--http2\fP requires that the underlying libcurl was built to support HTTP/2. This option overrides \fI--http1.1\fP and \fI-0, --http1.0\fP and \fI--http2-prior-knowledge\fP. Added in 7.33.0. +.IP "--ignore-content-length" +(FTP HTTP) For HTTP, Ignore the Content-Length header. This is particularly useful for +servers running Apache 1.x, which will report incorrect Content-Length for +files larger than 2 gigabytes. + +For FTP (since 7.46.0), skip the RETR command to figure out the size before +downloading a file. +.IP "-i, --include" +Include the HTTP-header in the output. The HTTP-header includes things like +server-name, date of the document, HTTP-version and more... + +See also \fI-v, --verbose\fP. +.IP "-k, --insecure" +(TLS) This option explicitly allows curl to perform "insecure" SSL connections and +transfers. All SSL connections are attempted to be made secure by using the CA +certificate bundle installed by default. This makes all connections considered +\&"insecure" fail unless \fI-k, --insecure\fP is used. + +See this online resource for further details: + https://curl.haxx.se/docs/sslcerts.html +.IP "--interface " + +Perform an operation using a specified interface. You can enter interface +name, IP address or host name. An example could look like: + + curl --interface eth0:1 https://www.example.com/ + +If this option is used several times, the last one will be used. + +See also \fI--dns-interface\fP. +.IP "-4, --ipv4" +This option tells curl to resolve names to IPv4 addresses only, and not for +example try IPv6. + +See also \fI--http1.1\fP and \fI--http2\fP. This option overrides \fI-6, --ipv6\fP. +.IP "-6, --ipv6" +This option tells curl to resolve names to IPv6 addresses only, and not for +example try IPv4. + +See also \fI--http1.1\fP and \fI--http2\fP. This option overrides \fI-6, --ipv6\fP. +.IP "-j, --junk-session-cookies" +(HTTP) When curl is told to read cookies from a given file, this option will make it +discard all "session cookies". This will basically have the same effect as if +a new session is started. Typical browsers always discard session cookies when +they're closed down. + +See also \fI-b, --cookie\fP and \fI-c, --cookie-jar\fP. +.IP "--keepalive-time " +This option sets the time a connection needs to remain idle before sending +keepalive probes and the time between individual keepalive probes. It is +currently effective on operating systems offering the TCP_KEEPIDLE and +TCP_KEEPINTVL socket options (meaning Linux, recent AIX, HP-UX and more). This +option has no effect if \fI--no-keepalive\fP is used. + +If this option is used several times, the last one will be used. If +unspecified, the option defaults to 60 seconds. + +Added in 7.18.0. +.IP "--key-type " +(TLS) Private key file type. Specify which type your \fI--key\fP provided private key +is. DER, PEM, and ENG are supported. If not specified, PEM is assumed. + +If this option is used several times, the last one will be used. +.IP "--key " +(TLS SSH) Private key file name. Allows you to provide your private key in this separate +file. For SSH, if not specified, curl tries the following candidates in order: +'~/.ssh/id_rsa', '~/.ssh/id_dsa', './id_rsa', './id_dsa'. + +If this option is used several times, the last one will be used. +.IP "--krb " +(FTP) Enable Kerberos authentication and use. The level must be entered and should +be one of 'clear', 'safe', 'confidential', or 'private'. Should you use a +level that is not one of these, 'private' will instead be used. + +If this option is used several times, the last one will be used. + +\fI--krb\fP requires that the underlying libcurl was built to support Kerberos. +.IP "--libcurl " +Append this option to any ordinary curl command line, and you will get a +libcurl-using C source code written to the file that does the equivalent +of what your command-line operation does! + +If this option is used several times, the last given file name will be +used. + +Added in 7.16.1. +.IP "--limit-rate " +Specify the maximum transfer rate you want curl to use - for both downloads +and uploads. This feature is useful if you have a limited pipe and you'd like +your transfer not to use your entire bandwidth. To make it slower than it +otherwise would be. + +The given speed is measured in bytes/second, unless a suffix is appended. +Appending 'k' or 'K' will count the number as kilobytes, 'm' or M' makes it +megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G. + +If you also use the \fI-Y, --speed-limit\fP option, that option will take precedence and +might cripple the rate-limiting slightly, to help keeping the speed-limit +logic working. + +If this option is used several times, the last one will be used. +.IP "-l, --list-only" +(FTP POP3) (FTP) +When listing an FTP directory, this switch forces a name-only view. This is +especially useful if the user wants to machine-parse the contents of an FTP +directory since the normal directory view doesn't use a standard look or +format. When used like this, the option causes a NLST command to be sent to +the server instead of LIST. + +Note: Some FTP servers list only files in their response to NLST; they do not +include sub-directories and symbolic links. + +(POP3) +When retrieving a specific email from POP3, this switch forces a LIST command +to be performed instead of RETR. This is particularly useful if the user wants +to see if a specific message id exists on the server and what size it is. + +Note: When combined with \fI-X, --request\fP, this option can be used to send an UIDL +command instead, so the user may use the email's unique identifier rather than +it's message id to make the request. + +Added in 7.21.5. +.IP "--local-port " +Set a preferred single number or range (FROM-TO) of local port numbers to use +for the connection(s). Note that port numbers by nature are a scarce resource +that will be busy at times so setting this range to something too narrow might +cause unnecessary connection setup failures. + +Added in 7.15.2. +.IP "--location-trusted" +(HTTP) Like \fI-L, --location\fP, but will allow sending the name + password to all hosts that +the site may redirect to. This may or may not introduce a security breach if +the site redirects you to a site to which you'll send your authentication info +(which is plaintext in the case of HTTP Basic authentication). + +See also \fI-u, --user\fP. +.IP "-L, --location" +(HTTP) If the server reports that the requested page has moved to a different +location (indicated with a Location: header and a 3XX response code), this +option will make curl redo the request on the new place. If used together with +\fI-i, --include\fP or \fI-I, --head\fP, headers from all requested pages will be shown. When +authentication is used, curl only sends its credentials to the initial +host. If a redirect takes curl to a different host, it won't be able to +intercept the user+password. See also \fI--location-trusted\fP on how to change +this. You can limit the amount of redirects to follow by using the +\fI--max-redirs\fP option. + +When curl follows a redirect and the request is not a plain GET (for example +POST or PUT), it will do the following request with a GET if the HTTP response +was 301, 302, or 303. If the response code was any other 3xx code, curl will +re-send the following request using the same unmodified method. + +You can tell curl to not change the non-GET request method to GET after a 30x +response by using the dedicated options for that: \fI--post301\fP, \fI--post302\fP and +\fI--post303\fP. +.IP "--login-options " +(IMAP POP3 SMTP) Specify the login options to use during server authentication. + +You can use the login options to specify protocol specific options that may +be used during authentication. At present only IMAP, POP3 and SMTP support +login options. For more information about the login options please see +RFC 2384, RFC 5092 and IETF draft draft-earhart-url-smtp-00.txt + +If this option is used several times, the last one will be used. + +Added in 7.34.0. +.IP "--mail-auth
" +(SMTP) Specify a single address. This will be used to specify the authentication +address (identity) of a submitted message that is being relayed to another +server. + +See also \fI--mail-rcpt\fP and \fI--mail-from\fP. Added in 7.25.0. +.IP "--mail-from
" +(SMTP) Specify a single address that the given mail should get sent from. + +See also \fI--mail-rcpt\fP and \fI--mail-auth\fP. Added in 7.20.0. +.IP "--mail-rcpt
" +(SMTP) Specify a single address, user name or mailing list name. Repeat this +option several times to send to multiple recipients. + +When performing a mail transfer, the recipient should specify a valid email +address to send the mail to. + +When performing an address verification (VRFY command), the recipient should be +specified as the user name or user name and domain (as per Section 3.5 of +RFC5321). (Added in 7.34.0) + +When performing a mailing list expand (EXPN command), the recipient should be +specified using the mailing list name, such as "Friends" or "London-Office". +(Added in 7.34.0) + +Added in 7.20.0. +.IP "-M, --manual" +Manual. Display the huge help text. +.IP "--max-filesize " +Specify the maximum size (in bytes) of a file to download. If the file +requested is larger than this value, the transfer will not start and curl will +return with exit code 63. + +\fBNOTE:\fP The file size is not always known prior to download, and for such +files this option has no effect even if the file transfer ends up being larger +than this given limit. This concerns both FTP and HTTP transfers. + +See also \fI--limit-rate\fP. +.IP "--max-redirs " +(HTTP) Set maximum number of redirection-followings allowed. When \fI-L, --location\fP is used, +is used to prevent curl from following redirections \&"in absurdum". By +default, the limit is set to 50 redirections. Set this option to -1 to make it +unlimited. + +If this option is used several times, the last one will be used. +.IP "-m, --max-time