diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..128c6ac20 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +.git +.vscode +cmake-build-debug \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..440838e30 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,18 @@ +--- +name: Bug report +about: Marketmaker 1.0 bug report + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**Please answer following questions and attach requested info - it'll help to solve issue faster** +- What OS do you use? +- What marketmaker version do you run? +- Attach your coins.json config. +- Provide your enable script with response. +- Provide other curl scripts (with responses) which were executed prior to error. +- Attach full marketmaker console logs (start collecting right after marketmaker execution). +- ***Make sure that you don't send your passphrase, userpass and privkeys. Your funds might be stolen if you reveal this info publicly!*** +- Provide info for all nodes involved (e.g. if error occurs during atomic swap you should provide info for both Bob and Alice). diff --git a/.gitignore b/.gitignore index 3ae3a23ab..1355ce65a 100755 --- a/.gitignore +++ b/.gitignore @@ -263,4 +263,12 @@ Release/* build_win64_release/* DB/* +.env.client +.env.seed +etomic_build/client/DB +etomic_build/client/stats.log +etomic_build/client/unparsed.txt +etomic_build/seed/DB +etomic_build/seed/stats.log +etomic_build/seed/unparsed.txt iguana/exchanges/manychains diff --git a/.travis.yml b/.travis.yml index 5730c4869..581c49ba1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,12 +4,6 @@ matrix: include: - os: linux compiler: gcc - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-7 env: OS_NAME=Linux MATRIX_EVAL="CC=gcc-7 && CXX=g++-7" - os: osx compiler: clang @@ -17,14 +11,39 @@ matrix: osx_image: xcode9.2 before_install: + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt-get update && sudo apt-get install -y g++-7; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then chmod +x travis_cmake_linux.sh && ./travis_cmake_linux.sh; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then chmod +x travis_cmake_mac.sh && ./travis_cmake_mac.sh; fi - git submodule update --init --recursive script: + - export VERSION=`echo "$(git tag -l --points-at HEAD)"` + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export THREAD_COUNT=`echo "$(nproc --all)"`; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export THREAD_COUNT=`echo "$(sysctl -n hw.physicalcpu)"`; fi - mkdir build && cd build - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then cmake -DCMAKE_C_COMPILER=/usr/bin/gcc-7 -DCMAKE_CXX_COMPILER=/usr/bin/g++-7 ..; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cmake ..; fi - - cmake --build . --target marketmaker-mainnet + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then cmake -DMM_VERSION="$VERSION" -DCMAKE_C_COMPILER=/usr/bin/gcc-7 -DCMAKE_CXX_COMPILER=/usr/bin/g++-7 ..; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cmake -DMM_VERSION="$VERSION" ..; fi + - echo "cmake --build . --target marketmaker-mainnet -j $THREAD_COUNT" + - cmake --build . --target marketmaker-mainnet -j $THREAD_COUNT + - cmake --build . --target marketmaker-testnet -j $THREAD_COUNT cache: - directories: - - $HOME/.hunter \ No newline at end of file + apt: true + directories: + - $HOME/.hunter + +before_deploy: + - export TAG=`echo "$(git rev-parse --short HEAD)"` + - mkdir deploy + - strip iguana/exchanges/marketmaker-mainnet + - strip iguana/exchanges/marketmaker-testnet + - tar -cvzf deploy/marketmaker-"$TRAVIS_OS_NAME"-"$TAG".tar.gz -C iguana/exchanges marketmaker-mainnet marketmaker-testnet +deploy: + provider: releases + api_key: + secure: "JDwFBGO4WLra9bXr2dsovet8y/ymC0Y+LJNr5/qlUIDt97zVytGbIlUc8BuI2VZFcnAvrtfOGdCs9m/PcLzZd4bMxXSsuaU0AJk/Vj9KzrIIGPJ4uS39KpO1USUpPW+5e0Bisf30JN3N2NypwMbMu42TKjVqaXSbVQfh79Iu6PdnyfiFbbTEfMeiRRrD72c00rwAw7kmndf7Sv9MiMN8WTFe0cQz5eH8GU/BSbnDorSrtClU4r7McR98zXaig/8XVcT543tcqdYW95QO7OqOjAid3XzzA/bPUTjC/nF/AyTJDco26nts0bCrCYeZRXIWdEInFLIeRHhHD7sW7dILRT/I7WlaLWnRtwo8e1L+U1k1yZ84dQMpgBznttdwH3vSj0crwCbFuMaRMMbPeW0H8C1VitLy1mlapw3RDI9yKlcw4V6WjPbz0YKhAoZgT/M/SaGr4ZkoWNCPoV5+Gub78p24Y8Y9BptJgj5t9KAcmDwbJ9wPt006ObWnbXvapo+6N5Dk2zuyQe9seoupzy4CAiNdluzAAVWsV/SjnN2aapjXoxaAaLQC6T8C1l1BpYri9LSKrjerr4QLVl/nw2yovAKNEobLLBVpSwfg4R72fu1BMS65gVsOqtFfs+R47CY+1D1Slev+UmKNMdE51+aXM+1XeC6wDUS5d13mW1NLhOE=" + file_glob: true + file: "deploy/*" + on: + tags: true + skip_cleanup: true diff --git a/Dockerfile.clientnode b/Dockerfile.clientnode new file mode 100644 index 000000000..96d9177df --- /dev/null +++ b/Dockerfile.clientnode @@ -0,0 +1,9 @@ +FROM ubuntu:17.10 +USER root +RUN apt-get update && apt-get install -y rinetd curl libcurl3-gnutls +RUN echo "0.0.0.0 10271 10.100.0.1 10271" >> /etc/rinetd.conf +RUN echo "0.0.0.0 8923 10.100.0.1 8923" >> /etc/rinetd.conf +RUN useradd -u 111 jenkins +USER jenkins +WORKDIR /usr/mm/etomic_build/client +CMD /usr/sbin/rinetd && rm -rf DB && ./client \ No newline at end of file diff --git a/Dockerfile.seednode b/Dockerfile.seednode new file mode 100644 index 000000000..d431296b6 --- /dev/null +++ b/Dockerfile.seednode @@ -0,0 +1,9 @@ +FROM ubuntu:17.10 +USER root +RUN apt-get update && apt-get install -y rinetd curl libcurl3-gnutls +RUN echo "0.0.0.0 10271 10.100.0.1 10271" >> /etc/rinetd.conf +RUN echo "0.0.0.0 8923 10.100.0.1 8923" >> /etc/rinetd.conf +RUN useradd -u 111 jenkins +USER jenkins +WORKDIR /usr/mm/etomic_build/seed +CMD /usr/sbin/rinetd && rm -rf DB && ./run diff --git a/Jenkinsfile b/Jenkinsfile index f7bb536b0..ef2e76a87 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,11 +1,12 @@ pipeline { - agent { - docker { - image 'artempikulin/cmake-ubuntu' - } - - } + agent any stages { + stage('Prepare') { + steps { + sh '''cp -r /root/.env.client .env.client +cp -r /root/.env.seed .env.seed''' + } + } stage('Build') { steps { sh '''git submodule update --init --recursive @@ -13,7 +14,27 @@ rm -rf build mkdir build cd build cmake .. -cmake --build . --target marketmaker-testnet''' +cmake --build . --target marketmaker-testnet -j 4 +cd ../ +docker-compose build''' + } + } + stage('Trade BEER/ETH') { + steps { + sh '''docker-compose up -d +./start_BEER_OTHER_trade.sh ETH +timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f clientnode) +timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f seednode) +docker-compose down''' + } + } + stage('Trade ETH/BEER') { + steps { + sh '''docker-compose up -d +./start_BEER_OTHER_trade_inverted.sh ETH +timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f clientnode) +timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f seednode) +docker-compose down''' } } } diff --git a/appveyor.yml b/appveyor.yml index de2123bc5..3c82ea80a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,30 @@ version: 1.0.{build} -branches: - only: - - etomic build_script: -- cmd: marketmaker_build_etomic.cmd \ No newline at end of file +- cmd: marketmaker_build_etomic.cmd +cache: + - C:\.hunter + - marketmaker_depends + +after_build: + - '7z a mm-win.zip + .\build_win64_release\iguana\exchanges\Release\marketmaker-mainnet.exe + .\marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl.dll + .\marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.dll + "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\redist\\x64\\Microsoft.VC140.CRT\\msvcp140.dll" + "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\redist\\x64\\Microsoft.VC140.CRT\\vcruntime140.dll"' + +artifacts: + - path: mm-win.zip + name: marketmaker-mainnet + +deploy: + release: v$(appveyor_build_version) + provider: GitHub + auth_token: + secure: iabzoz73JgtOIyE/Nmz4a4XefmK+7pIeup+1Hunj4hGKrdfesFN+176DMApgfu8t + artifact: marketmaker-mainnet + draft: false + prerelease: false + on: + branch: master + appveyor_repo_tag: false \ No newline at end of file diff --git a/cpp-ethereum b/cpp-ethereum index 633c62c08..e804e95d9 160000 --- a/cpp-ethereum +++ b/cpp-ethereum @@ -1 +1 @@ -Subproject commit 633c62c08bc73c7c3935c948a8d6c656a3659976 +Subproject commit e804e95d9a71e87fc5e3e69a2888448f23bc724f diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 06a06116c..9da753811 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -425,6 +425,7 @@ bits256 bits256_sha256(bits256 data); void bits256_rmd160(uint8_t rmd160[20],bits256 data); void bits256_rmd160_sha256(uint8_t rmd160[20],bits256 data); double get_theoretical(double *avebidp,double *aveaskp,double *highbidp,double *lowaskp,double *CMC_averagep,double changes[3],char *name,char *base,char *rel,double *USD_averagep); +char *bitcoind_RPCnew(void *curl_handle,char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout); extern char *Iguana_validcommands[]; extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY; diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 1ae71342e..78c874cbe 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -14,6 +14,7 @@ ******************************************************************************/ +//#define KEEPALIVE breaks marketmaker api #ifndef FROM_JS #include "OS_portable.h" @@ -74,7 +75,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * char *retstr = 0; cJSON *json,*result,*error; #ifndef FROM_MARKETMAKER - usleep(1000); + //usleep(1000); #endif //printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 ) @@ -131,7 +132,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * * ************************************************************************/ -static int32_t USE_JAY; +//static int32_t USE_JAY; char *Jay_NXTrequest(char *command,char *params) { @@ -141,23 +142,28 @@ char *Jay_NXTrequest(char *command,char *params) return(retstr); } -char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout) + +static void bitcoind_init() { - CURL *curl_handle; static int didinit,count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY; - struct MemoryStruct chunk; - struct curl_slist *headers = NULL; struct return_string s; CURLcode res; - char *bracket0,*bracket1,*retstr,*databuf = 0; long len; int32_t specialcase,numretries; double starttime; + static int32_t didinit; if ( didinit == 0 ) { didinit = 1; curl_global_init(CURL_GLOBAL_ALL); //init the curl session - //curl_handle = curl_easy_init(); - } - if ( (0) && (USE_JAY != 0 && (strncmp(url,"http://127.0.0.1:7876/nxt",strlen("http://127.0.0.1:7876/nxt")) == 0 || strncmp(url,"https://127.0.0.1:7876/nxt",strlen("https://127.0.0.1:7876/nxt")) == 0)) ) - { - if ( (databuf= Jay_NXTrequest(command,params)) != 0 ) - return(databuf); } +} + +char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout) +{ +#ifdef KEEPALIVE + static +#endif + CURL *curl_handle = 0; + static int count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY; + struct MemoryStruct chunk; + struct curl_slist *headers = NULL; struct return_string s; CURLcode res; + char *bracket0,*bracket1,*retstr,*databuf = 0; long len; int32_t specialcase,numretries; double starttime; + bitcoind_init(); numretries = 0; if ( debugstr != 0 && strcmp(debugstr,"BTCD") == 0 && command != 0 && strcmp(command,"SuperNET") == 0 ) specialcase = 1; @@ -174,7 +180,8 @@ try_again: if ( retstrp != 0 ) *retstrp = 0; starttime = OS_milliseconds(); - curl_handle = curl_easy_init(); + if ( curl_handle == 0 ) + curl_handle = curl_easy_init(); headers = curl_slist_append(0,"Expect:"); curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )"); @@ -244,7 +251,10 @@ try_again: //laststart = milliseconds(); res = curl_easy_perform(curl_handle); curl_slist_free_all(headers); +#ifndef KEEPALIVE curl_easy_cleanup(curl_handle); + curl_handle = 0; +#endif if ( databuf != 0 ) // clean up temporary buffer { free(databuf); @@ -279,7 +289,7 @@ try_again: count++; elapsedsum += (OS_milliseconds() - starttime); if ( (count % 100000) == 0) - printf("%d: ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,elapsedsum/count,(OS_milliseconds() - starttime),command,url); + printf("%d: %s ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,debugstr,elapsedsum/count,(OS_milliseconds() - starttime),command,url); if ( retstrp != 0 ) { *retstrp = retstr; @@ -301,6 +311,153 @@ try_again: } } +char *bitcoind_RPCnew(void *curl_handle,char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout) +{ + static int count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY; + struct MemoryStruct chunk; + struct curl_slist *headers = NULL; struct return_string s; CURLcode res; + char *bracket0,*bracket1,*retstr,*databuf = 0; long len; int32_t flag=0,specialcase,numretries; double starttime; + bitcoind_init(); + numretries = 0; + if ( url[0] == 0 ) + strcpy(url,"http://127.0.0.1:7776"); +try_again: + if ( curl_handle == 0 ) + { + curl_handle = curl_easy_init(); + flag = 1; + } + if ( retstrp != 0 ) + *retstrp = 0; + starttime = OS_milliseconds(); + headers = curl_slist_append(0,"Expect:"); + curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )"); + curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl_handle,CURLOPT_URL, url); + if ( (0) ) + { + init_string(&s); + curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulate); // send all data to this function + curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback + } + else + { + memset(&chunk,0,sizeof(chunk)); + curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION,WriteMemoryCallback); + curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA,(void *)&chunk); + + } + 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 + if ( timeout > 0 ) + { + if ( bitcoind_RPC_inittime != 0 ) + { +#ifndef _WIN32 + curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT,1); +#else + curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, timeout*100); +#endif + } else 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); + curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYHOST,0); + } + if ( userpass != 0 ) + curl_easy_setopt(curl_handle,CURLOPT_USERPWD, userpass); + databuf = 0; + if ( params != 0 ) + { + if ( command != 0 ) + { + len = strlen(params); + if ( len > 0 && params[0] == '[' && params[len-1] == ']' ) { + bracket0 = bracket1 = (char *)""; + } + else + { + bracket0 = (char *)"["; + bracket1 = (char *)"]"; + } + char agentstr[64]; + databuf = (char *)malloc(256 + strlen(command) + strlen(params)); + if ( debugstr[0] != 0 ) + sprintf(agentstr,"\"agent\":\"%s\",",debugstr); + else agentstr[0] = 0; + sprintf(databuf,"{\"id\":\"jl777\",%s\"method\":\"%s\",\"params\":%s%s%s}",agentstr,command,bracket0,params,bracket1); + //printf("url.(%s) userpass.(%s) databuf.(%s)\n",url,userpass,databuf); + // + } //else if ( specialcase != 0 ) fprintf(stderr,"databuf.(%s)\n",params); + curl_easy_setopt(curl_handle,CURLOPT_POST,1L); + if ( databuf != 0 ) + curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,databuf); + else curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,params); + } + res = curl_easy_perform(curl_handle); + curl_slist_free_all(headers); + if ( databuf != 0 ) // clean up temporary buffer + { + free(databuf); + databuf = 0; + } + if ( flag != 0 ) + { + curl_easy_cleanup(curl_handle); + curl_handle = 0; + } + retstr = chunk.memory; // retstr = s.ptr; + if ( res != CURLE_OK ) + { + numretries++; + if ( timeout != 0 ) + { + //printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,retstr,res); + free(retstr); + return(0); + } + else if ( numretries >= 4 ) + { + printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries); + //printf("Maximum number of retries exceeded!\n"); + free(retstr); + return(0); + } + free(retstr); + sleep((1< (%s)\n",params,retstr); + count2++; + elapsedsum2 += (OS_milliseconds() - starttime); + if ( (count2 % 10000) == 0) + printf("%d: ave %9.6f | elapsed %.3f millis | NXT calls.(%s) cmd.(%s)\n",count2,elapsedsum2/count2,(double)(OS_milliseconds() - starttime),url,command); + return(retstr); + } + } +} + /************************************************************************ * * Initialize the string handler so that it is thread safe diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index d62b71683..e0665e378 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -902,10 +902,10 @@ char *get_cJSON_fieldname(cJSON *obj) { if ( obj != 0 ) { - if ( obj->child != 0 && obj->child->string != 0 ) - return(obj->child->string); - else if ( obj->string != 0 ) + if ( obj->string != 0 ) return(obj->string); + if ( obj->child != 0 && obj->child->string != 0 ) + return(obj->child->string); } return((char *)""); } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..52da982c7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,41 @@ +version: '2' +services: + seednode: + build: + context: ./ + dockerfile: Dockerfile.seednode + volumes: + - ~/.zcash-params:/home/jenkins/.zcash-params + - ~/.komodo:/home/jenkins/.komodo + - .:/usr/mm + env_file: + - .env.seed + tty: true + networks: + default: + ipv4_address: 10.100.0.2 + + clientnode: + build: + context: ./ + dockerfile: Dockerfile.clientnode + volumes: + - ~/.zcash-params:/home/jenkins/.zcash-params + - ~/.komodo:/home/jenkins/.komodo + - .:/usr/mm + links: + - seednode + tty: true + env_file: + - .env.client + networks: + default: + ipv4_address: 10.100.0.3 + +networks: + default: + driver: bridge + ipam: + config: + - subnet: 10.100.0.0/16 + gateway: 10.100.0.1 \ No newline at end of file diff --git a/etomic_build/client b/etomic_build/client deleted file mode 100755 index fb4f0c935..000000000 --- a/etomic_build/client +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -source passphrase -source coins -./stop -iguana/exchanges/marketmaker "{\"netid\":9999,\"seednode\":\"5.9.253.204\",\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & diff --git a/etomic_build/client/buy_BEER_OTHER b/etomic_build/client/buy_BEER_OTHER new file mode 100755 index 000000000..1b4fb5ff6 --- /dev/null +++ b/etomic_build/client/buy_BEER_OTHER @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"$1\",\"rel\":\"BEER\",\"price\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"buy\",\"base\":\"BEER\",\"rel\":\"$1\",\"relvolume\":0.1,\"price\":1}" diff --git a/etomic_build/client/client b/etomic_build/client/client new file mode 100755 index 000000000..22f5c462e --- /dev/null +++ b/etomic_build/client/client @@ -0,0 +1,4 @@ +#!/bin/bash +source passphrase +source ../coins +../../build/iguana/exchanges/marketmaker-testnet "{\"netid\":9999,\"seednode\":\"10.100.0.2\",\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" diff --git a/etomic_build/client/enable b/etomic_build/client/enable new file mode 100755 index 000000000..0bda2f3ce --- /dev/null +++ b/etomic_build/client/enable @@ -0,0 +1,7 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETOMIC\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETH\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"NODEC\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"JST\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BEER\"}" diff --git a/etomic_build/client/myipaddr b/etomic_build/client/myipaddr new file mode 100644 index 000000000..f1649949c --- /dev/null +++ b/etomic_build/client/myipaddr @@ -0,0 +1 @@ +10.100.0.3 diff --git a/etomic_build/client/passphrase b/etomic_build/client/passphrase new file mode 100644 index 000000000..d54ee899d --- /dev/null +++ b/etomic_build/client/passphrase @@ -0,0 +1 @@ +export passphrase="$PASSPHRASE" diff --git a/etomic_build/client/setpassphrase b/etomic_build/client/setpassphrase new file mode 100755 index 000000000..81cc0b28f --- /dev/null +++ b/etomic_build/client/setpassphrase @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +source passphrase +curl --url "http://127.0.0.1:7783" --data "{\"netid\":9999,\"seednode\":\"10.100.0.2\",\"userpass\":\"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f\",\"method\":\"passphrase\",\"passphrase\":\"$passphrase\",\"gui\":\"nogui\"}" diff --git a/etomic_build/client/userpass b/etomic_build/client/userpass new file mode 100644 index 000000000..19fc21189 --- /dev/null +++ b/etomic_build/client/userpass @@ -0,0 +1,2 @@ +#export userpass="" +export userpass="$USERPASS" diff --git a/etomic_build/coins b/etomic_build/coins index 988b79784..4afe84fea 100755 --- a/etomic_build/coins +++ b/etomic_build/coins @@ -1,3 +1,3 @@ -export coins="[{\"coin\":\"OOT\",\"asset\":\"OOT\",\"rpcport\":12467}, {\"coin\":\"ETH\",\"name\":\"ethereum\",\"etomic\":\"0x0000000000000000000000000000000000000000\",\"rpcport\":80}, {\"coin\":\"EOS\",\"name\":\"EOS\",\"etomic\":\"0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0\",\"rpcport\":80}, {\"coin\":\"ZOI\",\"name\":\"zoin\",\"rpcport\":8255,\"pubtype\":80,\"p2shtype\":7,\"wiftype\":208,\"txfee\":1000}, {\"coin\": \"PIZZA\",\"asset\": \"PIZZA\",\"rpcport\": 11116},{\"coin\": \"BEER\",\"asset\": \"BEER\",\"rpcport\": 8923}, {\"coin\":\"GRS\",\"name\":\"groestlcoin\",\"rpcport\":1441,\"pubtype\":36,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"XMCC\",\"name\":\"monoeci\",\"confpath\":\"${HOME#}/.monoeciCore/monoeci.conf\",\"rpcport\":24156,\"pubtype\":50,\"p2shtype\":73,\"wiftype\":77,\"txfee\":10000}, {\"coin\":\"BTCH\",\"asset\":\"BTCH\",\"rpcport\":8800},{\"coin\":\"ETOMIC\",\"asset\":\"ETOMIC\",\"rpcport\":10271},{\"coin\":\"AXO\",\"asset\":\"AXO\",\"rpcport\":12927},{\"coin\":\"CRC\",\"name\":\"crowdcoin\",\"confpath\":\"${HOME#}/.crowdcoincore/crowdcoin.conf\",\"rpcport\":11998,\"pubtype\":28,\"p2shtype\":88,\"wiftype\":0,\"txfee\":10000}, {\"coin\":\"VOT\",\"name\":\"votecoin\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"INN\",\"name\":\"innova\",\"confpath\":\"${HOME#}/.innovacore/innova.conf\",\"rpcport\":8818,\"pubtype\":102,\"p2shtype\":20,\"wiftype\":195,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":28,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"EFL\",\"name\":\"egulden\",\"confpath\":\"${HOME#}/.egulden/coin.conf\",\"rpcport\":21015,\"pubtype\":48,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"GBX\",\"name\":\"gobyte\",\"confpath\":\"${HOME#}/.gobytecore/gobyte.conf\",\"rpcport\":12454,\"pubtype\":38,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\":\"BCO\",\"name\":\"bridgecoin\",\"rpcport\":6332,\"pubtype\":27,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BLK\",\"name\":\"blackcoin\",\"confpath\":\"${HOME#}/.lore/blackcoin.conf\",\"isPoS\":1,\"rpcport\":15715,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":100000}, {\"coin\":\"BTG\",\"name\":\"bitcoingold\",\"rpcport\":8332,\"pubtype\":38,\"p2shtype\":23,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BCH\",\"name\":\"bch\",\"rpcport\":33333,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"ABY\",\"name\":\"applebyte\",\"rpcport\":8607,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":100000}, {\"coin\":\"STAK\",\"name\":\"straks\",\"rpcport\":7574,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"XZC\",\"name\":\"zcoin\",\"rpcport\":8888,\"pubtype\":82,\"p2shtype\":7,\"wiftype\":210,\"txfee\":10000}, {\"coin\":\"QTUM\",\"name\":\"qtum\",\"rpcport\":3889,\"pubtype\":58,\"p2shtype\":50,\"wiftype\":128,\"txfee\":400000}, {\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"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\":2000000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"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\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"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\":\"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\":10000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"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\":100000}, {\"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\":10000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":10000}, {\"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\":\"MSHARK\",\"asset\":\"MSHARK\",\"rpcport\":8846}, {\"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}]" +export coins="[{\"coin\":\"OOT\",\"asset\":\"OOT\",\"rpcport\":12467}, {\"coin\":\"ETH\",\"name\":\"ethereum\",\"etomic\":\"0x0000000000000000000000000000000000000000\",\"rpcport\":80}, {\"coin\":\"EOS\",\"name\":\"EOS\",\"etomic\":\"0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0\",\"rpcport\":80},{\"coin\":\"JST\", \"name\":\"JST\",\"etomic\":\"0xc0eb7AeD740E1796992A08962c15661bDEB58003\",\"rpcport\":80},{\"coin\":\"NODEC\",\"name\":\"NODEC\",\"etomic\":\"0x05beb0a9ead354283041a6d35f3b833450fb5680\",\"rpcport\":80,\"decimals\":18},{\"coin\":\"ZOI\",\"name\":\"zoin\",\"rpcport\":8255,\"pubtype\":80,\"p2shtype\":7,\"wiftype\":208,\"txfee\":1000}, {\"coin\": \"PIZZA\",\"asset\": \"PIZZA\",\"rpcport\": 11116},{\"coin\": \"BEER\",\"asset\": \"BEER\",\"rpcport\": 8923}, {\"coin\":\"GRS\",\"name\":\"groestlcoin\",\"rpcport\":1441,\"pubtype\":36,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"XMCC\",\"name\":\"monoeci\",\"confpath\":\"${HOME#}/.monoeciCore/monoeci.conf\",\"rpcport\":24156,\"pubtype\":50,\"p2shtype\":73,\"wiftype\":77,\"txfee\":10000}, {\"coin\":\"BTCH\",\"asset\":\"BTCH\",\"rpcport\":8800},{\"coin\":\"ETOMIC\",\"asset\":\"ETOMIC\",\"rpcport\":10271},{\"coin\":\"AXO\",\"asset\":\"AXO\",\"rpcport\":12927},{\"coin\":\"CRC\",\"name\":\"crowdcoin\",\"confpath\":\"${HOME#}/.crowdcoincore/crowdcoin.conf\",\"rpcport\":11998,\"pubtype\":28,\"p2shtype\":88,\"wiftype\":0,\"txfee\":10000}, {\"coin\":\"VOT\",\"name\":\"votecoin\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"INN\",\"name\":\"innova\",\"confpath\":\"${HOME#}/.innovacore/innova.conf\",\"rpcport\":8818,\"pubtype\":102,\"p2shtype\":20,\"wiftype\":195,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":28,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"EFL\",\"name\":\"egulden\",\"confpath\":\"${HOME#}/.egulden/coin.conf\",\"rpcport\":21015,\"pubtype\":48,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"GBX\",\"name\":\"gobyte\",\"confpath\":\"${HOME#}/.gobytecore/gobyte.conf\",\"rpcport\":12454,\"pubtype\":38,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\":\"BCO\",\"name\":\"bridgecoin\",\"rpcport\":6332,\"pubtype\":27,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BLK\",\"name\":\"blackcoin\",\"confpath\":\"${HOME#}/.lore/blackcoin.conf\",\"isPoS\":1,\"rpcport\":15715,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":100000}, {\"coin\":\"BTG\",\"name\":\"bitcoingold\",\"rpcport\":8332,\"pubtype\":38,\"p2shtype\":23,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BCH\",\"name\":\"bch\",\"rpcport\":33333,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"ABY\",\"name\":\"applebyte\",\"rpcport\":8607,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":100000}, {\"coin\":\"STAK\",\"name\":\"straks\",\"rpcport\":7574,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"XZC\",\"name\":\"zcoin\",\"rpcport\":8888,\"pubtype\":82,\"p2shtype\":7,\"wiftype\":210,\"txfee\":10000}, {\"coin\":\"QTUM\",\"name\":\"qtum\",\"rpcport\":3889,\"pubtype\":58,\"p2shtype\":50,\"wiftype\":128,\"txfee\":400000}, {\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"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\":2000000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"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\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"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\":\"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\":10000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"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\":100000}, {\"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\":10000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":10000}, {\"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\":\"MSHARK\",\"asset\":\"MSHARK\",\"rpcport\":8846}, {\"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}]" #{\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, diff --git a/etomic_build/enable b/etomic_build/enable index 0bcf62166..f43d63ff7 100755 --- a/etomic_build/enable +++ b/etomic_build/enable @@ -1,5 +1,4 @@ #!/bin/bash source userpass -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETH\"}" -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"KMD\"}" curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETOMIC\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETH\"}" diff --git a/etomic_build/passphrase b/etomic_build/passphrase deleted file mode 100644 index eb00095d6..000000000 --- a/etomic_build/passphrase +++ /dev/null @@ -1 +0,0 @@ -export passphrase="" diff --git a/etomic_build/run b/etomic_build/run deleted file mode 100755 index b757bb993..000000000 --- a/etomic_build/run +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -source passphrase -source coins -./stop - $1 iguana/exchanges/marketmaker "{\"netid\":9999,\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & diff --git a/etomic_build/seed/enable b/etomic_build/seed/enable new file mode 100755 index 000000000..0bda2f3ce --- /dev/null +++ b/etomic_build/seed/enable @@ -0,0 +1,7 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETOMIC\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETH\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"NODEC\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"JST\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BEER\"}" diff --git a/etomic_build/seed/myipaddr b/etomic_build/seed/myipaddr new file mode 100644 index 000000000..da7788dc2 --- /dev/null +++ b/etomic_build/seed/myipaddr @@ -0,0 +1 @@ +10.100.0.2 diff --git a/etomic_build/seed/passphrase b/etomic_build/seed/passphrase new file mode 100644 index 000000000..d54ee899d --- /dev/null +++ b/etomic_build/seed/passphrase @@ -0,0 +1 @@ +export passphrase="$PASSPHRASE" diff --git a/etomic_build/seed/run b/etomic_build/seed/run new file mode 100755 index 000000000..96ceba6ca --- /dev/null +++ b/etomic_build/seed/run @@ -0,0 +1,4 @@ +#!/bin/bash +source passphrase +source ../coins +../../build/iguana/exchanges/marketmaker-testnet "{\"netid\":9999,\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" diff --git a/etomic_build/seed/sell_BEER_OTHER b/etomic_build/seed/sell_BEER_OTHER new file mode 100755 index 000000000..6ec45e1b9 --- /dev/null +++ b/etomic_build/seed/sell_BEER_OTHER @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"BEER\",\"rel\":\"$1\",\"price\":0.9}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"BEER\",\"rel\":\"$1\",\"basevolume\":0.1,\"price\":0.9}" diff --git a/etomic_build/seed/setpassphrase b/etomic_build/seed/setpassphrase new file mode 100755 index 000000000..b3df81427 --- /dev/null +++ b/etomic_build/seed/setpassphrase @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +source passphrase +curl --url "http://127.0.0.1:7783" --data "{\"netid\":9999,\"seednode\":\"5.9.253.204\",\"userpass\":\"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f\",\"method\":\"passphrase\",\"passphrase\":\"$passphrase\",\"gui\":\"nogui\"}" diff --git a/etomic_build/seed/userpass b/etomic_build/seed/userpass new file mode 100644 index 000000000..19fc21189 --- /dev/null +++ b/etomic_build/seed/userpass @@ -0,0 +1,2 @@ +#export userpass="" +export userpass="$USERPASS" diff --git a/etomic_build/userpass b/etomic_build/userpass index d097e0445..19fc21189 100644 --- a/etomic_build/userpass +++ b/etomic_build/userpass @@ -1,2 +1,2 @@ #export userpass="" -export userpass="c3d8c2a364b7d18c1f9d7321d017b92e9f9c791e4f5c741214fefdea8a071256" +export userpass="$USERPASS" diff --git a/iguana/coins/ccl_7776 b/iguana/coins/ccl_7776 new file mode 100755 index 000000000..1aeadab25 --- /dev/null +++ b/iguana/coins/ccl_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"CCL.conf\",\"path\":\"${HOME#"/"}/.komodo/CCL\",\"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\":\"CCL\",\"name\":\"CCL\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"5c31ff66\",\"p2p\":20848,\"rpc\":20849,\"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/rfox_7776 b/iguana/coins/rfox_7776 new file mode 100755 index 000000000..a3f269f1a --- /dev/null +++ b/iguana/coins/rfox_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"RFOX.conf\",\"path\":\"${HOME#"/"}/.komodo/RFOX\",\"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\":\"RFOX\",\"name\":\"RFOX\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"4cad0644\",\"p2p\":32268,\"rpc\":32269,\"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/sec_7776 b/iguana/coins/sec_7776 new file mode 100755 index 000000000..1edbb8c17 --- /dev/null +++ b/iguana/coins/sec_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"SEC.conf\",\"path\":\"${HOME#"/"}/.komodo/SEC\",\"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\":\"SEC\",\"name\":\"SEC\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"8f27938c\",\"p2p\":11539,\"rpc\":11540,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"185.148.145.43\"}" + diff --git a/iguana/coins/vrsc_7776 b/iguana/coins/vrsc_7776 new file mode 100755 index 000000000..bdbc4f58e --- /dev/null +++ b/iguana/coins/vrsc_7776 @@ -0,0 +1,2 @@ + +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"VRSC.conf\",\"path\":\"${HOME#"/"}/.komodo/VRSC\",\"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\":\"VRSC\",\"name\":\"Verus\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"91db4d20\",\"p2p\":27485,\"rpc\":27486,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"54.39.23.248\"}" diff --git a/iguana/coins/zilla_7776 b/iguana/coins/zilla_7776 new file mode 100755 index 000000000..8652fb357 --- /dev/null +++ b/iguana/coins/zilla_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"ZILLA.conf\",\"path\":\"${HOME#"/"}/.komodo/ZILLA\",\"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\":\"ZILLA\",\"name\":\"ZILLA\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"91db4d20\",\"p2p\":10040,\"rpc\":10041,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"54.39.23.248\"}" diff --git a/iguana/dPoW.h b/iguana/dPoW.h index 61e9e0234..bc343f144 100755 --- a/iguana/dPoW.h +++ b/iguana/dPoW.h @@ -109,7 +109,7 @@ struct dpow_recvdata { uint64_t recvmask,bestmask; int8_t bestk; }; struct dpow_block { - bits256 hashmsg,desttxid,srctxid,beacon,commit,MoM; + bits256 hashmsg,desttxid,srctxid,beacon,commit,MoM,mysrcutxo,mydestutxo; struct iguana_info *srccoin,*destcoin; char *opret_symbol; uint64_t destsigsmasks[DPOW_MAXRELAYS],srcsigsmasks[DPOW_MAXRELAYS]; uint64_t recvmask,bestmask,ratifybestmask,ratifyrecvmask,pendingbestmask,pendingratifybestmask,ratifysigmasks[2]; @@ -119,6 +119,7 @@ struct dpow_block int32_t rawratifiedlens[2],height,numnotaries,numerrors,completed,minsigs,duration,numratified,isratify,require0,scores[DPOW_MAXRELAYS]; int8_t myind,bestk,ratifybestk,pendingbestk,pendingratifybestk,matches,bestmatches; cJSON *ratified; + uint16_t CCid; uint8_t ratified_pubkeys[DPOW_MAXRELAYS][33],ratifysigs[2][DPOW_MAXSIGLEN],ratifysiglens[2]; char handles[DPOW_MAXRELAYS][32]; char signedtx[32768]; uint8_t ratifyrawtx[2][32768]; uint32_t pendingcrcs[2]; @@ -143,6 +144,7 @@ struct dpow_info uint32_t SRCREALTIME,lastsrcupdate,destupdated,srcconfirms,numdesttx,numsrctx,lastsplit,cancelratify; int32_t lastheight,maxblocks,SRCHEIGHT,DESTHEIGHT,prevDESTHEIGHT,SHORTFLAG,ratifying,minsigs,freq; struct pax_transaction *PAX; + uint32_t fullCCid; portable_mutex_t paxmutex,dexmutex; uint32_t ipbits[128],numipbits; struct dpow_block **blocks,*currentbp; @@ -158,7 +160,7 @@ struct komodo_ccdataMoMoM }; uint64_t dpow_notarybestk(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp); -int32_t dpow_paxpending(uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,int32_t src_or_dest,struct dpow_block *bp); +int32_t dpow_paxpending(struct supernet_info *myinfo,uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,uint16_t CCid,int32_t src_or_dest,struct dpow_block *bp); void dex_updateclient(struct supernet_info *myinfo); char *dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *data,int32_t datalen,int32_t M,char *field); char *basilisk_respond_addmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen,uint8_t *data,int32_t datalen,int32_t sendping,uint32_t duration); diff --git a/iguana/dpow/dpow_fsm.c b/iguana/dpow/dpow_fsm.c index 9887c7b2d..c531c27a7 100755 --- a/iguana/dpow/dpow_fsm.c +++ b/iguana/dpow/dpow_fsm.c @@ -235,7 +235,7 @@ bits256 dpow_calcMoM(uint32_t *MoMdepthp,struct supernet_info *myinfo,struct igu bits256 MoM; cJSON *MoMjson,*infojson; int32_t prevMoMheight; *MoMdepthp = 0; memset(MoM.bytes,0,sizeof(MoM)); - if ( strcmp(coin->symbol,"GAME") == 0 ) // 80 byte OP_RETURN limit + if ( strcmp(coin->symbol,"GAME") == 0 || strcmp(coin->symbol,"HUSH") == 0 ) // 80 byte OP_RETURN limit return(MoM); if ( (infojson= dpow_getinfo(myinfo,coin)) != 0 ) { @@ -302,6 +302,7 @@ void dpow_statemachinestart(void *ptr) Numallocated++; bp->MoM = MoM; bp->MoMdepth = MoMdepth; + bp->CCid = dp->fullCCid & 0xffff; bp->minsigs = minsigs; bp->duration = duration; bp->srccoin = src; @@ -438,7 +439,7 @@ void dpow_statemachinestart(void *ptr) return; } bp->myind = myind; - printf("[%d] notarize %s->%s %s ht.%d minsigs.%d duration.%d start.%u MoM[%d] %s\n",bp->myind,dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height,minsigs,duration,checkpoint.timestamp,bp->MoMdepth,bits256_str(str2,bp->MoM)); + printf("[%d] notarize %s->%s %s ht.%d minsigs.%d duration.%d start.%u MoM[%d] %s CCid.%u\n",bp->myind,dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height,minsigs,duration,checkpoint.timestamp,bp->MoMdepth,bits256_str(str2,bp->MoM),bp->CCid); if ( bp->isratify != 0 && memcmp(bp->notaries[0].pubkey,bp->ratified_pubkeys[0],33) != 0 ) { for (i=0; i<33; i++) @@ -487,6 +488,11 @@ void dpow_statemachinestart(void *ptr) bp->notaries[myind].ratifydestutxo = ep->dest.prev_hash; bp->notaries[myind].ratifydestvout = ep->dest.prev_vout; } + else + { + bp->mysrcutxo = ep->src.prev_hash; + bp->mydestutxo = ep->dest.prev_hash; + } } /*if ( strcmp(dp->symbol,"CHIPS") == 0 && myind == 0 ) { @@ -520,7 +526,7 @@ void dpow_statemachinestart(void *ptr) if ( strcmp(bp->destcoin->symbol,"KMD") == 0 ) src_or_dest = 0; else src_or_dest = 1; - extralen = dpow_paxpending(extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp); + extralen = dpow_paxpending(myinfo,extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp); bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc; } printf("PAXWDCRC.%x myind.%d isratify.%d DPOW.%s statemachine checkpoint.%d %s start.%u+dur.%d vs %ld MoM[%d] %s\n",bp->paxwdcrc,bp->myind,bp->isratify,src->symbol,checkpoint.blockhash.height,bits256_str(str,checkpoint.blockhash.hash),starttime,bp->duration,time(NULL),bp->MoMdepth,bits256_str(str2,bp->MoM)); @@ -541,7 +547,7 @@ void dpow_statemachinestart(void *ptr) if ( strcmp(bp->destcoin->symbol,"KMD") == 0 ) src_or_dest = 0; else src_or_dest = 1; - extralen = dpow_paxpending(extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp); + extralen = dpow_paxpending(myinfo,extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp); bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc; } if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) //(checkpoint.blockhash.height % 100) != 0 && diff --git a/iguana/dpow/dpow_network.c b/iguana/dpow/dpow_network.c index 2f20dcca3..fb8300d80 100755 --- a/iguana/dpow/dpow_network.c +++ b/iguana/dpow/dpow_network.c @@ -1308,8 +1308,8 @@ int32_t dpow_addnotary(struct supernet_info *myinfo,struct dpow_info *dp,char *i char str[512]; uint32_t ipbits,*ptr; int32_t i,iter,n,retval = -1; if ( myinfo->IAMNOTARY == 0 ) return(-1); - if ( strcmp(ipaddr,"88.99.251.101") == 0 || strcmp(ipaddr,"82.202.193.100") == 0 ) - return(-1); + //if ( strcmp(ipaddr,"88.99.251.101") == 0 || strcmp(ipaddr,"82.202.193.100") == 0 ) + // return(-1); portable_mutex_lock(&myinfo->notarymutex); if ( myinfo->dpowsock >= 0 )//&& myinfo->dexsock >= 0 ) { @@ -1869,16 +1869,24 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru return; if ( bp->isratify == 0 && bp->state != 0xffffffff && senderind >= 0 && senderind < bp->numnotaries && bits256_nonz(srcutxo) != 0 && bits256_nonz(destutxo) != 0 ) { - if ( bits256_nonz(srcutxo) != 0 ) + if ( bp->myind != senderind ) { - bp->notaries[senderind].src.prev_hash = srcutxo; - bp->notaries[senderind].src.prev_vout = srcvout; - //char str[65]; printf("%s senderind.%d <- %s/v%d\n",dp->symbol,senderind,bits256_str(str,srcutxo),srcvout); + if ( bits256_nonz(srcutxo) != 0 ) + { + bp->notaries[senderind].src.prev_hash = srcutxo; + bp->notaries[senderind].src.prev_vout = srcvout; + //char str[65]; printf("%s senderind.%d <- %s/v%d\n",dp->symbol,senderind,bits256_str(str,srcutxo),srcvout); + } + if ( bits256_nonz(destutxo) != 0 ) + { + bp->notaries[senderind].dest.prev_hash = destutxo; + bp->notaries[senderind].dest.prev_vout = destvout; + } } - if ( bits256_nonz(destutxo) != 0 ) + else { - bp->notaries[senderind].dest.prev_hash = destutxo; - bp->notaries[senderind].dest.prev_vout = destvout; + bp->notaries[bp->myind].src.prev_hash = bp->mysrcutxo; + bp->notaries[bp->myind].dest.prev_hash = bp->mydestutxo; } if ( bestmask != 0 ) bp->notaries[senderind].bestmask = bestmask; @@ -2070,7 +2078,7 @@ void dpow_send(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_blo if ( strcmp(bp->destcoin->symbol,"KMD") == 0 ) src_or_dest = 0; else src_or_dest = 1; - extralen = dpow_paxpending(extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp); + extralen = dpow_paxpending(myinfo,extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp); bp->paxwdcrc = bp->notaries[bp->myind].paxwdcrc = np->notarize.paxwdcrc = paxwdcrc; //dpow_bestconsensus(dp,bp); dpow_nanoutxoset(myinfo,dp,&np->notarize,bp,0); diff --git a/iguana/dpow/dpow_rpc.c b/iguana/dpow/dpow_rpc.c index 806ca32e5..edcd687d3 100755 --- a/iguana/dpow/dpow_rpc.c +++ b/iguana/dpow/dpow_rpc.c @@ -78,6 +78,17 @@ cJSON *dpow_getinfo(struct supernet_info *myinfo,struct iguana_info *coin) return(json); } +uint32_t dpow_CCid(struct supernet_info *myinfo,struct iguana_info *coin) +{ + uint32_t CCid = 0; cJSON *retjson; + if ( (retjson= dpow_getinfo(myinfo,coin)) != 0 ) + { + CCid = juint(retjson,"CCid"); + free_json(retjson); + } + return(CCid); +} + char *Notaries_elected[65][2]; //char *seeds[] = { "78.47.196.146", "5.9.102.210", "149.56.29.163", "191.235.80.138", "88.198.65.74", "94.102.63.226", "129.232.225.202", "104.255.64.3", "52.72.135.200", "149.56.28.84", "103.18.58.150", "221.121.144.140", "123.249.79.12", "103.18.58.146", "27.50.93.252", "176.9.0.233", "94.102.63.227", "167.114.227.223", "27.50.68.219", "192.99.233.217", "94.102.63.217", "45.64.168.216" }; int32_t Notaries_numseeds;// = (int32_t)(sizeof(seeds)/sizeof(*seeds)) @@ -251,16 +262,16 @@ cJSON *issue_calcMoM(struct iguana_info *coin,int32_t height,int32_t MoMdepth) return(retjson); } -cJSON *dpow_MoMoMdata(struct iguana_info *coin,char *symbol,int32_t kmdheight) +cJSON *dpow_MoMoMdata(struct iguana_info *coin,char *symbol,int32_t kmdheight,uint16_t CCid) { char buf[128],*retstr=0; cJSON *retjson = 0; struct iguana_info *src; if ( coin->FULLNODE < 0 && strcmp(coin->symbol,"KMD") == 0 && (src= iguana_coinfind(symbol)) != 0 ) { - sprintf(buf,"[\"%s\", \"%d\", \"%d\"]",symbol,kmdheight,src->MoMoMheight); + sprintf(buf,"[\"%s\", \"%d\", \"%d\"]",symbol,kmdheight,CCid); if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"MoMoMdata",buf)) != 0 ) { retjson = cJSON_Parse(retstr); - printf("MoMoM.%s -> %s\n",buf,retstr); + printf("%s kmdheight.%d CCid.%u MoMoM.%s -> %s\n",symbol,kmdheight,CCid,buf,retstr); free(retstr); } usleep(10000); @@ -268,22 +279,29 @@ cJSON *dpow_MoMoMdata(struct iguana_info *coin,char *symbol,int32_t kmdheight) return(retjson); } -int32_t dpow_paxpending(uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,int32_t src_or_dest,struct dpow_block *bp) +int32_t dpow_paxpending(struct supernet_info *myinfo,uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,uint16_t CCid,int32_t src_or_dest,struct dpow_block *bp) { - struct iguana_info *coin,*kmdcoin=0; char *retstr,*hexstr; cJSON *retjson; int32_t hexlen=0,n=0; uint32_t paxwdcrc; + struct iguana_info *coin,*kmdcoin=0; char *retstr,*hexstr; cJSON *retjson,*infojson; int32_t kmdheight=0,hexlen=0,n=0; uint32_t paxwdcrc; paxwdcrc = 0; if ( strcmp(bp->srccoin->symbol,"GAME") != 0 || src_or_dest != 0 ) { n += iguana_rwbignum(1,&hex[n],sizeof(MoM),MoM.bytes); + MoMdepth = (MoMdepth & 0xffff) | ((uint32_t)CCid<<16); n += iguana_rwnum(1,&hex[n],sizeof(MoMdepth),(uint32_t *)&MoMdepth); if ( strncmp(bp->srccoin->symbol,"TXSCL",5) == 0 && src_or_dest == 0 && strcmp(bp->destcoin->symbol,"KMD") == 0 ) { kmdcoin = bp->destcoin; - if ( (retjson= dpow_MoMoMdata(kmdcoin,bp->srccoin->symbol,(kmdcoin->lastbestheight/10)*10 - 5)) != 0 ) + if ( (infojson= dpow_getinfo(myinfo,kmdcoin)) != 0 ) + { + kmdheight = jint(infojson,"blocks"); + free_json(infojson); + } + if ( (retjson= dpow_MoMoMdata(kmdcoin,bp->srccoin->symbol,kmdheight,bp->CCid)) != 0 ) { if ( (hexstr= jstr(retjson,"data")) != 0 && (hexlen= (int32_t)strlen(hexstr)) > 0 && n+hexlen/2 <= hexsize ) { hexlen >>= 1; + printf("add MoMoMdata.(%s)\n",hexstr); decode_hex(&hex[n],hexlen,hexstr), n += hexlen; } free_json(retjson); diff --git a/iguana/dpow/dpow_tx.c b/iguana/dpow/dpow_tx.c index 5fd42d5ff..040d9e873 100755 --- a/iguana/dpow/dpow_tx.c +++ b/iguana/dpow/dpow_tx.c @@ -199,7 +199,7 @@ struct dpow_block *dpow_heightfind(struct supernet_info *myinfo,struct dpow_info return(bp); } -int32_t dpow_voutstandard(struct dpow_block *bp,uint8_t *serialized,int32_t m,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified) +int32_t dpow_voutstandard(struct supernet_info *myinfo,struct dpow_block *bp,uint8_t *serialized,int32_t m,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified) { uint32_t paxwdcrc=0,locktime=0,numvouts; struct iguana_info *coin; uint64_t satoshis,satoshisB; int32_t i,n=0,opretlen,len=0; uint8_t opret[16384],data[16384],extras[16384]; numvouts = 2; @@ -238,7 +238,7 @@ int32_t dpow_voutstandard(struct dpow_block *bp,uint8_t *serialized,int32_t m,in } if ( bp->MoMdepth > 0 && strcmp(bp->destcoin->symbol,"KMD") == 0 ) // || strcmp(bp->srccoin->symbol,"KMD") == 0) ) { - n = dpow_paxpending(extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp); + n = dpow_paxpending(myinfo,extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp); } satoshis = 0; len += iguana_rwnum(1,&serialized[len],sizeof(satoshis),&satoshis); @@ -264,7 +264,7 @@ int32_t dpow_voutstandard(struct dpow_block *bp,uint8_t *serialized,int32_t m,in return(len); } -bits256 dpow_notarytx(char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t usesigs,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified) +bits256 dpow_notarytx(struct supernet_info *myinfo,char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t usesigs,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified) { uint32_t k,m,numsigs,version,vout,crcval,sequenceid = 0xffffffff; bits256 zero; int32_t n,siglen,len; uint8_t serialized[32768],*sig; bits256 txid; struct dpow_entry *ep; struct dpow_coinentry *cp; signedtx[0] = 0; @@ -329,7 +329,7 @@ bits256 dpow_notarytx(char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow memcpy(&serialized[len],sig,siglen); len += siglen; numsigs++; - } else printf("Missing sig from k.%d\n",k); + } //else printf("%s -> %s src_or_dest.%d Missing sig from k.%d\n",bp->srccoin->symbol,bp->destcoin->symbol,src_or_dest,k); } else serialized[len++] = 0; len += iguana_rwnum(1,&serialized[len],sizeof(sequenceid),&sequenceid); //printf("height.%d mod.%d VINI.%d <- i.%d j.%d\n",height,height % numnotaries,m,i,j); @@ -338,7 +338,7 @@ bits256 dpow_notarytx(char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow break; } } - if ( (n= dpow_voutstandard(bp,&serialized[len],m,src_or_dest,pubkeys,numratified)) < 0 ) + if ( (n= dpow_voutstandard(myinfo,bp,&serialized[len],m,src_or_dest,pubkeys,numratified)) < 0 ) { printf("error dpow_voutstandard m.%d src_or_dest.%d\n",m,src_or_dest); return(zero); @@ -516,7 +516,7 @@ int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct dpow_info *dp,struc srchash.bytes[j] = dp->minerkey33[j+1]; if ( (vins= dpow_vins(coin,bp,bestk,bestmask,1,src_or_dest,useratified)) != 0 ) { - txid = dpow_notarytx(rawtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,bp->numratified!=0?bp->ratified_pubkeys:0,useratified*bp->numratified); + txid = dpow_notarytx(myinfo,rawtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,bp->numratified!=0?bp->ratified_pubkeys:0,useratified*bp->numratified); //char str[65]; printf("%s signedtxgen %s src_or_dest.%d (%d %llx) useratified.%d raw.(%s)\n",dp->symbol,bits256_str(str,txid),src_or_dest,bestk,(long long)bestmask,useratified,rawtx); if ( bits256_nonz(txid) != 0 && rawtx[0] != 0 ) // send tx to share utxo set { @@ -579,8 +579,8 @@ void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_info *dp,struct dpo channel = (src_or_dest != 0) ? DPOW_SIGBTCCHANNEL : DPOW_SIGCHANNEL; if ( bestk >= 0 && bp->state != 0xffffffff && coin != 0 ) { - dpow_notarytx(bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,pubkeys,numratified); // setcrcval - signedtxid = dpow_notarytx(bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,1,src_or_dest,pubkeys,numratified); + dpow_notarytx(myinfo,bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,pubkeys,numratified); // setcrcval + signedtxid = dpow_notarytx(myinfo,bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,1,src_or_dest,pubkeys,numratified); if ( strcmp("GAME",coin->symbol) == 0 ) printf("src_or_dest.%d bestk.%d %llx %s numsigs.%d signedtx.(%s)\n",src_or_dest,bestk,(long long)bestmask,bits256_str(str,signedtxid),numsigs,bp->signedtx); bp->state = 1; diff --git a/iguana/exchanges/CMakeLists.txt b/iguana/exchanges/CMakeLists.txt index 793aeb5a4..011e4cd37 100644 --- a/iguana/exchanges/CMakeLists.txt +++ b/iguana/exchanges/CMakeLists.txt @@ -31,4 +31,9 @@ target_link_libraries(marketmaker-mainnet ${MM_LIBS} etomiclib-mainnet) if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") target_link_libraries(marketmaker-mainnet -static-libgcc -static-libstdc++) target_link_libraries(marketmaker-testnet -static-libgcc -static-libstdc++) -endif() \ No newline at end of file +endif() +if(NOT DEFINED MM_VERSION) + SET(MM_VERSION UNKNOWN) +endif() +target_compile_definitions(marketmaker-mainnet PRIVATE -DMM_VERSION="${MM_VERSION}") +target_compile_definitions(marketmaker-testnet PRIVATE -DMM_VERSION="${MM_VERSION}") \ No newline at end of file diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 2201d67d7..c083d6afe 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -2011,16 +2011,25 @@ int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,c return(n); } -char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params) +char *bitcoind_passthrut(char *coinstr,char *serverport,char *userpass,char *method,char *params,int32_t timeout) { - if ( userpass[0] == 0 ) - return(clonestr("{\"error\":\"no rpcusername rpcpassword in coin.conf\"}")); - return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,4)); + /*struct iguana_info *coin; char *retstr; + if ( (coin= LP_coinfind(coinstr)) != 0 ) + { + portable_mutex_lock(&coin->curl_mutex); + retstr = bitcoind_RPCnew(coin->curl_handle,0,coinstr,serverport,userpass,method,params,timeout); + portable_mutex_unlock(&coin->curl_mutex); + return(retstr); + }*/ + return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,timeout)); } -char *bitcoind_passthrut(char *coinstr,char *serverport,char *userpass,char *method,char *params,int32_t timeout) +char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params) { - return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,timeout)); + if ( userpass[0] == 0 ) + return(clonestr("{\"error\":\"no rpcusername rpcpassword in coin.conf\"}")); + return(bitcoind_passthrut(coinstr,serverport,userpass,method,params,4)); + //return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,4)); } bits256 bits256_calcaddrhash(char *symbol,uint8_t *serialized,int32_t len) @@ -2093,7 +2102,7 @@ int32_t bitcoin_addr2rmd160(char *symbol,uint8_t taddr,uint8_t *addrtypep,uint8_ } else if ( (strcmp(symbol,"GRS") == 0 || strcmp(symbol,"SMART") == 0) && (buf[20+offset]&0xff) == hash.bytes[0] && (buf[21+offset]&0xff) == hash.bytes[1] && (buf[22+offset]&0xff) == hash.bytes[2] && (buf[23+offset]&0xff) == hash.bytes[3] ) return(20); - else + else if ( strcmp(symbol,"BTC") != 0 || *addrtypep == 0 || *addrtypep == 5 ) { int32_t i; //if ( len > 20 ) diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index f625b2c01..ce948fa95 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -251,10 +251,14 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) } #ifndef NOTETOMIC else if (coin->etomic[0] != 0) { - //balance = LP_etomic_get_balance(coin, coin->smartaddr); + int error = 0; + if (coin->inactive == 0) { + balance = LP_etomic_get_balance(coin, coin->smartaddr, &error); + } else { + balance = 0; + } jaddnum(item,"height",-1); - //jaddnum(item,"balance",dstr(balance)); - jaddnum(item,"balance",0); + jaddnum(item,"balance",dstr(balance)); } #endif else @@ -373,7 +377,8 @@ struct iguana_info *LP_coinadd(struct iguana_info *cdata) return(coin); } -uint16_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) +void *curl_easy_init(); +uint16_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,uint8_t decimals) { static void *ctx; char *name2; uint16_t origport = port; @@ -434,6 +439,9 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse coin->zcash = LP_IS_BITCOINCASH; //printf("set coin.%s <- LP_IS_BITCOINCASH %d\n",symbol,coin->zcash); } + coin->curl_handle = curl_easy_init(); + portable_mutex_init(&coin->curl_mutex); + coin->decimals = decimals; return(port); } @@ -477,7 +485,7 @@ struct iguana_info *LP_coinfind(char *symbol) else if ( strcmp(symbol,"KMD") == 0 ) name = "komodo"; else return(0); - port = LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0,0,busport,0); + port = LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0,0,busport,0,0); if ( port == 0 ) isinactive = 1; else isinactive = 0; @@ -519,7 +527,9 @@ struct iguana_info *LP_coincreate(cJSON *item) } 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 ) + + uint8_t decimals = juint(item,"decimals"); + 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"),decimals) < 0 ) { coin = LP_coinadd(&cdata); coin->inactive = (uint32_t)time(NULL); diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 8483bf7d8..1c77bc4f7 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -120,6 +120,7 @@ cancel(uuid)\n\ buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce)\n\ sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)\n\ withdraw(coin, outputs[], broadcast=0)\n\ +eth_withdraw(coin, to, amount, gas, gas_price, broadcast=0)\n\ txblast(coin, utxotxid, utxovout, utxovalue, txfee, passphrase, outputs[], broadcast=0)\n\ sendrawtransaction(coin, signedtx)\n\ swapstatus(pending=0, fast=0)\n\ @@ -151,6 +152,7 @@ getprice(base, rel)\n\ //getmessages(firsti=0, num=100)\n\ //deletemessages(firsti=0, num=100)\n\ secretaddresses(prefix='secretaddress', passphrase, num=10, pubtype=60, taddr=0)\n\ +gen64addrs(passphrase, taddr=0, pubtype=60)\n\ electrum(coin, ipaddr, port)\n\ snapshot(coin, height)\n\ snapshot_balance(coin, height, addresses[])\n\ @@ -173,10 +175,17 @@ unlockedspend(coin, txid)\n\ opreturndecrypt(coin, txid, passphrase)\n\ getendpoint(port=5555)\n\ getfee(coin)\n\ +mpnet(onoff)\n\ sleep(seconds=60)\n\ listtransactions(coin, address, count=10, skip=0)\n\ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ +version\n\ \"}")); + if ( strcmp(method,"version") == 0 ) { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",MM_VERSION); + return(jprint(retjson,1)); + } if ( (base= jstr(argjson,"base")) == 0 ) base = ""; @@ -232,12 +241,23 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ { if ( (ptr= LP_coinsearch("KMD")) != 0 ) { - if ( jint(argjson,"weeks") <= 0 || jdouble(argjson,"amount") < 10. ) - return(clonestr("{\"error\":\"instantdex_deposit needs to have weeks and amount\"}")); - else return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jobj(argjson,"broadcast") != 0 ? jint(argjson,"broadcast") : 1)); + if ( jint(argjson,"weeks") <= 0 ) { + return(clonestr("{\"error\":\"instantdex_deposit weeks param must be greater than zero\"}")); + } + if ( jdouble(argjson,"amount") < 10. ) { + return(clonestr("{\"error\":\"instantdex_deposit amount param must be equal or greater than 10\"}")); + } + + return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jobj(argjson,"broadcast") != 0 ? jint(argjson,"broadcast") : 1)); } return(clonestr("{\"error\":\"cant find KMD\"}")); } + else if ( strcmp(method,"mpnet") == 0 ) + { + G.mpnet = jint(argjson,"onoff"); + printf("MPNET onoff.%d\n",G.mpnet); + return(clonestr("{\"status\":\"success\"}")); + } else if ( strcmp(method,"getendpoint") == 0 ) { int32_t err,mode; uint16_t wsport = 5555; char endpoint[64],bindpoint[64]; @@ -277,6 +297,10 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ } return(jprint(retjson,1)); } + else if ( strcmp(method,"verus") == 0 ) + { + return(verusblocks()); + } else if ( strcmp(method,"instantdex_claim") == 0 ) { if ( (ptr= LP_coinsearch("KMD")) != 0 ) @@ -392,11 +416,6 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ jaddbits256(retjson,"privkey",privkey); bitcoin_priv2wif(coin,wiftaddr,wifstr,privkey,wiftype); jaddstr(retjson,"wif",wifstr); -#ifndef NOTETOMIC - char ethaddr[50]; - LP_etomic_pubkeystr_to_addr(pubsecp, ethaddr); - jaddstr(retjson,"ethaddr",ethaddr); -#endif return(jprint(retjson,1)); } else return(clonestr("{\"error\":\"need to have passphrase\"}")); } @@ -408,6 +427,13 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ { return(LP_ticker(jstr(argjson,"base"),jstr(argjson,"rel"))); } + else if ( strcmp(method,"gen64addrs") == 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_gen64addrs(ctx,jstr(argjson,"passphrase"),taddr,pubtype)); + } else if ( strcmp(method,"secretaddresses") == 0 ) { uint8_t taddr,pubtype; @@ -452,6 +478,12 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ } else if ( strcmp(method,"inuse") == 0 ) return(jprint(LP_inuse_json(),1)); +#ifndef NOTETOMIC + else if ( strcmp(method,"eth_gas_price") == 0 ) + { + return LP_eth_gas_price(); + } +#endif else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) return(retstr); if ( base[0] != 0 && rel[0] != 0 ) @@ -482,14 +514,14 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ double price,bid,ask; if ( strcmp(method,"getprice") == 0 ) { - ask = LP_price(base,rel); - if ( (bid= LP_price(rel,base)) > SMALLVAL ) + ask = LP_price(1,base,rel); + if ( (bid= LP_price(1,rel,base)) > SMALLVAL ) bid = 1./bid; } else { - ask = LP_getmyprice(base,rel); - if ( (bid= LP_getmyprice(rel,base)) > SMALLVAL ) + ask = LP_getmyprice(1,base,rel); + if ( (bid= LP_getmyprice(1,rel,base)) > SMALLVAL ) bid = 1./bid; } price = _pairaved(bid,ask); @@ -503,24 +535,24 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ jaddnum(retjson,"price",price); return(jprint(retjson,1)); } + else if ( strcmp(method,"orderbook") == 0 ) + return(LP_orderbook(base,rel,jint(argjson,"duration"))); 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 ( LP_mypriceset(&changed,base,rel,price) < 0 ) + if ( LP_mypriceset(1,&changed,base,rel,price) < 0 ) return(clonestr("{\"error\":\"couldnt set price\"}")); - //else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 ) + //else if ( LP_mypriceset(1,&changed,rel,base,1./price) < 0 ) // return(clonestr("{\"error\":\"couldnt set price\"}")); else if ( price == 0. || jobj(argjson,"broadcast") == 0 || jint(argjson,"broadcast") != 0 ) return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio)); else return(clonestr("{\"result\":\"success\"}")); } - else if ( strcmp(method,"orderbook") == 0 ) - return(LP_orderbook(base,rel,jint(argjson,"duration"))); else if ( strcmp(method,"myprice") == 0 ) { - if ( LP_myprice(&bid,&ask,base,rel) > SMALLVAL ) + if ( LP_myprice(1,&bid,&ask,base,rel) > SMALLVAL ) { retjson = cJSON_CreateObject(); jaddstr(retjson,"base",base); @@ -541,7 +573,7 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ } else vol = jdouble(argjson,"relvolume"); if ( price > SMALLVAL ) { - return(LP_autobuy(ctx,fomo,myipaddr,pubsock,base,rel,price,vol,jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0,jstr(argjson,"uuid"))); + return(LP_autobuy(ctx,fomo,myipaddr,pubsock,base,rel,price,vol,jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0,jstr(argjson,"uuid"),jint(argjson,"fill"),jint(argjson,"gtc"))); } else return(clonestr("{\"error\":\"no price set\"}")); } else if ( strcmp(method,"sell") == 0 ) @@ -555,7 +587,7 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ } else vol = jdouble(argjson,"basevolume"); if ( price > SMALLVAL ) { - return(LP_autobuy(ctx,fomo,myipaddr,pubsock,rel,base,1./price,vol,jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0,jstr(argjson,"uuid"))); + return(LP_autobuy(ctx,fomo,myipaddr,pubsock,rel,base,1./price,vol,jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0,jstr(argjson,"uuid"),jint(argjson,"fill"),jint(argjson,"gtc"))); } else return(clonestr("{\"error\":\"no price set\"}")); } } @@ -580,12 +612,35 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ jaddstr(retjson,"coin",coin); return(jprint(retjson,1)); } +#ifndef NOTETOMIC + if (strcmp(coin, "ETOMIC") == 0 && LP_RTsmartbalance(ptr) < 20 * SATOSHIDEN) { + if (get_etomic_from_faucet(ptr->smartaddr) != 1) { + return(clonestr("{\"error\":\"Could not get ETOMIC from faucet!\"}")); + } + } + + if (ptr->etomic[0] != 0) { + if (isValidAddress(ptr->etomic) == 0) { + return(clonestr("{\"error\":\"'etomic' field is not valid address!\"}")); + } + + struct iguana_info *etomic_coin = LP_coinsearch("ETOMIC"); + if (etomic_coin->inactive != 0) { + return(clonestr("{\"error\":\"Enable ETOMIC first to use ETH/ERC20!\"}")); + } + + if (ptr->decimals == 0 && strcmp(coin, "ETH") != 0) { + ptr->decimals = getErc20DecimalsZeroOnError(ptr->etomic); + if (ptr->decimals == 0) { + return(clonestr("{\"error\":\"Could not get token decimals or token has zero decimals which is not supported!\"}")); + } + } + } +#endif if ( LP_conflicts_find(ptr) == 0 ) { cJSON *array; ptr->inactive = 0; - if ( ptr->smartaddr[0] != 0 ) - LP_unspents_load(coin,ptr->smartaddr); LP_unspents_load(coin,ptr->smartaddr); if ( strcmp(ptr->symbol,"KMD") == 0 ) LP_importaddress("KMD",BOTS_BONDADDRESS); @@ -797,7 +852,7 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ return(jprint(retjson,1)); } else if ( strcmp(method,"myprices") == 0 ) - return(LP_myprices()); + return(LP_myprices(1)); else if ( strcmp(method,"trust") == 0 ) return(LP_pubkey_trustset(jbits256(argjson,"pubkey"),jint(argjson,"trust"))); else if ( strcmp(method,"trusted") == 0 ) @@ -858,14 +913,14 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ double price,bid,ask; if ( strcmp(method,"getprice") == 0 ) { - ask = LP_price(base,rel); - if ( (bid= LP_price(rel,base)) > SMALLVAL ) + ask = LP_price(1,base,rel); + if ( (bid= LP_price(1,rel,base)) > SMALLVAL ) bid = 1./bid; } else { - ask = LP_getmyprice(base,rel); - if ( (bid= LP_getmyprice(rel,base)) > SMALLVAL ) + ask = LP_getmyprice(1,base,rel); + if ( (bid= LP_getmyprice(1,rel,base)) > SMALLVAL ) bid = 1./bid; } price = _pairaved(bid,ask); diff --git a/iguana/exchanges/LP_etomic.c b/iguana/exchanges/LP_etomic.c index 532f8f4d5..2964ea03d 100644 --- a/iguana/exchanges/LP_etomic.c +++ b/iguana/exchanges/LP_etomic.c @@ -22,6 +22,9 @@ // Created by artem on 24.01.18. // #include "LP_etomic.h" +#define ALICE_PAYMENT_SENT 1 +#define BOB_DEPOSIT_SENT 1 +#define BOB_PAYMENT_SENT 1 int32_t LP_etomic_wait_for_confirmation(char *txId) { @@ -38,13 +41,16 @@ void LP_etomic_pubkeystr_to_addr(char *pubkey, char *output) char *LP_etomicalice_send_fee(struct basilisk_swap *swap) { char amount[100], secretKey[70], dexaddr[50]; - satoshisToWei(amount, swap->myfee.I.amount); + satoshisToWei(amount, LP_DEXFEE(swap->I.alicerealsat)); + swap->myfee.I.eth_amount = LP_DEXFEE(swap->I.alicerealsat); uint8arrayToHex(secretKey, swap->persistent_privkey.bytes, 32); LP_etomic_pubkeystr_to_addr(INSTANTDEX_PUBKEY, dexaddr); if (strcmp(swap->I.alicestr,"ETH") == 0 ) { - return(sendEth(dexaddr, amount, secretKey, 1)); + return(sendEth(dexaddr, amount, secretKey, 1, 0, 0, 1)); } else { - return(sendErc20(swap->I.alicetomic, dexaddr, amount, secretKey, 1)); + struct iguana_info *alicecoin = LP_coinfind(swap->I.alicestr); + + return(sendErc20(swap->I.alicetomic, dexaddr, amount, secretKey, 1, 0, 0, 1, alicecoin->decimals)); } } @@ -55,7 +61,7 @@ uint8_t LP_etomic_verify_alice_fee(struct basilisk_swap *swap) return(0); } EthTxData data = getEthTxData(swap->otherfee.I.ethTxid); - if (strcmp(data.from, swap->I.etomicdest) != 0) { + if (compareAddresses(data.from, swap->I.etomicdest) == 0) { printf("Alice fee tx %s was sent from wrong address %s\n", swap->otherfee.I.ethTxid, data.from); return(0); } @@ -63,31 +69,33 @@ uint8_t LP_etomic_verify_alice_fee(struct basilisk_swap *swap) char dexaddr[50]; LP_etomic_pubkeystr_to_addr(INSTANTDEX_PUBKEY, dexaddr); if ( strcmp(swap->I.alicestr,"ETH") == 0 ) { - if (strcmp(data.to, dexaddr) != 0) { + if (compareAddresses(data.to, dexaddr) == 0) { printf("Alice fee %s was sent to wrong address %s\n", swap->otherfee.I.ethTxid, data.to); return(0); } uint64_t txValue = weiToSatoshi(data.valueHex); - if (txValue != swap->otherfee.I.amount) { - printf("Alice fee %s amount %" PRIu64 " is not equal to expected %" PRIu64 "\n", swap->otherfee.I.ethTxid, txValue, swap->otherfee.I.amount); + if (txValue != LP_DEXFEE(swap->I.alicerealsat)) { + printf("Alice fee %s amount %" PRIu64 " is not equal to expected %" PRId64 "\n", swap->otherfee.I.ethTxid, txValue, LP_DEXFEE(swap->I.alicerealsat)); return(0); } return(1); } else { - if (strcmp(data.to, swap->I.alicetomic) != 0) { + struct iguana_info *alicecoin = LP_coinfind(swap->I.alicestr); + + if (compareAddresses(data.to, swap->I.alicetomic) == 0) { printf("Alice ERC20 fee %s token address %s is not equal to expected %s\n", swap->otherfee.I.ethTxid, data.to, swap->I.alicetomic); return(0); } char weiAmount[70]; - satoshisToWei(weiAmount, swap->otherfee.I.amount); - return(verifyAliceErc20FeeData(swap->I.alicetomic, dexaddr, weiAmount, data.input)); + satoshisToWei(weiAmount, LP_DEXFEE(swap->I.alicerealsat)); + return(verifyAliceErc20FeeData(swap->I.alicetomic, dexaddr, weiAmount, data.input, alicecoin->decimals)); } } char *LP_etomicalice_send_payment(struct basilisk_swap *swap) { AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20; BasicTxData txData; - + swap->alicepayment.I.eth_amount = swap->I.alicerealsat; // set input and txData fields from the swap data structure memset(&txData,0,sizeof(txData)); if ( strcmp(swap->I.alicestr,"ETH") == 0 ) @@ -100,28 +108,31 @@ char *LP_etomicalice_send_payment(struct basilisk_swap *swap) strcpy(txData.from, swap->I.etomicdest); strcpy(txData.to, ETOMIC_ALICECONTRACT); - satoshisToWei(txData.amount, swap->I.alicesatoshis); + satoshisToWei(txData.amount, swap->I.alicerealsat); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); return(aliceSendsEthPayment(input,txData)); } else { + struct iguana_info *alicecoin = LP_coinfind(swap->I.alicestr); + memset(&input20,0,sizeof(input20)); strcpy(input20.bobAddress, swap->I.etomicsrc); uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20); uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20); uint8arrayToHex(input20.dealId, swap->alicepayment.I.actualtxid.bytes, 32); strcpy(input20.tokenAddress, swap->I.alicetomic); - satoshisToWei(input20.amount, swap->I.alicesatoshis); + satoshisToWei(input20.amount, swap->I.alicerealsat); + input20.decimals = alicecoin->decimals; strcpy(txData.from, swap->I.etomicdest); strcpy(txData.to, ETOMIC_ALICECONTRACT); strcpy(txData.amount, "0"); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); - uint64_t allowance = getErc20Allowance(swap->I.etomicdest, ETOMIC_ALICECONTRACT, swap->I.alicetomic); - if (allowance < swap->I.alicesatoshis) { + uint64_t allowance = getErc20Allowance(swap->I.etomicdest, ETOMIC_ALICECONTRACT, swap->I.alicetomic, alicecoin->decimals); + if (allowance < swap->I.alicerealsat) { printf("Alice token allowance is too low, setting new allowance\n"); ApproveErc20Input approveErc20Input; strcpy(approveErc20Input.tokenAddress, swap->I.alicetomic); @@ -149,20 +160,19 @@ uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId) return(0); } EthTxData data = getEthTxData(txId); - if (strcmp(data.to, ETOMIC_ALICECONTRACT) != 0) { + if (compareAddresses(data.to, ETOMIC_ALICECONTRACT) == 0) { printf("Alice payment %s was sent to wrong address %s\n", txId, data.to); return(0); } - if (strcmp(data.from, swap->I.etomicdest) != 0) { + if (compareAddresses(data.from, swap->I.etomicdest) == 0) { printf("Alice payment %s was done from wrong address %s\n", txId, data.from); return(0); } AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20; - if ( strcmp(swap->I.alicestr,"ETH") == 0 ) { uint64_t paymentAmount = weiToSatoshi(data.valueHex); - if (paymentAmount != swap->I.alicesatoshis) { - printf("Alice payment amount %" PRIu64 " does not match expected %" PRIu64 "\n", paymentAmount, swap->I.alicesatoshis); + if (paymentAmount != swap->I.alicerealsat) { + printf("Alice payment amount %" PRIu64 " does not match expected %" PRIu64 "\n", paymentAmount, swap->I.alicerealsat); return(0); } memset(&input,0,sizeof(input)); @@ -173,13 +183,16 @@ uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId) return(verifyAliceEthPaymentData(input, data.input)); } else { + struct iguana_info *alicecoin = LP_coinfind(swap->I.alicestr); + memset(&input20,0,sizeof(input20)); strcpy(input20.bobAddress, swap->I.etomicsrc); uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20); uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20); uint8arrayToHex(input20.dealId, swap->alicepayment.I.actualtxid.bytes, 32); strcpy(input20.tokenAddress, swap->I.alicetomic); - satoshisToWei(input20.amount, swap->I.alicesatoshis); + satoshisToWei(input20.amount, swap->I.alicerealsat); + input20.decimals = alicecoin->decimals; return(verifyAliceErc20PaymentData(input20, data.input)); } @@ -187,11 +200,11 @@ uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId) char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap) { - if (waitForConfirmation(swap->alicePaymentEthTx) < 0) { - printf("Alice ETH payment %s is not found, can't reclaim\n", swap->alicePaymentEthTx); + if (waitForConfirmation(swap->eth_tx_ids[BASILISK_ALICEPAYMENT]) < 0) { + printf("Alice ETH payment %s is not found, can't reclaim\n", swap->eth_tx_ids[BASILISK_ALICEPAYMENT]); return NULL; } - EthTxReceipt receipt = getEthTxReceipt(swap->alicePaymentEthTx); + EthTxReceipt receipt = getEthTxReceipt(swap->eth_tx_ids[BASILISK_ALICEPAYMENT]); if (strcmp(receipt.status, "0x1") != 0) { printf("Alice payment receipt status failed, can't reclaim\n"); return NULL; @@ -201,13 +214,18 @@ char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap) memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); - struct iguana_info *ecoin; + struct iguana_info *ecoin, *alice_coin; bits256 privkey; ecoin = LP_coinfind("ETOMIC"); + alice_coin = LP_coinfind(swap->dest); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); uint8arrayToHex(input.dealId, swap->txids[BASILISK_ALICEPAYMENT].bytes, 32); - satoshisToWei(input.amount, swap->destamount); + if (alicePaymentStatus(input.dealId + 2) != ALICE_PAYMENT_SENT) { + printf("Alice payment smart contract status check failed, can't spend\n"); + return NULL; + } + satoshisToWei(input.amount, swap->alicerealsat); if (swap->alicetomic[0] != 0) { strcpy(input.tokenAddress, swap->alicetomic); @@ -223,6 +241,8 @@ char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap) } uint8arrayToHex(input.bobSecret, invertedSecret.bytes, 32); + input.decimals = alice_coin->decimals; + strcpy(txData.from, swap->etomicdest); strcpy(txData.to, ETOMIC_ALICECONTRACT); strcpy(txData.amount, "0"); @@ -232,11 +252,11 @@ char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap) char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap) { - if (waitForConfirmation(swap->alicePaymentEthTx) < 0) { - printf("Alice ETH payment %s is not found, can't spend\n", swap->alicePaymentEthTx); + if (waitForConfirmation(swap->eth_tx_ids[BASILISK_ALICEPAYMENT]) < 0) { + printf("Alice ETH payment %s is not found, can't spend\n", swap->eth_tx_ids[BASILISK_ALICEPAYMENT]); return NULL; } - EthTxReceipt receipt = getEthTxReceipt(swap->alicePaymentEthTx); + EthTxReceipt receipt = getEthTxReceipt(swap->eth_tx_ids[BASILISK_ALICEPAYMENT]); if (strcmp(receipt.status, "0x1") != 0) { printf("Alice payment receipt status failed, can't spend\n"); return NULL; @@ -253,7 +273,12 @@ char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap) privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); uint8arrayToHex(input.dealId, swap->txids[BASILISK_ALICEPAYMENT].bytes, 32); - satoshisToWei(input.amount, swap->destamount); + if (alicePaymentStatus(input.dealId + 2) != ALICE_PAYMENT_SENT) { + printf("Alice payment smart contract status check failed, can't spend\n"); + return NULL; + } + + satoshisToWei(input.amount, swap->alicerealsat); if (swap->alicetomic[0] != 0) { strcpy(input.tokenAddress, swap->alicetomic); @@ -268,6 +293,8 @@ char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap) } uint8arrayToHex(input.aliceSecret, invertedSecret.bytes, 32); uint8arrayToHex(input.bobHash, swap->secretBn, 20); + struct iguana_info *alice_coin = LP_coinfind(swap->dest); + input.decimals = alice_coin->decimals; strcpy(txData.from, swap->etomicsrc); strcpy(txData.to, ETOMIC_ALICECONTRACT); @@ -292,24 +319,27 @@ char *LP_etomicbob_sends_deposit(struct basilisk_swap *swap) strcpy(txData.from, swap->I.etomicsrc); strcpy(txData.to, ETOMIC_BOBCONTRACT); - satoshisToWei(txData.amount, swap->bobdeposit.I.amount); + satoshisToWei(txData.amount, LP_DEPOSITSATOSHIS(swap->I.bobrealsat)); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); return bobSendsEthDeposit(input, txData); } else { + struct iguana_info *bobcoin = LP_coinfind(swap->I.bobstr); + uint8arrayToHex(input20.depositId, swap->bobdeposit.I.actualtxid.bytes, 32); strcpy(input20.aliceAddress, swap->I.etomicdest); uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20); - satoshisToWei(input20.amount, swap->bobdeposit.I.amount); + satoshisToWei(input20.amount, LP_DEPOSITSATOSHIS(swap->I.bobrealsat)); strcpy(input20.tokenAddress, swap->I.bobtomic); input20.lockTime = swap->bobdeposit.I.locktime; + input20.decimals = bobcoin->decimals; strcpy(txData.from, swap->I.etomicsrc); strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.amount, "0"); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); - uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic); - if (allowance < swap->bobdeposit.I.amount) { + uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic, bobcoin->decimals); + if (allowance < LP_DEPOSITSATOSHIS(swap->I.bobrealsat)) { printf("Bob token allowance is too low, setting new allowance\n"); ApproveErc20Input approveErc20Input; strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic); @@ -337,11 +367,11 @@ uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId) return(0); } EthTxData data = getEthTxData(txId); - if (strcmp(data.to, ETOMIC_BOBCONTRACT) != 0) { + if (compareAddresses(data.to, ETOMIC_BOBCONTRACT) == 0) { printf("Bob deposit txid %s was sent to wrong address %s\n", txId, data.to); return(0); } - if (strcmp(data.from, swap->I.etomicsrc) != 0) { + if (compareAddresses(data.from, swap->I.etomicsrc) == 0) { printf("Bob deposit txid %s was sent from wrong address %s\n", txId, data.from); return(0); } @@ -351,8 +381,8 @@ uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId) memset(&input20,0,sizeof(input20)); if ( strcmp(swap->I.bobstr,"ETH") == 0 ) { uint64_t depositAmount = weiToSatoshi(data.valueHex); - if (depositAmount != swap->bobdeposit.I.amount) { - printf("Bob deposit %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, depositAmount, swap->bobdeposit.I.amount); + if (depositAmount != LP_DEPOSITSATOSHIS(swap->I.bobrealsat)) { + printf("Bob deposit %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, depositAmount, LP_DEPOSITSATOSHIS(swap->I.bobrealsat)); return(0); } uint8arrayToHex(input.depositId, swap->bobdeposit.I.actualtxid.bytes, 32); @@ -362,12 +392,15 @@ uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId) return verifyBobEthDepositData(input, data.input); } else { + struct iguana_info *bobcoin = LP_coinfind(swap->I.bobstr); + uint8arrayToHex(input20.depositId, swap->bobdeposit.I.actualtxid.bytes, 32); strcpy(input20.aliceAddress, swap->I.etomicdest); uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20); - satoshisToWei(input20.amount, swap->bobdeposit.I.amount); + satoshisToWei(input20.amount, LP_DEPOSITSATOSHIS(swap->I.bobrealsat)); strcpy(input20.tokenAddress, swap->I.bobtomic); input20.lockTime = swap->bobdeposit.I.locktime; + input20.decimals = bobcoin->decimals; return verifyBobErc20DepositData(input20, data.input); } @@ -375,8 +408,8 @@ uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId) char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap) { - if (waitForConfirmation(swap->bobDepositEthTx) < 0) { - printf("Bob deposit %s is not found, can't refund\n", swap->bobDepositEthTx); + if (waitForConfirmation(swap->eth_tx_ids[BASILISK_BOBDEPOSIT]) < 0) { + printf("Bob deposit %s is not found, can't refund\n", swap->eth_tx_ids[BASILISK_BOBDEPOSIT]); return NULL; } BobRefundsDepositInput input; @@ -384,17 +417,23 @@ char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap) memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); - struct iguana_info *ecoin; + struct iguana_info *ecoin, *bobcoin; bits256 privkey; ecoin = LP_coinfind("ETOMIC"); + bobcoin = LP_coinfind(swap->src); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); - EthTxReceipt receipt = getEthTxReceipt(swap->bobDepositEthTx); + EthTxReceipt receipt = getEthTxReceipt(swap->eth_tx_ids[BASILISK_BOBDEPOSIT]); if (strcmp(receipt.status, "0x1") != 0) { - printf("Bob deposit %s receipt status failed, can't refund\n", swap->bobDepositEthTx); + printf("Bob deposit %s receipt status failed, can't refund\n", swap->eth_tx_ids[BASILISK_BOBDEPOSIT]); return NULL; } uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32); + if (bobDepositStatus(input.depositId + 2) != BOB_DEPOSIT_SENT) { + printf("Bob deposit smart contract status check failed, can't claim\n"); + return NULL; + } + strcpy(input.aliceAddress, swap->etomicdest); bits256 invertedSecret; @@ -409,7 +448,8 @@ char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap) } else { strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); } - satoshisToWei(input.amount, swap->values[BASILISK_BOBDEPOSIT]); + satoshisToWei(input.amount, LP_DEPOSITSATOSHIS(swap->bobrealsat)); + input.decimals = bobcoin->decimals; strcpy(txData.from, swap->etomicsrc); strcpy(txData.to, ETOMIC_BOBCONTRACT); @@ -435,24 +475,27 @@ char *LP_etomicbob_sends_payment(struct basilisk_swap *swap) strcpy(txData.from, swap->I.etomicsrc); strcpy(txData.to, ETOMIC_BOBCONTRACT); - satoshisToWei(txData.amount, swap->bobpayment.I.amount); + satoshisToWei(txData.amount, swap->I.bobrealsat); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); return bobSendsEthPayment(input, txData); } else { + struct iguana_info *bobcoin = LP_coinfind(swap->I.bobstr); + uint8arrayToHex(input20.paymentId, swap->bobpayment.I.actualtxid.bytes, 32); strcpy(input20.aliceAddress, swap->I.etomicdest); uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20); - satoshisToWei(input20.amount, swap->bobpayment.I.amount); + satoshisToWei(input20.amount, swap->I.bobrealsat); strcpy(input20.tokenAddress, swap->I.bobtomic); input20.lockTime = swap->bobpayment.I.locktime; + input20.decimals = bobcoin->decimals; strcpy(txData.from, swap->I.etomicsrc); strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.amount, "0"); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); - uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic); - if (allowance < swap->bobpayment.I.amount) { + uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic, bobcoin->decimals); + if (allowance < swap->I.bobrealsat) { printf("Bob token allowance is too low, setting new allowance\n"); ApproveErc20Input approveErc20Input; strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic); @@ -480,21 +523,20 @@ uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId) return 0; } EthTxData data = getEthTxData(txId); - if (strcmp(data.to, ETOMIC_BOBCONTRACT) != 0) { + if (compareAddresses(data.to, ETOMIC_BOBCONTRACT) == 0) { printf("Bob payment %s was sent to wrong address %s\n", txId, data.to); } - if (strcmp(data.from, swap->I.etomicsrc) != 0) { + if (compareAddresses(data.from, swap->I.etomicsrc) == 0) { printf("Bob payment %s was sent from wrong address %s\n", txId, data.from); } BobSendsEthPaymentInput input; BobSendsErc20PaymentInput input20; memset(&input,0,sizeof(input)); memset(&input20,0,sizeof(input20)); - if ( strcmp(swap->I.bobstr,"ETH") == 0 ) { uint64_t paymentAmount = weiToSatoshi(data.valueHex); - if (paymentAmount != swap->bobpayment.I.amount) { - printf("Bob payment %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, paymentAmount, swap->bobpayment.I.amount); + if (paymentAmount != swap->I.bobrealsat) { + printf("Bob payment %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, paymentAmount, swap->I.bobrealsat); return(0); } uint8arrayToHex(input.paymentId, swap->bobpayment.I.actualtxid.bytes, 32); @@ -504,12 +546,15 @@ uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId) return verifyBobEthPaymentData(input, data.input); } else { + struct iguana_info *bobcoin = LP_coinfind(swap->I.bobstr); + uint8arrayToHex(input20.paymentId, swap->bobpayment.I.actualtxid.bytes, 32); strcpy(input20.aliceAddress, swap->I.etomicdest); uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20); - satoshisToWei(input20.amount, swap->bobpayment.I.amount); + satoshisToWei(input20.amount, swap->I.bobrealsat); strcpy(input20.tokenAddress, swap->I.bobtomic); input20.lockTime = swap->bobpayment.I.locktime; + input20.decimals = bobcoin->decimals; return verifyBobErc20PaymentData(input20, data.input); } @@ -517,8 +562,8 @@ uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId) char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap) { - if (waitForConfirmation(swap->bobPaymentEthTx) < 0) { - printf("Bob payment %s is not found, can't reclaim\n", swap->bobPaymentEthTx); + if (waitForConfirmation(swap->eth_tx_ids[BASILISK_BOBPAYMENT]) < 0) { + printf("Bob payment %s is not found, can't reclaim\n", swap->eth_tx_ids[BASILISK_BOBPAYMENT]); return NULL; } BobReclaimsBobPaymentInput input; @@ -526,17 +571,22 @@ char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap) memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); - struct iguana_info *ecoin; + struct iguana_info *ecoin, *bobcoin; bits256 privkey; ecoin = LP_coinfind("ETOMIC"); + bobcoin = LP_coinfind(swap->src); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); - EthTxReceipt receipt = getEthTxReceipt(swap->bobPaymentEthTx); + EthTxReceipt receipt = getEthTxReceipt(swap->eth_tx_ids[BASILISK_BOBPAYMENT]); if (strcmp(receipt.status, "0x1") != 0) { printf("Bob payment receipt status failed, can't reclaim\n"); return NULL; } uint8arrayToHex(input.paymentId, swap->txids[BASILISK_BOBPAYMENT].bytes, 32); + if (bobPaymentStatus(input.paymentId + 2) != BOB_PAYMENT_SENT) { + printf("Bob payment smart contract status check failed, can't spend\n"); + return NULL; + } strcpy(input.aliceAddress, swap->etomicdest); uint8arrayToHex(input.aliceHash, swap->secretAm, 20); @@ -545,7 +595,8 @@ char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap) } else { strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); } - satoshisToWei(input.amount, swap->values[BASILISK_BOBPAYMENT]); + satoshisToWei(input.amount, swap->bobrealsat); + input.decimals = bobcoin->decimals; strcpy(txData.from, swap->etomicsrc); strcpy(txData.to, ETOMIC_BOBCONTRACT); @@ -556,8 +607,8 @@ char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap) char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap) { - if (waitForConfirmation(swap->bobPaymentEthTx) < 0) { - printf("Bob payment %s is not found, can't spend\n", swap->bobPaymentEthTx); + if (waitForConfirmation(swap->eth_tx_ids[BASILISK_BOBPAYMENT]) < 0) { + printf("Bob payment %s is not found, can't spend\n", swap->eth_tx_ids[BASILISK_BOBPAYMENT]); return NULL; } AliceSpendsBobPaymentInput input; @@ -565,18 +616,23 @@ char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap) memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); - EthTxReceipt receipt = getEthTxReceipt(swap->bobPaymentEthTx); + EthTxReceipt receipt = getEthTxReceipt(swap->eth_tx_ids[BASILISK_BOBPAYMENT]); if (strcmp(receipt.status, "0x1") != 0) { - printf("Bob payment %s receipt status failed, can't spend\n", swap->bobPaymentEthTx); + printf("Bob payment %s receipt status failed, can't spend\n", swap->eth_tx_ids[BASILISK_BOBPAYMENT]); return NULL; } - struct iguana_info *ecoin; + struct iguana_info *ecoin, *bobcoin; bits256 privkey; ecoin = LP_coinfind("ETOMIC"); + bobcoin = LP_coinfind(swap->src); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); uint8arrayToHex(input.paymentId, swap->txids[BASILISK_BOBPAYMENT].bytes, 32); - satoshisToWei(input.amount, swap->values[BASILISK_BOBPAYMENT]); + if (bobPaymentStatus(input.paymentId + 2) != BOB_PAYMENT_SENT) { + printf("Bob payment smart contract status check failed, can't spend\n"); + return NULL; + } + satoshisToWei(input.amount, swap->bobrealsat); if (swap->bobtomic[0] != 0) { strcpy(input.tokenAddress, swap->bobtomic); @@ -591,6 +647,7 @@ char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap) invertedSecret.bytes[i] = swap->privAm.bytes[31 - i]; } uint8arrayToHex(input.aliceSecret, invertedSecret.bytes, 32); + input.decimals = bobcoin->decimals; strcpy(txData.from, swap->etomicdest); strcpy(txData.to, ETOMIC_BOBCONTRACT); @@ -601,8 +658,8 @@ char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap) char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap) { - if (waitForConfirmation(swap->bobDepositEthTx) < 0) { - printf("Bob deposit %s is not found, can't claim\n", swap->bobDepositEthTx); + if (waitForConfirmation(swap->eth_tx_ids[BASILISK_BOBDEPOSIT]) < 0) { + printf("Bob deposit %s is not found, can't claim\n", swap->eth_tx_ids[BASILISK_BOBDEPOSIT]); return NULL; } AliceClaimsBobDepositInput input; @@ -610,19 +667,25 @@ char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap) memset(&txData,0,sizeof(txData)); memset(&input,0,sizeof(input)); - EthTxReceipt receipt = getEthTxReceipt(swap->bobDepositEthTx); + EthTxReceipt receipt = getEthTxReceipt(swap->eth_tx_ids[BASILISK_BOBDEPOSIT]); if (strcmp(receipt.status, "0x1") != 0) { printf("Bob deposit receipt status failed, can't claim\n"); return NULL; } - struct iguana_info *ecoin; + struct iguana_info *ecoin, *bobcoin; bits256 privkey; ecoin = LP_coinfind("ETOMIC"); + bobcoin = LP_coinfind(swap->src); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32); - satoshisToWei(input.amount, swap->values[BASILISK_BOBDEPOSIT]); + if (bobDepositStatus(input.depositId + 2) != BOB_DEPOSIT_SENT) { + printf("Bob deposit smart contract status check failed, can't claim\n"); + return NULL; + } + + satoshisToWei(input.amount, LP_DEPOSITSATOSHIS(swap->bobrealsat)); if (swap->bobtomic[0] != 0) { strcpy(input.tokenAddress, swap->bobtomic); @@ -632,6 +695,7 @@ char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap) strcpy(input.bobAddress, swap->etomicsrc); uint8arrayToHex(input.bobHash, swap->secretBn, 20); + input.decimals = bobcoin->decimals; strcpy(txData.from, swap->etomicdest); strcpy(txData.to, ETOMIC_BOBCONTRACT); @@ -702,13 +766,13 @@ int32_t LP_etomic_pub2addr(char *coinaddr,uint8_t pub64[64]) uint8_t LP_etomic_is_empty_tx_id(char *txId) { - if (strcmp(txId, EMPTY_ETH_TX_ID) == 0) { + if (txId[0] == 0 || strcmp(txId, EMPTY_ETH_TX_ID) == 0) { return 1; } return 0; } -uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr) +uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr, int *error) { if (coin->etomic[0] == 0) { printf("Trying to get etomic balance for non-etomic coin %s!", coin->symbol); @@ -716,8 +780,8 @@ uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr) } if (strcmp(coin->symbol, "ETH") == 0) { - return getEthBalance(coinaddr); + return getEthBalance(coinaddr, error); } else { - return getErc20BalanceSatoshi(coinaddr, coin->etomic); + return getErc20BalanceSatoshi(coinaddr, coin->etomic, coin->decimals, error); } } diff --git a/iguana/exchanges/LP_etomic.h b/iguana/exchanges/LP_etomic.h index af5de5f63..8a744cb3d 100644 --- a/iguana/exchanges/LP_etomic.h +++ b/iguana/exchanges/LP_etomic.h @@ -49,7 +49,7 @@ int32_t LP_etomic_pub2addr(char *coinaddr,uint8_t pub64[64]); uint8_t LP_etomic_is_empty_tx_id(char *txId); -uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr); +uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr, int *error); void LP_etomic_pubkeystr_to_addr(char *pubkey, char *output); diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 4080ba31c..dbb46e4f1 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -59,7 +59,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping //#define LP_DISABLE_DISTCOMBINE #define LP_MAXVINS 64 -#define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) +#define LP_HTTP_TIMEOUT 10 // 1 is too small due to edge cases of time(NULL) #define LP_AUTOTRADE_TIMEOUT 30 #define LP_RESERVETIME (LP_AUTOTRADE_TIMEOUT * 3) #define ELECTRUM_TIMEOUT 13 @@ -206,7 +206,7 @@ struct basilisk_rawtxinfo { char destaddr[64],ethTxid[75]; bits256 txid,signedtxid,actualtxid; - int64_t amount,change,inputsum; + int64_t amount,change,inputsum,eth_amount; int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys; uint32_t locktime,crcs[2]; uint8_t addrtype,pubkey33[33],rmd160[20]; @@ -220,7 +220,7 @@ struct basilisk_request bits256 desthash; char src[68],dest[68]; uint64_t destamount; - int32_t optionhours,DEXselector; + uint32_t optionhours,DEXselector; }; struct basilisk_rawtx @@ -241,7 +241,7 @@ struct basilisk_swapinfo bits256 myhash,otherhash,orderhash; uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration; int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad,aliceistrusted,bobistrusted,otheristrusted,otherstrust,alicemaxconfirms,bobmaxconfirms; - int64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee; + int64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee,alicerealsat,bobrealsat; 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]; @@ -256,29 +256,31 @@ struct basilisk_swapinfo uint8_t userdata_bobrefund[256],userdata_bobrefundlen; }; -#define BASILISK_ALICESPEND 0 -#define BASILISK_BOBSPEND 1 -#define BASILISK_BOBPAYMENT 2 +#define BASILISK_MYFEE 0 +#define BASILISK_OTHERFEE 1 +#define BASILISK_BOBDEPOSIT 2 #define BASILISK_ALICEPAYMENT 3 -#define BASILISK_BOBDEPOSIT 4 -#define BASILISK_OTHERFEE 5 -#define BASILISK_MYFEE 6 +#define BASILISK_BOBPAYMENT 4 +#define BASILISK_ALICESPEND 5 +#define BASILISK_BOBSPEND 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 -static char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" }; +static char *txnames[] = { "myfee", "otherfee", "bobdeposit", "alicepayment", "bobpayment", "alicespend", "bobspend", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" }; struct LP_swap_remember { bits256 pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)]; - uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid; + uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid,alicerealsat,bobrealsat; int64_t values[sizeof(txnames)/sizeof(*txnames)]; uint32_t finishtime,tradeid,requestid,quoteid,plocktime,dlocktime,expiration,state,otherstate; int32_t iambob,finishedflag,origfinishedflag,Predeemlen,Dredeemlen,sentflags[sizeof(txnames)/sizeof(*txnames)]; uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],Predeemscript[1024],Dredeemscript[1024],pubkey33[33],other33[33]; - char uuidstr[65],Agui[65],Bgui[65],gui[65],src[65],dest[65],bobtomic[128],alicetomic[128],etomicsrc[65],etomicdest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)],bobDepositEthTx[75],bobPaymentEthTx[75],alicePaymentEthTx[75]; + char uuidstr[65],Agui[65],Bgui[65],gui[65],src[65],dest[65],bobtomic[128],alicetomic[128],etomicsrc[65],etomicdest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)]; + char eth_tx_ids[sizeof(txnames)/sizeof(*txnames)][75]; + int64_t eth_values[sizeof(txnames)/sizeof(*txnames)]; }; struct LP_outpoint @@ -303,7 +305,7 @@ struct iguana_info { UT_hash_handle hh; portable_mutex_t txmutex,addrmutex,addressutxo_mutex; struct LP_transaction *transactions; struct LP_address *addresses; - uint64_t txfee; + uint64_t txfee,do_autofill_merge; int32_t numutxos,notarized,longestchain,firstrefht,firstscanht,lastscanht,height; uint16_t busport,did_addrutxo_reset; uint32_t txversion,dPoWtime,lastautosplit,lastresetutxo,loadedcache,electrumlist,lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime; uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag,userconfirms,isassetchain,maxconfirms; @@ -311,9 +313,10 @@ struct iguana_info // portfolio double price_kmd,force,perc,goal,goalperc,relvolume,rate; void *electrum; void *ctx; - uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB; - uint8_t pubkey33[33],zcash; - int32_t privkeydepth; + uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB,fillsatoshis; + uint8_t pubkey33[33],zcash,decimals; + int32_t privkeydepth,bobfillheight; + void *curl_handle; portable_mutex_t curl_mutex; bits256 cachedtxid,notarizationtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen; bits256 cachedmerkle,notarizedhash; int32_t cachedmerkleheight; }; @@ -377,9 +380,10 @@ struct LP_quoteinfo { struct basilisk_request R; bits256 srchash,desthash,txid,txid2,desttxid,feetxid,privkey; + double maxprice; int64_t othercredits; uint64_t satoshis,txfee,destsatoshis,desttxfee,aliceid; - uint32_t timestamp,quotetime,tradeid; + uint32_t timestamp,quotetime,tradeid,gtc,fill,mpnet; int32_t vout,vout2,destvout,feevout,pair; char srccoin[65],coinaddr[64],destcoin[65],destaddr[64],gui[64],etomicsrc[65],etomicdest[65],uuidstr[65]; }; @@ -427,7 +431,7 @@ struct LP_swapstats struct LP_pubswap { struct LP_pubswap *next,*prev; struct LP_swapstats *swap; }; -#define LP_MAXPRICEINFOS 256 +#define LP_MAXPRICEINFOS 255 struct LP_pubkey_info { UT_hash_handle hh; @@ -531,6 +535,7 @@ void HashKeccak(uint8_t *hash,void *data,size_t len); void test_validate(struct iguana_info *coin,char *signedtx); void LP_instantdex_depositadd(char *coinaddr,bits256 txid); int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid,char *refaddr,char *origcoinaddr); +char *LP_autofillbob(struct iguana_info *coin,uint64_t satoshis); void LP_ports(uint16_t *pullportp,uint16_t *pubportp,uint16_t *busportp,uint16_t netid); int32_t LP_destaddr(char *destaddr,cJSON *item); int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration); @@ -580,6 +585,7 @@ int32_t LP_trades_canceluuid(char *uuidstr); int _decreasing_uint64(const void *a,const void *b); int32_t LP_alice_eligible(uint32_t quotetime); int32_t LP_is_slowcoin(char *symbol); +void LP_alicequery_clear(); void LP_listunspent_query(char *symbol,char *coinaddr); int32_t bitcoin_priv2wif(char *symbol,uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype); diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index 63068518b..db381bbcf 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -639,7 +639,7 @@ int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue) printf("unfinished alice %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis))); } } - //printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); + printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); } if ( 0 && credits != 0 ) printf("%s %s othercredits %.8f debits %.8f + %.8f -> %.8f\n",coin->symbol,coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue),dstr(credits - (swaps_kmdvalue+kmdvalue))); @@ -679,9 +679,9 @@ int64_t LP_instantdex_proofcheck(char *symbol,char *coinaddr,cJSON *proof,int32_ credits = ap->instantdex_credits; ap->didinstantdex = 1; ap->instantdextime = (uint32_t)time(NULL); - if ( 0 && ap->instantdex_credits > 0 ) + if ( 1 && ap->instantdex_credits > 0 ) printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits)); - } //else printf("cant find ap.%p or already did %d %.8f\n",ap,ap!=0?ap->didinstantdex:-1,ap!=0?dstr(ap->instantdex_credits):-1); + } else printf("cant find ap.%p or already did %d %.8f\n",ap,ap!=0?ap->didinstantdex:-1,ap!=0?dstr(ap->instantdex_credits):-1); } return(credits); } diff --git a/iguana/exchanges/LP_mmjson.c b/iguana/exchanges/LP_mmjson.c index 0dc67da56..591f46025 100644 --- a/iguana/exchanges/LP_mmjson.c +++ b/iguana/exchanges/LP_mmjson.c @@ -259,7 +259,11 @@ int32_t MMJSON_decodeitem(cJSON *lineobj,uint8_t *linebuf,int32_t i,int32_t len, arbstr[j++] = c; } arbstr[j] = 0; - jaddstr(lineobj,fieldstr,arbstr); + if (strcmp(fieldstr, "txChain") == 0) { + cJSON_AddItemToObject(lineobj, fieldstr, cJSON_Parse(arbstr)); + } else { + jaddstr(lineobj, fieldstr, arbstr); + } break; default: if ( valind < MMJSON_BOUNDARY ) diff --git a/iguana/exchanges/LP_mpnet.c b/iguana/exchanges/LP_mpnet.c new file mode 100644 index 000000000..ca1e7ea1c --- /dev/null +++ b/iguana/exchanges/LP_mpnet.c @@ -0,0 +1,254 @@ + +/****************************************************************************** + * Copyright © 2014-2018 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_mpnet.c +// marketmaker +// + +bits256 MPNET_txids[1024]; +int32_t num_MPNET_txids; + +int32_t LP_tradecommand(int32_t from_mpnet,void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen); +int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson); +void LP_gtc_addorder(struct LP_quoteinfo *qp); +char *LP_withdraw(struct iguana_info *coin,cJSON *argjson); + +int32_t LP_mpnet_find(bits256 txid) +{ + int32_t i; + for (i=0; i= 0 ) + { + MPNET_txids[i] = MPNET_txids[--num_MPNET_txids]; + return(i); + } + return(-1); +} + +int32_t LP_mpnet_addorder(struct LP_quoteinfo *qp) +{ + uint64_t destvalue,destvalue2; + if ( LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) > 0 ) + { + LP_gtc_addorder(qp); + return(0); + } + return(-1); +} + +void LP_mpnet_init() // problem is coins not enabled yet +{ + char fname[1024],line[8192]; FILE *fp; struct LP_quoteinfo Q; cJSON *argjson; + sprintf(fname,"%s/GTC/orders",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (fp= fopen(fname,"rb+")) != 0 ) + { + while ( fgets(line,sizeof(line),fp) > 0 ) + { + if ( (argjson= cJSON_Parse(line)) != 0 ) + { + if ( LP_quoteparse(&Q,argjson) == 0 ) + { + if ( LP_mpnet_addorder(&Q) == 0 ) + printf("GTC %s",line); + } + free_json(argjson); + } + } + fclose(fp); + } +} + +void LP_mpnet_send(int32_t localcopy,char *msg,int32_t sendflag,char *otheraddr) +{ + char fname[1024]; int32_t len; FILE *fp; char *hexstr,*retstr; cJSON *argjson,*outputs,*item; struct iguana_info *coin; uint8_t linebuf[8192]; + if ( localcopy != 0 ) + { + sprintf(fname,"%s/GTC/orders",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (fp= fopen(fname,"rb+")) == 0 ) + fp = fopen(fname,"wb+"); + else fseek(fp,0,SEEK_END); + fprintf(fp,"%s\n",msg); + fclose(fp); + } + if ( G.mpnet != 0 && sendflag != 0 && (coin= LP_coinfind("CHIPS")) != 0 && coin->inactive == 0 ) + { + len = MMJSON_encode(linebuf,msg); + //curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"withdraw\",\"coin\":\"CHIPS\",\"outputs\":[{\"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj\":0.0001}],\"opreturn\":\"deadbeef\"}" + if ( len > 0 ) + { + argjson = cJSON_CreateObject(); + outputs = cJSON_CreateArray(); + if ( otheraddr != 0 && otheraddr[0] != 0 ) + { + item = cJSON_CreateObject(); + jaddnum(item,otheraddr,dstr(10000)); + jaddi(outputs,item); + } + item = cJSON_CreateObject(); + jaddnum(item,coin->smartaddr,dstr(10000)); + jaddi(outputs,item); + jadd(argjson,"outputs",outputs); + jaddnum(argjson,"broadcast",1); + jaddstr(argjson,"coin",coin->symbol); + hexstr = calloc(1,len*2 + 1); + init_hexbytes_noT(hexstr,linebuf,len); + jaddstr(argjson,"opreturn",hexstr); + free(hexstr); + retstr = LP_withdraw(coin,argjson); + free_json(argjson); + if ( retstr != 0 ) + { + //printf("mpnet.%s\n",retstr); + free(retstr); + } + } + } +} + +cJSON *LP_mpnet_parse(struct iguana_info *coin,bits256 txid) +{ + cJSON *txobj,*vouts,*sobj,*argjson = 0; char *decodestr,*hexstr; uint8_t *buf,linebuf[8192]; int32_t len,n,hlen; + if ( (txobj= LP_gettx("mpnet",coin->symbol,txid,0)) != 0 ) + { + if ( (vouts= jarray(&n,txobj,"vout")) != 0 ) + { + if ( (sobj= jobj(jitem(vouts,n-1),"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (hlen= strlen(hexstr)) < sizeof(linebuf)*2 ) + { + len = (hlen >> 1); + decode_hex(linebuf,len,hexstr); + buf = linebuf; + //printf("hexstr.(%s)\n",hexstr); + if ( *buf == 0x6a ) + { + buf++, len--; + if ( *buf == 0x4d ) + { + buf++, len--; + n = buf[0] + buf[1]*256; + buf += 2, len -= 2; + if ( n == len ) + { + if ( (decodestr= MMJSON_decode(buf,len)) != 0 ) + argjson = cJSON_Parse(decodestr); + } + } + } + if ( 0 && argjson == 0 ) + printf("unhandled case.(%s)\n",hexstr); + } + } + if ( 0 && argjson == 0 ) + printf("unhandled tx.(%s)\n",jprint(txobj,0)); + free_json(txobj); + } + return(argjson); +} + +// 2151978 +// 404bc4ac452db07ed16376b3d7e77dbfc22b4a68f7243797125bd0d3bdddf8d1 +// 893b46634456034a6d5d73b67026aa157b5e2addbfc6344dfbea6bae85f7dde0 +// 717c7ef9de8504bd331f3ef52ed0a16ea0e070434e12cb4d63f5f081e999c43d dup + +void LP_mpnet_process(void *ctx,char *myipaddr,int32_t pubsock,struct iguana_info *coin,bits256 txid) +{ + cJSON *argjson; char str[65]; + if ( LP_mpnet_find(txid) < 0 ) + { + //printf("unique %s\n",bits256_str(str,txid)); + if ( (argjson= LP_mpnet_parse(coin,txid)) != 0 ) + { + //printf("MPNET.(%s)\n",jprint(argjson,0)); + LP_tradecommand(1,ctx,myipaddr,pubsock,argjson,0,0); + free_json(argjson); + } + LP_mpnet_add(txid); + } +} + +cJSON *LP_mpnet_get(void *ctx,char *myipaddr,int32_t pubsock,struct iguana_info *coin) +{ + static int32_t lastheight; static bits256 lasthash; + int32_t i,n=0,numtx,checkht = 0,height = 0; bits256 latesthash,hash,txid,zero; char hashstr[65],str[65]; cJSON *txs,*blockjson; + memset(zero.bytes,0,sizeof(zero)); + latesthash = LP_getbestblockhash(coin); + bits256_str(hashstr,latesthash); + if ( (blockjson= LP_blockjson(&checkht,coin->symbol,hashstr,0)) != 0 ) + { + hash = latesthash; + while ( bits256_cmp(lasthash,hash) != 0 && n++ < 3 ) + { + if ( (txs= jarray(&numtx,blockjson,"tx")) != 0 ) + { + for (i=0; isymbol,hashstr,0)) == 0 ) + break; + } + lasthash = latesthash; + if ( blockjson != 0 ) + free_json(blockjson); + if ( (txs= LP_getmempool(coin->symbol,coin->smartaddr,zero,zero)) != 0 ) + { + numtx = cJSON_GetArraySize(txs); + for (i=0; iinactive == 0 && time(NULL) > lasttime+5 ) + { + LP_mpnet_get(ctx,myipaddr,pubsock,coin); + lasttime = (uint32_t)time(NULL); + } +} diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 62df2b22c..7e8b66f4d 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -30,6 +30,9 @@ // there is an issue about waiting for notarization for a swap that never starts (expiration ok) #include +#ifndef MM_VERSION +#define MM_VERSION "UNKNOWN" +#endif long LP_cjson_allocated,LP_cjson_total,LP_cjson_count; @@ -90,7 +93,7 @@ void LP_millistats_update(struct LP_millistats *mp) #include "LP_etomic.h" #endif -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,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex,LP_tradesmutex,LP_commandQmutex,LP_blockinit_mutex,LP_pendswap_mutex,LP_listmutex; +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,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex,LP_tradesmutex,LP_commandQmutex,LP_blockinit_mutex,LP_pendswap_mutex,LP_listmutex,LP_gtcmutex; int32_t LP_canbind; char *Broadcaststr,*Reserved_msgs[2][1000]; int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; @@ -117,10 +120,10 @@ struct LP_globals { //struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2]; bits256 LP_mypub25519,LP_privkey,LP_mypriv25519,LP_passhash; - uint64_t LP_skipstatus[10000]; + uint64_t LP_skipstatus[10000], LP_required_etomic_balance; uint16_t netid; uint8_t LP_myrmd160[20],LP_pubsecp[33]; - uint32_t LP_sessionid,counter; + uint32_t LP_sessionid,counter,mpnet; int32_t LP_IAMLP,LP_pendingswaps,USERPASS_COUNTER,LP_numprivkeys,initializing,waiting,LP_numskips; char seednode[64],USERPASS[65],USERPASS_WIFSTR[64],LP_myrmd160str[41],gui[65],LP_NXTaddr[64]; struct LP_privkey LP_privkeys[100]; @@ -176,6 +179,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_ #include "LP_bitcoin.c" #include "LP_coins.c" #include "LP_rpc.c" +#include "LP_mpnet.c" #include "LP_NXT.c" #include "LP_cache.c" #include "LP_RTmetrics.c" @@ -202,7 +206,7 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson char *retstr=0; cJSON *retjson; bits256 zero; if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 ) return(0); - if ( stats_JSONonly != 0 || LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) + if ( stats_JSONonly != 0 || LP_tradecommand(0,ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) { if ( (retstr= stats_JSON(ctx,0,myipaddr,pubsock,argjson,"127.0.0.1",stats_JSONonly)) != 0 ) { @@ -423,7 +427,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int /*if ( (argjson= cJSON_Parse(str)) != 0 ) { //portable_mutex_lock(&LP_commandmutex); - if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,0,0) <= 0 ) + if ( LP_tradecommand(0,ctx,myipaddr,pubsock,argjson,0,0) <= 0 ) { if ( (retstr= stats_JSON(ctx,0,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 ) free(retstr); @@ -480,6 +484,8 @@ int32_t LP_nanomsg_recvs(void *ctx) nonz += LP_sock_check("PULL",ctx,origipaddr,-1,LP_mypullsock,"127.0.0.1",1); } portable_mutex_unlock(&LP_nanorecvsmutex); + //if ( G.mpnet != 0 ) + LP_mpnet_check(ctx,origipaddr,LP_mypubsock); return(nonz); } @@ -513,21 +519,21 @@ void command_rpcloop(void *ctx) void LP_coinsloop(void *_coins) { static int32_t didfilescreate; - struct LP_address *ap=0; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t notarized,oldht,j,nonz; char *coins = _coins; + struct LP_address *ap=0; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65],*retstr,*hexstr,*txidstr; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t notarized,oldht,j,nonz; char *coins = _coins; if ( strcmp("BTC",coins) == 0 ) { strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); - LP_coinsloopBTC_stats.threshold = 20000.; + LP_coinsloopBTC_stats.threshold = 200000.; } else if ( strcmp("KMD",coins) == 0 ) { strcpy(LP_coinsloopKMD_stats.name,"KMD coin loop"); - LP_coinsloopKMD_stats.threshold = 10000.; + LP_coinsloopKMD_stats.threshold = 100000.; } else { strcpy(LP_coinsloop_stats.name,"other coins loop"); - LP_coinsloop_stats.threshold = 5000.; + LP_coinsloop_stats.threshold = 50000.; } while ( LP_STOP_RECEIVED == 0 ) { @@ -576,6 +582,29 @@ void LP_coinsloop(void *_coins) LP_address_utxo_reset(&num,coin); coin->did_addrutxo_reset = 1; } + //free_json(LP_address_balance(coin,coin->smartaddr,1)); expensive invoking gettxout + if ( coin->do_autofill_merge != 0 ) + { + if ( (retstr= LP_autofillbob(coin,coin->do_autofill_merge*1.02)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (hexstr= jstr(retjson,"hex")) != 0 ) + { + if ( (txidstr= LP_sendrawtransaction(coin->symbol,hexstr,0)) != 0 ) + { + printf("autofill created %s\n",txidstr); + free(txidstr); + coin->fillsatoshis = coin->do_autofill_merge; + coin->do_autofill_merge = 0; + coin->bobfillheight = LP_getheight(¬arized,coin); + } + } + free_json(retjson); + } + free(retstr); + } + } if ( coin->longestchain == 1 ) // special init value coin->longestchain = LP_getheight(¬arized,coin); if ( (ep= coin->electrum) != 0 ) @@ -656,6 +685,7 @@ void LP_coinsloop(void *_coins) continue; } //if ( strcmp(coin->symbol,"BTC") != 0 && strcmp(coin->symbol,"KMD") != 0 ) // SPV as backup + if ( coin->lastscanht < coin->longestchain ) { nonz++; if ( strcmp("BTC",coins) == 0 )//&& coin->lastscanht < coin->longestchain-3 ) @@ -664,7 +694,7 @@ void LP_coinsloop(void *_coins) { if ( LP_blockinit(coin,coin->lastscanht) < 0 ) { - printf("pleae ignore this blockinit.%s %d error\n",coin->symbol,coin->lastscanht); + printf("please ignore this blockinit.%s %d error\n",coin->symbol,coin->lastscanht); sleep(10); break; } @@ -1099,6 +1129,7 @@ void LP_swapsloop(void *ctx) if ( (sp->finished= LP_swapwait(0,sp->requestid,sp->quoteid,-1,0)) != 0 ) { } + sleep(3); } } if ( nonz == 0 ) @@ -1109,7 +1140,8 @@ void LP_swapsloop(void *ctx) LP_alice_eligible((uint32_t)time(NULL)); sleep(6); } - } + } else sleep(10); + LP_gtc_iteration(ctx,LP_myipaddr,LP_mypubsock); } } @@ -1194,7 +1226,7 @@ void queue_loop(void *ctx) } if ( (json= cJSON_Parse((char *)ptr->msg)) != 0 ) { - if ( 1 && ptr->msglen < sizeof(linebuf) ) + if ( ptr->msglen < sizeof(linebuf) ) { if ( (k= MMJSON_encode(linebuf,(char *)ptr->msg)) > 0 ) { @@ -1393,8 +1425,7 @@ extern int32_t bitcoind_RPC_inittime; void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybusport,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson) { - char *myipaddr=0,version[64]; long filesize,n; int32_t valid,timeout; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128],*coins_str=0; cJSON *coinsjson=0; void *ctx = bitcoin_ctx(); - sprintf(version,"Marketmaker %s.%s %s rsize.%ld",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER,sizeof(struct basilisk_request)); + char *myipaddr=0; long filesize,n; int32_t valid,timeout; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128],*coins_str=0; cJSON *coinsjson=0; void *ctx = bitcoin_ctx(); bitcoind_RPC_inittime = 1; if ( LP_MAXPRICEINFOS > 256 ) { @@ -1402,7 +1433,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu exit(-1); } LP_showwif = juint(argjson,"wif"); - printf("showwif.%d %s %u\n",LP_showwif,version,calc_crc32(0,version,(int32_t)strlen(version))); + printf("showwif.%d version: %s %u\n",LP_showwif,MM_VERSION,calc_crc32(0,MM_VERSION,(int32_t)strlen(MM_VERSION))); if ( passphrase == 0 || passphrase[0] == 0 ) { printf("jeezy says we cant use the nullstring as passphrase and I agree\n"); @@ -1473,13 +1504,14 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu portable_mutex_init(&LP_blockinit_mutex); portable_mutex_init(&LP_pendswap_mutex); portable_mutex_init(&LP_listmutex); + portable_mutex_init(&LP_gtcmutex); myipaddr = clonestr("127.0.0.1"); #ifndef _WIN32 #ifndef FROM_JS - if ( system("curl -s4 checkip.amazonaws.com > myipaddr") == 0 ) + char ipfname[64]; + strcpy(ipfname,"myipaddr"); + if ( access( ipfname, F_OK ) != -1 || system("curl -s4 checkip.amazonaws.com > myipaddr") == 0 ) { - char ipfname[64]; - strcpy(ipfname,"myipaddr"); if ( (myipaddr= OS_filestr(&filesize,ipfname)) != 0 && myipaddr[0] != 0 ) { n = strlen(myipaddr); @@ -1621,6 +1653,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu int32_t nonz,didremote=0; LP_statslog_parse(); bitcoind_RPC_inittime = 0; + //LP_mpnet_init(); seems better to have the GUI send in persistent orders, exit mm is a cancel all while ( LP_STOP_RECEIVED == 0 ) { nonz = 0; diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index b35d17a61..34bb7300d 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -18,6 +18,14 @@ // LP_ordermatch.c // marketmaker // + +struct LP_gtcorder +{ + struct LP_gtcorder *next,*prev; + struct LP_quoteinfo Q; + uint32_t cancelled,pending; +} *GTCorders; + struct LP_quoteinfo LP_Alicequery,LP_Alicereserved; double LP_Alicemaxprice; bits256 LP_Alicedestpubkey,LP_bobs_reserved; @@ -190,12 +198,12 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str if ( strcmp(autxo->coinaddr,qp->destaddr) != 0 ) return(-10); } - if ( autxo != 0 && destvalue < qp->desttxfee+qp->destsatoshis ) + if ( strcmp(destcoin, "ETOMIC") != 0 && autxo != 0 && destvalue < qp->desttxfee+qp->destsatoshis ) { printf("destvalue %.8f destsatoshis %.8f is too small txfee %.8f?\n",dstr(destvalue),dstr(qp->destsatoshis),dstr(qp->desttxfee)); return(-11); } - if ( butxo != 0 && srcvalue < qp->txfee+qp->satoshis ) + if ( strcmp(srccoin, "ETOMIC") != 0 && butxo != 0 && srcvalue < qp->txfee+qp->satoshis ) { printf("srcvalue %.8f [%.8f] satoshis %.8f is too small txfee %.8f?\n",dstr(srcvalue),dstr(srcvalue) - dstr(qp->txfee+qp->satoshis),dstr(qp->satoshis),dstr(qp->txfee)); return(-33); @@ -213,7 +221,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str printf("error -14: txfee %.8f < %.8f or desttxfee %.8f < %.8f\n",dstr(qp->txfee),dstr(LP_REQUIRED_TXFEE*txfee),dstr(qp->desttxfee),dstr(LP_REQUIRED_TXFEE*desttxfee)); return(-14); } - if ( butxo != 0 ) + if ( butxo != 0 && strcmp(srccoin, "ETOMIC") != 0) { if ( qp->satoshis < (srcvalue / LP_MINVOL) || srcvalue < qp->txfee*LP_MINSIZE_TXFEEMULT ) { @@ -413,14 +421,22 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb memset(butxo,0,sizeof(*butxo)); if ( iambob != 0 ) { - targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee) + 3*txfee; + if (strcmp(coin->symbol, "ETOMIC") == 0) { + targetval = 100000000 + 3*txfee; + } else { + targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee) + 3*txfee; + } targetval2 = (targetval / 8) * 9 + 3*txfee; fee = txfee; ratio = LP_MINVOL; } else { - targetval = relvolume*SATOSHIDEN + 3*desttxfee; + if (strcmp(coin->symbol, "ETOMIC") == 0) { + targetval = 100000000 + 3*desttxfee; + } else { + targetval = relvolume*SATOSHIDEN + 3*desttxfee; + } targetval2 = (targetval / 777) + 3*desttxfee; fee = desttxfee; ratio = LP_MINCLIENTVOL; @@ -429,7 +445,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) { - if ( 0 ) + if ( 1 ) { int32_t i; for (i=0; isrchash) == 0 ) { - LP_requestinit(&qp->R,qp->srchash,qp->desthash,base,qp->satoshis-qp->txfee,rel,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); + LP_requestinit(&qp->R,qp->srchash,qp->desthash,base,qp->satoshis-qp->txfee,rel,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector,qp->fill,qp->gtc); dtrust = LP_dynamictrust(qp->othercredits,qp->desthash,LP_kmdvalue(qp->destcoin,qp->destsatoshis)); if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp,dtrust > 0)) == 0 ) { @@ -517,27 +533,35 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double LP_importaddress(qp->destcoin,qp->destaddr); LP_otheraddress(qp->srccoin,otheraddr,qp->destcoin,qp->destaddr); LP_importaddress(qp->srccoin,otheraddr); - bits256 zero; - memset(zero.bytes,0,sizeof(zero)); - for (i=0; i<1; i++) { - LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); - break; - sleep(10); - if ( swap->received != 0 ) + bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + for (i=0; i<1; i++) { - printf("swap %u-%u has started t%u\n",swap->I.req.requestid,swap->I.req.quoteid,swap->received); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); break; + sleep(10); + if ( swap->received != 0 ) + { + printf("swap %u-%u has started t%u\n",swap->I.req.requestid,swap->I.req.quoteid,swap->received); + break; + } + printf("bob tries %u-%u again i.%d\n",swap->I.req.requestid,swap->I.req.quoteid,i); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); } - printf("bob tries %u-%u again i.%d\n",swap->I.req.requestid,swap->I.req.quoteid,i); + sleep(1); + printf("send CONNECT for %u-%u\n",qp->R.requestid,qp->R.quoteid); LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); + if ( IPC_ENDPOINT >= 0 ) + LP_queuecommand(0,jprint(reqjson,0),IPC_ENDPOINT,-1,0); } - sleep(1); - printf("send CONNECT for %u-%u\n",qp->R.requestid,qp->R.quoteid); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); - if ( IPC_ENDPOINT >= 0 ) - LP_queuecommand(0,jprint(reqjson,1),IPC_ENDPOINT,-1,0); - else free_json(reqjson); + if ( qp->mpnet != 0 && qp->gtc == 0 ) + { + char *msg = jprint(reqjson,0); + LP_mpnet_send(0,msg,1,qp->destaddr); + free(msg); + } + free_json(reqjson); retval = 0; } else @@ -567,10 +591,60 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double return(retval); } +void LP_gtc_iteration(void *ctx,char *myipaddr,int32_t mypubsock) +{ + struct LP_gtcorder *gtc,*tmp; struct LP_quoteinfo *qp; uint64_t destvalue,destvalue2; uint32_t oldest = 0; + if ( Alice_expiration != 0 ) + return; + DL_FOREACH_SAFE(GTCorders,gtc,tmp) + { + qp = >c->Q; + if ( gtc->cancelled == 0 && (oldest == 0 || gtc->pending < oldest) ) + oldest = gtc->pending; + } + DL_FOREACH_SAFE(GTCorders,gtc,tmp) + { + qp = >c->Q; + if ( gtc->cancelled == 0 && LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 ) + { + gtc->cancelled = (uint32_t)time(NULL); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-9997,qp->uuidstr); + } + if ( gtc->cancelled != 0 ) + { + portable_mutex_lock(&LP_gtcmutex); + DL_DELETE(GTCorders,gtc); + free(gtc); + portable_mutex_unlock(&LP_gtcmutex); + } + else + { + if ( gtc->pending <= oldest+60 && time(NULL) > gtc->pending+600 )//LP_AUTOTRADE_TIMEOUT*10 ) + { + gtc->pending = qp->timestamp = (uint32_t)time(NULL); + LP_query(ctx,myipaddr,mypubsock,"request",qp); + LP_Alicequery = *qp, LP_Alicemaxprice = gtc->Q.maxprice, Alice_expiration = qp->timestamp + 2*LP_AUTOTRADE_TIMEOUT, LP_Alicedestpubkey = qp->srchash; + char str[65]; printf("LP_gtc fill.%d gtc.%d %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f etomicdest.(%s) uuid.%s fill.%d gtc.%d\n",qp->fill,qp->gtc,qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),gtc->Q.maxprice,qp->etomicdest,qp->uuidstr,qp->fill,qp->gtc); + break; + } + } + } +} + +void LP_gtc_addorder(struct LP_quoteinfo *qp) +{ + struct LP_gtcorder *gtc; + gtc = calloc(1,sizeof(*gtc)); + gtc->Q = *qp; + gtc->pending = (uint32_t)time(NULL); + portable_mutex_lock(&LP_gtcmutex); + DL_APPEND(GTCorders,gtc); + portable_mutex_unlock(&LP_gtcmutex); +} + char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid,bits256 destpubkey,char *uuidstr) { - double price; - price = 0.; + struct LP_gtcorder *gtc; memset(qp->txid.bytes,0,sizeof(qp->txid)); qp->txid2 = qp->txid; qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); @@ -578,9 +652,25 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q qp->tradeid = LP_rand(); qp->srchash = destpubkey; strncpy(qp->uuidstr,uuidstr,sizeof(qp->uuidstr)-1); - LP_query(ctx,myipaddr,mypubsock,"request",qp); - LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = destpubkey; - char str[65]; printf("LP_trade %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f etomicdest.(%s) uuid.%s\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),maxprice,qp->etomicdest,qp->uuidstr); + qp->maxprice = maxprice; + qp->timestamp = (uint32_t)time(NULL); + if ( qp->gtc != 0 ) + { + //strcpy(&qp->uuidstr[strlen(qp->uuidstr)-6],"cccccc"); + LP_gtc_addorder(qp); + } + { + LP_query(ctx,myipaddr,mypubsock,"request",qp); + LP_Alicequery = *qp, LP_Alicemaxprice = qp->maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = qp->srchash; + } + if ( qp->gtc == 0 ) + { + cJSON *reqjson = LP_quotejson(qp); + char *msg = jprint(reqjson,1); + LP_mpnet_send(1,msg,1,0); + free(msg); + } + char str[65]; printf("LP_trade mpnet.%d fill.%d gtc.%d %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f etomicdest.(%s) uuid.%s fill.%d gtc.%d\n",qp->mpnet,qp->fill,qp->gtc,qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),qp->maxprice,qp->etomicdest,qp->uuidstr,qp->fill,qp->gtc); return(LP_recent_swaps(0,uuidstr)); } @@ -615,7 +705,7 @@ int32_t LP_alice_eligible(uint32_t quotetime) { if ( Alice_expiration != 0 && quotetime > Alice_expiration ) { - if ( LP_Alicequery.uuidstr[0] != 0 ) + if ( LP_Alicequery.uuidstr[0] != 0 && LP_Alicequery.gtc == 0 ) LP_failedmsg(LP_Alicequery.R.requestid,LP_Alicequery.R.quoteid,-9999,LP_Alicequery.uuidstr); printf("time expired for Alice_request\n"); LP_alicequery_clear(); @@ -628,16 +718,45 @@ char *LP_cancel_order(char *uuidstr) int32_t num = 0; cJSON *retjson; if ( uuidstr != 0 ) { - num = LP_trades_canceluuid(uuidstr); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"numentries",num); - if ( strcmp(LP_Alicequery.uuidstr,uuidstr) == 0 ) + if ( uuidstr[0] == 'G' ) { - LP_failedmsg(LP_Alicequery.R.requestid,LP_Alicequery.R.quoteid,-9998,LP_Alicequery.uuidstr); - LP_alicequery_clear(); - jaddstr(retjson,"status","uuid canceled"); - } else jaddstr(retjson,"status","will stop trade negotiation, but if swap started it wont cancel"); + struct LP_gtcorder *gtc,*tmp; + DL_FOREACH_SAFE(GTCorders,gtc,tmp) + { + if ( strcmp(gtc->Q.uuidstr,uuidstr) == 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"cancelled",uuidstr); + jaddnum(retjson,"pending",gtc->pending); + if ( gtc->cancelled == 0 ) + { + gtc->cancelled = (uint32_t)time(NULL); + jaddstr(retjson,"status","uuid canceled"); + LP_failedmsg(gtc->Q.R.requestid,gtc->Q.R.quoteid,-9997,gtc->Q.uuidstr); + } + else + { + jaddstr(retjson,"status","uuid already canceled"); + LP_failedmsg(gtc->Q.R.requestid,gtc->Q.R.quoteid,-9996,gtc->Q.uuidstr); + } + } + } + return(clonestr("{\"error\":\"gtc uuid not found\"}")); + } + else + { + num = LP_trades_canceluuid(uuidstr); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"numentries",num); + if ( strcmp(LP_Alicequery.uuidstr,uuidstr) == 0 ) + { + LP_failedmsg(LP_Alicequery.R.requestid,LP_Alicequery.R.quoteid,-9998,LP_Alicequery.uuidstr); + LP_alicequery_clear(); + jaddstr(retjson,"status","uuid canceled"); + } else jaddstr(retjson,"status","will stop trade negotiation, but if swap started it wont cancel"); + } return(jprint(retjson,1)); } return(clonestr("{\"error\":\"uuid not cancellable\"}")); @@ -645,16 +764,22 @@ char *LP_cancel_order(char *uuidstr) char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice { - cJSON *retjson; char otheraddr[64],*msg; double bid,ask,price,qprice; int32_t pairsock = -1; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct basilisk_swap *swap; struct iguana_info *coin; + cJSON *retjson; char otheraddr[64],*msg; double bid,ask,price,qprice; int32_t changed,pairsock = -1; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct basilisk_swap *swap; struct iguana_info *coin; if ( bits256_cmp(qp->desthash,G.LP_mypub25519) != 0 ) { LP_aliceid(qp->tradeid,qp->aliceid,"error1",0,0); LP_failedmsg(qp->R.requestid,qp->R.quoteid,-4000,qp->uuidstr); return(clonestr("{\"result\",\"update stats\"}")); } - printf("CONNECTED numpending.%d tradeid.%u requestid.%u quoteid.%u pairstr.%s\n",G.LP_pendingswaps,qp->tradeid,qp->R.requestid,qp->R.quoteid,pairstr!=0?pairstr:""); - LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-qp->txfee,qp->destcoin,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); + printf("CONNECTED mpnet.%d fill.%d gtc.%d numpending.%d tradeid.%u requestid.%u quoteid.%u pairstr.%s\n",qp->mpnet,qp->fill,qp->gtc,G.LP_pendingswaps,qp->tradeid,qp->R.requestid,qp->R.quoteid,pairstr!=0?pairstr:""); + LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-qp->txfee,qp->destcoin,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector,qp->fill,qp->gtc); //printf("calculated requestid.%u quoteid.%u\n",qp->R.requestid,qp->R.quoteid); + if ( LP_Alicequery.srccoin[0] != 0 && LP_Alicequery.destcoin[0] != 0 ) + { + LP_mypriceset(0,&changed,LP_Alicequery.destcoin,LP_Alicequery.srccoin,0.); + LP_mypriceset(0,&changed,LP_Alicequery.srccoin,LP_Alicequery.destcoin,0.); + } + LP_alicequery_clear(); memset(&LP_Alicereserved,0,sizeof(LP_Alicereserved)); LP_aliceid(qp->tradeid,qp->aliceid,"connected",qp->R.requestid,qp->R.quoteid); autxo = &A; @@ -671,7 +796,7 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice printf("quote %s/%s validate error %.0f\n",qp->srccoin,qp->destcoin,qprice); return(clonestr("{\"error\":\"quote validation error\"}")); } - if ( LP_myprice(&bid,&ask,qp->srccoin,qp->destcoin) <= SMALLVAL || bid <= SMALLVAL ) + if ( LP_myprice(0,&bid,&ask,qp->srccoin,qp->destcoin) <= SMALLVAL || bid <= SMALLVAL ) { printf("this node has no price for %s/%s (%.8f %.8f)\n",qp->destcoin,qp->srccoin,bid,ask); LP_availableset(qp->desttxid,qp->vout); @@ -862,7 +987,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo double LP_trades_bobprice(double *bidp,double *askp,struct LP_quoteinfo *qp) { double price; struct iguana_info *coin; char str[65]; - price = LP_myprice(bidp,askp,qp->srccoin,qp->destcoin); + price = LP_myprice(1,bidp,askp,qp->srccoin,qp->destcoin); if ( (coin= LP_coinfind(qp->srccoin)) == 0 || price <= SMALLVAL || *askp <= SMALLVAL ) { //printf("this node has no price for %s/%s\n",qp->srccoin,qp->destcoin); @@ -906,7 +1031,7 @@ double LP_trades_pricevalidate(struct LP_quoteinfo *qp,struct iguana_info *coin, printf("quote %s/%s validate error %.0f\n",qp->srccoin,qp->destcoin,qprice); return(-3); } - if ( qprice < (price - 0.00000001) * 0.998 ) + if ( qprice < (price - 0.00000001) * 0.998) { printf(" quote price %.8f (%llu/%llu %.8f) too low vs %.8f for %s/%s price %.8f %.8f\n",qprice,(long long)qp->destsatoshis,(long long)(qp->satoshis-qp->txfee),(double)qp->destsatoshis/(qp->satoshis-qp->txfee),price,qp->srccoin,qp->destcoin,price,(price - 0.00000001) * 0.998); return(-77); @@ -916,10 +1041,11 @@ double LP_trades_pricevalidate(struct LP_quoteinfo *qp,struct iguana_info *coin, struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) { - double price=0.,p=0.,qprice,myprice,bestprice,range,bid,ask; struct iguana_info *coin,*othercoin; struct LP_utxoinfo A,B,*autxo,*butxo; cJSON *reqjson; char str[65]; struct LP_address_utxo *utxos[4096]; int32_t i,r,counter,max = (int32_t)(sizeof(utxos)/sizeof(*utxos)); + int32_t voliters=10,priceiters=33; + double price=0.,p=0.,qprice,myprice,bestprice,range,bid,ask; uint64_t satoshis; struct iguana_info *coin,*othercoin; struct LP_utxoinfo A,B,*autxo,*butxo; cJSON *reqjson,*retjson; char str[65],*retstr,*txidstr,*hexstr; struct LP_address_utxo *utxos[4096]; int32_t i,j,notarized,r,num,counter,max = (int32_t)(sizeof(utxos)/sizeof(*utxos)); *newqp = *qp; qp = newqp; -//printf("bob %s received REQUEST.(%s)\n",bits256_str(str,G.LP_mypub25519),qp->uuidstr+32); +printf("bob %s received REQUEST.(%s) mpnet.%d fill.%d gtc.%d\n",bits256_str(str,G.LP_mypub25519),qp->uuidstr+32,qp->mpnet,qp->fill,qp->gtc); if ( (coin= LP_coinfind(qp->srccoin)) == 0 || (othercoin= LP_coinfind(qp->destcoin)) == 0 ) return(0); if ( (myprice= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) @@ -970,7 +1096,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru } else { - //printf("ignore as qprice %.8f vs myprice %.8f\n",qprice,myprice); + printf("%s/%s ignore as qprice %.8f vs myprice %.8f\n",qp->srccoin,qp->destcoin,qprice,myprice); return(0); } //LP_RTmetrics_update(qp->srccoin,qp->destcoin); @@ -997,46 +1123,85 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru return(0); } } + LP_address_utxo_reset(&num,coin); i = 0; - while ( i < 33 && price >= myprice ) - { - if ( (butxo= LP_address_myutxopair(butxo,1,utxos,max,LP_coinfind(qp->srccoin),qp->coinaddr,qp->txfee,dstr(qp->destsatoshis),price,qp->desttxfee)) != 0 ) - { - strcpy(qp->gui,G.gui); - strcpy(qp->coinaddr,coin->smartaddr); - qp->srchash = G.LP_mypub25519; - qp->txid = butxo->payment.txid; - qp->vout = butxo->payment.vout; - qp->txid2 = butxo->deposit.txid; - qp->vout2 = butxo->deposit.vout; - qp->satoshis = butxo->swap_satoshis;// + qp->txfee; - qp->quotetime = (uint32_t)time(NULL); + while ( i < priceiters && price >= myprice ) + { + for (j=0; jdestsatoshis)); + if ( (butxo= LP_address_myutxopair(&B,1,utxos,max,coin,qp->coinaddr,qp->txfee,dstr(qp->destsatoshis),price,qp->desttxfee)) != 0 ) + { + strcpy(qp->gui,G.gui); + strcpy(qp->coinaddr,coin->smartaddr); + qp->srchash = G.LP_mypub25519; + qp->txid = butxo->payment.txid; + qp->vout = butxo->payment.vout; + qp->txid2 = butxo->deposit.txid; + qp->vout2 = butxo->deposit.vout; + if (coin->etomic[0] == 0) { + qp->satoshis = butxo->swap_satoshis;// + qp->txfee; + } else { + qp->satoshis = LP_basesatoshis(dstr(qp->destsatoshis), price, qp->txfee, qp->desttxfee); + } + qp->quotetime = (uint32_t)time(NULL); + break; + } + if ( qp->fill != 0 ) + break; + qp->destsatoshis = (qp->destsatoshis * 2) / 3; } - else + if ( butxo != 0 && j < voliters ) { - printf("i.%d cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f\n",i,(long long)qp->aliceid,qp->srccoin,qp->destcoin,dstr(LP_basesatoshis(dstr(qp->destsatoshis),price,qp->txfee,qp->desttxfee)),dstr(qp->destsatoshis)); - return(0); + if ( qp->satoshis <= qp->txfee ) + return(0); + p = (double)qp->destsatoshis / (qp->satoshis - qp->txfee); + if ( LP_trades_pricevalidate(qp,coin,p) < 0. ) + { + if ( qp->fill != 0 ) + return(0); + price *= 0.995; + i++; + continue; + } + if ( i == 0 && p < myprice ) + { + price = qprice; + printf("reset price <- qprice %.8f\n",qprice); + } + else + { + if ( qprice >= p || qp->fill != 0 ) + break; + price *= 0.995; + } + if ( qp->fill != 0 ) + break; + i++; } - if ( qp->satoshis <= qp->txfee ) - return(0); - p = (double)qp->destsatoshis / (qp->satoshis - qp->txfee); - if ( LP_trades_pricevalidate(qp,coin,p) < 0. ) - return(0); - if ( i == 0 && p < myprice ) + else if ( qp->fill != 0 || i == priceiters ) { - price = qprice; - printf("reset price <- qprice %.8f\n",qprice); + printf("i.%d cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f txfee %.8f\n",i,(long long)qp->aliceid,qp->srccoin,qp->destcoin,dstr(LP_basesatoshis(dstr(qp->destsatoshis),price,qp->txfee,qp->desttxfee)),dstr(qp->destsatoshis),dstr(qp->txfee)); + if ( qp->gtc != 0 && qp->fill != 0 && coin != 0 && coin->electrum == 0 ) + { + LP_address_utxo_reset(&num,coin); + satoshis = LP_basesatoshis(dstr(qp->destsatoshis),price,qp->txfee,qp->desttxfee) + 3*qp->txfee; + if ( LP_getheight(¬arized,coin) > coin->bobfillheight+3 && fabs((double)coin->fillsatoshis - satoshis)/satoshis > 0.1 ) + { + printf("queue up do_autofill_merge %.8f\n",dstr(satoshis)); + coin->do_autofill_merge = satoshis; + } + } + return(0); } else { - if ( qprice >= p ) - break; price *= 0.995; + i++; } - i++; } - printf("%s/%s i.%d qprice %.8f myprice %.8f price %.8f [%.8f]\n",qp->srccoin,qp->destcoin,i,qprice,myprice,price,p); - if ( LP_allocated(qp->txid,qp->vout) == 0 && LP_allocated(qp->txid2,qp->vout2) == 0 ) + printf("%s/%s i.%d j.%d qprice %.8f myprice %.8f price %.8f [%.8f]\n",qp->srccoin,qp->destcoin,i,j,qprice,myprice,price,p); + if ( butxo != 0 && bits256_nonz(qp->txid) != 0 && bits256_nonz(qp->txid2) != 0 && LP_allocated(qp->txid,qp->vout) == 0 && LP_allocated(qp->txid2,qp->vout2) == 0 ) { //printf("found unallocated txids\n"); reqjson = LP_quotejson(qp); @@ -1047,10 +1212,18 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru jaddnum(reqjson,"quotetime",qp->quotetime); jaddnum(reqjson,"pending",qp->timestamp + LP_RESERVETIME); jaddstr(reqjson,"method","reserved"); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); - bits256 zero; - memset(zero.bytes,0,sizeof(zero)); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); + { + LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); + bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); + } + if ( qp->mpnet != 0 && qp->gtc == 0 ) + { + char *msg = jprint(reqjson,0); + LP_mpnet_send(0,msg,1,qp->destaddr); + free(msg); + } free_json(reqjson); //printf("Send RESERVED id.%llu\n",(long long)qp->aliceid); return(qp); @@ -1061,7 +1234,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru struct LP_quoteinfo *LP_trades_gotreserved(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp) { char *retstr; double qprice; - //char str[65]; printf("alice %s received RESERVED.(%s) %.8f\n",bits256_str(str,G.LP_mypub25519),qp->uuidstr+32,(double)qp->destsatoshis/(qp->satoshis+1)); + char str[65]; printf("alice %s received RESERVED.(%s) %.8f mpnet.%d fill.%d gtc.%d\n",bits256_str(str,G.LP_mypub25519),qp->uuidstr+32,(double)qp->destsatoshis/(qp->satoshis+1),qp->mpnet,qp->fill,qp->gtc); *newqp = *qp; qp = newqp; if ( (qprice= LP_trades_alicevalidate(ctx,qp)) > 0. ) @@ -1103,7 +1276,7 @@ struct LP_quoteinfo *LP_trades_gotconnect(void *ctx,struct LP_quoteinfo *qp,stru struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) { char *retstr; int32_t changed; double val; - //char str[65]; printf("alice %s received CONNECTED.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); + char str[65]; printf("alice %s received CONNECTED.(%llu) mpnet.%d fill.%d gtc.%d\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid,qp->mpnet,qp->fill,qp->gtc); *newqp = *qp; qp = newqp; if ( (val= LP_trades_alicevalidate(ctx,qp)) > 0. ) @@ -1112,7 +1285,7 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st LP_aliceid(qp->tradeid,qp->aliceid,"connected",0,0); if ( (retstr= LP_connectedalice(qp,pairstr)) != 0 ) free(retstr); - LP_mypriceset(&changed,qp->destcoin,qp->srccoin,0.); + LP_mypriceset(0,&changed,qp->destcoin,qp->srccoin,0.); LP_alicequery_clear(); return(qp); } else LP_failedmsg(qp->R.requestid,qp->R.quoteid,val,qp->uuidstr); @@ -1367,7 +1540,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) //printf("queue.%d uuid.(%s)\n",funcid,qtp->Q.uuidstr); } -int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) +int32_t LP_tradecommand(int32_t from_mpnet,void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { int32_t Qtrades = 1; char *method,str[65]; int32_t i,num,DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; cJSON *proof; uint64_t rq; struct iguana_info *coin; struct LP_quoteinfo Q,Q2; int32_t counter,retval=-1; @@ -1380,7 +1553,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } if ( Q.satoshis < Q.txfee ) return(1); - 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); + 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,Q.fill,Q.gtc); rq = ((uint64_t)Q.R.requestid << 32) | Q.R.quoteid; if ( Q.uuidstr[0] == 0 || (Q.timestamp > 0 && time(NULL) > Q.timestamp + LP_AUTOTRADE_TIMEOUT*20) ) // eat expired packets, some old timestamps floating about? { @@ -1390,7 +1563,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, LP_tradecommand_log(argjson); qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); //jdouble(argjson,"price"); //printf("%s\n",jprint(argjson,0)); - printf("%-4d uuid.%32s %12s %5s/%-5s %12.8f -> %12.8f (%11.8f) | RT.%d %d n%d\n",(uint32_t)time(NULL) % 3600,Q.uuidstr+32,method,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),qprice,LP_RTcount,LP_swapscount,G.netid); + printf("%-4d uuid.%32s M.%d g.%d f.%d %12s %5s/%-5s %12.8f -> %12.8f (%11.8f) | RT.%d %d n%d\n",(uint32_t)time(NULL) % 3600,Q.uuidstr+32,from_mpnet,Q.gtc,Q.fill,method,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),qprice,LP_RTcount,LP_swapscount,G.netid); retval = 1; aliceid = j64bits(argjson,"aliceid"); if ( strcmp(method,"reserved") == 0 ) @@ -1438,7 +1611,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( i == sizeof(rqs)/sizeof(*rqs) ) i = (rand() % (sizeof(rqs)/sizeof(*rqs))); rqs[i] = rq; -//printf("CONNECTED.(%s)\n",jprint(argjson,0)); +printf("CONNECTED.(%s)\n",jprint(argjson,0)); if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) Q.othercredits = LP_instantdex_proofcheck(Q.srccoin,Q.coinaddr,proof,num); if ( Qtrades == 0 ) @@ -1446,7 +1619,9 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECTED); } } - price = LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin); + if ( strcmp(method,"request") == 0 || strcmp(method,"connect") == 0 ) // bob + price = LP_myprice(1,&bid,&ask,Q.srccoin,Q.destcoin); + else price = LP_myprice(0,&bid,&ask,Q.srccoin,Q.destcoin); // alice if ( (coin= LP_coinfind(Q.srccoin)) == 0 || coin->inactive != 0 ) { //printf("%s is not active\n",Q.srccoin); @@ -1459,7 +1634,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } if ( LP_aliceonly(Q.srccoin) > 0 ) { - printf("{\"error\":\"GAME can only be alice coin\"}\n"); + printf("{\"error\":\"alice only coins can only be alice coin\"}\n"); return(retval); } if ( strcmp(method,"request") == 0 ) // bob @@ -1469,6 +1644,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( Q.destvout != Q.feevout || bits256_cmp(Q.desttxid,Q.feetxid) != 0 ) { bestprice = LP_bob_competition(&counter,aliceid,qprice,-1); + //printf("bestprice %.8f\n",bestprice); if ( Qtrades == 0 )//|| (bits256_cmp(Q.srchash,G.LP_mypub25519) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0) ) LP_trades_gotrequest(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_REQUEST); @@ -1489,7 +1665,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, if ( i == sizeof(rqs)/sizeof(*rqs) ) i = (rand() % (sizeof(rqs)/sizeof(*rqs))); rqs[i] = rq; - //printf("CONNECT.(%s)\n",jprint(argjson,0)); + printf("CONNECT.(%s)\n",jprint(argjson,0)); if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) Q.othercredits = LP_instantdex_proofcheck(Q.destcoin,Q.destaddr,proof,num); if ( Qtrades == 0 ) @@ -1502,7 +1678,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } -char *LP_autobuy(void *ctx,int32_t fomoflag,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration,char *gui,uint32_t nonce,bits256 destpubkey,uint32_t tradeid,char *uuidstr) +char *LP_autobuy(void *ctx,int32_t fomoflag,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration,char *gui,uint32_t nonce,bits256 destpubkey,uint32_t tradeid,char *uuidstr,int32_t fillflag,int32_t gtcflag) { uint64_t desttxfee,txfee,balance; uint32_t lastnonce; int64_t bestsatoshis=0,destsatoshis; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,B,A; struct LP_quoteinfo Q; bits256 pubkeys[100]; struct LP_address_utxo *utxos[4096]; int32_t num=0,maxiters=100,i,max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); char _uuidstr[65]; basecoin = LP_coinfind(base); @@ -1589,6 +1765,10 @@ char *LP_autobuy(void *ctx,int32_t fomoflag,char *myipaddr,int32_t mypubsock,cha memset(&A,0,sizeof(A)); if ( (autxo= LP_address_myutxopair(&A,0,utxos,max,relcoin,relcoin->smartaddr,txfee,dstr(destsatoshis),maxprice,desttxfee)) != 0 ) break; + if ( fillflag != 0 ) + { + return(clonestr("{\"error\":\"cant find a deposit that is big enough in size. make another deposit that is just a bit larger than what you want to trade\"}")); + } destsatoshis *= 0.98; if ( destsatoshis < desttxfee*LP_MINSIZE_TXFEEMULT ) break; @@ -1604,13 +1784,13 @@ char *LP_autobuy(void *ctx,int32_t fomoflag,char *myipaddr,int32_t mypubsock,cha autxo->swap_satoshis = destsatoshis; //printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->swap_satoshis)); } - else if ( autxo->swap_satoshis - desttxfee < destsatoshis ) + else if ( autxo->swap_satoshis - desttxfee < destsatoshis && relcoin->etomic[0] == 0) { autxo->swap_satoshis -= desttxfee; destsatoshis = autxo->swap_satoshis; printf("second path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->swap_satoshis)); } - if ( destsatoshis < (autxo->payment.value / LP_MINCLIENTVOL) || autxo->payment.value < desttxfee*LP_MINSIZE_TXFEEMULT ) + if ( relcoin->etomic[0] == 0 && (destsatoshis < (autxo->payment.value / LP_MINCLIENTVOL) || autxo->payment.value < desttxfee*LP_MINSIZE_TXFEEMULT )) { printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value)); return(clonestr("{\"error\":\"cant find a deposit that is close enough in size. make another deposit that is a bit larger than what you want to trade\"}")); @@ -1640,8 +1820,11 @@ char *LP_autobuy(void *ctx,int32_t fomoflag,char *myipaddr,int32_t mypubsock,cha } } int32_t changed; - LP_mypriceset(&changed,rel,base,1. / maxprice); - LP_mypriceset(&changed,base,rel,0.); + Q.mpnet = G.mpnet; + Q.fill = fillflag; + Q.gtc = gtcflag; + LP_mypriceset(0,&changed,rel,base,1. / maxprice); + LP_mypriceset(0,&changed,base,rel,0.); if ( uuidstr == 0 || uuidstr[0] == 0 ) { uint8_t uuidhash[256]; bits256 hash; uint64_t millis; int32_t len = 0; diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index 29d54d1ee..bdfb9e2a9 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -95,14 +95,18 @@ uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr) cJSON *array,*item; bits256 zero; int32_t i,n; uint64_t valuesum,satoshisum,value; valuesum = satoshisum = 0; memset(zero.bytes,0,sizeof(zero)); -/* #ifndef NOTETOMIC struct iguana_info *coin = LP_coinfind(symbol); - if (coin->etomic[0] != 0) { - valuesum = LP_etomic_get_balance(coin, coinaddr); + if (coin->etomic[0] != 0 && coin->inactive == 0) { + int error = 0; + uint64_t etomic_balance = LP_etomic_get_balance(coin, coinaddr, &error); + if (error == 0) { + valuesum = etomic_balance; + } else { + valuesum = *valuep; + } } else #endif -*/ if ( (array= LP_listunspent(symbol,coinaddr,zero,zero)) != 0 ) { if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) @@ -152,7 +156,7 @@ char *LP_portfolio() 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"); + coin->price_kmd = LP_price(1,coin->symbol,"KMD"); else coin->price_kmd = 1.; coin->maxamount = coin->valuesumA; if ( coin->valuesumB > coin->maxamount ) @@ -274,7 +278,7 @@ void LP_autopriceset(int32_t ind,void *ctx,int32_t dir,struct LP_priceinfo *base oppomargin = basepp->buymargins[relpp->ind]; if ( (fixedprice= basepp->fixedprices[relpp->ind]) > SMALLVAL ) { - LP_mypriceset(&changed,relpp->symbol,basepp->symbol,fixedprice); + LP_mypriceset(1,&changed,relpp->symbol,basepp->symbol,fixedprice); //printf("autoprice FIXED %s/%s <- %.8f\n",basepp->symbol,relpp->symbol,fixedprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,fixedprice); return; @@ -285,7 +289,7 @@ void LP_autopriceset(int32_t ind,void *ctx,int32_t dir,struct LP_priceinfo *base factor = basepp->factors[relpp->ind]; if ( fabs(price) < SMALLVAL && refbase != 0 && refrel != 0 ) { - price = LP_myprice(&bid,&ask,refbase,refrel); + price = LP_myprice(1,&bid,&ask,refbase,refrel); //printf("%s/%s USE ref %s/%s %.8f factor %.8f offset %.8f margin %.8f/%.8f\n",basepp->symbol,relpp->symbol,refbase,refrel,price,factor,offset,oppomargin,margin); } if ( LP_pricevalid(price) > 0 ) @@ -312,7 +316,7 @@ void LP_autopriceset(int32_t ind,void *ctx,int32_t dir,struct LP_priceinfo *base newprice = LP_autorefs[ind].lastask; //printf("autopriceset %s/%s <- %.8f %.8f (%.8f %.8f)\n",basepp->symbol,relpp->symbol,price,newprice,LP_autorefs[ind].lastbid,LP_autorefs[ind].lastask); } - LP_mypriceset(&changed,relpp->symbol,basepp->symbol,newprice); + LP_mypriceset(1,&changed,relpp->symbol,basepp->symbol,newprice); if ( changed != 0 || time(NULL) > lasttime+LP_ORDERBOOK_DURATION*.777) { lasttime = (uint32_t)time(NULL); @@ -582,9 +586,9 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) LP_autorefs[i].lastask = askprice; else LP_autorefs[i].lastask = (LP_autorefs[i].lastask * 0.9) + (0.1 * askprice); askprice = LP_autorefs[i].lastask; - LP_mypriceset(&changed,rel,base,bidprice); + LP_mypriceset(1,&changed,rel,base,bidprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,bidprice); - LP_mypriceset(&changed,base,rel,askprice); + LP_mypriceset(1,&changed,base,rel,askprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,askprice); //printf("price %.8f -> %.8f %.8f\n",price,bidprice,askprice); } @@ -626,7 +630,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) LP_autorefs[i].lastbid = newprice; else LP_autorefs[i].lastbid = (LP_autorefs[i].lastbid * 0.99) + (0.01 * newprice); newprice = LP_autorefs[i].lastbid; - LP_mypriceset(&changed,rel,base,newprice); + LP_mypriceset(1,&changed,rel,base,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); //printf("%s/%s price %.8f margin %.8f/%.8f newprice %.8f %.8f\n",base,rel,price,buymargin,sellmargin,newprice,(1. / newprice) * (1. + sellmargin)); newprice = (1. / price) * (1. + sellmargin); @@ -634,7 +638,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) LP_autorefs[i].lastask = newprice; else LP_autorefs[i].lastask = (LP_autorefs[i].lastask * 0.99) + (0.01 * newprice); newprice = LP_autorefs[i].lastask; - LP_mypriceset(&changed,base,rel,newprice); + LP_mypriceset(1,&changed,base,rel,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); } //else printf("null return from CMC\n"); } @@ -782,7 +786,7 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str char *retstr2; uint64_t txfee,desttxfee; double bid,ask,maxprice; bits256 zero; uint32_t requestid,quoteid,iter,i; cJSON *retjson2; struct LP_utxoinfo A; struct LP_address_utxo *utxos[1000]; int32_t max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); LP_txfees(&txfee,&desttxfee,buy->symbol,sell->symbol); requestid = quoteid = 0; - LP_myprice(&bid,&ask,buy->symbol,sell->symbol); + LP_myprice(1,&bid,&ask,buy->symbol,sell->symbol); maxprice = ask; if ( setbaserel != 0 ) { @@ -802,7 +806,7 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str //if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 ) { memset(zero.bytes,0,sizeof(zero)); - if ( (retstr2= LP_autobuy(ctx,0,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1,zero,1,0)) != 0 ) + if ( (retstr2= LP_autobuy(ctx,0,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1,zero,1,0,0,0)) != 0 ) { if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) { diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index 0669b2c35..38d37c626 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -35,7 +35,7 @@ struct LP_priceinfo int32_t ind,pad; double diagval,high[2],low[2],last[2],bid[2],ask[2]; double relvals[LP_MAXPRICEINFOS]; - double myprices[LP_MAXPRICEINFOS]; + double myprices[2][LP_MAXPRICEINFOS]; double minprices[LP_MAXPRICEINFOS]; // autoprice double fixedprices[LP_MAXPRICEINFOS]; // fixedprices double buymargins[LP_MAXPRICEINFOS]; @@ -451,16 +451,16 @@ void LP_priceinfoupdate(char *base,char *rel,double price) } } -double LP_myprice(double *bidp,double *askp,char *base,char *rel) +double LP_myprice(int32_t iambob,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]; + *askp = basepp->myprices[iambob][relpp->ind]; if ( LP_pricevalid(*askp) > 0 ) { - val = relpp->myprices[basepp->ind]; + val = relpp->myprices[iambob][basepp->ind]; if ( LP_pricevalid(val) > 0 ) { *bidp = 1. / val; @@ -474,7 +474,7 @@ double LP_myprice(double *bidp,double *askp,char *base,char *rel) } else { - val = relpp->myprices[basepp->ind]; + val = relpp->myprices[iambob][basepp->ind]; if ( LP_pricevalid(val) > 0 ) { *bidp = 1. / val; @@ -486,7 +486,7 @@ double LP_myprice(double *bidp,double *askp,char *base,char *rel) return(0.); } -char *LP_myprices() +char *LP_myprices(int32_t iambob) { int32_t baseid,relid; double bid,ask; char *base,*rel; cJSON *item,*array; array = cJSON_CreateArray(); @@ -496,7 +496,7 @@ char *LP_myprices() for (relid=0; relid SMALLVAL ) + if ( LP_myprice(iambob,&bid,&ask,base,rel) > SMALLVAL ) { item = cJSON_CreateObject(); jaddstr(item,"base",base); @@ -510,7 +510,7 @@ char *LP_myprices() return(jprint(array,1)); } -int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) +int32_t LP_mypriceset(int32_t iambob,int32_t *changedp,char *base,char *rel,double price) { struct LP_priceinfo *basepp=0,*relpp=0; struct LP_pubkey_info *pubp; double minprice,maxprice,margin,buymargin,sellmargin; *changedp = 0; @@ -519,43 +519,46 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) if ( base != 0 && rel != 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { - if ( price == 0. || fabs(basepp->myprices[relpp->ind] - price)/price > 0.001 ) + if ( price == 0. || fabs(basepp->myprices[iambob][relpp->ind] - price)/price > 0.001 ) *changedp = 1; - sellmargin = relpp->sellmargins[basepp->ind]; - buymargin = relpp->buymargins[basepp->ind]; - margin = (sellmargin + buymargin) * 0.5; - if ( price == 0. ) + if ( iambob != 0 ) { - relpp->minprices[basepp->ind] = 0.; - relpp->fixedprices[basepp->ind] = 0.; - relpp->buymargins[basepp->ind] = 0.; - relpp->sellmargins[basepp->ind] = 0.; - relpp->offsets[basepp->ind] = 0.; - relpp->factors[basepp->ind] = 0.; - LP_autoref_clear(base,rel); - margin = 0.; - } - else if ( (minprice= basepp->minprices[relpp->ind]) > SMALLVAL && price < minprice ) - { - //printf("%s/%s price %.8f less than minprice %.8f\n",base,rel,price,minprice); - price = minprice * (1. - margin); - } - else if ( (maxprice= relpp->minprices[basepp->ind]) > SMALLVAL ) - { - if ( price > (1. / maxprice) ) + sellmargin = relpp->sellmargins[basepp->ind]; + buymargin = relpp->buymargins[basepp->ind]; + margin = (sellmargin + buymargin) * 0.5; + if ( price == 0. ) + { + relpp->minprices[basepp->ind] = 0.; + relpp->fixedprices[basepp->ind] = 0.; + relpp->buymargins[basepp->ind] = 0.; + relpp->sellmargins[basepp->ind] = 0.; + relpp->offsets[basepp->ind] = 0.; + relpp->factors[basepp->ind] = 0.; + LP_autoref_clear(base,rel); + margin = 0.; + } + else if ( (minprice= basepp->minprices[relpp->ind]) > SMALLVAL && price < minprice ) + { + //printf("%s/%s price %.8f less than minprice %.8f\n",base,rel,price,minprice); + price = minprice * (1. - margin); + } + else if ( (maxprice= relpp->minprices[basepp->ind]) > SMALLVAL ) { - //printf("%s/%s price %.8f less than maxprice %.8f, more than %.8f\n",base,rel,price,maxprice,1./maxprice); - price = (1. / maxprice) * (1. + margin); + if ( price > (1. / maxprice) ) + { + //printf("%s/%s price %.8f less than maxprice %.8f, more than %.8f\n",base,rel,price,maxprice,1./maxprice); + price = (1. / maxprice) * (1. + margin); + } } } /*else if ( basepp->myprices[relpp->ind] > SMALLVAL ) { price = (basepp->myprices[relpp->ind] * 0.9) + (0.1 * price); }*/ - basepp->myprices[relpp->ind] = price; // ask + basepp->myprices[iambob][relpp->ind] = price; // ask //printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); //relpp->myprices[basepp->ind] = (1. / price); // bid, but best to do one dir at a time - if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 ) + if ( iambob != 0 && (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 ) { pubp->timestamp = (uint32_t)time(NULL); LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,0,0,0,0,0); @@ -569,12 +572,12 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) return(-1); } -double LP_price(char *base,char *rel) +double LP_price(int32_t iambob,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. ) + if ( (price= basepp->myprices[iambob][relind]) == 0. ) { price = basepp->relvals[relind]; } @@ -582,19 +585,19 @@ double LP_price(char *base,char *rel) return(price); } -double LP_getmyprice(char *base,char *rel) +double LP_getmyprice(int32_t iambob,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. ) + if ( (price= basepp->myprices[iambob][relind]) == 0. ) { } } return(price); } -cJSON *LP_priceinfomatrix(int32_t usemyprices) +cJSON *LP_priceinfomatrix(int32_t iambob,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); @@ -611,7 +614,7 @@ cJSON *LP_priceinfomatrix(int32_t usemyprices) pp->diagval = sum = n = 0; for (j=0; jmyprices[j]) == 0. ) + if ( usemyprices == 0 || (val= pp->myprices[iambob][j]) == 0. ) val = pp->relvals[j]; if ( val > SMALLVAL ) { @@ -661,7 +664,7 @@ struct LP_priceinfo *LP_priceinfoadd(char *symbol) pp->coinbits = stringbits(symbol); pp->ind = LP_numpriceinfos++; //LP_numpriceinfos++; - if ( (retjson= LP_priceinfomatrix(0)) != 0 ) + if ( (retjson= LP_priceinfomatrix(1,0)) != 0 ) free_json(retjson); return(pp); } @@ -1016,7 +1019,7 @@ int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance) KMDvalue = balance; else { - if ( (price= LP_price(coin->symbol,"KMD")) > SMALLVAL ) + if ( (price= LP_price(1,coin->symbol,"KMD")) > SMALLVAL ) KMDvalue = price * balance; } } diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c index cd34c0f8c..8bfcdc67e 100644 --- a/iguana/exchanges/LP_privkey.c +++ b/iguana/exchanges/LP_privkey.c @@ -202,6 +202,66 @@ char *LP_secretaddresses(void *ctx,char *prefix,char *passphrase,int32_t n,uint8 return(jprint(retjson,1)); } +uint32_t komodo_segid32(char *coinaddr) +{ + bits256 addrhash; + vcalc_sha256(0,(uint8_t *)&addrhash,(uint8_t *)coinaddr,(int32_t)strlen(coinaddr)); + return(addrhash.uints[0]); +} + +char *LP_gen64addrs(void *ctx,char *passphrase,uint8_t taddr,uint8_t pubtype) +{ + int32_t i,segid,n=64; uint8_t tmptype,pubkey33[33],rmd160[20]; char str[65],str2[65],buf[8192],wifstr[64],coinaddr[64],coinaddrs[64][64],wifstrs[64][64]; uint64_t mask = 0; bits256 checkprivkey,privkey,pubkey; cJSON *retjson,*addrs,*array; + if ( passphrase == 0 || passphrase[0] == 0 ) + passphrase = "password"; + memset(coinaddrs,0,sizeof(coinaddrs)); + memset(wifstrs,0,sizeof(wifstrs)); + conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + bitcoin_priv2pub(ctx,"KMD",pubkey33,coinaddr,privkey,taddr,pubtype); + //sprintf(output,"\"addresses\":["); + for (i=0; bitweight(mask)<64; i++) + { + sprintf(buf,"%s %03d",passphrase,i); + conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)buf,(int32_t)strlen(buf)); + bitcoin_priv2pub(ctx,"KMD",pubkey33,coinaddr,privkey,taddr,pubtype); + bitcoin_priv2wif("KMD",0,wifstr,privkey,188); + bitcoin_wif2priv("KMD",0,&tmptype,&checkprivkey,wifstr); + bitcoin_addr2rmd160("KMD",taddr,&tmptype,rmd160,coinaddr); + if ( bits256_cmp(checkprivkey,privkey) != 0 ) + { + printf("WIF.(%s) error -> %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\"}")); + } + segid = komodo_segid32(coinaddr) & 0x3f; + if ( (mask & (1LL << segid)) == 0 ) + { + mask |= (1LL << segid); + strcpy(coinaddrs[segid],coinaddr); + strcpy(wifstrs[segid],wifstr); + printf("./komodo-cli -ac_name=POSTEST64 importprivkey %s "" %s\n",wifstr,bitweight(mask)<64?"false":"true"); + } + //sprintf(output+strlen(output),"\\\"%s\\\"%c ",coinaddr,i 5*a || a > 5*A || a > n*20 || A > n*20 ) // unlikely it is a real wif + if ( A > 5*a || a > 5*A || a > n*26 || A > n*26 ) // unlikely it is a real wif { printf("reject wif %s due to n.%d a.%d A.%d (%d %d %d %d)\n",wifstr,n,a,A,A > 5*a,a < 5*A,a > n*20,A > n*20); return(0); @@ -292,6 +352,7 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan { //static uint32_t counter; bits256 privkey,userpub,zero,userpass,checkkey,tmpkey; char str[65],str2[65],tmpstr[128]; cJSON *retjson; uint8_t tmptype,sig[128]; int32_t notarized,siglen; uint64_t nxtaddr; + uint8_t rmd160[20]; if ( (wifstr == 0 || wifstr[0] == 0) && LP_wifstr_valid(coin->symbol,passphrase) > 0 ) { wifstr = passphrase; @@ -339,7 +400,7 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan #ifndef NOTETOMIC if ( coin->etomic[0] != 0 ) { - uint8_t check64[64],checktype,checkrmd160[20],rmd160[20]; char checkaddr[64],checkaddr2[64]; + uint8_t check64[64],checktype,checkrmd160[20]; char checkaddr[64],checkaddr2[64]; if ( LP_etomic_priv2pub(check64,privkey) == 0 ) { if ( memcmp(check64,coin->pubkey33+1,32) == 0 ) @@ -374,8 +435,8 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan coin->counter++; memcpy(G.LP_pubsecp,coin->pubkey33,33); bitcoin_priv2wif(coin->symbol,coin->wiftaddr,tmpstr,privkey,coin->wiftype); - bitcoin_addr2rmd160(coin->symbol,coin->taddr,&tmptype,G.LP_myrmd160,coin->smartaddr); - LP_privkeyadd(privkey,G.LP_myrmd160); + bitcoin_addr2rmd160(coin->symbol,coin->taddr,&tmptype,rmd160,coin->smartaddr); + LP_privkeyadd(privkey,rmd160); G.LP_privkey = privkey; if ( G.counter++ == 0 ) { @@ -415,13 +476,47 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan return(privkey); } -void verusblocks(struct iguana_info *coin,char *coinaddr) +void verus_utxos(struct iguana_info *coin,char *coinaddr) +{ + cJSON *array,*item; char buf[64],str[65]; int32_t i,m,vout,n=0; bits256 txid; + sprintf(buf,"[%d, 99999999, [\"%s\"]]",1,coinaddr); + array = bitcoin_json(coin,"listunspent",buf); + if ( array != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=m=0; ismartaddr) != 0 ) + return(clonestr("{\"error\":\"mismatched smartaddr\"}")); + //verus_utxos(coin,coin->smartaddr); hash = LP_getbestblockhash(coin); memset(histo,0,sizeof(histo)); memset(myhisto,0,sizeof(myhisto)); - possum = powsum = supply = 0.; + num23000 = num16 = num17 = num10 = num20 = numstaked = 0; + avestakedsize = possum = powsum = supply = RTu3sum = 0.; numpow = numpos = num = npos = npow = 0; if ( bits256_nonz(hash) != 0 ) { @@ -430,6 +525,7 @@ void verusblocks(struct iguana_info *coin,char *coinaddr) while ( (blockjson= LP_blockjson(&height,coin->symbol,hashstr,0)) != 0 ) { num++; + stakedval = 0.; height = juint(blockjson,"height"); if ( (txs= jarray(&n,blockjson,"tx")) != 0 ) { @@ -437,6 +533,7 @@ void verusblocks(struct iguana_info *coin,char *coinaddr) value = 0; posflag = 0; locked = 0; + gotblock = 0; lastaddr = addr0 = ""; memset(script,0,sizeof(script)); memset(firstaddr,0,sizeof(firstaddr)); @@ -451,6 +548,13 @@ void verusblocks(struct iguana_info *coin,char *coinaddr) value = jdouble(vout,"value"); supply += value; hexstr = 0; + if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 ) + { + if ( strcmp(hexstr,"2102ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92ac") == 0 || strcmp(hexstr,"2102aef0f54a967031f4c63b36d12741fbb9ca39713baedfff7f8c0d0d8ee14ee0ebac") == 0 || strcmp(hexstr,"76a914cc39e9e699f86b03a5cf1d7f2a0b411cf652641788ac") == 0 || strcmp(hexstr,"76a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688ac") == 0 ) + { + gotblock = 1; + } + } if ( m == 2 && (vout1= jitem(vouts,1)) != 0 ) { // 6a2001039bbc0bb17576a9149a3af738444dd86b55c86752247aec2e7deb842688ac @@ -470,7 +574,7 @@ void verusblocks(struct iguana_info *coin,char *coinaddr) locked = ((int32_t)script[6] << 16) + ((int32_t)script[5] << 8) + script[4]; addr0 = firstaddr; } else printf("unexpected vout1.(%s) (%s).%d %.8f\n",jprint(vout1,0),hexstr!=0?hexstr:"",(int32_t)strlen(hexstr),jdouble(vout1,"value")); - } else printf("coinbase without opret (%s)\n",jprint(vouts,0)); + } //else printf("coinbase without opret (%s)\n",jprint(vouts,0)); } } free_json(txobj); @@ -489,8 +593,12 @@ void verusblocks(struct iguana_info *coin,char *coinaddr) else { strcpy(stakingaddr,lastaddr); + stakedval = jdouble(vout,"value"); + avestakedsize += stakedval; + numstaked++; + //printf("stakedval %f\n",stakedval); posflag = 1; - //printf("ht.%d found staking address.(%s)\n",height,stakingaddr); + //printf("ht.%d found staking address.(%s) %.8f (%s)\n",height,stakingaddr,stakedval,jprint(vout,0)); } } else printf("no addresses[0] in (%s) %s\n",jprint(vout,0),sobj!=0?jprint(sobj,0):""); } //else printf("n.%d m.%d no first out in lastvout.(%s)\n",n,m,jprint(txobj,0)); @@ -500,17 +608,37 @@ void verusblocks(struct iguana_info *coin,char *coinaddr) if ( posflag != 0 ) { numpos++; - if ( num < 100 ) - printf("ht.%-5d lock.%-7d PoS coinbase.(%s) staked.(%s) %.8f\n",height,locked,addr0,stakingaddr,value); if ( strcmp(coinaddr,stakingaddr) == 0 || strcmp("RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC",stakingaddr) == 0 ) + { + if (strcmp("RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC",stakingaddr) == 0 ) + RTu3sum += value; possum += value, npos++; + if ( num < 1500 ) + printf("ht.%-5d lock.%-7d PoS cb.(%s) stake.(%s) %.8f %.8f\n",height,locked,addr0,stakingaddr,value,stakedval); + if ( height > 23000 ) + { + char strbuf[64]; + sprintf(strbuf,"%.0f",stakedval); + if ( strcmp(strbuf,"20") == 0 ) + num20++; + else if ( strcmp(strbuf,"17") == 0 ) + num17++; + else if ( strcmp(strbuf,"16") == 0 ) + num16++; + else if ( strcmp(strbuf,"10") == 0 ) + num10++; + else printf("got strbuf.(%s)\n",strbuf); + } + } + else if ( 0 && num < 100 ) + printf("ht.%-5d lock.%-7d PoS cb.(%s) stake.(%s) %.8f %.8f\n",height,locked,addr0,stakingaddr,value,stakedval); } else { numpow++; - if ( num < 100 ) + if ( num < 100 && strcmp(coinaddr,addr0) == 0 ) printf("ht.%-5d lock.%-7d PoW coinbase.(%s) %.8f\n",height,locked,addr0,value); - if ( strcmp(coinaddr,addr0) == 0 || strcmp("RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC",stakingaddr) == 0 ) + if ( strcmp(coinaddr,addr0) == 0 || gotblock != 0 ) powsum += value, npow++; } histo[locked/1000] += value; @@ -521,24 +649,34 @@ void verusblocks(struct iguana_info *coin,char *coinaddr) free_json(blockjson); if ( height == 5040 ) break; - else if ( num == 1000 ) + else if ( height == 23000 ) { - printf("num.%d PoW %.2f%% %.8f %d v %d PoS %.2f%% %.8f -> %.8f supply %.8f PoW %.1f%% PoS %.1f%% both %.1f%%\n",num,100.*(double)numpow/num,powsum,npow,npos,100.*(double)numpos/num,possum,powsum+possum,supply,100.*powsum/supply,100.*possum/supply,100.*(powsum+possum)/supply); + num23000 = num; + printf("num10.%d num16.%d num17.%d num20.%d / num23000.%d -> %.2f%% %.2f%% %.2f%% %.2f%% [%.3f %.3f %.3f %.3f] %.3f ave %.8f\n",num10,num16,num17,num20,num23000,100.*(double)num10/num23000,100.*(double)num16/num23000,100.*(double)num17/num23000,100.*(double)num20/num23000,(100.*(double)num10/num23000)/2.87,(100.*(double)num16/num23000)/10.5,(100.*(double)num17/num23000)/4.88,(100.*(double)num20/num23000)/5.74,(100.*(double)(num10+num16+num17+num20)/num23000)/24,avestakedsize/numstaked); + } + else if ( (num % 1000) == 0 || (num < 1000 && (num % 100) == 0) ) + { + printf("num.%d PoW %.2f%% %.0f %d v %d PoS %.2f%% %.0f -> %.0f supply %.0f PoW %.1f%% PoS %.1f%% both %.1f%% RTu3 %.8f %.1f%%\n",num,100.*(double)numpow/num,powsum,npow,npos,100.*(double)numpos/num,possum,powsum+possum,supply,100.*powsum/supply,100.*possum/supply,100.*(powsum+possum)/supply,RTu3sum,100.*RTu3sum/supply); } } } if ( num > 0 ) { - for (i=0; i %.8f supply %.8f PoW %.1f%% PoS %.1f%% both %.1f%%\n",num,100.*(double)numpow/num,powsum,npow,npos,100.*(double)numpos/num,possum,powsum+possum,supply,100.*powsum/supply,100.*possum/supply,100.*(powsum+possum)/supply); + if ( 0 ) + { + for (i=0; i %.8f supply %.8f PoW %.1f%% PoS %.1f%% both %.1f%% RTu3sum %.8f %.1f%%\n",num,100.*(double)numpow/num,powsum,npow,npos,100.*(double)numpos/num,possum,powsum+possum,supply,100.*powsum/supply,100.*possum/supply,100.*(powsum+possum)/supply,RTu3sum,100.*RTu3sum/supply); + printf("num10.%d num16.%d num17.%d num20.%d / num23000.%d -> %.2f%% %.2f%% %.2f%% %.2f%% [%.3f %.3f %.3f %.3f] %.3f ave %.8f\n",num10,num16,num17,num20,num23000,100.*(double)num10/num23000,100.*(double)num16/num23000,100.*(double)num17/num23000,100.*(double)num20/num23000,(100.*(double)num10/num23000)/2.87,(100.*(double)num16/num23000)/10.5,(100.*(double)num17/num23000)/4.88,(100.*(double)num20/num23000)/5.74,(100.*(double)(num10+num16+num17+num20)/num23000)/24,avestakedsize/numstaked); } + return(clonestr("{\"result\":\"success\"}")); } void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase) @@ -559,10 +697,6 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase) if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 ) { privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,""); - if ( strcmp(coin->symbol,"VRSC") == 0 && strcmp("RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj",coin->smartaddr) == 0 ) - { - verusblocks(coin,coin->smartaddr); - } } } //printf("i.%d of %d\n",i,LP_numcoins); @@ -580,6 +714,7 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase) int32_t LP_passphrase_init(char *passphrase,char *gui,uint16_t netid,char *seednode) { static void *ctx; struct iguana_info *coin,*tmp; int32_t counter; + uint8_t pubkey33[100]; if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( G.LP_pendingswaps != 0 ) @@ -614,8 +749,11 @@ int32_t LP_passphrase_init(char *passphrase,char *gui,uint16_t netid,char *seedn memset(&G,0,sizeof(G)); G.netid = netid; safecopy(G.seednode,seednode,sizeof(G.seednode)); + vcalc_sha256(0,G.LP_passhash.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); LP_privkey_updates(ctx,LP_mypubsock,passphrase); + bitcoin_pubkey33(ctx, pubkey33, G.LP_privkey); + calc_rmd160_sha256(G.LP_myrmd160, pubkey33, 33); init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20); G.LP_sessionid = (uint32_t)time(NULL); safecopy(G.gui,gui,sizeof(G.gui)); diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index deaacf1c9..dd694d9ab 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -13,10 +13,33 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ +#include "LP_include.h" +#include "../../includes/cJSON.h" // // LP_remember.c // marketmaker // +char *coin_name_by_tx_index(struct LP_swap_remember *rswap, int32_t tx_index) +{ + switch (tx_index) { + case BASILISK_MYFEE: + case BASILISK_OTHERFEE: + case BASILISK_ALICEPAYMENT: + case BASILISK_ALICERECLAIM: + case BASILISK_BOBSPEND: + return rswap->dest; + case BASILISK_BOBDEPOSIT: + case BASILISK_BOBPAYMENT: + case BASILISK_BOBRECLAIM: + case BASILISK_BOBREFUND: + case BASILISK_ALICESPEND: + case BASILISK_ALICECLAIM: + return rswap->src; + default: + return 0; + } +} + void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,int32_t scriptlen) { int32_t i; char scriptstr[513]; @@ -70,6 +93,13 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx fprintf(fp,",\"bobtomic\":\"%s\"",swap->I.bobtomic); if ( swap->I.etomicsrc[0] != 0 ) fprintf(fp,",\"etomicsrc\":\"%s\"",swap->I.etomicsrc); +#ifndef NOTETOMIC + if (swap->myfee.I.ethTxid[0] != 0) { + fprintf(fp,",\"aliceFeeEthTx\":\"%s\"", swap->myfee.I.ethTxid); + } + if (swap->otherfee.I.ethTxid[0] != 0) { + fprintf(fp,",\"aliceFeeEthTx\":\"%s\"", swap->otherfee.I.ethTxid); + } if (swap->bobdeposit.I.ethTxid[0] != 0) { fprintf(fp,",\"bobDepositEthTx\":\"%s\"", swap->bobdeposit.I.ethTxid); } @@ -80,6 +110,9 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx fprintf(fp,",\"alicePaymentEthTx\":\"%s\"", swap->alicepayment.I.ethTxid); } + fprintf(fp,",\"aliceRealSat\":\"%" PRId64 "\"", swap->I.alicerealsat); + fprintf(fp,",\"bobRealSat\":\"%" PRId64 "\"", swap->I.bobrealsat); +#endif fprintf(fp,",\"alicecoin\":\"%s\"",swap->I.alicestr); if ( swap->I.alicetomic[0] != 0 ) fprintf(fp,",\"alicetomic\":\"%s\"",swap->I.alicetomic); @@ -250,6 +283,22 @@ void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx { if ( (reqjson= cJSON_Parse(fstr)) != 0 ) { +#ifndef NOTETOMIC + if (strcmp(rawtx->symbol,"ETOMIC") == 0) { + jdelete(reqjson,"txid"); + jdelete(reqjson,"amount"); + jaddstr(reqjson,"txid", rawtx->I.ethTxid); + jaddnum(reqjson,"amount", dstr(rawtx->I.eth_amount)); + jdelete(reqjson, "coin"); + if (rawtx == &swap->myfee || rawtx == &swap->otherfee || rawtx == &swap->alicepayment || rawtx == &swap->bobspend || rawtx == &swap->alicereclaim) { + jaddstr(reqjson,"coin", swap->I.alicestr); + } + + if (rawtx == &swap->bobdeposit || rawtx == &swap->bobrefund || rawtx == &swap->aliceclaim || rawtx == &swap->bobpayment || rawtx == &swap->bobreclaim || rawtx == &swap->alicespend) { + jaddstr(reqjson,"coin", swap->I.bobstr); + } + } +#endif if ( jobj(reqjson,"method") != 0 ) jdelete(reqjson,"method"); jaddstr(reqjson,"method","update"); @@ -429,9 +478,9 @@ int32_t basilisk_isbobcoin(int32_t iambob,int32_t ind) case BASILISK_OTHERFEE: return(!iambob); break; case BASILISK_BOBSPEND: case BASILISK_ALICEPAYMENT: - case BASILISK_ALICERECLAIM: - case BASILISK_ALICECLAIM: return(0); + case BASILISK_ALICERECLAIM: return(0); break; + case BASILISK_ALICECLAIM: case BASILISK_BOBDEPOSIT: case BASILISK_ALICESPEND: case BASILISK_BOBPAYMENT: @@ -656,13 +705,31 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) jaddnum(item,"alicetxfee",dstr(rswap->Atxfee)); jadd64bits(item,"aliceid",rswap->aliceid); array = cJSON_CreateArray(); + cJSON *tx_chain = cJSON_CreateArray(); for (i=0; isentflags[i] != 0 ) - jaddistr(array,txnames[i]); + if ( rswap->sentflags[i] != 0 ) { + jaddistr(array, txnames[i]); + cJSON *tx = cJSON_CreateObject(); + jaddstr(tx, "stage", txnames[i]); + jaddstr(tx, "coin", coin_name_by_tx_index(rswap, i)); +#ifndef NOTETOMIC + if (LP_etomic_is_empty_tx_id(rswap->eth_tx_ids[i]) == 0) { + jaddstr(tx, "txid", rswap->eth_tx_ids[i]); + jaddnum(tx, "amount", dstr(rswap->eth_values[i])); + } else { +#endif + jaddbits256(tx, "txid", rswap->txids[i]); + jaddnum(tx, "amount", dstr(rswap->values[i])); +#ifndef NOTETOMIC + } +#endif + jaddi(tx_chain, tx); + } if ( rswap->txbytes[i] != 0 ) free(rswap->txbytes[i]), rswap->txbytes[i] = 0; } + jadd(item, "txChain", tx_chain); jadd(item,"sentflags",array); array = cJSON_CreateArray(); for (i=0; ipaymentspent); jaddbits256(item,"Apaymentspent",rswap->Apaymentspent); jaddbits256(item,"depositspent",rswap->depositspent); + jaddbits256(item,"alicedexfee",rswap->iambob == 0 ? rswap->txids[BASILISK_MYFEE] : rswap->txids[BASILISK_OTHERFEE]); return(item); } @@ -901,16 +969,32 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag) strcpy(rswap->etomicdest,jstr(txobj,"etomicdest")); } + rswap->bobrealsat = jint(txobj, "bobRealSat"); + rswap->alicerealsat = jint(txobj, "aliceRealSat"); + + if (jstr(txobj,"aliceFeeEthTx") != 0) { + if (rswap->iambob == 0) { + strcpy(rswap->eth_tx_ids[BASILISK_MYFEE], jstr(txobj, "aliceFeeEthTx")); + rswap->eth_values[BASILISK_MYFEE] = LP_DEXFEE(rswap->alicerealsat); + } else { + strcpy(rswap->eth_tx_ids[BASILISK_OTHERFEE], jstr(txobj, "aliceFeeEthTx")); + rswap->eth_values[BASILISK_OTHERFEE] = LP_DEXFEE(rswap->alicerealsat); + } + } + if (jstr(txobj,"bobDepositEthTx") != 0) { - strcpy(rswap->bobDepositEthTx, jstr(txobj,"bobDepositEthTx")); + strcpy(rswap->eth_tx_ids[BASILISK_BOBDEPOSIT], jstr(txobj,"bobDepositEthTx")); + rswap->eth_values[BASILISK_BOBDEPOSIT] = LP_DEPOSITSATOSHIS(rswap->bobrealsat); } if (jstr(txobj,"bobPaymentEthTx") != 0) { - strcpy(rswap->bobPaymentEthTx, jstr(txobj,"bobPaymentEthTx")); + strcpy(rswap->eth_tx_ids[BASILISK_BOBPAYMENT], jstr(txobj,"bobPaymentEthTx")); + rswap->eth_values[BASILISK_BOBPAYMENT] = rswap->bobrealsat; } if (jstr(txobj,"alicePaymentEthTx") != 0) { - strcpy(rswap->alicePaymentEthTx, jstr(txobj,"alicePaymentEthTx")); + strcpy(rswap->eth_tx_ids[BASILISK_ALICEPAYMENT], jstr(txobj,"alicePaymentEthTx")); + rswap->eth_values[BASILISK_ALICEPAYMENT] = rswap->alicerealsat; } if (jstr(txobj,"bobtomic") != 0) { @@ -1275,6 +1359,8 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals, { char *aliceSpendEthTxId = LP_etomicalice_spends_bob_payment(&rswap); if (aliceSpendEthTxId != NULL) { + strcpy(rswap.eth_tx_ids[BASILISK_ALICESPEND], aliceSpendEthTxId); + rswap.eth_values[BASILISK_ALICESPEND] = rswap.bobrealsat; free(aliceSpendEthTxId); } else { printf("Alice spend ETH tx send failed!\n"); @@ -1324,6 +1410,8 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals, { char *aliceClaimsEthTxId = LP_etomicalice_claims_bob_deposit(&rswap); if (aliceClaimsEthTxId != NULL) { + strcpy(rswap.eth_tx_ids[BASILISK_ALICECLAIM], aliceClaimsEthTxId); + rswap.eth_values[BASILISK_ALICECLAIM] = LP_DEPOSITSATOSHIS(rswap.bobrealsat); free(aliceClaimsEthTxId); } else { printf("Alice Bob deposit claim ETH tx failed!\n"); @@ -1356,7 +1444,13 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals, if ( rswap.alicetomic[0] != 0 ) { char *aliceReclaimEthTx = LP_etomicalice_reclaims_payment(&rswap); - free(aliceReclaimEthTx); + if (aliceReclaimEthTx != NULL) { + strcpy(rswap.eth_tx_ids[BASILISK_ALICERECLAIM], aliceReclaimEthTx); + rswap.eth_values[BASILISK_ALICERECLAIM] = rswap.alicerealsat; + free(aliceReclaimEthTx); + } else { + printf("Alice could not reclaim ETH/ERC20 payment!\n"); + } } #endif } @@ -1400,6 +1494,8 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals, { char *bobSpendEthTx = LP_etomicbob_spends_alice_payment(&rswap); if (bobSpendEthTx != NULL) { + strcpy(rswap.eth_tx_ids[BASILISK_BOBSPEND], bobSpendEthTx); + rswap.eth_values[BASILISK_BOBSPEND] = rswap.alicerealsat; free(bobSpendEthTx); } else { printf("Bob spends Alice payment ETH tx send failed!\n"); @@ -1437,6 +1533,8 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals, { char *bobReclaimEthTx = LP_etomicbob_reclaims_payment(&rswap); if (bobReclaimEthTx != NULL) { + strcpy(rswap.eth_tx_ids[BASILISK_BOBRECLAIM], bobReclaimEthTx); + rswap.eth_values[BASILISK_BOBRECLAIM] = rswap.bobrealsat; free(bobReclaimEthTx); } else { printf("Bob reclaims payment ETH tx send failed!\n"); @@ -1490,6 +1588,8 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals, { char *bobRefundsEthTx = LP_etomicbob_refunds_deposit(&rswap); if (bobRefundsEthTx != NULL) { + strcpy(rswap.eth_tx_ids[BASILISK_BOBREFUND], bobRefundsEthTx); + rswap.eth_values[BASILISK_BOBREFUND] = LP_DEPOSITSATOSHIS(rswap.bobrealsat); free(bobRefundsEthTx); } else { printf("Bob refunds deposit ETH tx send failed!\n"); diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 3d9139bb0..8979239fd 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -137,6 +137,12 @@ int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin) uint64_t LP_RTsmartbalance(struct iguana_info *coin) { +#ifndef NOTETOMIC + if (coin->etomic[0] != 0) { + int error = 0; + return LP_etomic_get_balance(coin, coin->smartaddr, &error); + } +#endif cJSON *array,*item; char buf[512],*retstr; int32_t i,n; uint64_t valuesum,value; bits256 zero; valuesum = 0; memset(zero.bytes,0,sizeof(zero)); @@ -249,18 +255,21 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout) if ( bits256_nonz(txid) == 0 ) return(cJSON_Parse("{\"error\":\"null txid\"}")); if ( coin->electrum == 0 ) - { - sprintf(buf,"[\"%s\", %d, true]",bits256_str(str,txid),vout); - return(bitcoin_json(coin,"gettxout",buf)); - } - else { if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts ) { if ( tx->outpoints[vout].spendheight > 0 ) + { + //fprintf(stderr,"LP_gettxout (%s) tx->outpoints[vout].spendheight > 0\n",coinaddr); return(0); + } //return(LP_gettxout_json(txid,vout,tx->height,tx->outpoints[vout].coinaddr,tx->outpoints[vout].value)); } + sprintf(buf,"[\"%s\", %d, true]",bits256_str(str,txid),vout); + return(bitcoin_json(coin,"gettxout",buf)); + } + else + { if ( coinaddr[0] == 0 ) { if ( (txobj= electrum_transaction(&height,symbol,coin->electrum,&txobj,txid,0)) != 0 ) @@ -275,7 +284,10 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout) if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 ) { if ( up->spendheight > 0 ) + { + //fprintf(stderr,"LP_gettxout (%s) up->spendheight > 0\n",coinaddr); return(0); + } //return(LP_gettxout_json(txid,vout,up->U.height,coinaddr,up->U.value)); } memset(zero.bytes,0,sizeof(zero)); @@ -401,6 +413,8 @@ int32_t LP_address_isvalid(char *symbol,char *address) int32_t isvalid = 0; cJSON *retjson; if ( symbol == 0 || symbol[0] == 0 ) return(0); + if ( strcmp(symbol,"BCH") == 0 && (address[0] == '1' || address[0] == '3') ) + return(-1); if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) { if ( jobj(retjson,"isvalid") != 0 && is_cJSON_True(jobj(retjson,"isvalid")) != 0 ) @@ -750,7 +764,9 @@ again: } if ( strcmp(coin->estimatefeestr,"estimatesmartfee") == 0 && (rate= jdouble(errjson,"feerate")) != 0 ) { - printf("extracted feerate %.8f from estimatesmartfee\n",rate); + static uint32_t counter; + if ( counter++ < 10 ) + printf("extracted feerate %.8f from estimatesmartfee\n",rate); rate /= 1024.; } free_json(errjson); @@ -1036,7 +1052,7 @@ cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t hei coin = LP_coinfind(symbol); if ( coin == 0 || coin->electrum != 0 ) { - printf("unexpected electrum path for %s\n",symbol); + //printf("unexpected electrum path for %s\n",symbol); return(0); } if ( blockhashstr == 0 ) @@ -1135,7 +1151,7 @@ int32_t LP_txhasnotarization(bits256 *notarizedhashp,struct iguana_info *coin,bi { cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[1024]; bits256 spenttxid; uint64_t notarymask; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0; memset(notarizedhashp,0,sizeof(*notarizedhashp)); - if ( (txobj= LP_gettx("LP_txhasnotarization",coin->symbol,txid,0)) != 0 ) + if ( (txobj= LP_gettx("LP_txhasnotarization",coin->symbol,txid,1)) != 0 ) { if ( (vins= jarray(&numvins,txobj,"vin")) != 0 ) { @@ -1147,7 +1163,7 @@ int32_t LP_txhasnotarization(bits256 *notarizedhashp,struct iguana_info *coin,bi vin = jitem(vins,i); spenttxid = jbits256(vin,"txid"); spentvout = jint(vin,"vout"); - if ( (spentobj= LP_gettx("LP_txhasnotarization",coin->symbol,spenttxid,0)) != 0 ) + if ( (spentobj= LP_gettx("LP_txhasnotarization",coin->symbol,spenttxid,1)) != 0 ) { if ( (vouts= jarray(&numvouts,spentobj,"vout")) != 0 ) { diff --git a/iguana/exchanges/LP_scan.c b/iguana/exchanges/LP_scan.c index 1229c2782..52edf5943 100644 --- a/iguana/exchanges/LP_scan.c +++ b/iguana/exchanges/LP_scan.c @@ -23,7 +23,7 @@ int32_t LP_blockinit(struct iguana_info *coin,int32_t height) { int32_t i,iter,numtx,checkht=-1; cJSON *blockobj,*txs,*txobj; bits256 txid; struct LP_transaction *tx; portable_mutex_lock(&LP_blockinit_mutex); - if ( (blockobj= LP_blockjson(&checkht,coin->symbol,0,height)) != 0 && checkht == height ) + if ( (blockobj= LP_blockjson(&checkht,coin->symbol,0,height)) != 0 && (checkht == 0 || checkht == height) ) { if ( (txs= jarray(&numtx,blockobj,"tx")) != 0 ) { @@ -54,9 +54,10 @@ int32_t LP_blockinit(struct iguana_info *coin,int32_t height) free_json(blockobj); } portable_mutex_unlock(&LP_blockinit_mutex); - if ( checkht == height ) + if ( checkht == 0 || checkht == height ) return(0); - else return(-1); + printf("%s blockinit error checkht.%d vs height.%d\n",ASSETCHAINS_SYMBOL,checkht,height); + return(-1); } int32_t LP_scanblockchain(struct iguana_info *coin,int32_t startheight,int32_t endheight) diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 2c45e53ce..00318551b 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -19,7 +19,7 @@ // marketmaker // -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 *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,int32_t fillflag,int32_t gtcflag) { struct basilisk_request R; memset(rp,0,sizeof(*rp)); @@ -45,6 +45,14 @@ cJSON *LP_quotejson(struct LP_quoteinfo *qp) if ( jobj(retjson,"gui") == 0 ) jaddstr(retjson,"gui",qp->gui[0] != 0 ? qp->gui : LP_gui); jaddstr(retjson,"uuid",qp->uuidstr); + if ( qp->maxprice != 0 ) + jaddnum(retjson,"maxprice",qp->maxprice); + if ( qp->mpnet != 0 ) + jaddnum(retjson,"mpnet",qp->mpnet); + if ( qp->gtc != 0 ) + jaddnum(retjson,"gtc",qp->gtc); + if ( qp->fill != 0 ) + jaddnum(retjson,"fill",qp->fill); jadd64bits(retjson,"aliceid",qp->aliceid); jaddnum(retjson,"tradeid",qp->tradeid); jaddstr(retjson,"base",qp->srccoin); @@ -113,28 +121,36 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson) { uint32_t rid,qid; char etomic[64],activesymbol[65],*etomicstr; memset(qp,0,sizeof(*qp)); + qp->maxprice = jdouble(argjson,"maxprice"); + qp->mpnet = juint(argjson,"mpnet"); + qp->gtc = juint(argjson,"gtc"); + qp->fill = juint(argjson,"fill"); safecopy(qp->gui,LP_gui,sizeof(qp->gui)); safecopy(qp->srccoin,jstr(argjson,"base"),sizeof(qp->srccoin)); safecopy(qp->uuidstr,jstr(argjson,"uuid"),sizeof(qp->uuidstr)); +#ifndef NOTETOMIC if ( LP_etomicsymbol(activesymbol,etomic,qp->srccoin) != 0 ) { - if ( (etomicstr= jstr(argjson,"bobtomic")) == 0 || strcmp(etomicstr,etomic) != 0 ) + if ( (etomicstr= jstr(argjson,"bobtomic")) == 0 || compareAddresses(etomicstr,etomic) == 0 ) { printf("etomic src mismatch (%s) vs (%s)\n",etomicstr!=0?etomicstr:"",etomic); return(-1); } } +#endif safecopy(qp->coinaddr,jstr(argjson,"address"),sizeof(qp->coinaddr)); safecopy(qp->etomicsrc,jstr(argjson,"etomicsrc"),sizeof(qp->etomicsrc)); safecopy(qp->destcoin,jstr(argjson,"rel"),sizeof(qp->destcoin)); +#ifndef NOTETOMIC if ( LP_etomicsymbol(activesymbol,etomic,qp->destcoin) != 0 ) { - if ( (etomicstr= jstr(argjson,"alicetomic")) == 0 || strcmp(etomicstr,etomic) != 0 ) + if ( (etomicstr= jstr(argjson,"alicetomic")) == 0 || compareAddresses(etomicstr,etomic) == 0 ) { printf("etomic dest mismatch (%s) vs (%s)\n",etomicstr!=0?etomicstr:"",etomic); return(-1); } } +#endif safecopy(qp->destaddr,jstr(argjson,"destaddr"),sizeof(qp->destaddr)); safecopy(qp->etomicdest,jstr(argjson,"etomicdest"),sizeof(qp->etomicdest)); qp->aliceid = j64bits(argjson,"aliceid"); @@ -152,9 +168,9 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson) qp->destvout = jint(argjson,"destvout"); qp->desthash = jbits256(argjson,"desthash"); qp->txfee = j64bits(argjson,"txfee"); - if ( (qp->satoshis= j64bits(argjson,"satoshis")) > qp->txfee ) + if ( (qp->satoshis= j64bits(argjson,"satoshis")) > qp->txfee && fabs(qp->maxprice) < SMALLVAL ) { - //qp->price = (double)qp->destsatoshis / (qp->satoshis = qp->txfee); + qp->maxprice = (double)qp->destsatoshis / (qp->satoshis - qp->txfee); } qp->destsatoshis = j64bits(argjson,"destsatoshis"); qp->desttxfee = j64bits(argjson,"desttxfee"); @@ -442,6 +458,17 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re jaddstr(reqjson,"pubsecp",pubsecpstr); if ( (kmd= LP_coinfind("KMD")) != 0 && (ap= LP_address(kmd,kmd->smartaddr)) != 0 && ap->instantdex_credits != 0 ) jaddnum(reqjson,"credits",dstr(ap->instantdex_credits)); +#ifndef NOTETOMIC + if (basecoin->etomic[0] != 0) { + int error = 0; + uint64_t etomic_coin_balance = LP_etomic_get_balance(basecoin, basecoin->smartaddr, &error); + jaddstr(reqjson,"utxocoin","ETH_OR_ERC20"); + jaddnum(reqjson,"bal",dstr(etomic_coin_balance)); + jaddnum(reqjson,"min",dstr(etomic_coin_balance)); + jaddnum(reqjson,"max",dstr(etomic_coin_balance)); + jaddnum(reqjson,"n",1); + } else +#endif if ( (numutxos= LP_address_minmax(1,&median,&minsize,&maxsize,basecoin,basecoin->smartaddr)) != 0 ) { //printf("send %s numutxos.%d median %.8f min %.8f max %.8f\n",base,numutxos,dstr(median),dstr(minsize),dstr(maxsize)); @@ -717,13 +744,20 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_ jadd(reqjson,"proof",LP_instantdex_txids(0,coin->smartaddr)); } msg = jprint(reqjson,1); - //printf("QUERY.(%s)\n",msg); - if ( IPC_ENDPOINT >= 0 ) - LP_queuecommand(0,msg,IPC_ENDPOINT,-1,0); - memset(&zero,0,sizeof(zero)); - if ( bits256_nonz(qp->srchash) != 0 ) - LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->srchash,clonestr(msg)); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); + { + //printf("QUERY.(%s)\n",msg); + if ( IPC_ENDPOINT >= 0 ) + LP_queuecommand(0,msg,IPC_ENDPOINT,-1,0); + memset(&zero,0,sizeof(zero)); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); + //if ( bits256_nonz(qp->srchash) != 0 ) + { + sleep(1); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->srchash,clonestr(msg)); + } + } + if ( strcmp(method,"connect") == 0 && qp->mpnet != 0 && qp->gtc == 0 ) + LP_mpnet_send(0,msg,1,qp->coinaddr); free(msg); } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index b8e74e84c..8c71e1586 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -25,6 +25,83 @@ #define WIN32_LEAN_AND_MEAN #include #endif +#ifdef _WIN32 +#include +#endif + +int32_t set_blocking_mode(int32_t sock,int32_t is_blocking) // from https://stackoverflow.com/questions/2149798/how-to-reset-a-socket-back-to-blocking-mode-after-i-set-it-to-nonblocking-mode?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa +{ + int32_t ret; +#ifdef _WIN32 + /// @note windows sockets are created in blocking mode by default + // currently on windows, there is no easy way to obtain the socket's current blocking mode since WSAIsBlocking was deprecated + u_long non_blocking = is_blocking ? 0 : 1; + ret = (NO_ERROR == ioctlsocket(sock,FIONBIO,&non_blocking)); +#else + const int flags = fcntl(sock, F_GETFL, 0); + if ((flags & O_NONBLOCK) && !is_blocking) { fprintf(stderr,"set_blocking_mode(): socket was already in non-blocking mode\n"); return ret; } + if (!(flags & O_NONBLOCK) && is_blocking) { fprintf(stderr,"set_blocking_mode(): socket was already in blocking mode\n"); return ret; } + ret = (0 == fcntl(sock, F_SETFL, is_blocking ? (flags ^ O_NONBLOCK) : (flags | O_NONBLOCK))); +#endif + if ( ret == 0 ) + return(-1); + else return(0); +} + +int32_t komodo_connect(int32_t sock,struct sockaddr *saddr,socklen_t addrlen) +{ + struct timeval tv; fd_set wfd,efd; int32_t res,so_error; socklen_t len; +#ifdef _WIN32 + set_blocking_mode(sock, 0); +#else + fcntl(sock, F_SETFL, O_NONBLOCK); +#endif // _WIN32 + res = connect(sock,saddr,addrlen); + + if ( res == -1 ) + { +#ifdef _WIN32 + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms737625%28v=vs.85%29.aspx - read about WSAEWOULDBLOCK return + errno = WSAGetLastError(); + printf("[Decker] errno.%d --> ", errno); + if ( errno != EINPROGRESS && errno != WSAEWOULDBLOCK ) // connect failed, do something... +#else + if ( errno != EINPROGRESS ) // connect failed, do something... +#endif + { + printf("close socket ...\n"); + closesocket(sock); + return(-1); + } + //printf("continue with select ...\n"); + FD_ZERO(&wfd); + FD_SET(sock,&wfd); + FD_ZERO(&efd); + FD_SET(sock,&efd); + tv.tv_sec = 10; + tv.tv_usec = 0; + res = select(sock+1,NULL,&wfd,&efd,&tv); + if ( res == -1 ) // select failed, do something... + { + closesocket(sock); + return(-1); + } + if ( res == 0 ) // connect timed out... + { + closesocket(sock); + return(-1); + } + if ( FD_ISSET(sock,&efd) ) + { + // connect failed, do something... + getsockopt(sock,SOL_SOCKET,SO_ERROR,&so_error,&len); + closesocket(sock); + return(-1); + } + } + set_blocking_mode(sock,1); + return(0); +} int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port) { @@ -124,25 +201,35 @@ int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port) #endif if ( bindflag == 0 ) { - //printf("call connect sock.%d\n",sock); - result = connect(sock,(struct sockaddr *)&saddr,addrlen); - //printf("called connect result.%d\n",result); - timeout.tv_sec = 2; - timeout.tv_usec = 0; - setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); - if ( result != 0 ) +//#ifdef _WIN32 + if ( 1 ) // connect using async to allow timeout, then switch to sync { - if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) + uint32_t starttime = (uint32_t)time(NULL); + //printf("call connect sock.%d\n",sock); + result = komodo_connect(sock,(struct sockaddr *)&saddr,addrlen); + //printf("called connect result.%d lag.%d\n",result,(int32_t)(time(NULL) - starttime)); + if ( result < 0 ) + return(-1); + timeout.tv_sec = 10; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + } +//#else + else + { + result = connect(sock,(struct sockaddr *)&saddr,addrlen); + if ( result != 0 ) { - //printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + 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); } - if ( sock >= 0 ) - closesocket(sock); - return(-1); } - timeout.tv_sec = 10; - timeout.tv_usec = 0; - setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); +//#endif } else { @@ -422,7 +509,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch { *retjsonp = 0; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); -//printf("%s %s",symbol,stratumreq); +//printf("timeout.%d exp.%d %s %s",timeout,(int32_t)(expiration-time(NULL)),symbol,stratumreq); memset(ep->buf,0,ep->bufsize); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); portable_mutex_lock(&ep->mutex); // this helps performance! @@ -1190,7 +1277,21 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) jaddnum(retjson,"restart",kickval); } } +#ifndef NOTETOMIC + if (strcmp(coin->symbol, "ETOMIC") == 0) { + cJSON *balance = cJSON_CreateObject(); + electrum_address_getbalance(coin->symbol, ep, &balance, coin->smartaddr); + int64_t confirmed = get_cJSON_int(balance, "confirmed"); + int64_t unconfirmed = get_cJSON_int(balance, "unconfirmed"); + if ((confirmed + unconfirmed) < 20 * SATOSHIDEN && get_etomic_from_faucet(coin->smartaddr) != 1) { + coin->inactive = (uint32_t)time(NULL); + coin->electrum = ep->prev; + cJSON_Delete(balance); + return(cJSON_Parse("{\"error\":\"Could not get ETOMIC from faucet!\"}")); + } + cJSON_Delete(balance); + } +#endif //printf("(%s)\n",jprint(retjson,0)); return(retjson); } - diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index 9268e2674..8127a6b0b 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -3645,7 +3645,7 @@ if ( LP_pricevalid(price) > 0 ) { LP_query(ctx,myipaddr,mypubsock,"connect",qp); //price = LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout); - LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-2*qp->txfee,qp->destcoin,qp->destsatoshis-2*qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); + LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-2*qp->txfee,qp->destcoin,qp->destsatoshis-2*qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector,qp->fill,qp->gtc); while ( time(NULL) < expiration ) { if ( aliceutxo->S.swap != 0 ) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index c28f06495..e5de198db 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -854,7 +854,17 @@ void LP_bobloop(void *_swap) expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; bobwaittimeout = LP_calc_waittimeout(bobstr); alicewaittimeout = LP_calc_waittimeout(alicestr); - if ( swap != 0 ) +#ifndef NOTETOMIC + if (swap->I.bobtomic[0] != 0 || swap->I.alicetomic[0] != 0) { + int error = 0; + uint64_t eth_balance = getEthBalance(swap->I.etomicsrc, &error); + if (eth_balance < 500000) { + err = -5000, printf("Bob ETH balance too low, aborting swap!\n"); + } + } +#endif + + if ( swap != 0 && err == 0) { if ( LP_waitsend("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) err = -2000, printf("error waitsend pubkeys\n"); @@ -866,7 +876,6 @@ void LP_bobloop(void *_swap) err = -2003, printf("error bobscripts deposit\n"); else { - uint8_t error = 0; swap->bobrefund.utxovout = 0; swap->bobrefund.utxotxid = swap->bobdeposit.I.signedtxid; basilisk_bobdeposit_refund(swap,swap->I.putduration); @@ -876,24 +885,32 @@ void LP_bobloop(void *_swap) LP_unavailableset(swap->bobdeposit.utxotxid,swap->bobdeposit.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash); if ( LP_waitfor(swap->N.pair,swap,bobwaittimeout,LP_verify_otherfee) < 0 ) { - error = 1; err = -2004, printf("error waiting for alicefee\n"); } - if ( error == 0 ) + if ( err == 0 ) { if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0) == 0 ) { - error = 1; err = -2005, printf("error sending bobdeposit\n"); } } - LP_unavailableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash); - if ( error == 0 && LP_waitfor(swap->N.pair,swap,alicewaittimeout,LP_verify_alicepayment) < 0 ) - { - error = 1; - err = -2006, printf("error waiting for alicepayment\n"); + if (err == 0) { + LP_unavailableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash); + m = swap->I.bobconfirms; + while ((n = LP_numconfirms(bobstr, swap->bobdeposit.I.destaddr, swap->bobdeposit.I.signedtxid, 0, 1)) < m) { + LP_swap_critical = (uint32_t) time(NULL); + LP_unavailableset(swap->bobpayment.utxotxid, swap->bobpayment.utxovout, (uint32_t) time(NULL) + 60, swap->I.otherhash); + char str[65]; + printf("%d wait for bobdeposit %s numconfs.%d %s %s\n", n, swap->bobdeposit.I.destaddr, m, bobstr, bits256_str(str, swap->bobdeposit.I.signedtxid)); + sleep(10); + } + + printf("wait for alicepayment\n"); + if (LP_waitfor(swap->N.pair, swap, bobwaittimeout + alicewaittimeout, LP_verify_alicepayment) < 0) { + err = -2006, printf("error waiting for alicepayment\n"); + } } - if (error == 0) + if (err == 0) { LP_swap_critical = (uint32_t)time(NULL); if ( basilisk_bobscripts_set(swap,0,1) < 0 ) @@ -901,6 +918,7 @@ void LP_bobloop(void *_swap) else { m = swap->I.aliceconfirms; + LP_unavailableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash); while ( (n= LP_numconfirms(alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) // sync with alice { LP_unavailableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash); @@ -927,7 +945,8 @@ void LP_bobloop(void *_swap) LP_swap_endcritical = (uint32_t)time(NULL); if ( err < 0 ) LP_failedmsg(swap->I.req.requestid,swap->I.req.quoteid,err,swap->uuidstr); - sleep(13); + if ( swap->I.aliceconfirms > 0 ) + sleep(13); LP_pendswap_add(swap->I.expiration,swap->I.req.requestid,swap->I.req.quoteid); //swap->I.finished = LP_swapwait(swap->I.expiration,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*3,swap->I.aliceconfirms == 0 ? 3 : 30); basilisk_swap_finished(swap); @@ -939,6 +958,7 @@ void LP_bobloop(void *_swap) void LP_aliceloop(void *_swap) { uint8_t *data; char bobstr[65],alicestr[65]; int32_t bobwaittimeout,alicewaittimeout,maxlen,n,m,err=0; uint32_t expiration; struct basilisk_swap *swap = _swap; + LP_alicequery_clear(); G.LP_pendingswaps++; LP_etomicsymbol(bobstr,swap->I.bobtomic,swap->I.bobstr); LP_etomicsymbol(alicestr,swap->I.alicetomic,swap->I.alicestr); @@ -947,7 +967,18 @@ void LP_aliceloop(void *_swap) expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; bobwaittimeout = LP_calc_waittimeout(bobstr); alicewaittimeout = LP_calc_waittimeout(alicestr); - if ( swap != 0 ) + +#ifndef NOTETOMIC + if (swap->I.bobtomic[0] != 0 || swap->I.alicetomic[0] != 0) { + int error = 0; + uint64_t eth_balance = getEthBalance(swap->I.etomicdest, &error); + if (eth_balance < 500000) { + err = -5001, printf("Alice ETH balance too low, aborting swap!\n"); + } + } +#endif + + if ( swap != 0 && err == 0) { printf("start swap iamalice pair.%d\n",swap->N.pair); if ( LP_sendwait("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) @@ -973,6 +1004,7 @@ void LP_aliceloop(void *_swap) while ( (n= LP_numconfirms(bobstr,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,1)) < m ) { LP_swap_critical = (uint32_t)time(NULL); + LP_unavailableset(swap->alicepayment.utxotxid,swap->alicepayment.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash); char str[65];printf("%d wait for bobdeposit %s numconfs.%d %s %s\n",n,swap->bobdeposit.I.destaddr,m,bobstr,bits256_str(str,swap->bobdeposit.I.signedtxid)); sleep(10); } @@ -999,6 +1031,7 @@ void LP_aliceloop(void *_swap) char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,bobstr,bits256_str(str,swap->bobpayment.I.signedtxid)); sleep(10); } + char str[65];printf("%d waited for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,bobstr,bits256_str(str,swap->bobpayment.I.signedtxid)); if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; } @@ -1009,7 +1042,8 @@ void LP_aliceloop(void *_swap) LP_swap_endcritical = (uint32_t)time(NULL); if ( err < 0 ) LP_failedmsg(swap->I.req.requestid,swap->I.req.quoteid,err,swap->uuidstr); - sleep(13); + if ( swap->I.bobconfirms > 0 ) + sleep(13); LP_pendswap_add(swap->I.expiration,swap->I.req.requestid,swap->I.req.quoteid); //swap->I.finished = LP_swapwait(swap->I.expiration,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*3,swap->I.aliceconfirms == 0 ? 3 : 30); basilisk_swap_finished(swap); @@ -1178,6 +1212,16 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 free(swap); return(0); } +#ifndef NOTETOMIC + if (strcmp(alicestr, "ETOMIC") == 0) { + swap->I.alicerealsat = swap->I.alicesatoshis; + swap->I.alicesatoshis = 100000000; + } + if (strcmp(bobstr, "ETOMIC") == 0) { + swap->I.bobrealsat = swap->I.bobsatoshis; + swap->I.bobsatoshis = 100000000; + } +#endif 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 ) @@ -1298,6 +1342,20 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 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; +#ifndef NOTETOMIC + if (strcmp(alicestr, "ETOMIC") == 0) { + swap->alicepayment.I.eth_amount = swap->I.alicerealsat; + if (swap->I.iambob == 1) { + swap->otherfee.I.eth_amount = LP_DEXFEE(swap->I.alicerealsat); + } else { + swap->myfee.I.eth_amount = LP_DEXFEE(swap->I.alicerealsat); + } + } + if (strcmp(bobstr, "ETOMIC") == 0) { + swap->bobpayment.I.eth_amount = swap->I.bobrealsat; + swap->bobdeposit.I.eth_amount = LP_DEPOSITSATOSHIS(swap->I.bobrealsat); + } +#endif LP_mark_spent(bobstr,qp->txid,qp->vout); LP_mark_spent(bobstr,qp->txid2,qp->vout2); LP_mark_spent(alicestr,qp->desttxid,qp->destvout); diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 3e14102ab..bf02fd44e 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -338,7 +338,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) { if ( remaining < 0.001 ) break; - if ( (retstr= LP_autobuy(ctx,0,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining/i,0,0,G.gui,0,destpubkey,tradeid,0)) != 0 ) + if ( (retstr= LP_autobuy(ctx,0,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining/i,0,0,G.gui,0,destpubkey,tradeid,0,0,0)) != 0 ) { if ( (retjson2= cJSON_Parse(retstr)) != 0 ) { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index e1d5a9ebb..a58b4ae4a 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1117,13 +1117,13 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ preselected[numpre++] = up; else { - printf("couldnt add address_utxo %s/v%d after not finding\n",bits256_str(str,utxotxid),utxovout); + //printf("couldnt add address_utxo %s/v%d after not finding\n",bits256_str(str,utxotxid),utxovout); sleep(1); value = LP_txvalue(0,coin->symbol,utxotxid,utxovout); LP_address_utxoadd(0,(uint32_t)time(NULL),"withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1); if ( (up= LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout)) != 0 ) preselected[numpre++] = up; - else printf("second couldnt add address_utxo after not finding\n"); + else printf("second couldnt add address_utxo %s/v%d after not finding\n",bits256_str(str,utxotxid),utxovout); //return(0); } } @@ -1831,6 +1831,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) locktime = juint(argjson,"locktime"); txfee = juint(argjson,"txfee"); autofee = (strcmp(coin->symbol,"BTC") == 0); + //printf("LP_withdraw: %s/v%d %s\n",bits256_str(str,utxotxid),utxovout,jprint(outputs,0)); if ( txfee == 0 ) { autofee = 1; @@ -1886,7 +1887,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) if ( autofee != 0 && iter == 0 && strcmp(coin->symbol,"BTC") == 0 ) { txfee = newtxfee = LP_txfeecalc(coin,0,datalen); - printf("txfee %.8f -> newtxfee %.8f, numvins.%d\n",dstr(txfee),dstr(newtxfee),numvins); + printf("txfee %.8f -> newtxfee %.8f, numvins.%d datalen.%d\n",dstr(txfee),dstr(newtxfee),numvins,datalen); for (i=0; ietomic[0] == 0 ) { if ( coin->electrum != 0 ) @@ -1961,17 +1962,21 @@ char *LP_autosplit(struct iguana_info *coin) //printf("balance %.8f, txfee %.8f, threshold %.8f\n",dstr(balance),dstr(txfee),dstr((1000000 - (txfee + 100000)))); if ( balance > txfee && balance >= (1000000 - (txfee + 100000)) ) { - halfval = (balance / 100) * 45; + // .95 / .02 / .02 / 0.005 + //halfval = (balance / 100) * 45; argjson = cJSON_CreateObject(); outputs = cJSON_CreateArray(); item = cJSON_CreateObject(); - jaddnum(item,coin->smartaddr,dstr(halfval)); + jaddnum(item,coin->smartaddr,dstr(balance/100) * 95); jaddi(outputs,item); item = cJSON_CreateObject(); - jaddnum(item,coin->smartaddr,dstr(halfval)); + jaddnum(item,coin->smartaddr,dstr(balance/50)); jaddi(outputs,item); item = cJSON_CreateObject(); - jaddnum(item,coin->smartaddr,dstr(balance - 2*halfval)); + jaddnum(item,coin->smartaddr,dstr(balance/50)); + jaddi(outputs,item); + item = cJSON_CreateObject(); + jaddnum(item,coin->smartaddr,0.0001); jaddi(outputs,item); jadd(argjson,"outputs",outputs); jaddnum(argjson,"broadcast",1); @@ -1985,6 +1990,43 @@ char *LP_autosplit(struct iguana_info *coin) return(clonestr("{\"error\":\"couldnt autosplit\"}")); } +char *LP_autofillbob(struct iguana_info *coin,uint64_t satoshis) +{ + char *retstr; cJSON *argjson,*withdrawjson,*outputs,*item; int64_t total,balance,txfee; + if ( coin->etomic[0] == 0 ) + { + if ( coin->electrum != 0 ) + balance = LP_unspents_load(coin->symbol,coin->smartaddr); + else balance = LP_RTsmartbalance(coin); + if ( strcmp("BTC",coin->symbol) == 0 ) + txfee = LP_txfeecalc(coin,0,1000); + balance -= (txfee + 1000000); + if ( balance < (satoshis<<2) ) + return(clonestr("{\"error\":\"couldnt autofill balance too small\"}")); + if ( balance > satoshis+3*txfee && balance >= (txfee + 1000000) ) + { + argjson = cJSON_CreateObject(); + outputs = cJSON_CreateArray(); + item = cJSON_CreateObject(); + jaddnum(item,coin->smartaddr,dstr(satoshis + 3000000)); + jaddi(outputs,item); + item = cJSON_CreateObject(); + jaddnum(item,coin->smartaddr,dstr(LP_DEPOSITSATOSHIS(satoshis) + 3000000)); + jaddi(outputs,item); + item = cJSON_CreateObject(); + jaddnum(item,coin->smartaddr,0.0001); + jaddi(outputs,item); + jadd(argjson,"outputs",outputs); + jaddnum(argjson,"broadcast",0); + jaddstr(argjson,"coin",coin->symbol); + retstr = LP_withdraw(coin,argjson); + free_json(argjson); + return(retstr); + } else return(clonestr("{\"error\":\"balance too small to autosplit, please make more deposits\"}")); + } + return(clonestr("{\"error\":\"couldnt autofill etomic needs separate support\"}")); +} + char *LP_movecoinbases(char *symbol) { static bits256 zero; bits256 utxotxid,txid; struct iguana_info *coin; cJSON *retjson,*outputs,*argjson,*txids,*unspents,*item,*gen,*output; int32_t i,n,utxovout; char *retstr,*hexstr; @@ -2045,31 +2087,112 @@ char *LP_movecoinbases(char *symbol) #ifndef NOTETOMIC +char *LP_eth_tx_fee(struct iguana_info *coin, char *dest_addr, char *amount, int64_t gas, int64_t gas_price) +{ + bits256 privkey; + cJSON *retjson = cJSON_CreateObject(); + int64_t actual_gas_price = 0, actual_gas = 0; + char privkey_str[70]; + + if (gas_price > 0) { + actual_gas_price = gas_price; + } else { + actual_gas_price = getGasPriceFromStation(0); + if (actual_gas_price == 0) { + return (clonestr("{\"error\":\"Couldn't get gas price from station!\"}")); + } + } + cJSON_AddNumberToObject(retjson, "gas_price", actual_gas_price); + + if (gas > 0) { + actual_gas = gas; + } else if (strcmp(coin->symbol, "ETH") == 0) { + actual_gas = 21000; + } else { + privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr); + uint8arrayToHex(privkey_str, privkey.bytes, 32); + actual_gas = estimate_erc20_gas(coin->etomic, dest_addr, amount, privkey_str, coin->decimals); + if (actual_gas == 0) { + return (clonestr("{\"error\":\"Couldn't estimate erc20 transfer gas usage!\"}")); + } + } + cJSON_AddNumberToObject(retjson, "gas", actual_gas); + + double_t eth_fee = (actual_gas_price * actual_gas) / 1000000000.0; + cJSON_AddNumberToObject(retjson, "eth_fee", eth_fee); + return(jprint(retjson,1)); +} + char *LP_eth_withdraw(struct iguana_info *coin,cJSON *argjson) { cJSON *retjson = cJSON_CreateObject(); + cJSON *gas_json = cJSON_GetObjectItem(argjson, "gas"); + cJSON *gas_price_json = cJSON_GetObjectItem(argjson, "gas_price"); char *dest_addr, *tx_id, privkey_str[70], amount_str[100]; - int64_t amount; + int64_t amount = 0, gas = 0, gas_price = 0, broadcast = 0; bits256 privkey; dest_addr = jstr(argjson, "to"); + if (dest_addr == NULL) { + return(clonestr("{\"error\":\"param 'to' is required!\"}")); + } + + if (isValidAddress(dest_addr) == 0) { + return(clonestr("{\"error\":\"'to' address is not valid!\"}")); + } + amount = jdouble(argjson, "amount") * 100000000; - privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr); - uint8arrayToHex(privkey_str, privkey.bytes, 32); + if (amount == 0) { + return(clonestr("{\"error\":\"'amount' is not set or equal to zero!\"}")); + } + if (gas_json != NULL && is_cJSON_Number(gas_json)) { + gas = gas_json->valueint; + if (gas < 21000) { + return (clonestr("{\"error\":\"'gas' can't be lower than 21000!\"}")); + } + } + if (gas_price_json != NULL && is_cJSON_Number(gas_price_json)) { + gas_price = gas_price_json->valueint; + if (gas_price < 1) { + return (clonestr("{\"error\":\"'gas_price' can't be lower than 1!\"}")); + } + } + + broadcast = jint(argjson, "broadcast"); satoshisToWei(amount_str, amount); - if (strcmp(coin->symbol, "ETH") == 0) { - tx_id = sendEth(dest_addr, amount_str, privkey_str, 0); + if (broadcast == 1) { + privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr); + uint8arrayToHex(privkey_str, privkey.bytes, 32); + if (strcmp(coin->symbol, "ETH") == 0) { + tx_id = sendEth(dest_addr, amount_str, privkey_str, 0, gas, gas_price, 0); + } else { + tx_id = sendErc20(coin->etomic, dest_addr, amount_str, privkey_str, 0, gas, gas_price, 0, coin->decimals); + } + if (tx_id != NULL) { + jaddstr(retjson, "tx_id", tx_id); + free(tx_id); + } else { + jaddstr(retjson, "error", "Error sending transaction"); + } + return (jprint(retjson, 1)); } else { - tx_id = sendErc20(coin->etomic, dest_addr, amount_str, privkey_str, 0); + return LP_eth_tx_fee(coin, dest_addr, amount_str, gas, gas_price); } - jaddstr(retjson, "tx_id", tx_id); - return(jprint(retjson,1)); } +char *LP_eth_gas_price() +{ + cJSON *retjson = cJSON_CreateObject(); + uint64_t gas_price = getGasPriceFromStation(0); + if (gas_price > 0) { + cJSON_AddNumberToObject(retjson, "gas_price", gas_price); + } else { + cJSON_AddStringToObject(retjson, "error", "Could not get gas price from station!"); + } + return(jprint(retjson,1)); +} #endif - - 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) { struct iguana_info *coin; int32_t len,retval=-1; char *retstr,*hexstr; cJSON *argjson,*outputs,*item,*retjson,*obj; @@ -2196,7 +2319,7 @@ int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vou { cJSON *retjson; coinaddr[0] = 0; - if ( (retjson= LP_gettx("LP_swap_getcoinaddr",symbol,txid,0)) != 0 ) + if ( (retjson= LP_gettx("LP_swap_getcoinaddr",symbol,txid,1)) != 0 ) { LP_txdestaddr(coinaddr,txid,vout,retjson); free_json(retjson); diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index eb4b37131..92f91e686 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -699,7 +699,8 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr //printf("address balance call LP_listunspent %s electrum.%p etomic.%d\n",coin->symbol,coin->electrum,coin->etomic[0]); #ifndef NOTETOMIC if (coin->etomic[0] != 0) { - balance = LP_etomic_get_balance(coin, coinaddr); + int error = 0; + balance = LP_etomic_get_balance(coin, coinaddr, &error); } else #endif if ( coin->electrum == 0 ) @@ -724,7 +725,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr } else { - if ( strcmp(coin->smartaddr,coinaddr) != 0 ) + //if ( strcmp(coin->smartaddr,coinaddr) != 0 ) { if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,coinaddr,2,zero,zero)) != 0 ) free_json(retjson); @@ -787,7 +788,14 @@ cJSON *LP_balances(char *coinaddr) } else { - if ( (balance= LP_RTsmartbalance(coin)) != 0 ) +#ifndef NOTETOMIC + if (coin->etomic[0] == 0 || coin->inactive == 0) { +#endif + balance = LP_RTsmartbalance(coin); +#ifndef NOTETOMIC + } +#endif + if ( balance != 0 ) { item = cJSON_CreateObject(); jaddstr(item,"coin",coin->symbol); @@ -898,7 +906,7 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS struct LP_transaction *tx; int32_t i,height,numvouts,numvins,spentvout; cJSON *vins,*vouts,*vout,*vin; bits256 spenttxid; char str[65]; if ( coin->inactive != 0 ) return(0); - if ( txobj != 0 || (txobj= LP_gettx("LP_transactioninit",coin->symbol,txid,0)) != 0 ) + if ( txobj != 0 || (txobj= LP_gettx("LP_transactioninit",coin->symbol,txid,1)) != 0 ) { if ( coin->electrum == 0 ) height = LP_txheight(coin,txid); @@ -964,7 +972,7 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid) return(height); if ( coin->electrum == 0 ) { - if ( (txobj= LP_gettx("LP_txheight",coin->symbol,txid,0)) != 0 ) + if ( (txobj= LP_gettx("LP_txheight",coin->symbol,txid,1)) != 0 ) { //*timestampp = juint(txobj,"locktime"); //*blocktimep = juint(txobj,"blocktime"); @@ -1067,7 +1075,7 @@ uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_inf { if ( (value= LP_value_extract(txobj,0,txid)) == 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); + // 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 ) { @@ -1185,7 +1193,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol return(-1); } destaddr[0] = destaddr2[0] = 0; - if ( coin != 0 && IAMLP != 0 && coin->inactive != 0 ) + if ( coin != 0 && (strcmp(coin->symbol, "ETOMIC") == 0 || (coin->inactive != 0 && IAMLP != 0))) bypass = 1; if ( bypass != 0 ) val = satoshis; @@ -1209,16 +1217,27 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol strcpy(destaddr,destaddr2); if ( coin != 0 ) { - if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 ) - return(0); + char txid_str[100], txid2_str[100]; + bits256_str(txid_str, txid); + bits256_str(txid2_str, txid2); + if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 ) { + printf("Could not find tx out: %s %d\n", txid_str, vout); + return (0); + } else free_json(txobj); - if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 ) - return(0); + if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 ) { + printf("Could not find tx out2: %s %d\n", txid_str, vout2); + return (0); + } else free_json(txobj); - if ( LP_numconfirms(coin->symbol,destaddr,txid,vout,0) <= 0 ) - return(0); - if ( LP_numconfirms(coin->symbol,destaddr,txid2,vout2,0) <= 0 ) - return(0); + if ( LP_numconfirms(coin->symbol,destaddr,txid,vout,0) <= 0 ) { + printf("Txid numconfirms is less or equal to zero: %s %d\n", txid_str, vout); + return (0); + } + if ( LP_numconfirms(coin->symbol,destaddr,txid2,vout2,0) <= 0 ) { + printf("Txid numconfirms is less or equal to zero: %s %d\n", txid2_str, vout2); + return (0); + } } return(1); } diff --git a/iguana/exchanges/auto_chipsbtc b/iguana/exchanges/auto_chipsbtc index 35b9319e4..40e61d94b 100755 --- a/iguana/exchanges/auto_chipsbtc +++ b/iguana/exchanges/auto_chipsbtc @@ -1,2 +1,2 @@ source userpass -curl --url "http://127.0.0.1:7783" --data "{\"minprice\":0.00006,\"maxprice\":0.0002,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"BTC\",\"margin\":0.05,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}" +curl --url "http://127.0.0.1:7783" --data "{\"minprice\":0.00002,\"maxprice\":0.0002,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"BTC\",\"margin\":0.05,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}" diff --git a/iguana/exchanges/auto_chipskmd b/iguana/exchanges/auto_chipskmd index 5a5794c86..fd2c7d6ca 100755 --- a/iguana/exchanges/auto_chipskmd +++ b/iguana/exchanges/auto_chipskmd @@ -1,2 +1,2 @@ source userpass -curl --url "http://127.0.0.1:7783" --data "{\"minprice\":0.15,\"maxprice\":0.4,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"KMD\",\"margin\":0.05,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}" +curl --url "http://127.0.0.1:7783" --data "{\"minprice\":0.05,\"maxprice\":0.4,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"KMD\",\"margin\":0.05,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}" diff --git a/iguana/exchanges/coins b/iguana/exchanges/coins index e7eb50e5c..c380a7756 100644 --- a/iguana/exchanges/coins +++ b/iguana/exchanges/coins @@ -1,2 +1,2 @@ -export coins="[{\"coin\":\"SANC\",\"name\":\"sancoj\",\"etomic\":\"0x03ec7bb59be036870ef696a2abf124f496d6735a\",\"rpcport\":80},{\"coin\":\"LRC\",\"name\":\"loopring\",\"etomic\":\"0xEF68e7C694F40c8202821eDF525dE3782458639f\",\"rpcport\":80,\"decimals\":18},{\"coin\":\"CMM\",\"name\":\"commercium\",\"rpcport\":9657,\"pubtype\":28,\"p2shtype\":50,\"wiftype\":140,\"txfee\":10000}, {\"coin\":\"IOST\",\"name\":\"iostoken\",\"etomic\":\"0xfa1a856cfa3409cfa145fa4e20eb270df3eb21ab\",\"rpcport\":80}, {\"coin\":\"WTC\",\"name\":\"waltonchain\",\"etomic\":\"0xb7cb1c96db6b22b0d3d9536e0108d062bd488f74\",\"rpcport\":80}, {\"coin\":\"XOV\",\"name\":\"xovbank\",\"etomic\":\"0x153eD9CC1b792979d2Bde0BBF45CC2A7e436a5F9\",\"rpcport\":80}, {\"coin\":\"FSN\",\"name\":\"fusion\",\"etomic\":\"0xd0352a019e9ab9d757776f532377aaebd36fd541\",\"rpcport\":80}, {\"coin\":\"AION\",\"name\":\"aion\",\"etomic\":\"0x4CEdA7906a5Ed2179785Cd3A40A69ee8bc99C466\",\"rpcport\":80}, {\"coin\":\"NAS\",\"name\":\"nebulas-token\",\"etomic\":\"0x5d65d971895edc438f465c17db6992698a52318d\",\"rpcport\":80}, {\"coin\":\"RHOC\",\"name\":\"rchain\",\"etomic\":\"0x168296bb09e24a88805cb9c33356536b980d3fc5\",\"rpcport\":80}, {\"coin\":\"BTM\",\"name\":\"bytom\",\"etomic\":\"0xcB97e65F07DA24D46BcDD078EBebd7C6E6E3d750\",\"rpcport\":80}, {\"coin\":\"AE\",\"name\":\"aeternity\",\"etomic\":\"0x5ca9a71b1d01849c0a95490cc00559717fcf0d1d\",\"rpcport\":80}, {\"coin\":\"ZIL\",\"name\":\"zilliqa\",\"etomic\":\"0x05f4a42e251f2d52b8ed15e9fedaacfcef1fad27\",\"rpcport\":80}, {\"coin\":\"FLLW\",\"name\":\"followcoin\",\"etomic\":\"0x0200412995f1bafef0d3f97c4e28ac2515ec1ece\",\"rpcport\":80}, {\"coin\":\"HYD\",\"name\":\"hydra\",\"etomic\":\"0xD233495C48EB0143661fFC8458EAfc21b633f97f\",\"rpcport\":80}, {\"coin\":\"VRSC\",\"asset\":\"VRSC\",\"rpcport\":27486}, {\"coin\":\"CHAIN\",\"asset\":\"CHAIN\",\"rpcport\":15587},{\"coin\":\"POWR\",\"name\":\"power-ledger\",\"etomic\":\"0x595832f8fc6bf59c85c527fec3740a1b7a361269\",\"rpcport\":80},{\"coin\":\"TUSD\",\"name\":\"trueusd\",\"etomic\":\"0x8dd5fbce2f6a956c3022ba3663759011dd51e73e\",\"rpcport\":80}, {\"coin\":\"VEN\",\"name\":\"vechain\",\"etomic\":\"0xd850942ef8811f2a866692a623011bde52a462c1\",\"rpcport\":80}, {\"coin\":\"DSEC\",\"asset\":\"DSEC\",\"rpcport\":11557},{\"coin\":\"LOOM\",\"name\":\"loom-network\",\"etomic\":\"0xa4e8c3ec456107ea67d3075bf9e3df3a75823db0\",\"rpcport\":80}, {\"coin\":\"ANN\",\"name\":\"agentnotneeded\",\"etomic\":\"0xe0e73E8fc3a0fA161695be1D75E1Bc3E558957c4\",\"rpcport\":80},{\"coin\": \"DSEC\",\"asset\": \"DSEC\",\"rpcport\": 11557},{\"coin\":\"PRL\",\"name\":\"oyster\",\"etomic\":\"0x1844b21593262668b7248d0f57a220caaba46ab9\",\"rpcport\":80}, {\"coin\":\"MGO\",\"name\":\"mobilego\",\"etomic\":\"0x40395044Ac3c0C57051906dA938B54BD6557F212\",\"rpcport\":80},{\"coin\":\"DRGN\",\"name\":\"dragonchain\",\"etomic\":\"0x419c4db4b9e25d6db2ad9691ccb832c8d9fda05e\",\"rpcport\":80}, {\"coin\":\"GLD\",\"name\":\"goldcoin\",\"rpcport\":9332,\"pubtype\":32,\"p2shtype\":5,\"wiftype\":160,\"txfee\":100000}, {\"coin\":\"BTK\",\"name\":\"bitcointoken\",\"etomic\":\"0xdb8646F5b487B5Dd979FAC618350e85018F557d4\",\"rpcport\":80},{\"coin\":\"DGPT\",\"name\":\"digipulse\",\"etomic\":\"0xf6cFe53d6FEbaEEA051f400ff5fc14F0cBBDacA1\",\"rpcport\":80}, {\"coin\":\"OCT\",\"name\":\"octus\",\"etomic\":\"0x7e9d365C0C97Fe5FcAdcc1B513Af974b768C5867\",\"rpcport\":80},{\"coin\":\"STWY\",\"name\":\"storweeytoken\",\"etomic\":\"0x8a8c71f032362fca2994f75d854f911ec381ac5a\",\"rpcport\":80}, {\"coin\":\"SPK\",\"name\":\"Sparks\",\"rpcport\":8892,\"pubtype\":38,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\":\"PCL\",\"name\":\"peculium\",\"etomic\":\"0x3618516f45cd3c913f81f9987af41077932bc40d\",\"rpcport\":80}, {\"coin\":\"RLTY\",\"name\":\"smartrealty\",\"etomic\":\"0xbe99b09709fc753b09bcf557a992f6605d5997b0\",\"rpcport\":80},{\"coin\":\"CIX\",\"name\":\"cryptonetix\",\"etomic\":\"0x1175a66a5c3343Bbf06AA818BB482DdEc30858E0\",\"rpcport\":80}, {\"coin\":\"GLXT\",\"asset\":\"GLXT\",\"rpcport\":15723}, {\"coin\":\"PYRO\",\"name\":\"pyro\",\"confpath\":\"${HOME#}/.pyrocore/pyro.conf\",\"rpcport\":9696,\"pubtype\":55,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\": \"BNTN\",\"asset\": \"BNTN\",\"rpcport\": 14358},{\"coin\":\"ORE\",\"name\":\"galactrum\",\"rpcport\":6269,\"pubtype\":38,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"ELD\",\"name\":\"maker\",\"etomic\":\"0xaaf7d4cd097317d68174215395eb02c2cca81e31\",\"rpcport\":80}, {\"coin\":\"CENNZ\",\"name\":\"centrality\",\"etomic\":\"0x1122b6a0e00dce0563082b6e2953f3a943855c1f\",\"rpcport\":80}, {\"coin\":\"PGN\",\"name\":\"pigeon\",\"rpcport\":8756,\"pubtype\":55,\"p2shtype\":122,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"XCG\",\"name\":\"Xchange\",\"confpath\":\"${HOME#}/.Xchangecore/Xchange.conf\",\"rpcport\":9386,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"AXE\",\"name\":\"axe\",\"confpath\":\"${HOME#}/.axecore/axe.conf\",\"rpcport\":9337,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"PEW\",\"name\":\"brofist\",\"rpcport\":12454,\"pubtype\":55,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000,\"confpath\":\"${HOME#}/.brofistcore/brofist.conf\"}, {\"coin\":\"BCBC\",\"name\":\"bitcoin@cbc\",\"confpath\":\"${HOME#}/.bitcoin@cbc/bitcoin.conf\",\"rpcport\":8340,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"GRLC\",\"name\":\"garlicoin\",\"rpcport\":42068,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"EQL\",\"asset\":\"EQL\",\"rpcport\":10306}, {\"coin\":\"OCC\",\"name\":\"originalcryptocoin\",\"etomic\":\"0x0235fe624e044a05eed7a43e16e3083bc8a4287a\",\"rpcport\":80}, {\"coin\":\"DIN\",\"name\":\"dinero\",\"rpcport\":9998,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":204,\"txfee\":10000,\"confpath\":\"${HOME#}/.dinerocore/dinero.conf\"}, {\"coin\":\"BUCK\",\"name\":\"buck\",\"rpcport\":5739,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"LYS\",\"name\":\"lightyears\",\"etomic\":\"0xdd41fbd1ae95c5d9b198174a28e04be6b3d1aa27\",\"rpcport\":80}, {\"coin\":\"RAP\",\"name\":\"rapture\",\"rpcport\":14776,\"pubtype\":60,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000,\"confpath\":\"${HOME#}/.rapturecore/rapture.conf\"}, {\"coin\":\"RADIUS\",\"name\":\"radius\",\"rpcport\":4089,\"pubtype\":60,\"p2shtype\":16,\"wiftype\":15,\"txfee\":10000,\"confpath\":\"${HOME#}/.radiuscore/radius.conf\"},{\"coin\":\"BTCL\",\"name\":\"btclite\",\"etomic\":\"0x5acd19b9c91e596b1f062f18e3d02da7ed8d1e50\",\"rpcport\":80}, {\"coin\":\"SEQ\",\"name\":\"sequence\",\"rpcport\":16663,\"isPoS\":1,\"pubtype\":63,\"p2shtype\":64,\"wiftype\":170,\"txfee\":10000}, {\"coin\":\"DYN\",\"name\":\"dynamic\",\"rpcport\":33350,\"pubtype\":30,\"p2shtype\":10,\"wiftype\":140,\"txfee\":10000}, {\"coin\":\"SBTC\",\"name\":\"SuperBitcoin\",\"rpcport\":28282,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000,\"confpath\":\"${HOME#}/.sbtc/sbtc.conf\"}, {\"coin\":\"FJC\",\"name\":\"fujicoin\",\"rpcport\":3776,\"pubtype\":36,\"p2shtype\":16,\"wiftype\":164,\"txfee\":100000}, {\"coin\":\"AIR\",\"name\":\"airtoken\",\"etomic\":\"0x27dce1ec4d3f72c3e457cc50354f1f975ddef488\",\"rpcport\":80}, {\"coin\":\"VRT\",\"name\":\"virtus\",\"confpath\":\"${HOME#}/.virtuscore/virtus.conf\",\"rpcport\":13880,\"pubtype\":70,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"DRT\",\"name\":\"domraider\",\"etomic\":\"0x9af4f26941677c706cfecf6d3379ff01bb85d5ab\",\"rpcport\":80}, {\"coin\":\"BITS\",\"name\":\"bitstar\",\"rpcport\":15715,\"isPoS\":1,\"pubtype\":25,\"p2shtype\":8,\"wiftype\":153,\"txfee\":10000}, {\"coin\":\"FTC\",\"name\":\"feathercoin\",\"rpcport\":9337,\"pubtype\":14,\"p2shtype\":5,\"wiftype\":142,\"txfee\":1000000}, {\"coin\":\"PXT\",\"name\":\"populous-xbrl-token\",\"etomic\":\"0xc14830e53aa344e8c14603a91229a0b925b0b262\",\"rpcport\":80}, {\"coin\":\"USDT\",\"name\":\"tether\",\"etomic\":\"0xdac17f958d2ee523a2206206994597c13d831ec7\",\"rpcport\":80}, {\"coin\":\"ELI\",\"name\":\"elicoin\",\"rpcport\":9332,\"pubtype\":33,\"p2shtype\":102,\"wiftype\":205,\"txfee\":10000}, {\"coin\":\"SCRIV\",\"name\":\"scriv\",\"confpath\":\"${HOME#}/.scrivcore/scriv.conf\",\"rpcport\":7998,\"pubtype\":125,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"ELP\",\"name\":\"ellerium\",\"rpcport\":61020,\"pubtype\":23,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"ROI\",\"name\":\"ROIcoin\",\"rpcport\":3376,\"pubtype\":60,\"p2shtype\":122,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"XCOIN\",\"name\":\"xcoin\",\"rpcport\":22717,\"pubtype\":137,\"p2shtype\":15,\"wiftype\":75,\"txfee\":100000}, {\"coin\":\"BBT\",\"name\":\"bitboost\",\"etomic\":\"0x1500205f50bf3fd976466d0662905c9ff254fc9c\",\"rpcport\":80}, {\"coin\":\"TRX\",\"name\":\"tron\",\"etomic\":\"0xf230b790e05390fc8295f4d3f60332c93bed42e2\",\"rpcport\":80}, {\"coin\":\"OMG\",\"name\":\"omisego\",\"etomic\":\"0xd26114cd6EE289AccF82350c8d8487fedB8A0C07\",\"rpcport\":80}, {\"coin\":\"ICX\",\"name\":\"icon\",\"etomic\":\"0xb5a5f22694352c15b00323844ad545abb2b11028\",\"rpcport\":80,\"decimals\":18}, {\"coin\":\"BNB\",\"name\":\"binance-coin\",\"etomic\":\"0xB8c77482e45F1F44dE1745F52C74426C631bDD52\",\"rpcport\":80}, {\"coin\":\"DGD\",\"name\":\"digixdao\",\"etomic\":\"0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A\",\"rpcport\":80,\"decimals\":9}, {\"coin\":\"PPT\",\"name\":\"populous\",\"etomic\":\"0xd4fa1460F537bb9085d22C7bcCB5DD450Ef28e3a\",\"rpcport\":80}, {\"coin\":\"MKR\",\"name\":\"maker\",\"etomic\":\"0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2\",\"rpcport\":80}, {\"coin\":\"SNT\",\"name\":\"status\",\"etomic\":\"0x744d70FDBE2Ba4CF95131626614a1763DF805B9E\",\"rpcport\":80}, {\"coin\":\"REP\",\"name\":\"augur\",\"etomic\":\"0xE94327D07Fc17907b4DB788E5aDf2ed424adDff6\",\"rpcport\":80}, {\"coin\":\"ZRX\",\"name\":\"0x\",\"etomic\":\"0xE41d2489571d322189246DaFA5ebDe1F4699F498\",\"rpcport\":80}, {\"coin\":\"BAT\",\"name\":\"basic-attention-token\",\"etomic\":\"0x0D8775F648430679A709E98d2b0Cb6250d2887EF\",\"rpcport\":80}, {\"coin\":\"ETHOS\",\"name\":\"ethos\",\"etomic\":\"0x5Af2Be193a6ABCa9c8817001F45744777Db30756\",\"rpcport\":80}, {\"coin\":\"QASH\",\"name\":\"qash\",\"etomic\":\"0x618E75Ac90b12c6049Ba3b27f5d5F8651b0037F6\",\"rpcport\":80}, {\"coin\":\"FUN\",\"name\":\"funfair\",\"etomic\":\"0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b\",\"rpcport\":80}, {\"coin\":\"KNC\",\"name\":\"kyber-network\",\"etomic\":\"0xdd974D5C2e2928deA5F71b9825b8b646686BD200\",\"rpcport\":80}, {\"coin\":\"SALT\",\"name\":\"salt\",\"etomic\":\"0x4156D3342D5c385a87D264F90653733592000581\",\"rpcport\":80}, {\"coin\":\"BNT\",\"name\":\"bancor\",\"etomic\":\"0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C\",\"rpcport\":80}, {\"coin\":\"ICN\",\"name\":\"iconomi\",\"etomic\":\"0x888666CA69E0f178DED6D75b5726Cee99A87D698\",\"rpcport\":80}, {\"coin\":\"PAY\",\"name\":\"tenx\",\"etomic\":\"0xB97048628DB6B661D4C2aA833e95Dbe1A905B280\",\"rpcport\":80}, {\"coin\":\"REQ\",\"name\":\"request-network\",\"etomic\":\"0x8f8221aFbB33998d8584A2B05749bA73c37a938a\",\"rpcport\":80}, {\"coin\":\"STORJ\",\"name\":\"storj\",\"etomic\":\"0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC\",\"rpcport\":80}, {\"coin\":\"GNO\",\"name\":\"gnosis-gno\",\"etomic\":\"0x6810e776880C02933D47DB1b9fc05908e5386b96\",\"rpcport\":80}, {\"coin\":\"RLC\",\"name\":\"rlc\",\"etomic\":\"0x607F4C5BB672230e8672085532f7e901544a7375\",\"rpcport\":80}, {\"coin\":\"ENJ\",\"name\":\"enjin-coin\",\"etomic\":\"0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c\",\"rpcport\":80}, {\"coin\":\"QSP\",\"name\":\"quantstamp\",\"etomic\":\"0x99ea4dB9EE77ACD40B119BD1dC4E33e1C070b80d\",\"rpcport\":80}, {\"coin\":\"RDN\",\"name\":\"raiden-network-token\",\"etomic\":\"0x255Aa6DF07540Cb5d3d297f0D0D4D84cb52bc8e6\",\"rpcport\":80}, {\"coin\":\"CVC\",\"name\":\"civic\",\"etomic\":\"0x41e5560054824eA6B0732E656E3Ad64E20e94E45\",\"rpcport\":80}, {\"coin\":\"SAN\",\"name\":\"santiment\",\"etomic\":\"0x7C5A0CE9267ED19B22F8cae653F198e3E8daf098\",\"rpcport\":80}, {\"coin\":\"ANT\",\"name\":\"aragon\",\"etomic\":\"0x960b236A07cf122663c4303350609A66A7B288C0\",\"rpcport\":80}, {\"coin\":\"MANA\",\"name\":\"decentraland\",\"etomic\":\"0x0F5D2fB29fb7d3CFeE444a200298f468908cC942\",\"rpcport\":80}, {\"coin\":\"MCO\",\"name\":\"monaco\",\"etomic\":\"0xB63B606Ac810a52cCa15e44bB630fd42D8d1d83d\",\"rpcport\":80}, {\"coin\":\"MTL\",\"name\":\"metal\",\"etomic\":\"0xF433089366899D83a9f26A773D59ec7eCF30355e\",\"rpcport\":80}, {\"coin\":\"EDG\",\"name\":\"edgeless\",\"etomic\":\"0x08711D3B02C8758F2FB3ab4e80228418a7F8e39c\",\"rpcport\":80}, {\"coin\":\"MLN\",\"name\":\"melon\",\"etomic\":\"0xBEB9eF514a379B997e0798FDcC901Ee474B6D9A1\",\"rpcport\":80}, {\"coin\":\"AMB\",\"name\":\"amber\",\"etomic\":\"0x4DC3643DbC642b72C158E7F3d2ff232df61cb6CE\",\"rpcport\":80}, {\"coin\":\"WINGS\",\"name\":\"wings\",\"etomic\":\"0x667088b212ce3d06a1b553a7221E1fD19000d9aF\",\"rpcport\":80}, {\"coin\":\"RCN\",\"name\":\"ripio-credit-network\",\"etomic\":\"0xF970b8E36e23F7fC3FD752EeA86f8Be8D83375A6\",\"rpcport\":80}, {\"coin\":\"SNGLS\",\"name\":\"singulardtv\",\"etomic\":\"0xaeC2E87E0A235266D9C5ADc9DEb4b2E29b54D009\",\"rpcport\":80}, {\"coin\":\"TAAS\",\"name\":\"taas\",\"etomic\":\"0xE7775A6e9Bcf904eb39DA2b68c5efb4F9360e08C\",\"rpcport\":80}, {\"coin\":\"DNT\",\"name\":\"district0x\",\"etomic\":\"0x0AbdAce70D3790235af448C88547603b945604ea\",\"rpcport\":80}, {\"coin\":\"CFI\",\"name\":\"cofound-it\",\"etomic\":\"0x12FEF5e57bF45873Cd9B62E9DBd7BFb99e32D73e\",\"rpcport\":80}, {\"coin\":\"LUN\",\"name\":\"lunyr\",\"etomic\":\"0xfa05A73FfE78ef8f1a739473e462c54bae6567D9\",\"rpcport\":80}, {\"coin\":\"ADT\",\"name\":\"adtoken\",\"etomic\":\"0xD0D6D6C5Fe4a677D343cC433536BB717bAe167dD\",\"rpcport\":80}, {\"coin\":\"AST\",\"name\":\"airswap\",\"etomic\":\"0x27054b13b1B798B345b591a4d22e6562d47eA75a\",\"rpcport\":80}, {\"coin\":\"CDT\",\"name\":\"blox\",\"etomic\":\"0x177d39AC676ED1C67A2b268AD7F1E58826E5B0af\",\"rpcport\":80}, {\"coin\":\"TKN\",\"name\":\"tokencard\",\"etomic\":\"0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a\",\"rpcport\":80}, {\"coin\":\"HMQ\",\"name\":\"humaniq\",\"etomic\":\"0xcbCC0F036ED4788F63FC0fEE32873d6A7487b908\",\"rpcport\":80}, {\"coin\":\"BCAP\",\"name\":\"bcap\",\"etomic\":\"0xFf3519eeeEA3e76F1F699CCcE5E23ee0bdDa41aC\",\"rpcport\":80}, {\"coin\":\"NMR\",\"name\":\"numeraire\",\"etomic\":\"0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671\",\"rpcport\":80}, {\"coin\":\"NET\",\"name\":\"nimiq\",\"etomic\":\"0xcfb98637bcae43C13323EAa1731cED2B716962fD\",\"rpcport\":80}, {\"coin\":\"TRST\",\"name\":\"trust\",\"etomic\":\"0xCb94be6f13A1182E4A4B6140cb7bf2025d28e41B\",\"rpcport\":80}, {\"coin\":\"GUP\",\"name\":\"guppy\",\"etomic\":\"0xf7B098298f7C69Fc14610bf71d5e02c60792894C\",\"rpcport\":80}, {\"coin\":\"1ST\",\"name\":\"firstblood\",\"etomic\":\"0xAf30D2a7E90d7DC361c8C4585e9BB7D2F6f15bc7\",\"rpcport\":80}, {\"coin\":\"TIME\",\"name\":\"chronobank\",\"etomic\":\"0x6531f133e6DeeBe7F2dcE5A0441aA7ef330B4e53\",\"rpcport\":80}, {\"coin\":\"SWT\",\"name\":\"swarm-city\",\"etomic\":\"0xB9e7F8568e08d5659f5D29C4997173d84CdF2607\",\"rpcport\":80}, {\"coin\":\"ROL\",\"name\":\"dice\",\"etomic\":\"0x2e071D2966Aa7D8dECB1005885bA1977D6038A65\",\"rpcport\":80}, {\"coin\":\"XAUR\",\"name\":\"xaurum\",\"etomic\":\"0x4DF812F6064def1e5e029f1ca858777CC98D2D81\",\"rpcport\":80}, {\"coin\":\"PLU\",\"name\":\"pluton\",\"etomic\":\"0xD8912C10681D8B21Fd3742244f44658dBA12264E\",\"rpcport\":80}, {\"coin\":\"HGT\",\"name\":\"hellogold\",\"etomic\":\"0xba2184520A1cC49a6159c57e61E1844E085615B6\",\"rpcport\":80}, {\"coin\":\"VSL\",\"name\":\"vslice\",\"etomic\":\"0x5c543e7AE0A1104f78406C340E9C64FD9fCE5170\",\"rpcport\":80}, {\"coin\":\"IND\",\"name\":\"indorse-token\",\"etomic\":\"0xf8e386EDa857484f5a12e4B5DAa9984E06E73705\",\"rpcport\":80}, {\"coin\":\"FYN\",\"name\":\"fundyourselfnow\",\"etomic\":\"0x88FCFBc22C6d3dBaa25aF478C578978339BDe77a\",\"rpcport\":80},{\"coin\":\"SMART\",\"name\":\"smartcash\",\"rpcport\":9679,\"pubtype\":63,\"p2shtype\":18,\"wiftype\":191,\"txfee\":200000}, {\"coin\":\"BTCP\",\"name\":\"btcprivate\",\"rpcport\":7932,\"taddr\":19,\"pubtype\":37,\"p2shtype\":175,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"DNR\",\"isPoS\":1,\"active\":1,\"name\":\"denarius\",\"rpcport\":32339,\"pubtype\":30,\"p2shtype\":90,\"wiftype\":158,\"txfee\":10000}, {\"coin\":\"RVN\",\"name\":\"raven\",\"rpcport\":8766,\"pubtype\":60,\"p2shtype\":122,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"VIVO\",\"name\":\"vivo\",\"confpath\":\"${HOME#}/.vivocore/vivo.conf\",\"rpcport\":9998,\"pubtype\":70,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\":\"KNG\",\"name\":\"kings\",\"rpcport\":44888,\"pubtype\":75,\"p2shtype\":125,\"wiftype\":203,\"txfee\":10000}, {\"coin\":\"UFO\",\"name\":\"ufocoin\",\"confpath\":\"${HOME#}/.ufo/ufocoin.conf\",\"rpcport\":9888,\"pubtype\":27,\"p2shtype\":5,\"wiftype\":155,\"txfee\":100000}, {\"coin\":\"ETH\",\"name\":\"ethereum\",\"etomic\":\"0x0000000000000000000000000000000000000000\",\"rpcport\":80}, {\"coin\":\"EOS\",\"name\":\"EOS\",\"etomic\":\"0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0\",\"rpcport\":80}, {\"coin\":\"KREDS\",\"name\":\"kreds\",\"rpcport\":3850,\"pubtype\":45,\"p2shtype\":5,\"wiftype\":195,\"txfee\":10000}, {\"coin\":\"SNG\",\"name\":\"snowgem\",\"rpcport\":16112,\"taddr\":28,\"pubtype\":40,\"p2shtype\":45,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"ZEL\",\"name\":\"zelcash\",\"rpcport\":16124,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"HTML\",\"name\":\"htmlcoin\",\"rpcport\":4889,\"pubtype\":41,\"p2shtype\":100,\"wiftype\":169,\"txfee\":400000}, {\"coin\":\"MNX\",\"name\":\"Minexcoin\",\"rpcport\":17786,\"pubtype\":75,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"LTZ\",\"name\":\"litecoinz\",\"rpcport\":29332,\"taddr\":10,\"pubtype\":179,\"p2shtype\":184,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"BAY\",\"name\":\"bitbay\",\"isPoS\":1,\"rpcport\":19915,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":10000}, {\"coin\":\"OOT\",\"asset\":\"OOT\",\"rpcport\":12467}, {\"coin\":\"ZOI\",\"name\":\"zoin\",\"rpcport\":8255,\"pubtype\":80,\"p2shtype\":7,\"wiftype\":208,\"txfee\":1000}, {\"coin\": \"PIZZA\",\"asset\": \"PIZZA\",\"rpcport\": 11116},{\"coin\": \"BEER\",\"asset\": \"BEER\",\"rpcport\": 8923}, {\"coin\":\"GRS\",\"name\":\"groestlcoin\",\"rpcport\":1441,\"pubtype\":36,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"XMCC\",\"name\":\"monoeci\",\"confpath\":\"${HOME#}/.monoeciCore/monoeci.conf\",\"rpcport\":24156,\"pubtype\":50,\"p2shtype\":73,\"wiftype\":77,\"txfee\":10000}, {\"coin\":\"BTCH\",\"asset\":\"BTCH\",\"rpcport\":8800},{\"coin\":\"ETOMIC\",\"asset\":\"ETOMIC\",\"rpcport\":10271},{\"coin\":\"AXO\",\"asset\":\"AXO\",\"rpcport\":12927},{\"coin\":\"CRC\",\"name\":\"crowdcoin\",\"confpath\":\"${HOME#}/.crowdcoincore/crowdcoin.conf\",\"rpcport\":11998,\"pubtype\":28,\"p2shtype\":88,\"wiftype\":0,\"txfee\":10000}, {\"coin\":\"VOT\",\"name\":\"votecoin\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"INN\",\"name\":\"innova\",\"confpath\":\"${HOME#}/.innovacore/innova.conf\",\"rpcport\":8818,\"pubtype\":102,\"p2shtype\":20,\"wiftype\":195,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":28,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"EFL\",\"name\":\"egulden\",\"confpath\":\"${HOME#}/.egulden/coin.conf\",\"rpcport\":21015,\"pubtype\":48,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"GBX\",\"name\":\"gobyte\",\"confpath\":\"${HOME#}/.gobytecore/gobyte.conf\",\"rpcport\":12454,\"pubtype\":38,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\":\"BCO\",\"name\":\"bridgecoin\",\"rpcport\":6332,\"pubtype\":27,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BLK\",\"name\":\"blackcoin\",\"confpath\":\"${HOME#}/.lore/blackcoin.conf\",\"isPoS\":1,\"rpcport\":15715,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":100000}, {\"coin\":\"BTG\",\"name\":\"bitcoingold\",\"rpcport\":8332,\"pubtype\":38,\"p2shtype\":23,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BCH\",\"name\":\"bch\",\"rpcport\":33333,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"ABY\",\"name\":\"applebyte\",\"rpcport\":8607,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":100000}, {\"coin\":\"STAK\",\"name\":\"straks\",\"rpcport\":7574,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"XZC\",\"name\":\"zcoin\",\"rpcport\":8888,\"pubtype\":82,\"p2shtype\":7,\"wiftype\":210,\"txfee\":10000}, {\"coin\":\"QTUM\",\"name\":\"qtum\",\"rpcport\":3889,\"pubtype\":58,\"p2shtype\":50,\"wiftype\":128,\"txfee\":400000}, {\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"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\":2000000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"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\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"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\":\"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\":10000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"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\":100000}, {\"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\":10000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":10000}, {\"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\":\"MSHARK\",\"asset\":\"MSHARK\",\"rpcport\":8846}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]" -#, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}]" +export coins="[{\"coin\":\"SEC\",\"asset\":\"SEC\",\"rpcport\":11540},{\"coin\":\"PAT\",\"name\":\"pat\",\"etomic\":\"0xBB1fA4FdEB3459733bF67EbC6f893003fA976a82\",\"rpcport\":80},{\"coin\":\"PRLPAY\",\"asset\":\"PRLPAY\",\"rpcport\":9679}, {\"coin\":\"MLM\",\"name\":\"mktcoin\",\"rpcport\":9276,\"pubtype\":110,\"p2shtype\":115,\"wiftype\":238,\"txfee\":10000}, {\"coin\":\"CRDS\",\"name\":\"credits\",\"rpcport\":31050,\"pubtype\":28,\"p2shtype\":10,\"wiftype\":140,\"txfee\":10000}, {\"coin\":\"UCASH\",\"name\":\"ucash\",\"etomic\":\"0x92e52a1a235d9a103d970901066ce910aacefd37\",\"rpcport\":80}, {\"coin\":\"RVT\",\"name\":\"rivetz\",\"etomic\":\"0x3d1ba9be9f66b8ee101911bc36d3fb562eac2244\",\"rpcport\":80}, {\"coin\":\"DCN\",\"name\":\"dentacoin\",\"etomic\":\"0x08d32b0da63e2C3bcF8019c9c5d849d7a9d791e6\",\"rpcport\":80}, {\"coin\":\"ATB\",\"name\":\"atbcoin\",\"confpath\":\"${HOME#}/.ATBCoinWallet/atbcoin.conf\",\"rpcport\":8332,\"pubtype\":23,\"p2shtype\":83,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"SRN\",\"name\":\"sirin-labs-token\",\"etomic\":\"0x68d57c9a1c35f63e2c83ee8e49a64e9d70528d25\",\"rpcport\":80},{\"coin\":\"ELF\",\"name\":\"aelf\",\"etomic\":\"0xbf2179859fc6D5BEE9Bf9158632Dc51678a4100e\",\"rpcport\":80}, {\"coin\":\"HXX\",\"name\":\"hexxcoin\",\"rpcport\":29200,\"pubtype\":40,\"p2shtype\":10,\"wiftype\":210,\"txfee\":100000}, {\"coin\":\"XSN\",\"name\":\"xsn\",\"confpath\":\"${HOME#}/.xsncore/xsn.conf\",\"rpcport\":51473,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"DROP\",\"name\":\"dropil\",\"etomic\":\"0x4672bad527107471cb5067a887f4656d585a8a31\",\"rpcport\":80}, {\"coin\":\"GPN\",\"name\":\"gpncoin\",\"etomic\":\"0xE2b407160AAd5540eAc0e80338b9a5085C60F25B\",\"rpcport\":80}, {\"coin\":\"SANC\",\"name\":\"sancoj\",\"etomic\":\"0x03ec7bb59be036870ef696a2abf124f496d6735a\",\"rpcport\":80},{\"coin\":\"LRC\",\"name\":\"loopring\",\"etomic\":\"0xEF68e7C694F40c8202821eDF525dE3782458639f\",\"rpcport\":80,\"decimals\":18}, {\"coin\":\"IOST\",\"name\":\"iostoken\",\"etomic\":\"0xfa1a856cfa3409cfa145fa4e20eb270df3eb21ab\",\"rpcport\":80}, {\"coin\":\"WTC\",\"name\":\"waltonchain\",\"etomic\":\"0xb7cb1c96db6b22b0d3d9536e0108d062bd488f74\",\"rpcport\":80}, {\"coin\":\"XOV\",\"name\":\"xovbank\",\"etomic\":\"0x153eD9CC1b792979d2Bde0BBF45CC2A7e436a5F9\",\"rpcport\":80}, {\"coin\":\"FSN\",\"name\":\"fusion\",\"etomic\":\"0xd0352a019e9ab9d757776f532377aaebd36fd541\",\"rpcport\":80}, {\"coin\":\"AION\",\"name\":\"aion\",\"etomic\":\"0x4CEdA7906a5Ed2179785Cd3A40A69ee8bc99C466\",\"rpcport\":80}, {\"coin\":\"NAS\",\"name\":\"nebulas-token\",\"etomic\":\"0x5d65d971895edc438f465c17db6992698a52318d\",\"rpcport\":80}, {\"coin\":\"RHOC\",\"name\":\"rchain\",\"etomic\":\"0x168296bb09e24a88805cb9c33356536b980d3fc5\",\"rpcport\":80}, {\"coin\":\"BTM\",\"name\":\"bytom\",\"etomic\":\"0xcB97e65F07DA24D46BcDD078EBebd7C6E6E3d750\",\"rpcport\":80}, {\"coin\":\"AE\",\"name\":\"aeternity\",\"etomic\":\"0x5ca9a71b1d01849c0a95490cc00559717fcf0d1d\",\"rpcport\":80}, {\"coin\":\"ZIL\",\"name\":\"zilliqa\",\"etomic\":\"0x05f4a42e251f2d52b8ed15e9fedaacfcef1fad27\",\"rpcport\":80}, {\"coin\":\"FLLW\",\"name\":\"followcoin\",\"etomic\":\"0x0200412995f1bafef0d3f97c4e28ac2515ec1ece\",\"rpcport\":80}, {\"coin\":\"HYD\",\"name\":\"hydra\",\"etomic\":\"0xD233495C48EB0143661fFC8458EAfc21b633f97f\",\"rpcport\":80}, {\"coin\":\"VRSC\",\"asset\":\"VRSC\",\"rpcport\":27486}, {\"coin\":\"CHAIN\",\"asset\":\"CHAIN\",\"rpcport\":15587},{\"coin\":\"POWR\",\"name\":\"power-ledger\",\"etomic\":\"0x595832f8fc6bf59c85c527fec3740a1b7a361269\",\"rpcport\":80},{\"coin\":\"TUSD\",\"name\":\"trueusd\",\"etomic\":\"0x8dd5fbce2f6a956c3022ba3663759011dd51e73e\",\"rpcport\":80}, {\"coin\":\"VEN\",\"name\":\"vechain\",\"etomic\":\"0xd850942ef8811f2a866692a623011bde52a462c1\",\"rpcport\":80}, {\"coin\":\"DSEC\",\"asset\":\"DSEC\",\"rpcport\":11557},{\"coin\":\"LOOM\",\"name\":\"loom-network\",\"etomic\":\"0xa4e8c3ec456107ea67d3075bf9e3df3a75823db0\",\"rpcport\":80}, {\"coin\":\"ANN\",\"name\":\"agentnotneeded\",\"etomic\":\"0xe0e73E8fc3a0fA161695be1D75E1Bc3E558957c4\",\"rpcport\":80},{\"coin\":\"PRL\",\"name\":\"oyster\",\"etomic\":\"0x1844b21593262668b7248d0f57a220caaba46ab9\",\"rpcport\":80}, {\"coin\":\"MGO\",\"name\":\"mobilego\",\"etomic\":\"0x40395044Ac3c0C57051906dA938B54BD6557F212\",\"rpcport\":80},{\"coin\":\"DRGN\",\"name\":\"dragonchain\",\"etomic\":\"0x419c4db4b9e25d6db2ad9691ccb832c8d9fda05e\",\"rpcport\":80}, {\"coin\":\"GLD\",\"name\":\"goldcoin\",\"rpcport\":9332,\"pubtype\":32,\"p2shtype\":5,\"wiftype\":160,\"txfee\":100000}, {\"coin\":\"BTK\",\"name\":\"bitcointoken\",\"etomic\":\"0xdb8646F5b487B5Dd979FAC618350e85018F557d4\",\"rpcport\":80},{\"coin\":\"DGPT\",\"name\":\"digipulse\",\"etomic\":\"0xf6cFe53d6FEbaEEA051f400ff5fc14F0cBBDacA1\",\"rpcport\":80}, {\"coin\":\"OCT\",\"name\":\"octus\",\"etomic\":\"0x7e9d365C0C97Fe5FcAdcc1B513Af974b768C5867\",\"rpcport\":80},{\"coin\":\"STWY\",\"name\":\"storweeytoken\",\"etomic\":\"0x8a8c71f032362fca2994f75d854f911ec381ac5a\",\"rpcport\":80}, {\"coin\":\"SPK\",\"name\":\"Sparks\",\"rpcport\":8892,\"pubtype\":38,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\":\"PCL\",\"name\":\"peculium\",\"etomic\":\"0x3618516f45cd3c913f81f9987af41077932bc40d\",\"rpcport\":80}, {\"coin\":\"RLTY\",\"name\":\"smartrealty\",\"etomic\":\"0xbe99b09709fc753b09bcf557a992f6605d5997b0\",\"rpcport\":80},{\"coin\":\"CIX\",\"name\":\"cryptonetix\",\"etomic\":\"0x1175a66a5c3343Bbf06AA818BB482DdEc30858E0\",\"rpcport\":80}, {\"coin\":\"GLXT\",\"asset\":\"GLXT\",\"rpcport\":15723}, {\"coin\":\"PYRO\",\"name\":\"pyro\",\"confpath\":\"${HOME#}/.pyrocore/pyro.conf\",\"rpcport\":9696,\"pubtype\":55,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\": \"BNTN\",\"asset\": \"BNTN\",\"rpcport\": 14358},{\"coin\":\"ORE\",\"name\":\"galactrum\",\"rpcport\":6269,\"pubtype\":38,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"ELD\",\"name\":\"maker\",\"etomic\":\"0xaaf7d4cd097317d68174215395eb02c2cca81e31\",\"rpcport\":80}, {\"coin\":\"CENNZ\",\"name\":\"centrality\",\"etomic\":\"0x1122b6a0e00dce0563082b6e2953f3a943855c1f\",\"rpcport\":80}, {\"coin\":\"PGN\",\"name\":\"pigeon\",\"rpcport\":8756,\"pubtype\":55,\"p2shtype\":122,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"XCG\",\"name\":\"Xchange\",\"confpath\":\"${HOME#}/.Xchangecore/Xchange.conf\",\"rpcport\":9386,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"AXE\",\"name\":\"axe\",\"confpath\":\"${HOME#}/.axecore/axe.conf\",\"rpcport\":9337,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"PEW\",\"name\":\"brofist\",\"rpcport\":12454,\"pubtype\":55,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000,\"confpath\":\"${HOME#}/.brofistcore/brofist.conf\"}, {\"coin\":\"BCBC\",\"name\":\"bitcoin@cbc\",\"confpath\":\"${HOME#}/.bitcoin@cbc/bitcoin.conf\",\"rpcport\":8340,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"GRLC\",\"name\":\"garlicoin\",\"rpcport\":42068,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"EQL\",\"asset\":\"EQL\",\"rpcport\":10306}, {\"coin\":\"OCC\",\"name\":\"originalcryptocoin\",\"etomic\":\"0x0235fe624e044a05eed7a43e16e3083bc8a4287a\",\"rpcport\":80}, {\"coin\":\"DIN\",\"name\":\"dinero\",\"rpcport\":9998,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":204,\"txfee\":10000,\"confpath\":\"${HOME#}/.dinerocore/dinero.conf\"}, {\"coin\":\"BUCK\",\"name\":\"buck\",\"rpcport\":5739,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"LYS\",\"name\":\"lightyears\",\"etomic\":\"0xdd41fbd1ae95c5d9b198174a28e04be6b3d1aa27\",\"rpcport\":80}, {\"coin\":\"RAP\",\"name\":\"rapture\",\"rpcport\":14776,\"pubtype\":60,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000,\"confpath\":\"${HOME#}/.rapturecore/rapture.conf\"}, {\"coin\":\"RADIUS\",\"name\":\"radius\",\"rpcport\":4089,\"pubtype\":60,\"p2shtype\":16,\"wiftype\":15,\"txfee\":10000,\"confpath\":\"${HOME#}/.radiuscore/radius.conf\"},{\"coin\":\"BTCL\",\"name\":\"btclite\",\"etomic\":\"0x5acd19b9c91e596b1f062f18e3d02da7ed8d1e50\",\"rpcport\":80}, {\"coin\":\"SEQ\",\"name\":\"sequence\",\"rpcport\":16663,\"isPoS\":1,\"pubtype\":63,\"p2shtype\":64,\"wiftype\":170,\"txfee\":10000}, {\"coin\":\"DYN\",\"name\":\"dynamic\",\"rpcport\":33350,\"pubtype\":30,\"p2shtype\":10,\"wiftype\":140,\"txfee\":10000}, {\"coin\":\"SBTC\",\"name\":\"SuperBitcoin\",\"rpcport\":28282,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000,\"confpath\":\"${HOME#}/.sbtc/sbtc.conf\"}, {\"coin\":\"FJC\",\"name\":\"fujicoin\",\"rpcport\":3776,\"pubtype\":36,\"p2shtype\":16,\"wiftype\":164,\"txfee\":100000}, {\"coin\":\"AIR\",\"name\":\"airtoken\",\"etomic\":\"0x27dce1ec4d3f72c3e457cc50354f1f975ddef488\",\"rpcport\":80}, {\"coin\":\"VRT\",\"name\":\"virtus\",\"confpath\":\"${HOME#}/.virtuscore/virtus.conf\",\"rpcport\":13880,\"pubtype\":70,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"DRT\",\"name\":\"domraider\",\"etomic\":\"0x9af4f26941677c706cfecf6d3379ff01bb85d5ab\",\"rpcport\":80}, {\"coin\":\"BITS\",\"name\":\"bitstar\",\"rpcport\":15715,\"isPoS\":1,\"pubtype\":25,\"p2shtype\":8,\"wiftype\":153,\"txfee\":10000}, {\"coin\":\"FTC\",\"name\":\"feathercoin\",\"rpcport\":9337,\"pubtype\":14,\"p2shtype\":5,\"wiftype\":142,\"txfee\":1000000}, {\"coin\":\"PXT\",\"name\":\"populous-xbrl-token\",\"etomic\":\"0xc14830e53aa344e8c14603a91229a0b925b0b262\",\"rpcport\":80}, {\"coin\":\"USDT\",\"name\":\"tether\",\"etomic\":\"0xdac17f958d2ee523a2206206994597c13d831ec7\",\"rpcport\":80}, {\"coin\":\"ELI\",\"name\":\"elicoin\",\"rpcport\":9332,\"pubtype\":33,\"p2shtype\":102,\"wiftype\":205,\"txfee\":10000}, {\"coin\":\"SCRIV\",\"name\":\"scriv\",\"confpath\":\"${HOME#}/.scrivcore/scriv.conf\",\"rpcport\":7998,\"pubtype\":125,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"ELP\",\"name\":\"ellerium\",\"rpcport\":61020,\"pubtype\":23,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"ROI\",\"name\":\"ROIcoin\",\"rpcport\":3376,\"pubtype\":60,\"p2shtype\":122,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"XCOIN\",\"name\":\"xcoin\",\"rpcport\":22717,\"pubtype\":137,\"p2shtype\":15,\"wiftype\":75,\"txfee\":100000}, {\"coin\":\"BBT\",\"name\":\"bitboost\",\"etomic\":\"0x1500205f50bf3fd976466d0662905c9ff254fc9c\",\"rpcport\":80}, {\"coin\":\"TRX\",\"name\":\"tron\",\"etomic\":\"0xf230b790e05390fc8295f4d3f60332c93bed42e2\",\"rpcport\":80}, {\"coin\":\"OMG\",\"name\":\"omisego\",\"etomic\":\"0xd26114cd6EE289AccF82350c8d8487fedB8A0C07\",\"rpcport\":80}, {\"coin\":\"ICX\",\"name\":\"icon\",\"etomic\":\"0xb5a5f22694352c15b00323844ad545abb2b11028\",\"rpcport\":80,\"decimals\":18}, {\"coin\":\"BNB\",\"name\":\"binance-coin\",\"etomic\":\"0xB8c77482e45F1F44dE1745F52C74426C631bDD52\",\"rpcport\":80}, {\"coin\":\"DGD\",\"name\":\"digixdao\",\"etomic\":\"0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A\",\"rpcport\":80,\"decimals\":9}, {\"coin\":\"PPT\",\"name\":\"populous\",\"etomic\":\"0xd4fa1460F537bb9085d22C7bcCB5DD450Ef28e3a\",\"rpcport\":80}, {\"coin\":\"MKR\",\"name\":\"maker\",\"etomic\":\"0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2\",\"rpcport\":80}, {\"coin\":\"SNT\",\"name\":\"status\",\"etomic\":\"0x744d70FDBE2Ba4CF95131626614a1763DF805B9E\",\"rpcport\":80}, {\"coin\":\"REP\",\"name\":\"augur\",\"etomic\":\"0xE94327D07Fc17907b4DB788E5aDf2ed424adDff6\",\"rpcport\":80}, {\"coin\":\"ZRX\",\"name\":\"0x\",\"etomic\":\"0xE41d2489571d322189246DaFA5ebDe1F4699F498\",\"rpcport\":80}, {\"coin\":\"BAT\",\"name\":\"basic-attention-token\",\"etomic\":\"0x0D8775F648430679A709E98d2b0Cb6250d2887EF\",\"rpcport\":80}, {\"coin\":\"ETHOS\",\"name\":\"ethos\",\"etomic\":\"0x5Af2Be193a6ABCa9c8817001F45744777Db30756\",\"rpcport\":80}, {\"coin\":\"QASH\",\"name\":\"qash\",\"etomic\":\"0x618E75Ac90b12c6049Ba3b27f5d5F8651b0037F6\",\"rpcport\":80}, {\"coin\":\"FUN\",\"name\":\"funfair\",\"etomic\":\"0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b\",\"rpcport\":80}, {\"coin\":\"KNC\",\"name\":\"kyber-network\",\"etomic\":\"0xdd974D5C2e2928deA5F71b9825b8b646686BD200\",\"rpcport\":80}, {\"coin\":\"SALT\",\"name\":\"salt\",\"etomic\":\"0x4156D3342D5c385a87D264F90653733592000581\",\"rpcport\":80}, {\"coin\":\"BNT\",\"name\":\"bancor\",\"etomic\":\"0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C\",\"rpcport\":80}, {\"coin\":\"ICN\",\"name\":\"iconomi\",\"etomic\":\"0x888666CA69E0f178DED6D75b5726Cee99A87D698\",\"rpcport\":80}, {\"coin\":\"PAY\",\"name\":\"tenx\",\"etomic\":\"0xB97048628DB6B661D4C2aA833e95Dbe1A905B280\",\"rpcport\":80}, {\"coin\":\"REQ\",\"name\":\"request-network\",\"etomic\":\"0x8f8221aFbB33998d8584A2B05749bA73c37a938a\",\"rpcport\":80}, {\"coin\":\"STORJ\",\"name\":\"storj\",\"etomic\":\"0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC\",\"rpcport\":80}, {\"coin\":\"GNO\",\"name\":\"gnosis-gno\",\"etomic\":\"0x6810e776880C02933D47DB1b9fc05908e5386b96\",\"rpcport\":80}, {\"coin\":\"RLC\",\"name\":\"rlc\",\"etomic\":\"0x607F4C5BB672230e8672085532f7e901544a7375\",\"rpcport\":80}, {\"coin\":\"ENJ\",\"name\":\"enjin-coin\",\"etomic\":\"0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c\",\"rpcport\":80}, {\"coin\":\"QSP\",\"name\":\"quantstamp\",\"etomic\":\"0x99ea4dB9EE77ACD40B119BD1dC4E33e1C070b80d\",\"rpcport\":80}, {\"coin\":\"RDN\",\"name\":\"raiden-network-token\",\"etomic\":\"0x255Aa6DF07540Cb5d3d297f0D0D4D84cb52bc8e6\",\"rpcport\":80}, {\"coin\":\"CVC\",\"name\":\"civic\",\"etomic\":\"0x41e5560054824eA6B0732E656E3Ad64E20e94E45\",\"rpcport\":80}, {\"coin\":\"SAN\",\"name\":\"santiment\",\"etomic\":\"0x7C5A0CE9267ED19B22F8cae653F198e3E8daf098\",\"rpcport\":80}, {\"coin\":\"ANT\",\"name\":\"aragon\",\"etomic\":\"0x960b236A07cf122663c4303350609A66A7B288C0\",\"rpcport\":80}, {\"coin\":\"MANA\",\"name\":\"decentraland\",\"etomic\":\"0x0F5D2fB29fb7d3CFeE444a200298f468908cC942\",\"rpcport\":80}, {\"coin\":\"MCO\",\"name\":\"monaco\",\"etomic\":\"0xB63B606Ac810a52cCa15e44bB630fd42D8d1d83d\",\"rpcport\":80}, {\"coin\":\"MTL\",\"name\":\"metal\",\"etomic\":\"0xF433089366899D83a9f26A773D59ec7eCF30355e\",\"rpcport\":80}, {\"coin\":\"EDG\",\"name\":\"edgeless\",\"etomic\":\"0x08711D3B02C8758F2FB3ab4e80228418a7F8e39c\",\"rpcport\":80}, {\"coin\":\"MLN\",\"name\":\"melon\",\"etomic\":\"0xBEB9eF514a379B997e0798FDcC901Ee474B6D9A1\",\"rpcport\":80}, {\"coin\":\"AMB\",\"name\":\"amber\",\"etomic\":\"0x4DC3643DbC642b72C158E7F3d2ff232df61cb6CE\",\"rpcport\":80}, {\"coin\":\"WINGS\",\"name\":\"wings\",\"etomic\":\"0x667088b212ce3d06a1b553a7221E1fD19000d9aF\",\"rpcport\":80}, {\"coin\":\"RCN\",\"name\":\"ripio-credit-network\",\"etomic\":\"0xF970b8E36e23F7fC3FD752EeA86f8Be8D83375A6\",\"rpcport\":80}, {\"coin\":\"SNGLS\",\"name\":\"singulardtv\",\"etomic\":\"0xaeC2E87E0A235266D9C5ADc9DEb4b2E29b54D009\",\"rpcport\":80}, {\"coin\":\"TAAS\",\"name\":\"taas\",\"etomic\":\"0xE7775A6e9Bcf904eb39DA2b68c5efb4F9360e08C\",\"rpcport\":80}, {\"coin\":\"DNT\",\"name\":\"district0x\",\"etomic\":\"0x0AbdAce70D3790235af448C88547603b945604ea\",\"rpcport\":80}, {\"coin\":\"CFI\",\"name\":\"cofound-it\",\"etomic\":\"0x12FEF5e57bF45873Cd9B62E9DBd7BFb99e32D73e\",\"rpcport\":80}, {\"coin\":\"LUN\",\"name\":\"lunyr\",\"etomic\":\"0xfa05A73FfE78ef8f1a739473e462c54bae6567D9\",\"rpcport\":80}, {\"coin\":\"ADT\",\"name\":\"adtoken\",\"etomic\":\"0xD0D6D6C5Fe4a677D343cC433536BB717bAe167dD\",\"rpcport\":80}, {\"coin\":\"AST\",\"name\":\"airswap\",\"etomic\":\"0x27054b13b1B798B345b591a4d22e6562d47eA75a\",\"rpcport\":80}, {\"coin\":\"CDT\",\"name\":\"blox\",\"etomic\":\"0x177d39AC676ED1C67A2b268AD7F1E58826E5B0af\",\"rpcport\":80}, {\"coin\":\"TKN\",\"name\":\"tokencard\",\"etomic\":\"0xaAAf91D9b90dF800Df4F55c205fd6989c977E73a\",\"rpcport\":80}, {\"coin\":\"HMQ\",\"name\":\"humaniq\",\"etomic\":\"0xcbCC0F036ED4788F63FC0fEE32873d6A7487b908\",\"rpcport\":80}, {\"coin\":\"NMR\",\"name\":\"numeraire\",\"etomic\":\"0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671\",\"rpcport\":80}, {\"coin\":\"NET\",\"name\":\"nimiq\",\"etomic\":\"0xcfb98637bcae43C13323EAa1731cED2B716962fD\",\"rpcport\":80}, {\"coin\":\"TRST\",\"name\":\"trust\",\"etomic\":\"0xCb94be6f13A1182E4A4B6140cb7bf2025d28e41B\",\"rpcport\":80}, {\"coin\":\"GUP\",\"name\":\"guppy\",\"etomic\":\"0xf7B098298f7C69Fc14610bf71d5e02c60792894C\",\"rpcport\":80}, {\"coin\":\"1ST\",\"name\":\"firstblood\",\"etomic\":\"0xAf30D2a7E90d7DC361c8C4585e9BB7D2F6f15bc7\",\"rpcport\":80}, {\"coin\":\"TIME\",\"name\":\"chronobank\",\"etomic\":\"0x6531f133e6DeeBe7F2dcE5A0441aA7ef330B4e53\",\"rpcport\":80}, {\"coin\":\"SWT\",\"name\":\"swarm-city\",\"etomic\":\"0xB9e7F8568e08d5659f5D29C4997173d84CdF2607\",\"rpcport\":80}, {\"coin\":\"ROL\",\"name\":\"dice\",\"etomic\":\"0x2e071D2966Aa7D8dECB1005885bA1977D6038A65\",\"rpcport\":80}, {\"coin\":\"XAUR\",\"name\":\"xaurum\",\"etomic\":\"0x4DF812F6064def1e5e029f1ca858777CC98D2D81\",\"rpcport\":80}, {\"coin\":\"PLU\",\"name\":\"pluton\",\"etomic\":\"0xD8912C10681D8B21Fd3742244f44658dBA12264E\",\"rpcport\":80}, {\"coin\":\"HGT\",\"name\":\"hellogold\",\"etomic\":\"0xba2184520A1cC49a6159c57e61E1844E085615B6\",\"rpcport\":80}, {\"coin\":\"VSL\",\"name\":\"vslice\",\"etomic\":\"0x5c543e7AE0A1104f78406C340E9C64FD9fCE5170\",\"rpcport\":80,\"decimals\":18}, {\"coin\":\"IND\",\"name\":\"indorse-token\",\"etomic\":\"0xf8e386EDa857484f5a12e4B5DAa9984E06E73705\",\"rpcport\":80}, {\"coin\":\"FYN\",\"name\":\"fundyourselfnow\",\"etomic\":\"0x88FCFBc22C6d3dBaa25aF478C578978339BDe77a\",\"rpcport\":80},{\"coin\":\"SMART\",\"name\":\"smartcash\",\"rpcport\":9679,\"pubtype\":63,\"p2shtype\":18,\"wiftype\":191,\"txfee\":200000}, {\"coin\":\"BTCP\",\"name\":\"btcprivate\",\"rpcport\":7932,\"taddr\":19,\"pubtype\":37,\"p2shtype\":175,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"DNR\",\"isPoS\":1,\"active\":1,\"name\":\"denarius\",\"rpcport\":32339,\"pubtype\":30,\"p2shtype\":90,\"wiftype\":158,\"txfee\":10000}, {\"coin\":\"RVN\",\"name\":\"raven\",\"rpcport\":8766,\"pubtype\":60,\"p2shtype\":122,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"VIVO\",\"name\":\"vivo\",\"confpath\":\"${HOME#}/.vivocore/vivo.conf\",\"rpcport\":9998,\"pubtype\":70,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\":\"KNG\",\"name\":\"kings\",\"rpcport\":44888,\"pubtype\":75,\"p2shtype\":125,\"wiftype\":203,\"txfee\":10000}, {\"coin\":\"UFO\",\"name\":\"ufocoin\",\"confpath\":\"${HOME#}/.ufo/ufocoin.conf\",\"rpcport\":9888,\"pubtype\":27,\"p2shtype\":5,\"wiftype\":155,\"txfee\":100000}, {\"coin\":\"ETH\",\"name\":\"ethereum\",\"etomic\":\"0x0000000000000000000000000000000000000000\",\"rpcport\":80}, {\"coin\":\"EOS\",\"name\":\"EOS\",\"etomic\":\"0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0\",\"rpcport\":80}, {\"coin\":\"KREDS\",\"name\":\"kreds\",\"rpcport\":3850,\"pubtype\":45,\"p2shtype\":5,\"wiftype\":195,\"txfee\":10000}, {\"coin\":\"SNG\",\"name\":\"snowgem\",\"rpcport\":16112,\"taddr\":28,\"pubtype\":40,\"p2shtype\":45,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"ZEL\",\"name\":\"zelcash\",\"rpcport\":16124,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"HTML\",\"name\":\"htmlcoin\",\"rpcport\":4889,\"pubtype\":41,\"p2shtype\":100,\"wiftype\":169,\"txfee\":400000}, {\"coin\":\"MNX\",\"name\":\"Minexcoin\",\"rpcport\":17786,\"pubtype\":75,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"LTZ\",\"name\":\"litecoinz\",\"rpcport\":29332,\"taddr\":10,\"pubtype\":179,\"p2shtype\":184,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"BAY\",\"name\":\"bitbay\",\"isPoS\":1,\"rpcport\":19915,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":10000}, {\"coin\":\"OOT\",\"asset\":\"OOT\",\"rpcport\":12467}, {\"coin\":\"ZOI\",\"name\":\"zoin\",\"rpcport\":8255,\"pubtype\":80,\"p2shtype\":7,\"wiftype\":208,\"txfee\":1000}, {\"coin\": \"PIZZA\",\"asset\": \"PIZZA\",\"rpcport\": 11116},{\"coin\": \"BEER\",\"asset\": \"BEER\",\"rpcport\": 8923}, {\"coin\":\"GRS\",\"name\":\"groestlcoin\",\"rpcport\":1441,\"pubtype\":36,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"XMCC\",\"name\":\"monoeci\",\"confpath\":\"${HOME#}/.monoeciCore/monoeci.conf\",\"rpcport\":24156,\"pubtype\":50,\"p2shtype\":73,\"wiftype\":77,\"txfee\":10000}, {\"coin\":\"BTCH\",\"asset\":\"BTCH\",\"rpcport\":8800},{\"coin\":\"ETOMIC\",\"asset\":\"ETOMIC\",\"rpcport\":10271},{\"coin\":\"AXO\",\"asset\":\"AXO\",\"rpcport\":12927},{\"coin\":\"CRC\",\"name\":\"crowdcoin\",\"confpath\":\"${HOME#}/.crowdcoincore/crowdcoin.conf\",\"rpcport\":11998,\"pubtype\":28,\"p2shtype\":88,\"wiftype\":0,\"txfee\":10000}, {\"coin\":\"VOT\",\"name\":\"votecoin\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"INN\",\"name\":\"innova\",\"confpath\":\"${HOME#}/.innovacore/innova.conf\",\"rpcport\":8818,\"pubtype\":102,\"p2shtype\":20,\"wiftype\":195,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":28,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"EFL\",\"name\":\"egulden\",\"confpath\":\"${HOME#}/.egulden/coin.conf\",\"rpcport\":21015,\"pubtype\":48,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"GBX\",\"name\":\"gobyte\",\"confpath\":\"${HOME#}/.gobytecore/gobyte.conf\",\"rpcport\":12454,\"pubtype\":38,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\":\"BCO\",\"name\":\"bridgecoin\",\"rpcport\":6332,\"pubtype\":27,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BLK\",\"name\":\"blackcoin\",\"confpath\":\"${HOME#}/.lore/blackcoin.conf\",\"isPoS\":1,\"rpcport\":15715,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":100000}, {\"coin\":\"BTG\",\"name\":\"bitcoingold\",\"rpcport\":8332,\"pubtype\":38,\"p2shtype\":23,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BCH\",\"name\":\"bch\",\"rpcport\":33333,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"ABY\",\"name\":\"applebyte\",\"rpcport\":8607,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":100000}, {\"coin\":\"STAK\",\"name\":\"straks\",\"rpcport\":7574,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"XZC\",\"name\":\"zcoin\",\"rpcport\":8888,\"pubtype\":82,\"p2shtype\":7,\"wiftype\":210,\"txfee\":10000}, {\"coin\":\"QTUM\",\"name\":\"qtum\",\"rpcport\":3889,\"pubtype\":58,\"p2shtype\":50,\"wiftype\":128,\"txfee\":400000}, {\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"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\":2000000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"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\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"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\":\"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\":10000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"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\":100000}, {\"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\":10000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":10000}, {\"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\":\"MSHARK\",\"asset\":\"MSHARK\",\"rpcport\":8846}, {\"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\":\"CMM\",\"name\":\"commercium\",\"rpcport\":9657,\"pubtype\":28,\"p2shtype\":50,\"wiftype\":140,\"txfee\":10000}, diff --git a/iguana/exchanges/etomicswap/etomiccurl.c b/iguana/exchanges/etomicswap/etomiccurl.c index e7f1296ee..a547111e0 100644 --- a/iguana/exchanges/etomicswap/etomiccurl.c +++ b/iguana/exchanges/etomicswap/etomiccurl.c @@ -1,7 +1,6 @@ #include "etomiccurl.h" #include -static char *ethRpcUrl = ETOMIC_URL; pthread_mutex_t sendTxMutex = PTHREAD_MUTEX_INITIALIZER; struct string { @@ -36,16 +35,15 @@ size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s) cJSON *parseEthRpcResponse(char *requestResult) { - printf("Trying to parse ETH RPC response: %s\n", requestResult); cJSON *json = cJSON_Parse(requestResult); if (json == NULL) { - printf("ETH RPC response parse failed!\n"); + printf("ETH RPC response parse failed: %s!\n", requestResult); return NULL; } cJSON *tmp = cJSON_GetObjectItem(json, "result"); cJSON *error = cJSON_GetObjectItem(json, "error"); cJSON *result = NULL; - if (!is_cJSON_Null(tmp)) { + if (tmp != NULL && !is_cJSON_Null(tmp)) { result = cJSON_Duplicate(tmp, 1); } else if (error != NULL && !is_cJSON_Null(error)) { char *errorString = cJSON_PrintUnformatted(error); @@ -56,7 +54,7 @@ cJSON *parseEthRpcResponse(char *requestResult) return result; } -char* sendRequest(char* request) +char* sendRequest(char *request, char *url) { CURL *curl; CURLcode res; @@ -72,13 +70,15 @@ char* sendRequest(char* request) curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); - curl_easy_setopt(curl, CURLOPT_URL, ethRpcUrl); + curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); /* Check for errors */ if (res != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); + curl_easy_cleanup(curl); + return NULL; } /* always cleanup */ @@ -98,7 +98,7 @@ cJSON *sendRpcRequest(char *method, cJSON *params) cJSON_AddItemToObject(request, "params", cJSON_Duplicate(params, 1)); cJSON_AddNumberToObject(request, "id", 1); string = cJSON_PrintUnformatted(request); - char* requestResult = sendRequest(string); + char* requestResult = sendRequest(string, ETOMIC_URL); free(string); cJSON_Delete(request); cJSON *result = parseEthRpcResponse(requestResult); @@ -151,8 +151,8 @@ char* sendRawTx(char* rawTx) int64_t getNonce(char* address) { - // we should lock this mutex and unlock it only when transaction was already sent. - // make sure that sendRawTx is called after getting a nonce! + // we should lock this mutex and unlock it only when transaction was already sent or failed. + // make sure that sendRawTx or unlock_send_tx_mutex is called after getting a nonce! if (pthread_mutex_lock(&sendTxMutex) != 0) { printf("Nonce mutex lock failed\n"); }; @@ -186,7 +186,7 @@ char* getEthBalanceRequest(char* address) return balance; } -char* ethCall(char* to, const char* data) +char *ethCall(char *to, const char *data) { cJSON *params = cJSON_CreateArray(); cJSON *txObject = cJSON_CreateObject(); @@ -196,7 +196,7 @@ char* ethCall(char* to, const char* data) cJSON_AddItemToArray(params, cJSON_CreateString("latest")); cJSON *resultJson = sendRpcRequest("eth_call", params); cJSON_Delete(params); - char* result = NULL; + char *result = NULL; if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) { result = (char *) malloc(strlen(resultJson->valuestring) + 1); strcpy(result, resultJson->valuestring); @@ -205,6 +205,26 @@ char* ethCall(char* to, const char* data) return result; } +uint64_t estimateGas(char *from, char *to, const char *data) +{ + cJSON *params = cJSON_CreateArray(); + cJSON *txObject = cJSON_CreateObject(); + cJSON_AddStringToObject(txObject, "from", from); + cJSON_AddStringToObject(txObject, "to", to); + cJSON_AddStringToObject(txObject, "data", data); + cJSON_AddItemToArray(params, txObject); + cJSON_AddItemToArray(params, cJSON_CreateString("latest")); + cJSON *resultJson = sendRpcRequest("eth_estimateGas", params); + cJSON_Delete(params); + uint64_t result = 0; + if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) { + result = (uint64_t)strtoul(resultJson->valuestring, NULL, 0); + result = (result / 100) * 120; // add 20% because real gas usage might differ from estimate + } + cJSON_Delete(resultJson); + return result; +} + EthTxReceipt getEthTxReceipt(char *txId) { EthTxReceipt result; @@ -265,7 +285,7 @@ EthTxData getEthTxData(char *txId) return result; } -uint64_t getGasPriceFromStation() +uint64_t getGasPriceFromStation(uint8_t defaultOnErr) { CURL *curl; CURLcode res; @@ -283,6 +303,12 @@ uint64_t getGasPriceFromStation() curl_easy_setopt(curl, CURLOPT_URL, "https://ethgasstation.info/json/ethgasAPI.json"); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); + uint64_t result; + if (defaultOnErr == 1) { + result = DEFAULT_GAS_PRICE; + } else { + result = 0; + } /* Check for errors */ if (res != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); @@ -292,9 +318,9 @@ uint64_t getGasPriceFromStation() /* always cleanup */ curl_easy_cleanup(curl); cJSON *resultJson = cJSON_Parse(s.ptr); - uint64_t result = DEFAULT_GAS_PRICE; free(s.ptr); if (resultJson == NULL) { + printf("Could not parse gas station response!\n"); return result; } @@ -342,3 +368,40 @@ int32_t waitForConfirmation(char *txId) return((int32_t)receipt.confirmations); } + +void unlock_send_tx_mutex() +{ + pthread_mutex_unlock(&sendTxMutex); +} + +uint8_t get_etomic_from_faucet(char *etomic_addr) +{ + char* string; + cJSON *request = cJSON_CreateObject(); + cJSON_AddStringToObject(request, "etomicAddress", etomic_addr); + string = cJSON_PrintUnformatted(request); + char* requestResult = sendRequest(string, FAUCET_URL); + free(string); + cJSON_Delete(request); + + if (requestResult == NULL) { + return 0; + } + + cJSON *json = cJSON_Parse(requestResult); + if (json == NULL) { + printf("ETOMIC faucet response parse failed!\n"); + return 0; + } + cJSON *error = cJSON_GetObjectItem(json, "error"); + uint8_t result = 0; + if (error != NULL && !is_cJSON_Null(error)) { + char *errorString = cJSON_PrintUnformatted(error); + printf("Got ETOMIC faucet error: %s\n", errorString); + free(errorString); + } else { + result = 1; + } + cJSON_Delete(json); + return result; +} diff --git a/iguana/exchanges/etomicswap/etomiccurl.h b/iguana/exchanges/etomicswap/etomiccurl.h index c0433bc75..2b765b150 100644 --- a/iguana/exchanges/etomicswap/etomiccurl.h +++ b/iguana/exchanges/etomicswap/etomiccurl.h @@ -16,9 +16,11 @@ extern "C"{ #define DEFAULT_GAS_PRICE 100 #else #define ETOMIC_URL "http://195.201.0.6:8555" -#define DEFAULT_GAS_PRICE 4 +#define DEFAULT_GAS_PRICE 10 #endif +#define FAUCET_URL "http://195.201.116.176:8000/getEtomic" + typedef struct { uint64_t blockNumber; @@ -39,13 +41,16 @@ typedef struct char* sendRawTx(char* rawTx); char* sendRawTxWaitConfirm(char* rawTx); char* ethCall(char* to, const char* data); +uint64_t estimateGas(char *from, char *to, const char *data); int64_t getNonce(char* address); char* getEthBalanceRequest(char* address); EthTxReceipt getEthTxReceipt(char *txId); EthTxData getEthTxData(char *txId); uint64_t getEthBlockNumber(); -uint64_t getGasPriceFromStation(); +uint64_t getGasPriceFromStation(uint8_t defaultOnErr); int32_t waitForConfirmation(char *txId); +void unlock_send_tx_mutex(); +uint8_t get_etomic_from_faucet(char *etomic_addr); #ifdef __cplusplus } diff --git a/iguana/exchanges/etomicswap/etomiclib.cpp b/iguana/exchanges/etomicswap/etomiclib.cpp index 204848477..f80ba22f4 100644 --- a/iguana/exchanges/etomicswap/etomiclib.cpp +++ b/iguana/exchanges/etomicswap/etomiclib.cpp @@ -4,6 +4,7 @@ #include "etomiclib.h" #include "etomiccurl.h" #include +#include #include #include #include @@ -27,18 +28,18 @@ TransactionSkeleton txDataToSkeleton(BasicTxData txData) tx.to = jsToAddress(txData.to); tx.value = jsToU256(txData.amount); tx.gas = 200000; - tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9); + tx.gasPrice = getGasPriceFromStation(1) * boost::multiprecision::pow(u256(10), 9); tx.nonce = getNonce(txData.from); return tx; } char *signTx(TransactionSkeleton& tx, char* secret) { - Secret& secretKey = *(new Secret(secret)); - auto baseTx = new TransactionBase(tx, secretKey); - RLPStream& rlpStream = *(new RLPStream()); - baseTx->streamRLP(rlpStream); - std::stringstream& ss = *(new std::stringstream); + Secret secretKey(secret); + TransactionBase baseTx(tx, secretKey); + RLPStream rlpStream; + baseTx.streamRLP(rlpStream); + std::stringstream ss; ss << rlpStream.out(); return stringStreamToChar(ss); } @@ -50,7 +51,7 @@ char *approveErc20(ApproveErc20Input input) tx.to = jsToAddress(input.tokenAddress); tx.value = 0; tx.gas = 300000; - tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9); + tx.gasPrice = getGasPriceFromStation(1) * boost::multiprecision::pow(u256(10), 9); tx.nonce = getNonce(input.owner); std::stringstream ss; ss << "0x095ea7b3" @@ -101,7 +102,12 @@ uint8_t verifyAliceEthPaymentData(AliceSendsEthPaymentInput input, char *data) std::stringstream aliceSendsErc20PaymentData(AliceSendsErc20PaymentInput input) { - uint8_t decimals = getErc20Decimals(input.tokenAddress); + uint8_t decimals; + if (input.decimals > 0) { + decimals = input.decimals; + } else { + decimals = getErc20Decimals(input.tokenAddress); + } u256 amount = jsToU256(input.amount); if (decimals < 18) { amount /= boost::multiprecision::pow(u256(10), 18 - decimals); @@ -148,12 +154,20 @@ char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxDat std::stringstream ss; u256 amount = jsToU256(input.amount); dev::Address tokenAddress = jsToAddress(input.tokenAddress); + if (tokenAddress != ZeroAddress) { - uint8_t decimals = getErc20Decimals(input.tokenAddress); + uint8_t decimals; + if (input.decimals > 0) { + decimals = input.decimals; + } else { + decimals = getErc20Decimals(input.tokenAddress); + } + if (decimals < 18) { amount /= boost::multiprecision::pow(u256(10), 18 - decimals); } } + ss << "0x8b9a167a" << toHex(jsToBytes(input.dealId)) << toHex(toBigEndian(amount)) @@ -179,12 +193,20 @@ char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData std::stringstream ss; u256 amount = jsToU256(input.amount); dev::Address tokenAddress = jsToAddress(input.tokenAddress); + if (tokenAddress != ZeroAddress) { - uint8_t decimals = getErc20Decimals(input.tokenAddress); + uint8_t decimals; + if (input.decimals > 0) { + decimals = input.decimals; + } else { + decimals = getErc20Decimals(input.tokenAddress); + } + if (decimals < 18) { amount /= boost::multiprecision::pow(u256(10), 18 - decimals); } } + ss << "0x392ec66b" << toHex(jsToBytes(input.dealId)) << toHex(toBigEndian(amount)) @@ -241,7 +263,13 @@ uint8_t verifyBobEthDepositData(BobSendsEthDepositInput input, char *data) std::stringstream bobSendsErc20DepositData(BobSendsErc20DepositInput input) { - uint8_t decimals = getErc20Decimals(input.tokenAddress); + uint8_t decimals; + if (input.decimals > 0) { + decimals = input.decimals; + } else { + decimals = getErc20Decimals(input.tokenAddress); + } + u256 amount = jsToU256(input.amount); u256 lockTime = input.lockTime; if (decimals < 18) { @@ -289,7 +317,13 @@ char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData) u256 amount = jsToU256(input.amount); dev::Address tokenAddress = jsToAddress(input.tokenAddress); if (tokenAddress != ZeroAddress) { - uint8_t decimals = getErc20Decimals(input.tokenAddress); + uint8_t decimals; + if (input.decimals > 0) { + decimals = input.decimals; + } else { + decimals = getErc20Decimals(input.tokenAddress); + } + if (decimals < 18) { amount /= boost::multiprecision::pow(u256(10), 18 - decimals); } @@ -316,7 +350,13 @@ char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData u256 amount = jsToU256(input.amount); dev::Address tokenAddress = jsToAddress(input.tokenAddress); if (tokenAddress != ZeroAddress) { - uint8_t decimals = getErc20Decimals(input.tokenAddress); + uint8_t decimals; + if (input.decimals > 0) { + decimals = input.decimals; + } else { + decimals = getErc20Decimals(input.tokenAddress); + } + if (decimals < 18) { amount /= boost::multiprecision::pow(u256(10), 18 - decimals); } @@ -374,9 +414,15 @@ uint8_t verifyBobEthPaymentData(BobSendsEthPaymentInput input, char *data) std::stringstream bobSendsErc20PaymentData(BobSendsErc20PaymentInput input) { - uint8_t decimals = getErc20Decimals(input.tokenAddress); u256 amount = jsToU256(input.amount); u256 lockTime = input.lockTime; + uint8_t decimals; + if (input.decimals > 0) { + decimals = input.decimals; + } else { + decimals = getErc20Decimals(input.tokenAddress); + } + if (decimals < 18) { amount /= boost::multiprecision::pow(u256(10), 18 - decimals); } @@ -422,7 +468,13 @@ char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData u256 amount = jsToU256(input.amount); dev::Address tokenAddress = jsToAddress(input.tokenAddress); if (tokenAddress != ZeroAddress) { - uint8_t decimals = getErc20Decimals(input.tokenAddress); + uint8_t decimals; + if (input.decimals > 0) { + decimals = input.decimals; + } else { + decimals = getErc20Decimals(input.tokenAddress); + } + if (decimals < 18) { amount /= boost::multiprecision::pow(u256(10), 18 - decimals); } @@ -450,7 +502,13 @@ char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData u256 amount = jsToU256(input.amount); dev::Address tokenAddress = jsToAddress(input.tokenAddress); if (tokenAddress != ZeroAddress) { - uint8_t decimals = getErc20Decimals(input.tokenAddress); + uint8_t decimals; + if (input.decimals > 0) { + decimals = input.decimals; + } else { + decimals = getErc20Decimals(input.tokenAddress); + } + if (decimals < 18) { amount /= boost::multiprecision::pow(u256(10), 18 - decimals); } @@ -472,54 +530,69 @@ char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData char* privKey2Addr(char* privKey) { - Secret& secretKey = *(new Secret(privKey)); - std::stringstream& ss = *(new std::stringstream); + Secret secretKey(privKey); + std::stringstream ss; ss << "0x" << toAddress(secretKey); return stringStreamToChar(ss); }; char* pubKey2Addr(char* pubKey) { - Public& publicKey = *(new Public(pubKey)); - std::stringstream& ss = *(new std::stringstream); + Public publicKey(pubKey); + std::stringstream ss; ss << "0x" << toAddress(publicKey); return stringStreamToChar(ss); }; -char* getPubKeyFromPriv(char* privKey) +char* getPubKeyFromPriv(char *privKey) { - Public publicKey = toPublic(*(new Secret(privKey))); - std::stringstream& ss = *(new std::stringstream); + Public publicKey = toPublic(Secret(privKey)); + std::stringstream ss; ss << "0x" << publicKey; return stringStreamToChar(ss); } -uint64_t getEthBalance(char* address) +uint64_t getEthBalance(char *address, int *error) { char* hexBalance = getEthBalanceRequest(address); - // convert wei to satoshi - u256 balance = jsToU256(hexBalance) / boost::multiprecision::pow(u256(10), 10); - free(hexBalance); - return static_cast(balance); + if (hexBalance != NULL) { + // convert wei to satoshi + u256 balance = jsToU256(hexBalance) / boost::multiprecision::pow(u256(10), 10); + free(hexBalance); + return static_cast(balance); + } else { + *error = 1; + return 0; + } } -uint64_t getErc20BalanceSatoshi(char *address, char *tokenAddress) +uint64_t getErc20BalanceSatoshi(char *address, char *tokenAddress, uint8_t setDecimals, int *error) { std::stringstream ss; ss << "0x70a08231" << "000000000000000000000000" << toHex(jsToAddress(address)); - std::stringstream& resultStream = *(new std::stringstream); char* hexBalance = ethCall(tokenAddress, ss.str().c_str()); // convert wei to satoshi - uint8_t decimals = getErc20Decimals(tokenAddress); - u256 balance = jsToU256(hexBalance); - if (decimals < 18) { - balance *= boost::multiprecision::pow(u256(10), 18 - decimals); + uint8_t decimals; + if (hexBalance != NULL) { + if (setDecimals > 0) { + decimals = setDecimals; + } else { + decimals = getErc20Decimals(tokenAddress); + } + + u256 balance = jsToU256(hexBalance); + if (decimals < 18) { + balance *= boost::multiprecision::pow(u256(10), 18 - decimals); + } + balance /= boost::multiprecision::pow(u256(10), 10); + free(hexBalance); + return static_cast(balance); + } else { + *error = 1; + return 0; } - balance /= boost::multiprecision::pow(u256(10), 10); - free(hexBalance); - return static_cast(balance); } char *getErc20BalanceHexWei(char *address, char *tokenAddress) @@ -532,7 +605,7 @@ char *getErc20BalanceHexWei(char *address, char *tokenAddress) return hexBalance; } -uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress) +uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress, uint8_t set_decimals) { std::stringstream ss; ss << "0xdd62ed3e" @@ -541,7 +614,12 @@ uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress) << "000000000000000000000000" << toHex(jsToAddress(spender)); char* hexAllowance = ethCall(tokenAddress, ss.str().c_str()); - uint8_t decimals = getErc20Decimals(tokenAddress); + uint8_t decimals; + if (set_decimals > 0) { + decimals = set_decimals; + } else { + decimals = getErc20Decimals(tokenAddress); + } u256 allowance = jsToU256(hexAllowance); if (decimals < 18) { allowance *= boost::multiprecision::pow(u256(10), 18 - decimals); @@ -560,6 +638,18 @@ uint8_t getErc20Decimals(char *tokenAddress) return decimals; } +uint8_t getErc20DecimalsZeroOnError(char *tokenAddress) +{ + char* hexDecimals = ethCall(tokenAddress, "0x313ce567"); + if (hexDecimals != NULL) { + auto decimals = (uint8_t) strtol(hexDecimals, NULL, 0); + free(hexDecimals); + return decimals; + } else { + return 0; + } +} + void uint8arrayToHex(char *dest, uint8_t *input, int len) { strcpy(dest, "0x"); @@ -582,17 +672,30 @@ uint64_t weiToSatoshi(char *wei) return static_cast(satoshi); } -char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm) +char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm, int64_t gas, int64_t gasPrice, uint8_t defaultGasOnErr) { TransactionSkeleton tx; char *from = privKey2Addr(privKey), *result; tx.from = jsToAddress(from); tx.to = jsToAddress(to); tx.value = jsToU256(amount); - tx.gas = 21000; - tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9); tx.nonce = getNonce(from); free(from); + if (gas > 0) { + tx.gas = gas; + } else { + tx.gas = 21000; + } + if (gasPrice > 0) { + tx.gasPrice = gasPrice * boost::multiprecision::pow(u256(10), 9); + } else { + tx.gasPrice = getGasPriceFromStation(defaultGasOnErr) * boost::multiprecision::pow(u256(10), 9); + if (tx.gasPrice == 0 && !defaultGasOnErr) { + printf("Could not get gas price from station!\n"); + unlock_send_tx_mutex(); + return NULL; + } + } char *rawTx = signTx(tx, privKey); if (waitConfirm == 0) { @@ -604,10 +707,15 @@ char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm) return result; } -std::stringstream getErc20TransferData(char *tokenAddress, char *to, char *amount) +std::stringstream getErc20TransferData(char *tokenAddress, char *to, char *amount, uint8_t setDecimals) { u256 amountWei = jsToU256(amount); - uint8_t decimals = getErc20Decimals(tokenAddress); + uint8_t decimals; + if (setDecimals > 0) { + decimals = setDecimals; + } else { + decimals = getErc20Decimals(tokenAddress); + } if (decimals < 18) { amountWei /= boost::multiprecision::pow(u256(10), 18 - decimals); } @@ -620,19 +728,64 @@ std::stringstream getErc20TransferData(char *tokenAddress, char *to, char *amoun return ss; } -char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8_t waitConfirm) +uint64_t estimate_erc20_gas( + char *tokenAddress, + char *to, + char *amount, + char *privKey, + uint8_t decimals +) +{ + std::stringstream ss = getErc20TransferData(tokenAddress, to, amount, decimals); + char *from = privKey2Addr(privKey); + uint64_t result = estimateGas(from, tokenAddress, ss.str().c_str()); + free(from); + return result; +} + +char *sendErc20( + char *tokenAddress, + char *to, + char *amount, + char *privKey, + uint8_t waitConfirm, + int64_t gas, + int64_t gasPrice, + uint8_t defaultGasOnErr, + uint8_t decimals +) { TransactionSkeleton tx; char *from = privKey2Addr(privKey), *result; + std::stringstream ss = getErc20TransferData(tokenAddress, to, amount, decimals); + tx.from = jsToAddress(from); tx.to = jsToAddress(tokenAddress); tx.value = 0; - tx.gas = 60000; - tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9); tx.nonce = getNonce(from); + + if (gas > 0) { + tx.gas = gas; + } else { + uint64_t gasEstimation = estimateGas(from, tokenAddress, ss.str().c_str()); + if (gasEstimation > 0) { + tx.gas = gasEstimation; + } else { + tx.gas = 150000; + } + } free(from); + if (gasPrice > 0) { + tx.gasPrice = gasPrice * boost::multiprecision::pow(u256(10), 9); + } else { + tx.gasPrice = getGasPriceFromStation(defaultGasOnErr) * boost::multiprecision::pow(u256(10), 9); + if (tx.gasPrice == 0 && !defaultGasOnErr) { + printf("Could not get gas price from station!\n"); + unlock_send_tx_mutex(); + return NULL; + } + } - std::stringstream ss = getErc20TransferData(tokenAddress, to, amount); tx.data = jsToBytes(ss.str()); char *rawTx = signTx(tx, privKey); @@ -645,12 +798,61 @@ char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8 return result; } -uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data) +uint8_t verifyAliceErc20FeeData(char *tokenAddress, char *to, char *amount, char *data, uint8_t decimals) { - std::stringstream ss = getErc20TransferData(tokenAddress, to, amount); + std::stringstream ss = getErc20TransferData(tokenAddress, to, amount, decimals); if (strcmp(ss.str().c_str(), data) != 0) { printf("Alice ERC20 fee data %s is not equal to expected %s\n", data, ss.str().c_str()); return 0; } return 1; } + +uint8_t alicePaymentStatus(char *paymentId) +{ + char buffer[100]; + memset(buffer, 0, sizeof(buffer)); + strcpy(buffer, "0x81cd872a"); + strcat(buffer, paymentId); + char *hexStatus = ethCall(ETOMIC_ALICECONTRACT, buffer); + auto status = (uint8_t) strtol(hexStatus + 66, NULL, 0); + free(hexStatus); + return status; +} + +uint8_t bobDepositStatus(char *depositId) +{ + char buffer[100]; + memset(buffer, 0, sizeof(buffer)); + strcpy(buffer, "0x3d4dff7b"); + strcat(buffer, depositId); + char *hexStatus = ethCall(ETOMIC_BOBCONTRACT, buffer); + auto status = (uint8_t) strtol(hexStatus + 130, NULL, 0); + free(hexStatus); + return status; +} + +uint8_t bobPaymentStatus(char *paymentId) +{ + char buffer[100]; + memset(buffer, 0, sizeof(buffer)); + strcpy(buffer, "0x0716326d"); + strcat(buffer, paymentId); + char *hexStatus = ethCall(ETOMIC_BOBCONTRACT, buffer); + auto status = (uint8_t) strtol(hexStatus + 130, NULL, 0); + free(hexStatus); + return status; +} + +uint8_t compareAddresses(char *address1, char *address2) +{ + auto addr_bytes_1 = jsToAddress(address1); + auto addr_bytes_2 = jsToAddress(address2); + return static_cast(addr_bytes_1 == addr_bytes_2); +} + +uint8_t isValidAddress(char *address) +{ + std::regex r("^(0x|0X)?[a-fA-F0-9]{40}$"); + return static_cast(std::regex_match(address, r)); +} diff --git a/iguana/exchanges/etomicswap/etomiclib.h b/iguana/exchanges/etomicswap/etomiclib.h index c7b846ddb..6075124a5 100644 --- a/iguana/exchanges/etomicswap/etomiclib.h +++ b/iguana/exchanges/etomicswap/etomiclib.h @@ -38,6 +38,7 @@ typedef struct { char bobAddress[65]; char aliceHash[65]; char bobHash[65]; + uint8_t decimals; } AliceSendsErc20PaymentInput; typedef struct { @@ -47,6 +48,7 @@ typedef struct { char bobAddress[65]; char aliceHash[65]; char bobSecret[70]; + uint8_t decimals; } AliceReclaimsAlicePaymentInput; typedef struct { @@ -56,6 +58,7 @@ typedef struct { char aliceAddress[65]; char aliceSecret[70]; char bobHash[65]; + uint8_t decimals; } BobSpendsAlicePaymentInput; typedef struct { @@ -72,6 +75,7 @@ typedef struct { char aliceAddress[65]; char bobHash[65]; uint64_t lockTime; + uint8_t decimals; } BobSendsErc20DepositInput; typedef struct { @@ -80,6 +84,7 @@ typedef struct { char tokenAddress[65]; char aliceAddress[65]; char bobSecret[70]; + uint8_t decimals; } BobRefundsDepositInput; typedef struct { @@ -88,6 +93,7 @@ typedef struct { char tokenAddress[65]; char bobAddress[65]; char bobHash[65]; + uint8_t decimals; } AliceClaimsBobDepositInput; typedef struct { @@ -104,6 +110,7 @@ typedef struct { char aliceAddress[65]; char aliceHash[65]; uint64_t lockTime; + uint8_t decimals; } BobSendsErc20PaymentInput; typedef struct { @@ -112,6 +119,7 @@ typedef struct { char tokenAddress[65]; char aliceAddress[65]; char aliceHash[65]; + uint8_t decimals; } BobReclaimsBobPaymentInput; typedef struct { @@ -120,6 +128,7 @@ typedef struct { char tokenAddress[65]; char aliceSecret[70]; char bobAddress[65]; + uint8_t decimals; } AliceSpendsBobPaymentInput; typedef struct { @@ -164,24 +173,50 @@ char* pubKey2Addr(char* pubKey); char* getPubKeyFromPriv(char* privKey); // returns satoshis, not wei! -uint64_t getEthBalance(char* address); -uint64_t getErc20BalanceSatoshi(char* address, char tokenAddress[65]); +uint64_t getEthBalance(char* address, int *error); +uint64_t getErc20BalanceSatoshi(char *address, char *tokenAddress, uint8_t setDecimals, int *error); char *getErc20BalanceHexWei(char* address, char tokenAddress[65]); uint8_t getErc20Decimals(char *tokenAddress); // returns satoshis, not wei! -uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress); +uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress, uint8_t set_decimals); void uint8arrayToHex(char *dest, uint8_t *input, int len); void satoshisToWei(char *dest, uint64_t input); uint64_t weiToSatoshi(char *wei); -char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm); -char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8_t waitConfirm); +char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm, int64_t gas, int64_t gasPrice, uint8_t defaultGasOnErr); +char *sendErc20( + char *tokenAddress, + char *to, + char *amount, + char *privKey, + uint8_t waitConfirm, + int64_t gas, + int64_t gasPrice, + uint8_t defaultGasOnErr, + uint8_t decimals +); + +uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data, uint8_t decimals); + +uint8_t alicePaymentStatus(char *paymentId); +uint8_t bobDepositStatus(char *depositId); +uint8_t bobPaymentStatus(char *paymentId); + +uint64_t estimate_erc20_gas( + char *tokenAddress, + char *to, + char *amount, + char *privKey, + uint8_t decimals +); + +uint8_t compareAddresses(char *address1, char *address2); +uint8_t isValidAddress(char *address); +uint8_t getErc20DecimalsZeroOnError(char *tokenAddress); -uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data); -// Your prototype or Definition #ifdef __cplusplus } #endif diff --git a/iguana/exchanges/gen64addrs b/iguana/exchanges/gen64addrs new file mode 100755 index 000000000..d907807dd --- /dev/null +++ b/iguana/exchanges/gen64addrs @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"gen64addrs\",\"passphrase\":\"default\"}" diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index aa0866b07..304ca6aa9 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -164,6 +164,7 @@ int main(int argc, const char * argv[]) { char dirname[512]; double incr; cJSON *retjson; OS_init(); + printf("BarterDEX Marketmaker %s \n",MM_VERSION); if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 ) { bits256 privkey,checkkey; uint8_t tmptype; char kmdwif[64],str[65],str2[65],*retstr; @@ -346,6 +347,12 @@ int main(int argc, const char * argv[]) printf("couldnt write to (%s)\n",dirname); exit(0); } + sprintf(dirname,"%s/GTC",GLOBAL_DBDIR), OS_ensure_directory(dirname); + if ( ensure_writable(dirname) < 0 ) + { + printf("couldnt write to (%s)\n",dirname); + exit(0); + } sprintf(dirname,"%s/PRICES",GLOBAL_DBDIR), OS_ensure_directory(dirname); if ( ensure_writable(dirname) < 0 ) { diff --git a/iguana/exchanges/mm2.md b/iguana/exchanges/mm2.md new file mode 100644 index 000000000..b88dfb815 --- /dev/null +++ b/iguana/exchanges/mm2.md @@ -0,0 +1,102 @@ +# Market Maker 2 + +This document will help us track the information related to the MarketMaker Rust rewrite. + +## Rewrite goals + +Rewrites and ports +[are costly](http://nibblestew.blogspot.com/2017/04/why-dont-you-just-rewrite-it-in-x.html). +We tend to think that porting is simple, and on some level this intuition is true +because we can skip some high-level design decisions and focus on translating the existing logic, +but it still takes a lot of time +and though we don't need to make some of the new design decisions, +we might spend no less effort to reverse-engineer and understand the old ones. + +So why the rewrite then? + +Carol, in her talk about rewrites, offers some possible reasons: + +"*If* you have some code in C or another language, and need to change it, or it’s slow, or it crashes a +lot, or no one understands it anymore, THEN maybe a rewrite in Rust would be a good fit. +I would also posit that more people are *able* to write production Rust than production C, so if your +team *is* willing to learn Rust, it might actually expand the number of +maintainers." - https://github.com/carols10cents/rust-out-your-c-talk, https://www.youtube.com/watch?v=SKGVItFlK3w. + +And we have some of these: + +* We *need to change* the MarketMaker: +A more approachable and reliable API. +Ability to embed the MarketMaker in the GUI applications. +Ways to more easily deploy it at home by running it from small computers like on a spare mobile phone or on a Raspberry Pi 3. +Ability to process multiple API calls in parallel. +A faster version of the `swapstatus` API call. + +* The MarketMaker *crashes a lot*, +to quote hyperDEX: "The biggest issue with the MM right now, is bobs crash or does not have the orders in users orderbook, or when users try to do a order it doesnt work or goes unmatched or other random stuff" +and lukechilds: "We've frequently experienced crashes while querying all swaps with swapstatus". +We want it to be stable and reliable instead. + +## Purely functional core + +One of our goals is to make the MarketMaker 2 more +[stable and reliable](https://softwareengineering.stackexchange.com/questions/158054/stability-vs-reliability). +We want it to crash less often. +If there was a failure, we want to simplify and preferably automate recovery. +And we want to reduce the time between a failure and a fix. + +We'll make a big step towards these goals if the core of the MarketMaker is purely functional. +That is, if we can untangle the *state* of the MarketMaker from the code operating on that state. + +The benefits we want to reap from this are: +* Transparency. Some bugs are hard to fix because we don't have enough information about them. We might be lucky to have been running the program in a debugger or finding the necessary bits it verbose logs, but more often than not this is not the case: we know that a failure has happened, but have no idea where and on what input. Separating the state from the code allows the state to be easily shared with a developer, which means much faster roundtrips between discovering a failure and fixing it. +* Replayability. Having a separate state allows us to easily replay any operation. If a failure occured in the middle of a transaction, it should be possible to try a new version of the code without manually repeating all the steps that were necessary to initiate the transaction. And the updated code will run exactly on the failing transaction, not on some other transaction initiated at a later time, which means that users will benefit from less friction and developers will have a better chance to fix the hard-to-reproduce bugs. +* Testability. Stateless code is much easier to test and according to Kent Beck is often a natural result of a Test-Driven development process. +* Portability. Separating the state from the code allows us to more easily use the stateless parts from the sandboxed environments, such as when running under the Web Assembly (WASM). We only need to port the state-managing layer, fully reusing the stateless code. +* Hot reloading. When the code is separated from state, it's trivial to reload it, both with the shared libraries in CPU-native environments (dlopen) and with WASM in GUI environments. This might positively affect the development cycle, reducing the round-trip time from a failure to a fix. +* Concurrency. MarketMaker can currently only perform a single API operation at the time. The more stateless code we have the easier it should be to introduce the parallel execution of API requests in the future. + +Implementation might consist of two layers. +A layer that is ported to the host environment (native, JS, Java, Objective-C, cross-compiled Raspberry Pi 3, etc) and implements the TCP/IP communication, state management, hot reloading, all things that won't fit into the WASM sandbox. +And a layer that implements the core logic in a stateless manner and which is compiled into a native shared library or, in the future, to WASM. + +Parts of the state might be marked as sensitive. +This will give the users an option to share only the information that can be freely shared, +without a risk of loosing money that is. +Even without the sensitive information a state snapshot might provide the developer with enough data to quickly triage and/or fix the failure, therefore improving the roundtrip time before a failure and a fix. +Plus users will more easily share their problems when it's quick, automatic and doesn't pose a monetary risk. + +The feasibility of this approach is yet to be evaluated, but we can move gradually towards it +by separating the code into the stateful and stateless layers while working on the basic Rust port. + +During the initial Rust port we're going to +a) Mark the ported functions as purely functional or stateful, allowing us to more easily focus on the state management code in the future. +b) Where possible, take a low-hanging fruit and try to refactor the functions towards being stateless. +c) Probably mark as stateful the `sleep`ing functions, because `sleep` can be seen as changing the global state (moving the time forwards) and might negatively affect Transparency (we have no idea what's going on while a function is sleeping), Testability (sleeping tests might kill the TDD development cycle), Portability (sleeps are not compatible with WASM), Hot reloading and Concurrency (let's say we want to load new version of the code, but the old version is still sleeping somewhere). + +## Gradual rewrite + +Above in the [Rewrite goals](#rewrite-goals) section we have identified some of the goals that we pursue with this rewrite. +These goals constitute the Value (in the Lean Production terms) that we are going to create. + +For a project to suceed it is usually important to make shorter the path the Value takes to the users. +(Inventory is waste. If we have created the Value but the users can't get their hands on it, we're wasting that Value). + +Hence we're going to start with a gradual rewrite. Keeping the version under rewrite immediately avaliable to the users willing to experiment with it. + +Let's list the good things that should come out of the gradual rewrite: +* Transparency. With the second version of the MarketMaker being immediately available we can always check the Value we're getting. Is it more stable? Does it have new functions? Or did we hit the wall? What's going on with the code and how can we help? Gradual rewrite is critical for transparency because the change is available in small increments. We can more easily see what function has changed or what new functionality was added when we aren't being uprooted from the familiar context. +* Risk reduction. It comes with transparency, as we can now more easily measure the progress, identify the roadblocks as they occur, see certain problems when they occur and not months after. Plus a gradual rewrite will by default follow the outline of the original project. We have a working system and we're improving it piece by piece, having the original design to fall back to. This makes it less likely for the rewrite to suffer from far-reaching redesign flaws (cf. [Second-system effect](https://en.wikipedia.org/wiki/Second-system_effect)) and creative blocks (cf. [Pantsing](https://www.wikiwrimo.org/wiki/Pantsing)). +* Feedback. Incorporating user feedback is critical for most projects out there, allowing us to iteratively improve the functionality in the right direction (cf. [Fail faster](https://www.youtube.com/watch?v=rDjrOaoHz9s), [PDIA](https://www.youtube.com/watch?v=ZKdjBbiGjao)). The more early we get the feedback, the more time we have to react, and at a lesser cost. +* Motivation. Feedback is not only important to guide us, but also to show us that our work is meaningful and changes lives to the better. It is the cornerstone of Agile (["Build projects around motivated individuals"](https://www.agilealliance.org/agile101/12-principles-behind-the-agile-manifesto/)) and affects our performance on all levels, down to the physical health. + +The plan so far is to by default use the C functions as the atomic units of rewrite. +Rust FFI allows us to swap any C function with a similar Rust function. +Porting on this level we +* reuse the function-level modularity of the C language; +* preserve the code meta-data (Git history will show a nice diff between the C and Rust functions, we'll be able to easily investigate the evolution of the code back to its roots); +* avoid the complexity and slow-downs associated with adding RPC/networking layers or drawing new lines of abstraction; +* have a good indicator of the porting progress (how many functions were ported, how many remains). + +Focusing on the function call chains that are a common part of a failure/crash or touch on the new functionality +will allow us to leverage the [Pareto principle](https://en.wikipedia.org/wiki/Pareto_principle), +advancing on 80% of desired Value (stability, functionality) with 20% of initial effort. \ No newline at end of file diff --git a/iguana/exchanges/mshark b/iguana/exchanges/mshark index 0d6260aad..fa3ae0a64 100755 --- a/iguana/exchanges/mshark +++ b/iguana/exchanges/mshark @@ -1,4 +1,4 @@ #!/bin/bash source userpass # this will only work for watchonly addresses that have been rescanned and with active coins -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC\",\"holdings\":[{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"bitcoin-cash\",\"balance\":1200}, {\"coin\":\"bitcoin\",\"balance\":100}, {\"coin\":\"komodo\",\"balance\":100000}, {\"coin\":\"chips\",\"balance\":100000}],\"divisor\":1400000}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC\",\"holdings\":[{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"bitcoin-cash\",\"balance\":1200}, {\"coin\":\"bitcoin\",\"balance\":25}],\"divisor\":1400000}" diff --git a/iguana/exchanges/prices/autoprice b/iguana/exchanges/prices/autoprice index 2e4b5dadb..8092b2bb2 100755 --- a/iguana/exchanges/prices/autoprice +++ b/iguana/exchanges/prices/autoprice @@ -35,15 +35,15 @@ source trackbtc #source revs #source trackbtc -sharkholdings="{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"komodo\",\"balance\":120000}, {\"coin\":\"bitcoin-cash\",\"balance\":1200}, {\"coin\":\"bitcoin\",\"balance\":100}" +sharkholdings="{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"bitcoin-cash\",\"balance\":1200}, {\"coin\":\"bitcoin\",\"balance\":25}" curl --url "http://127.0.0.1:7783" --data "{\"base\":\"MSHARK\",\"rel\":\"KMD\",\"fundvalue_bid\":\"NAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"margin\":$margin,\"address\":\"RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC\",\"holdings\":[$sharkholdings],\"divisor\":1400000}" -curl --url "http://127.0.0.1:7783" --data "{\"margin\":$margin,\"base\":\"SUPERNET\",\"rel\":\"KMD\",\"fundvalue_bid\":\"NAV_KMD\",\"fundvalue_ask\":\"NAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":0.10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":570}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":0.20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":0.150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":0.375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }, {\"coin\":\"utrum\",\"balance\":2100000}],\"divisor\":612529}" +curl --url "http://127.0.0.1:7783" --data "{\"margin\":$margin,\"base\":\"SUPERNET\",\"rel\":\"KMD\",\"fundvalue_bid\":\"NAV_KMD\",\"fundvalue_ask\":\"NAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":0.10000}, {\"coin\":\"syscoin\",\"balance\":0.20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":540}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":0.20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":0.150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":0.375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }, {\"coin\":\"utrum\",\"balance\":2100000}, {\"coin\":\"verus\",\"balance\":65000}],\"divisor\":777777}" curl --url "http://127.0.0.1:7783" --data "{\"margin\":$margin,\"base\":\"HODL\",\"rel\":\"KMD\",\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RNcUaMUEFLxVwtTo7rgruhwYanGk1jTkeU\",\"holdings\":[{\"coin\":\"siacoin\",\"balance\":185000000,\"comment\":\"using siafunds equal to million siacoin\"}],\"divisor\":10000000}" -dexholdings="{\"coin\":\"blocknet\",\"balance\":2500000}" +dexholdings="{\"coin\":\"blocknet\",\"balance\":2000000}" curl --url "http://127.0.0.1:7783" --data "{\"base\":\"DEX\",\"rel\":\"KMD\",\"margin\":$margin,\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf\",\"holdings\":[$dexholdings],\"divisor\":1000000}" curl --url "http://127.0.0.1:7783" --data "{\"base\":\"BOTS\",\"rel\":\"KMD\",\"margin\":$margin,\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RNdqHx26GWy9bk8MtmH1UiXjQcXE4RKK2P\",\"holdings\":[$dexholdings],\"divisor\":3333333}" diff --git a/iguana/exchanges/supernet b/iguana/exchanges/supernet index 1b55eee6e..e7e11b43f 100755 --- a/iguana/exchanges/supernet +++ b/iguana/exchanges/supernet @@ -15,5 +15,5 @@ echo supernet curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}" echo supernet -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":0.10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":570}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":0.20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":0.150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":0.375000}, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }, {\"coin\":\"utrum\",\"balance\":2100000}],\"divisor\":612529}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":0.10000}, {\"coin\":\"syscoin\",\"balance\":0.20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":540}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":0.20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":0.150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":0.375000}, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }, {\"coin\":\"utrum\",\"balance\":2350000}, {\"coin\":\"verus\",\"balance\":65000}],\"divisor\":777777}" diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 7e2906963..8c88ec624 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -1131,7 +1131,7 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, if ( coin->MAXMEM == 0 ) coin->MAXMEM = IGUANA_DEFAULTRAM; coin->MAXMEM *= (1024L * 1024 * 1024); - coin->enableCACHE = 0;//(strcmp("BTCD",coin->symbol) == 0); + coin->enableCACHE = 1;//0;//(strcmp("BTCD",coin->symbol) == 0); if ( jobj(json,"cache") != 0 ) coin->enableCACHE = juint(json,"cache"); if ( (coin->polltimeout= juint(json,"poll")) <= 0 ) diff --git a/iguana/iguana_notary.c b/iguana/iguana_notary.c index 2963dcfe2..6b6bf86f1 100755 --- a/iguana/iguana_notary.c +++ b/iguana/iguana_notary.c @@ -430,13 +430,11 @@ THREE_STRINGS_AND_DOUBLE(iguana,dpow,symbol,dest,pubkey,freq) portable_mutex_init(&dp->paxmutex); portable_mutex_init(&dp->dexmutex); PAX_init(); - //printf(">>>>>>>>>>>>>>> call paxpending\n"); - //uint8_t buf[32768]; - //dpow_paxpending(buf); + dp->fullCCid = dpow_CCid(myinfo,src); myinfo->numdpows++; for (i=0; i<33; i++) printf("%02x",dp->minerkey33[i]); - printf(" DPOW with pubkey.(%s) %s.valid%d %s -> %s %s.valid%d, num.%d freq.%d minsigs.%d\n",tmp,srcaddr,srcvalid,dp->symbol,dp->dest,destaddr,destvalid,myinfo->numdpows,dp->freq,dp->minsigs); + printf(" DPOW with pubkey.(%s) %s.valid%d %s -> %s %s.valid%d, num.%d freq.%d minsigs.%d CCid.%u\n",tmp,srcaddr,srcvalid,dp->symbol,dp->dest,destaddr,destvalid,myinfo->numdpows,dp->freq,dp->minsigs,dp->fullCCid); return(clonestr("{\"result\":\"success\"}")); } @@ -537,7 +535,7 @@ STRING_ARG(iguana,addnotary,ipaddr) } char NOTARY_CURRENCIES[][65] = { - "REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "BOTS", "MGW", "COQUI", "WLC", "KV", "CEAL", "MESH", "MNZ", "CHIPS", "MSHARK", "AXO", "ETOMIC", "BTCH", "VOTE2018", "NINJA", "OOT", "CHAIN", "BNTN", "PRLPAY", "DSEC", "GLXT", "EQL" + "REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "BOTS", "MGW", "COQUI", "WLC", "KV", "CEAL", "MESH", "MNZ", "CHIPS", "MSHARK", "AXO", "ETOMIC", "BTCH", "VOTE2018", "NINJA", "OOT", "CHAIN", "BNTN", "PRLPAY", "DSEC", "GLXT", "EQL", "ZILLA", "RFOX", "SEC", "CCL" }; // "LTC", "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", @@ -958,6 +956,18 @@ ZERO_ARGS(dpow,cancelratify) return(clonestr("{\"result\":\"queued dpow cancel ratify\"}")); } +ZERO_ARGS(dpow,ipaddrs) +{ + char ipaddr[64]; cJSON *array; int32_t i; + array = cJSON_CreateArray(); + for (i=0; inumdpowipbits; i++) + { + expand_ipbits(ipaddr,myinfo->dpowipbits[i]); + jaddistr(array,ipaddr); + } + return(jprint(array,1)); +} + TWOINTS_AND_ARRAY(dpow,ratify,minsigs,timestamp,ratified) { void **ptrs; bits256 zero; int32_t i; char *source; struct dpow_checkpoint checkpoint; diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index a7b83cd45..0f1b9527e 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1015,7 +1015,7 @@ int32_t iguana_ramchain_alloc(char *fname,struct iguana_info *coin,struct iguana char str[65],str2[65]; fprintf(stderr,"ht.%d wait for allocated %s < MAXMEM %s | elapsed %.2f minutes hashsize.%ld allocsize.%ld\n",height,mbstr(str,myallocated(0,-1)+hashsize+allocsize),mbstr(str2,coin->MAXMEM),(double)(time(NULL)-coin->startutc)/60.,(long)hashsize,(long)allocsize); sleep(13); } - iguana_meminit(hashmem,"ramhashmem",0,2*hashsize + 65536,0); + iguana_meminit(hashmem,"ramhashmem",0,3*hashsize + 65536,0); iguana_meminit(mem,"ramchain",0,allocsize + 65536,0); mem->alignflag = sizeof(uint32_t); hashmem->alignflag = sizeof(uint32_t); diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index 9caeac6d5..d633ff569 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -1402,7 +1402,7 @@ TWOSTRINGS_AND_INT(bitcoinrpc,walletpassphrase,password,permanentfile,timeout) THREE_STRINGS(bitcoinrpc,encryptwallet,passphrase,password,permanentfile) { - char *retstr,buf[128],wifstr[128]; cJSON *retjson; int32_t need_KMD = 0,need_BTC = 0,need_GAME = 0; + char *retstr,buf[128],wifstr[128]; cJSON *retjson; int32_t need_HUSH = 0,need_KMD = 0,need_BTC = 0,need_GAME = 0; if ( remoteaddr != 0 || coin == 0 ) return(clonestr("{\"error\":\"no remote encrypt or no coin\"}")); iguana_walletlock(myinfo,coin); @@ -1441,11 +1441,18 @@ THREE_STRINGS(bitcoinrpc,encryptwallet,passphrase,password,permanentfile) need_BTC = 1; if ( strcmp(coin->symbol,"GAME") != 0 ) need_GAME = 1; + if ( strcmp(coin->symbol,"HUSH") != 0 ) + need_HUSH = 1; if ( need_KMD != 0 && (coin= iguana_coinfind("KMD")) != 0 ) { bitcoin_priv2wif(wifstr,waddr.privkey,coin->chain->wiftype); jaddstr(retjson,"KMDwif",wifstr); } + if ( need_HUSH != 0 && (coin= iguana_coinfind("HUSH")) != 0 ) + { + bitcoin_priv2wif(wifstr,waddr.privkey,coin->chain->wiftype); + jaddstr(retjson,"HUSHwif",wifstr); + } if ( (coin= iguana_coinfind("LTC")) != 0 ) { bitcoin_priv2wif(wifstr,waddr.privkey,coin->chain->wiftype); diff --git a/iguana/m_notary b/iguana/m_notary index 9eff95e6b..c23e6f7d1 100755 --- a/iguana/m_notary +++ b/iguana/m_notary @@ -2,4 +2,4 @@ pkill -15 iguana rm -f ../agents/iguana *.o git pull -./m_notary_run $1 +./m_notary_run "$1" "$2" diff --git a/iguana/m_notary_run b/iguana/m_notary_run index 7e0d24480..fde6f4db9 100755 --- a/iguana/m_notary_run +++ b/iguana/m_notary_run @@ -8,7 +8,8 @@ clang -g -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../b clang -g -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm -stdbuf -oL $1 ../agents/iguana notary & #> iguana.log 2> error.log & +iguana_arg=${2:-notary} +stdbuf -oL $1 ../agents/iguana $iguana_arg & #> iguana.log 2> error.log & myip=`curl -s4 checkip.amazonaws.com` source pubkey.txt @@ -16,14 +17,31 @@ source pubkey.txt 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\":\"167.99.67.33\"}" 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\":\"95.213.238.98\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"82.202.193.98\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"82.202.193.100\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"54.95.68.31\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"142.54.164.114\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"103.6.12.111\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"155.254.17.21\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"138.121.203.210\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"139.99.149.41\"}" curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"209.58.169.65\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"5.189.232.34\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"46.4.33.66\"}" + +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"66.70.180.46\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"88.99.251.101\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"139.99.121.200\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"52.65.58.103\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"159.65.134.48\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"178.128.25.203\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"217.182.203.106\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"149.56.19.212\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"95.213.205.222\"}" + #tests/addnotarys_7776 coins/btc_7776 @@ -62,6 +80,11 @@ coins/prlpay_7776 coins/dsec_7776 coins/glxt_7776 coins/eql_7776 +coins/zilla_7776 +coins/vrsc_7776 +coins/rfox_7776 +coins/sec_7776 +coins/ccl_7776 #curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"passthru\",\"method\":\"paxfiats\",\"timeout\":900000}" diff --git a/iguana/m_splitfund b/iguana/m_splitfund index f82201432..3cf6d6e9b 100755 --- a/iguana/m_splitfund +++ b/iguana/m_splitfund @@ -35,3 +35,7 @@ curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CHAIN\",\"agent\":\"iguan curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DSEC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"GLXT\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"EQL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ZILLA\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RFOX\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SEC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CCL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" diff --git a/iguana/mini-gmp.c b/iguana/mini-gmp.c index 99cb68222..a40341c1b 100644 --- a/iguana/mini-gmp.c +++ b/iguana/mini-gmp.c @@ -4403,7 +4403,7 @@ int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr) if ( *p != '\0' ) { int32_t zeroval(); - printf("bitcoin_base58decode error: p %02x != 0x00\n",*p); + //printf("bitcoin_base58decode error: p %02x != 0x00\n",*p); mpz_clear(bn), mpz_clear(bn58); return(-1); } diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index 46db910d3..e8111a12a 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -27,6 +27,7 @@ TWOINTS_AND_ARRAY(dpow,ratify,minsigs,timestamp,ratified); ZERO_ARGS(dpow,cancelratify); STRING_ARG(dpow,bindaddr,ipaddr); STRING_AND_INT(dpow,fundnotaries,symbol,numblocks); +ZERO_ARGS(dpow,ipaddrs); ZERO_ARGS(pax,start); INT_ARG(passthru,paxfiats,mask); diff --git a/marketmaker_build_depends.cmd b/marketmaker_build_depends.cmd index a09e0ea04..6a294d20c 100644 --- a/marketmaker_build_depends.cmd +++ b/marketmaker_build_depends.cmd @@ -36,54 +36,66 @@ exit rem MSBuild /help echo. echo Decker will automatically download and build all needed *.dll and *.lib for you ;) -timeout /t 5 /nobreak mkdir marketmaker_depends mkdir x64\Release rem --- pthreads --- :compile_pthreads +if not exist marketmaker_depends\pthread-win32\bin\x64_MSVC2015.Release\pthread_lib.lib ( cd marketmaker_depends git clone https://github.com/DeckerSU/pthread-win32 cd pthread-win32 MSBuild pthread.2015.sln /t:Rebuild /p:Configuration=Release /p:Platform=Win32 MSBuild pthread.2015.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64 cd ../.. +) copy marketmaker_depends\pthread-win32\bin\x64_MSVC2015.Release\pthread_lib.lib OSlibs\win\x64\pthread_lib.lib rem --- nanomsg --- :compile_nanomsg - -cd marketmaker_depends -git clone https://github.com/nanomsg/nanomsg -cd nanomsg -mkdir build_msvc_2015_win32 -mkdir build_msvc_2015_win64 -cd build_msvc_2015_win64 -cmake -G "Visual Studio 14 2015 Win64" .. -cmake --build . --config Release --target nanomsg -cd ../../.. +if not exist marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.lib ( + if not exist marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.exp ( + if not exist marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.dll ( + cd marketmaker_depends + git clone https://github.com/nanomsg/nanomsg + cd nanomsg + mkdir build_msvc_2015_win32 + mkdir build_msvc_2015_win64 + cd build_msvc_2015_win64 + cmake -G "Visual Studio 14 2015 Win64" .. + cmake --build . --config Release --target nanomsg + cd ../../.. + ) + ) +) copy marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.lib OSlibs\win\x64\release\nanomsg.lib copy marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.exp OSlibs\win\x64\release\nanomsg.exp copy marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.dll x64\Release\nanomsg.dll rem --- curl --- :compile_curl -cd marketmaker_depends -git clone https://github.com/curl/curl -cd curl -mkdir build_msvc_2015_win32 -mkdir build_msvc_2015_win64 -cd build_msvc_2015_win64 -cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_USE_WINSSL:BOOL=ON .. -cmake --build . --config Release --target libcurl +if not exist marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.lib ( + if not exist marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.exp ( + if not exist marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl.dll ( + cd marketmaker_depends + git clone https://github.com/curl/curl + cd curl + mkdir build_msvc_2015_win32 + mkdir build_msvc_2015_win64 + cd build_msvc_2015_win64 + cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_USE_WINSSL:BOOL=ON .. + cmake --build . --config Release --target libcurl -rem cmake .. -G"Visual Studio 14 2015 Win64" -DCURL_STATICLIB=ON -DCURL_DISABLE_LDAP=ON -DCURL_STATIC_CRT=ON -rem cmake .. -G"Visual Studio 14 2015 Win64" -DCURL_STATICLIB:BOOL=ON -DCURL_STATIC_CRT:BOOL=ON -DHTTP_ONLY:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=RELEASE .. -rem cmake --build . --config Release -rem cmake --build . --config Release --target libcurl + rem cmake .. -G"Visual Studio 14 2015 Win64" -DCURL_STATICLIB=ON -DCURL_DISABLE_LDAP=ON -DCURL_STATIC_CRT=ON + rem cmake .. -G"Visual Studio 14 2015 Win64" -DCURL_STATICLIB:BOOL=ON -DCURL_STATIC_CRT:BOOL=ON -DHTTP_ONLY:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=RELEASE .. + rem cmake --build . --config Release + rem cmake --build . --config Release --target libcurl -cd ../../.. + cd ../../.. + ) + ) +) copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.lib OSlibs\win\x64\release\libcurl.lib copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.exp OSlibs\win\x64\release\libcurl.exp copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl.dll x64\Release\libcurl.dll \ No newline at end of file diff --git a/marketmaker_build_etomic.cmd b/marketmaker_build_etomic.cmd index ed76db72c..2b8f9a02d 100644 --- a/marketmaker_build_etomic.cmd +++ b/marketmaker_build_etomic.cmd @@ -7,16 +7,13 @@ copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.lib copy marketmaker_depends\pthread-win32\bin\x64_MSVC2015.Release\pthread_lib.lib marketmaker_depends\pthread-win32\bin\x64_MSVC2015.Release\pthread.lib echo [#2] Prepare build etomic needed things ... -git submodule init git submodule update --init --recursive cd cpp-ethereum -rem git submodule init -rem git submodule update --init -call scripts\install_deps.bat +call scripts\install_deps.bat cd .. mkdir build_win64_release cd build_win64_release -cmake .. -G "Visual Studio 14 2015 Win64" +cmake .. -G "Visual Studio 14 2015 Win64" -DMM_VERSION="%APPVEYOR_BUILD_VERSION%" rem Steps before build: rem diff --git a/start_BEER_OTHER_trade.sh b/start_BEER_OTHER_trade.sh new file mode 100755 index 000000000..a81500397 --- /dev/null +++ b/start_BEER_OTHER_trade.sh @@ -0,0 +1,8 @@ +#!/bin/bash +docker-compose exec -T clientnode ./enable +sleep 3 +docker-compose exec -T seednode ./enable +sleep 3 +docker-compose exec -T seednode ./sell_BEER_OTHER $1 +sleep 3 +docker-compose exec -T clientnode ./buy_BEER_OTHER $1 \ No newline at end of file diff --git a/start_BEER_OTHER_trade_inverted.sh b/start_BEER_OTHER_trade_inverted.sh new file mode 100755 index 000000000..1b0f9d4be --- /dev/null +++ b/start_BEER_OTHER_trade_inverted.sh @@ -0,0 +1,8 @@ +#!/bin/bash +docker-compose exec -T clientnode ./enable +sleep 3 +docker-compose exec -T seednode ./enable +sleep 3 +docker-compose exec -T clientnode ./buy_BEER_OTHER $1 +sleep 3 +docker-compose exec -T seednode ./sell_BEER_OTHER $1 \ No newline at end of file diff --git a/travis_cmake_linux.sh b/travis_cmake_linux.sh new file mode 100644 index 000000000..f11b08e4d --- /dev/null +++ b/travis_cmake_linux.sh @@ -0,0 +1,5 @@ +#!/bin/bash +sudo rm -rf /usr/local/cmake-3.9.2 && sudo rm -rf /usr/local/cmake +wget https://cmake.org/files/v3.12/cmake-3.12.0-rc2-Linux-x86_64.sh +chmod +x cmake-3.12.0-rc2-Linux-x86_64.sh +sudo ./cmake-3.12.0-rc2-Linux-x86_64.sh --skip-license --exclude-subdir --prefix=/usr/local \ No newline at end of file diff --git a/travis_cmake_mac.sh b/travis_cmake_mac.sh new file mode 100644 index 000000000..f2fbadca0 --- /dev/null +++ b/travis_cmake_mac.sh @@ -0,0 +1,6 @@ +#!/bin/bash +brew uninstall cmake --force +wget https://cmake.org/files/v3.12/cmake-3.12.0-rc2-Darwin-x86_64.tar.gz +tar -xzf cmake-3.12.0-rc2-Darwin-x86_64.tar.gz +cp -r cmake-3.12.0-rc2-Darwin-x86_64/CMake.app/Contents/bin/* /usr/local/bin/ +cp -r cmake-3.12.0-rc2-Darwin-x86_64/CMake.app/Contents/share/* /usr/local/share/ \ No newline at end of file