diff --git a/.gitignore b/.gitignore index 37c54960f..5cb2be3fe 100755 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,11 @@ x64 agents/iguana.exe Debug/* +iguana/nanomsglib +iguana/nanomsgsrc +OSlibs/linux +OSlibs/osx + iguana/pnacl/Release/iguana_unstripped.pexe iguana/pnacl/Release/iguana.pexe @@ -48,7 +53,6 @@ iguana/help.json iguana/autoAPI.md iguana/basilisk.o-2ad8cb38 -======= *.pbxproj iguana/tmp/.tmpmarker @@ -250,3 +254,11 @@ iguana/DB/UNSPENTS/.tmpmarker iguana/DB/instantdex_RQ4z6KrMZeEnCSCsChv1ZoR9ExQitHjbpg_append.json iguana/DB/instantdex_RQ4z6KrMZeEnCSCsChv1ZoR9ExQitHjbpg.json + +build + +.idea +Release/* + +build_win64_release/* +DB/* diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..432d28c90 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "cpp-ethereum"] + path = cpp-ethereum + url = https://github.com/artemii235/cpp-ethereum.git + branch = develop diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..1c557263a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,46 @@ +language: c + +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 + env: OS_NAME=Darwin + osx_image: xcode9.2 + +before_install: + - git submodule update --init --recursive + +script: + - 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 + - cmake --build . --target marketmaker-testnet + +cache: + directories: + - $HOME/.hunter + +before_deploy: + - export TAG=`echo "$(git rev-parse --short HEAD)"` + - mkdir deploy + - cp build/iguana/exchanges/marketmaker-mainnet deploy/marketmaket-mainnet-"$TRAVIS_OS_NAME"-"$TAG" + - cp build/iguana/exchanges/marketmaker-testnet deploy/marketmaket-testnet-"$TRAVIS_OS_NAME"-"$TAG" +deploy: + provider: releases + api_key: + secure: "KT5rtFexiRqOE39yeEXHa23cL1h4tPIKdWtlDoLr/E8eLA+X+4C6tyYuoZc1tqB/ZD3Wx3YovffAX0iHei61Je+So2mFp79+7XFPh08U1xi1g92KvGrjVnZcF+2KEwh6Yan+IcpQKvSlJAEYB2BPmxLNdYKSc1NNOT5vcjaPNhoDzqmz2V01bcePj8QbipgB2aeWl0Wvp+2mt/NsYF12DYLKHWKFITEXrAbgTp9jzczIhRBH4o83ZQhWZKAMl+X8Bo15WLGMTvd5dnjfix85LQIBJZ2D+piVDdjIIXJhdKK3/zVQMMGwrSvv/a0H5UOktpbUWpnK/W5TkkB3LWOdIifNY35KTics6PQevJq61fX8lWP0t4fMLzwqTNyMZnZmHUt/+eLPbFFmM0Kvje1x+FkQ5279OnNG1EMdfqwhmxs1j4G+37yz9+9hfqODhg70sqSDSzx+sWtBDl0/2EmdIsVq+UcT2xOWqwUqNLkO5/1LNHpNrB1UVQTnYIrF7tE1WoZcZy/9E9vxz1bQguzllv6boNtHdSejsDRKvAgUYivVqmrgjgIUfBFQxvxtrZJvmk8BHlI81AcxKc4Xf3H3sAEq7ssC8gQIBs6AcZdofdx/XSHQnq+EnMDBBNz2whV3BjsxN839AtM9C8yHZJbnue7dZwjp/vXE/s7eRwF094I=" + file: + - deploy/marketmaket-mainnet-"$TRAVIS_OS_NAME"-"$TAG" + - deploy/marketmaket-testnet-"$TRAVIS_OS_NAME"-"$TAG" + on: + tags: false diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..feb0c7acb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.9.2) +include("cmake/HunterGate.cmake") +HunterGate( + URL "https://github.com/ruslo/hunter/archive/v0.19.173.tar.gz" + SHA1 "750fb1d621af971fad6f303356b13017ad9f5e15" + LOCAL +) +project(SuperNET) +set(DEPS_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) +set(CMAKE_CXX_EXTENSIONS Off) + +include(cmake/DownloadProject.cmake) + +# Download and install nanomsg at CMake configure time +download_project(PROJ nanomsg + GIT_REPOSITORY https://github.com/nanomsg/nanomsg.git + GIT_TAG 1.1.2 + GIT_SHALLOW 1 + GIT_PROGRESS 1 + CMAKE_ARGS "-DNN_STATIC_LIB=ON -DNN_ENABLE_GETADDRINFO_A=OFF -DNN_ENABLE_DOC=OFF -DNN_TESTS=OFF -DNN_TOOLS=OFF -DNN_ENABLE_NANOCAT=OFF -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_PREFIX}" + UPDATE_DISCONNECTED 1 + ) + +find_library(NANOMSG_LIBRARY NAMES nanomsg PATHS ${DEPS_INSTALL_PREFIX}/lib NO_DEFAULT_PATH) +include_directories("${CMAKE_SOURCE_DIR}") +add_subdirectory(cpp-ethereum) +add_subdirectory(iguana/exchanges) +add_subdirectory(iguana/exchanges/etomicswap) +add_subdirectory(iguana/secp256k1) +add_subdirectory(crypto777) +add_subdirectory(crypto777/jpeg) \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..67d0044f1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM ubuntu:17.10 +RUN apt-get update && apt-get install -y git libcurl4-openssl-dev build-essential wget pax libleveldb-dev && apt-get clean +RUN wget https://cmake.org/files/v3.10/cmake-3.10.3-Linux-x86_64.sh && \ + chmod +x cmake-3.10.3-Linux-x86_64.sh && \ + ./cmake-3.10.3-Linux-x86_64.sh --skip-license --exclude-subdir --prefix=/usr && \ + rm -rf cmake-3.10.3-Linux-x86_64.sh +CMD rm -rf build && mkdir build && cd build && cmake .. && cmake --build . --target marketmaker-testnet diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..f7bb536b0 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,20 @@ +pipeline { + agent { + docker { + image 'artempikulin/cmake-ubuntu' + } + + } + stages { + stage('Build') { + steps { + sh '''git submodule update --init --recursive +rm -rf build +mkdir build +cd build +cmake .. +cmake --build . --target marketmaker-testnet''' + } + } + } +} \ No newline at end of file diff --git a/OSlibs/android/lib/libcrypto.so b/OSlibs/android/lib/libcrypto.so deleted file mode 100755 index 8fa44cee8..000000000 Binary files a/OSlibs/android/lib/libcrypto.so and /dev/null differ diff --git a/OSlibs/android/lib/libcurl.a b/OSlibs/android/lib/libcurl.a deleted file mode 100755 index bbc4fa4f0..000000000 Binary files a/OSlibs/android/lib/libcurl.a and /dev/null differ diff --git a/OSlibs/android/lib/libssl.so b/OSlibs/android/lib/libssl.so deleted file mode 100755 index 8c270c350..000000000 Binary files a/OSlibs/android/lib/libssl.so and /dev/null differ diff --git a/OSlibs/ios/lib/libcrypto.a b/OSlibs/ios/lib/libcrypto.a deleted file mode 100644 index 3e9849e14..000000000 Binary files a/OSlibs/ios/lib/libcrypto.a and /dev/null differ diff --git a/OSlibs/ios/lib/libcurl.a b/OSlibs/ios/lib/libcurl.a deleted file mode 100644 index 07109972f..000000000 Binary files a/OSlibs/ios/lib/libcurl.a and /dev/null differ diff --git a/OSlibs/ios/lib/libssl.a b/OSlibs/ios/lib/libssl.a deleted file mode 100644 index 646b0ad20..000000000 Binary files a/OSlibs/ios/lib/libssl.a and /dev/null differ diff --git a/OSlibs/js/libnanomsg.a b/OSlibs/js/libnanomsg.a deleted file mode 100644 index fb2a83981..000000000 Binary files a/OSlibs/js/libnanomsg.a and /dev/null differ diff --git a/OSlibs/js/libnanomsg.so b/OSlibs/js/libnanomsg.so deleted file mode 100644 index a8f7ea8ef..000000000 Binary files a/OSlibs/js/libnanomsg.so and /dev/null differ diff --git a/OSlibs/linux/x86_64/libnanomsg-static.a b/OSlibs/linux/x86_64/libnanomsg-static.a deleted file mode 100644 index 064e32591..000000000 Binary files a/OSlibs/linux/x86_64/libnanomsg-static.a and /dev/null differ diff --git a/OSlibs/osx/libcrypto.a b/OSlibs/osx/libcrypto.a deleted file mode 100644 index 4d3f97915..000000000 Binary files a/OSlibs/osx/libcrypto.a and /dev/null differ diff --git a/OSlibs/osx/libcurl.a b/OSlibs/osx/libcurl.a deleted file mode 100644 index 41192abb7..000000000 Binary files a/OSlibs/osx/libcurl.a and /dev/null differ diff --git a/OSlibs/osx/libgmp.a b/OSlibs/osx/libgmp.a deleted file mode 100644 index 3ed321825..000000000 Binary files a/OSlibs/osx/libgmp.a and /dev/null differ diff --git a/OSlibs/osx/libsecp256k1.a b/OSlibs/osx/libsecp256k1.a deleted file mode 100644 index 5b2034911..000000000 Binary files a/OSlibs/osx/libsecp256k1.a and /dev/null differ diff --git a/OSlibs/osx/libssl.a b/OSlibs/osx/libssl.a deleted file mode 100644 index badeb5f21..000000000 Binary files a/OSlibs/osx/libssl.a and /dev/null differ diff --git a/OSlibs/win/libcrypto-1_1.dll b/OSlibs/win/libcrypto-1_1.dll deleted file mode 100644 index 4b16b67be..000000000 Binary files a/OSlibs/win/libcrypto-1_1.dll and /dev/null differ diff --git a/OSlibs/win/libcrypto.a b/OSlibs/win/libcrypto.a deleted file mode 100755 index 62f2adfc8..000000000 Binary files a/OSlibs/win/libcrypto.a and /dev/null differ diff --git a/OSlibs/win/libcurl.a b/OSlibs/win/libcurl.a deleted file mode 100755 index 768133dde..000000000 Binary files a/OSlibs/win/libcurl.a and /dev/null differ diff --git a/OSlibs/win/libcurl.dll b/OSlibs/win/libcurl.dll deleted file mode 100644 index 8c80e23eb..000000000 Binary files a/OSlibs/win/libcurl.dll and /dev/null differ diff --git a/OSlibs/win/libcurldll.a b/OSlibs/win/libcurldll.a deleted file mode 100755 index 15cf86362..000000000 Binary files a/OSlibs/win/libcurldll.a and /dev/null differ diff --git a/OSlibs/win/libpthreadGC2.a b/OSlibs/win/libpthreadGC2.a deleted file mode 100755 index ff267089b..000000000 Binary files a/OSlibs/win/libpthreadGC2.a and /dev/null differ diff --git a/OSlibs/win/libpthreadGC2_64.a b/OSlibs/win/libpthreadGC2_64.a deleted file mode 100755 index 430162364..000000000 Binary files a/OSlibs/win/libpthreadGC2_64.a and /dev/null differ diff --git a/OSlibs/win/libsecp256k1.a b/OSlibs/win/libsecp256k1.a deleted file mode 100644 index 778d5d980..000000000 Binary files a/OSlibs/win/libsecp256k1.a and /dev/null differ diff --git a/OSlibs/win/libssl-1_1.dll b/OSlibs/win/libssl-1_1.dll deleted file mode 100644 index dee38788d..000000000 Binary files a/OSlibs/win/libssl-1_1.dll and /dev/null differ diff --git a/OSlibs/win/libssl.a b/OSlibs/win/libssl.a deleted file mode 100755 index ac3e692a7..000000000 Binary files a/OSlibs/win/libssl.a and /dev/null differ diff --git a/OSlibs/win/nanomsg.dll b/OSlibs/win/nanomsg.dll deleted file mode 100644 index 4f454d25e..000000000 Binary files a/OSlibs/win/nanomsg.dll and /dev/null differ diff --git a/OSlibs/win/pthreadGC2.dll b/OSlibs/win/pthreadGC2.dll deleted file mode 100755 index 67b9289df..000000000 Binary files a/OSlibs/win/pthreadGC2.dll and /dev/null differ diff --git a/OSlibs/win/pthreadGC2_64.dll b/OSlibs/win/pthreadGC2_64.dll deleted file mode 100755 index 841d4a216..000000000 Binary files a/OSlibs/win/pthreadGC2_64.dll and /dev/null differ diff --git a/OSlibs/win/release/nanomsg.dll b/OSlibs/win/release/nanomsg.dll deleted file mode 100644 index 5d5dc7e20..000000000 Binary files a/OSlibs/win/release/nanomsg.dll and /dev/null differ diff --git a/OSlibs/win/release/pthreadvc2.dll b/OSlibs/win/release/pthreadvc2.dll deleted file mode 100644 index 93f562baa..000000000 Binary files a/OSlibs/win/release/pthreadvc2.dll and /dev/null differ diff --git a/OSlibs/win/x64/libcurl.dll b/OSlibs/win/x64/libcurl.dll deleted file mode 100644 index c77ec1f0f..000000000 Binary files a/OSlibs/win/x64/libcurl.dll and /dev/null differ diff --git a/OSlibs/win/x64/libpthreadGC2.a b/OSlibs/win/x64/libpthreadGC2.a deleted file mode 100644 index 96f31306b..000000000 Binary files a/OSlibs/win/x64/libpthreadGC2.a and /dev/null differ diff --git a/OSlibs/win/x64/nanomsg.dll b/OSlibs/win/x64/nanomsg.dll deleted file mode 100644 index b5c4e1400..000000000 Binary files a/OSlibs/win/x64/nanomsg.dll and /dev/null differ diff --git a/OSlibs/win/x64/release/libcurl.dll b/OSlibs/win/x64/release/libcurl.dll deleted file mode 100644 index c77ec1f0f..000000000 Binary files a/OSlibs/win/x64/release/libcurl.dll and /dev/null differ diff --git a/OSlibs/win/x64/release/nanomsg.dll b/OSlibs/win/x64/release/nanomsg.dll deleted file mode 100644 index 1a9074fed..000000000 Binary files a/OSlibs/win/x64/release/nanomsg.dll and /dev/null differ diff --git a/README.md b/README.md index 57e2376e8..b0c77724c 100755 --- a/README.md +++ b/README.md @@ -255,3 +255,16 @@ Execute the OSX deploy script: ./osx_deploy.sh ``` The iguana binary and its linked libraries are in ```$HOME/tmp/iguana```. + +# Cmake build of marketmaker with linked etomic lib for ETH/ERC20 atomic swaps: +1. `make sure g++-7 ln to /usr/bin/g++` +1. `cd ~/SuperNET` +1. `git checkout dev` +1. `git submodule update --init --recursive` +1. `mkdir build` +1. `cd build` +1. `cmake ..` +1. `cmake --build . --target marketmaker-testnet` for Ropsten Ethereum testnet. +1. `cmake --build . --target marketmaker-mainnet` for Ethereum mainnet. +1. `cd build/iguana/exchanges` +1. `./marketmaker-testnet` or `./marketmaker-mainnet` diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..69d821f95 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,9 @@ +version: 1.0.{build} +branches: + only: + - etomic +build_script: +- cmd: marketmaker_build_etomic.cmd +cache: + - C:\.hunter + - cpp-ethereum \ No newline at end of file diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index a2a6d2200..0378c13b6 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -931,20 +931,20 @@ void basilisks_loop(void *arg) relay = iguana_coinfind("RELAY"); startmilli = OS_milliseconds(); endmilli = startmilli + 1000; - //fprintf(stderr,"A "); +//fprintf(stderr,"A "); basilisk_issued_purge(myinfo,600000); - //fprintf(stderr,"B "); +//fprintf(stderr,"B "); basilisk_p2pQ_process(myinfo,777); - //fprintf(stderr,"C "); +//fprintf(stderr,"C "); if ( myinfo->IAMNOTARY != 0 ) { if ( relay != 0 ) { - //fprintf(stderr,"D "); +//fprintf(stderr,"D "); basilisk_ping_send(myinfo,relay); } counter++; - //fprintf(stderr,"E "); +//fprintf(stderr,"E "); if ( myinfo->numdpows == 1 ) { iguana_dPoWupdate(myinfo,&myinfo->DPOWS[0]); @@ -961,11 +961,11 @@ void basilisks_loop(void *arg) } endmilli = startmilli + 30; } - //fprintf(stderr,"F "); +//fprintf(stderr,"F "); } else { - //fprintf(stderr,"G "); +//fprintf(stderr,"G "); dex_updateclient(myinfo); if ( myinfo->IAMLP != 0 ) endmilli = startmilli + 500; @@ -973,15 +973,15 @@ void basilisks_loop(void *arg) } if ( myinfo->expiration != 0 && (myinfo->dexsock >= 0 || myinfo->IAMLP != 0 || myinfo->DEXactive > time(NULL)) ) { - //fprintf(stderr,"H "); +//fprintf(stderr,"H "); for (i=0; i<100; i++) if ( basilisk_requests_poll(myinfo) <= 0 ) break; } - //printf("RELAYID.%d endmilli %f vs now %f\n",myinfo->NOTARY.RELAYID,endmilli,startmilli); +//printf("RELAYID.%d endmilli %f vs now %f\n",myinfo->NOTARY.RELAYID,endmilli,startmilli); while ( OS_milliseconds() < endmilli ) usleep(10000); - //printf("finished waiting numdpow.%d\n",myinfo->numdpows); +//printf("finished waiting numdpow.%d\n",myinfo->numdpows); iter++; } } @@ -1183,7 +1183,7 @@ HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr) HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) { - char *retstr=0,*symbol,*coinaddr,*infostr; cJSON *retjson,*sobj,*info,*addrs,*txoutjson,*txjson,*array; uint32_t basilisktag,blocktime,numtx=0; bits256 txid,blockhash; struct basilisk_item *ptr,Lptr; uint64_t value; int32_t timeoutmillis,vout,height,n,m; + char *retstr=0,*symbol,*coinaddr,*infostr; cJSON *retjson,*sobj,*info,*addrs,*txoutjson,*txjson,*array; uint32_t basilisktag,blocktime,numtx=0; bits256 txid,blockhash,merkleroot; struct basilisk_item *ptr,Lptr; uint64_t value; int32_t timeoutmillis,vout,height,n,m; if ( vals == 0 ) return(clonestr("{\"error\":\"null valsobj\"}")); //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) @@ -1219,7 +1219,7 @@ HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) jadd64bits(retjson,"satoshis",value); jaddnum(retjson,"value",dstr(value)); jaddnum(retjson,"amount",dstr(value)); - height = dpow_getchaintip(myinfo,&blockhash,&blocktime,0,&numtx,coin); + height = dpow_getchaintip(myinfo,&merkleroot,&blockhash,&blocktime,0,&numtx,coin); jaddnum(retjson,"height",height); jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); jaddbits256(retjson,"txid",txid); diff --git a/basilisk/basilisk_bitcoin.c b/basilisk/basilisk_bitcoin.c index 942539260..ab007f63a 100755 --- a/basilisk/basilisk_bitcoin.c +++ b/basilisk/basilisk_bitcoin.c @@ -26,7 +26,7 @@ char *bitcoin_balance(struct iguana_info *coin,char *coinaddr,int32_t lastheight { int32_t i,n,height,maxconf=1<<30; int64_t balance = 0; char params[512],*curlstr; cJSON *array,*retjson,*curljson; retjson = cJSON_CreateObject(); - if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getinfo",params)) != 0 ) + if ( (curlstr= bitcoind_getinfo(coin->symbol,coin->chain->serverport,coin->chain->userpass,coin->getinfostr)) != 0 ) { if ( (curljson= cJSON_Parse(curlstr)) != 0 ) { @@ -181,7 +181,7 @@ int32_t basilisk_bitcoinscan(struct iguana_info *coin,uint8_t origblockspace[IGU { struct iguana_txblock txdata; struct iguana_block B; int32_t len,starti,h,num=0,loadheight,hexlen,datalen,n,i,numtxids,flag=0,j,height=-1; cJSON *curljson,*blockjson,*txids; char *bitstr,*curlstr,params[128],str[65]; struct iguana_msghdr H; struct iguana_msgblock *msg; uint8_t *blockspace,revbits[4],bitsbuf[4]; bits256 hash2,checkhash2; strcpy(params,"[]"); - if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getinfo",params)) != 0 ) + if ( (curlstr= bitcoind_getinfo(coin->symbol,coin->chain->serverport,coin->chain->userpass,coin->getinfostr)) != 0 ) { if ( (curljson= cJSON_Parse(curlstr)) != 0 ) { @@ -602,7 +602,7 @@ char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coi free_json(vins); return(rawtx); } - printf("%s splitfunds tx.(%s) vins.(%s)\n",coin->symbol,rawtx,jprint(vins,0)); + //printf("%s splitfunds tx.(%s) vins.(%s)\n",coin->symbol,rawtx,jprint(vins,0)); if ( signedtxidp != 0 ) { if ( (signedtx= iguana_signrawtx(myinfo,coin,0,signedtxidp,completedp,vins,rawtx,0,0)) != 0 ) diff --git a/cmake/DownloadProject.CMakeLists.cmake.in b/cmake/DownloadProject.CMakeLists.cmake.in new file mode 100644 index 000000000..aabbbcb46 --- /dev/null +++ b/cmake/DownloadProject.CMakeLists.cmake.in @@ -0,0 +1,15 @@ +# Distributed under the OSI-approved MIT License. See accompanying +# file LICENSE or https://github.com/Crascit/DownloadProject for details. + +cmake_minimum_required(VERSION 2.8.2) + +project(${DL_ARGS_PROJ}-download NONE) + +include(ExternalProject) +ExternalProject_Add(${DL_ARGS_PROJ}-download + ${DL_ARGS_UNPARSED_ARGUMENTS} + SOURCE_DIR "${DL_ARGS_SOURCE_DIR}" + BINARY_DIR "${DL_ARGS_BINARY_DIR}" + BUILD_COMMAND "" + TEST_COMMAND "" +) diff --git a/cmake/DownloadProject.cmake b/cmake/DownloadProject.cmake new file mode 100644 index 000000000..e300f4265 --- /dev/null +++ b/cmake/DownloadProject.cmake @@ -0,0 +1,182 @@ +# Distributed under the OSI-approved MIT License. See accompanying +# file LICENSE or https://github.com/Crascit/DownloadProject for details. +# +# MODULE: DownloadProject +# +# PROVIDES: +# download_project( PROJ projectName +# [PREFIX prefixDir] +# [DOWNLOAD_DIR downloadDir] +# [SOURCE_DIR srcDir] +# [BINARY_DIR binDir] +# [QUIET] +# ... +# ) +# +# Provides the ability to download and unpack a tarball, zip file, git repository, +# etc. at configure time (i.e. when the cmake command is run). How the downloaded +# and unpacked contents are used is up to the caller, but the motivating case is +# to download source code which can then be included directly in the build with +# add_subdirectory() after the call to download_project(). Source and build +# directories are set up with this in mind. +# +# The PROJ argument is required. The projectName value will be used to construct +# the following variables upon exit (obviously replace projectName with its actual +# value): +# +# projectName_SOURCE_DIR +# projectName_BINARY_DIR +# +# The SOURCE_DIR and BINARY_DIR arguments are optional and would not typically +# need to be provided. They can be specified if you want the downloaded source +# and build directories to be located in a specific place. The contents of +# projectName_SOURCE_DIR and projectName_BINARY_DIR will be populated with the +# locations used whether you provide SOURCE_DIR/BINARY_DIR or not. +# +# The DOWNLOAD_DIR argument does not normally need to be set. It controls the +# location of the temporary CMake build used to perform the download. +# +# The PREFIX argument can be provided to change the base location of the default +# values of DOWNLOAD_DIR, SOURCE_DIR and BINARY_DIR. If all of those three arguments +# are provided, then PREFIX will have no effect. The default value for PREFIX is +# CMAKE_BINARY_DIR. +# +# The QUIET option can be given if you do not want to show the output associated +# with downloading the specified project. +# +# In addition to the above, any other options are passed through unmodified to +# ExternalProject_Add() to perform the actual download, patch and update steps. +# The following ExternalProject_Add() options are explicitly prohibited (they +# are reserved for use by the download_project() command): +# +# CONFIGURE_COMMAND +# BUILD_COMMAND +# INSTALL_COMMAND +# TEST_COMMAND +# +# Only those ExternalProject_Add() arguments which relate to downloading, patching +# and updating of the project sources are intended to be used. Also note that at +# least one set of download-related arguments are required. +# +# If using CMake 3.2 or later, the UPDATE_DISCONNECTED option can be used to +# prevent a check at the remote end for changes every time CMake is run +# after the first successful download. See the documentation of the ExternalProject +# module for more information. It is likely you will want to use this option if it +# is available to you. Note, however, that the ExternalProject implementation contains +# bugs which result in incorrect handling of the UPDATE_DISCONNECTED option when +# using the URL download method or when specifying a SOURCE_DIR with no download +# method. Fixes for these have been created, the last of which is scheduled for +# inclusion in CMake 3.8.0. Details can be found here: +# +# https://gitlab.kitware.com/cmake/cmake/commit/bdca68388bd57f8302d3c1d83d691034b7ffa70c +# https://gitlab.kitware.com/cmake/cmake/issues/16428 +# +# If you experience build errors related to the update step, consider avoiding +# the use of UPDATE_DISCONNECTED. +# +# EXAMPLE USAGE: +# +# include(DownloadProject) +# download_project(PROJ googletest +# GIT_REPOSITORY https://github.com/google/googletest.git +# GIT_TAG master +# UPDATE_DISCONNECTED 1 +# QUIET +# ) +# +# add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) +# +#======================================================================================== + + +set(_DownloadProjectDir "${CMAKE_CURRENT_LIST_DIR}") + +include(CMakeParseArguments) + +function(download_project) + + set(options QUIET) + set(oneValueArgs + PROJ + PREFIX + DOWNLOAD_DIR + SOURCE_DIR + BINARY_DIR + # Prevent the following from being passed through + CONFIGURE_COMMAND + BUILD_COMMAND + INSTALL_COMMAND + TEST_COMMAND + ) + set(multiValueArgs "") + + cmake_parse_arguments(DL_ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # Hide output if requested + if (DL_ARGS_QUIET) + set(OUTPUT_QUIET "OUTPUT_QUIET") + else() + unset(OUTPUT_QUIET) + message(STATUS "Downloading/updating ${DL_ARGS_PROJ}") + endif() + + # Set up where we will put our temporary CMakeLists.txt file and also + # the base point below which the default source and binary dirs will be. + # The prefix must always be an absolute path. + if (NOT DL_ARGS_PREFIX) + set(DL_ARGS_PREFIX "${CMAKE_BINARY_DIR}") + else() + get_filename_component(DL_ARGS_PREFIX "${DL_ARGS_PREFIX}" ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") + endif() + if (NOT DL_ARGS_DOWNLOAD_DIR) + set(DL_ARGS_DOWNLOAD_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-download") + endif() + + # Ensure the caller can know where to find the source and build directories + if (NOT DL_ARGS_SOURCE_DIR) + set(DL_ARGS_SOURCE_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-src") + endif() + if (NOT DL_ARGS_BINARY_DIR) + set(DL_ARGS_BINARY_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-build") + endif() + set(${DL_ARGS_PROJ}_SOURCE_DIR "${DL_ARGS_SOURCE_DIR}" PARENT_SCOPE) + set(${DL_ARGS_PROJ}_BINARY_DIR "${DL_ARGS_BINARY_DIR}" PARENT_SCOPE) + + # The way that CLion manages multiple configurations, it causes a copy of + # the CMakeCache.txt to be copied across due to it not expecting there to + # be a project within a project. This causes the hard-coded paths in the + # cache to be copied and builds to fail. To mitigate this, we simply + # remove the cache if it exists before we configure the new project. It + # is safe to do so because it will be re-generated. Since this is only + # executed at the configure step, it should not cause additional builds or + # downloads. + file(REMOVE "${DL_ARGS_DOWNLOAD_DIR}/CMakeCache.txt") + + # Create and build a separate CMake project to carry out the download. + # If we've already previously done these steps, they will not cause + # anything to be updated, so extra rebuilds of the project won't occur. + # Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project + # has this set to something not findable on the PATH. + configure_file("${_DownloadProjectDir}/DownloadProject.CMakeLists.cmake.in" + "${DL_ARGS_DOWNLOAD_DIR}/CMakeLists.txt") + execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" + -D "CMAKE_MAKE_PROGRAM:FILE=${CMAKE_MAKE_PROGRAM}" + . + RESULT_VARIABLE result + ${OUTPUT_QUIET} + WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}" + ) + if(result) + message(FATAL_ERROR "CMake step for ${DL_ARGS_PROJ} failed: ${result}") + endif() + execute_process(COMMAND ${CMAKE_COMMAND} --build . + RESULT_VARIABLE result + ${OUTPUT_QUIET} + WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}" + ) + if(result) + message(FATAL_ERROR "Build step for ${DL_ARGS_PROJ} failed: ${result}") + endif() + +endfunction() diff --git a/cmake/Hunter/config.cmake b/cmake/Hunter/config.cmake new file mode 100644 index 000000000..ad5e23194 --- /dev/null +++ b/cmake/Hunter/config.cmake @@ -0,0 +1,18 @@ +# cryptopp has very bad CMakeLists.txt config. +# We have to enforce "cross compiling mode" there by setting CMAKE_SYSTEM_VERSION=NO +# to any "false" value. +hunter_config(cryptopp VERSION ${HUNTER_cryptopp_VERSION} CMAKE_ARGS CMAKE_SYSTEM_VERSION=NO) + +hunter_config( + libjson-rpc-cpp + VERSION ${HUNTER_libjson-rpc-cpp_VERSION} + CMAKE_ARGS + UNIX_DOMAIN_SOCKET_SERVER=NO + UNIX_DOMAIN_SOCKET_CLIENT=NO + FILE_DESCRIPTOR_SERVER=NO + FILE_DESCRIPTOR_CLIENT=NO + TCP_SOCKET_SERVER=NO + TCP_SOCKET_CLIENT=NO + HTTP_SERVER=NO + HTTP_CLIENT=NO +) \ No newline at end of file diff --git a/cmake/HunterGate.cmake b/cmake/HunterGate.cmake new file mode 100644 index 000000000..cdc37afe6 --- /dev/null +++ b/cmake/HunterGate.cmake @@ -0,0 +1,529 @@ +# Copyright (c) 2013-2017, Ruslan Baratov +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# This is a gate file to Hunter package manager. +# Include this file using `include` command and add package you need, example: +# +# cmake_minimum_required(VERSION 3.0) +# +# include("cmake/HunterGate.cmake") +# HunterGate( +# URL "https://github.com/path/to/hunter/archive.tar.gz" +# SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d" +# ) +# +# project(MyProject) +# +# hunter_add_package(Foo) +# hunter_add_package(Boo COMPONENTS Bar Baz) +# +# Projects: +# * https://github.com/hunter-packages/gate/ +# * https://github.com/ruslo/hunter + +option(HUNTER_ENABLED "Enable Hunter package manager support" ON) +if(HUNTER_ENABLED) + if(CMAKE_VERSION VERSION_LESS "3.0") + message(FATAL_ERROR "At least CMake version 3.0 required for hunter dependency management." + " Update CMake or set HUNTER_ENABLED to OFF.") + endif() +endif() + +include(CMakeParseArguments) # cmake_parse_arguments + +option(HUNTER_STATUS_PRINT "Print working status" ON) +option(HUNTER_STATUS_DEBUG "Print a lot info" OFF) + +set(HUNTER_WIKI "https://github.com/ruslo/hunter/wiki") + +function(hunter_gate_status_print) + foreach(print_message ${ARGV}) + if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG) + message(STATUS "[hunter] ${print_message}") + endif() + endforeach() +endfunction() + +function(hunter_gate_status_debug) + foreach(print_message ${ARGV}) + if(HUNTER_STATUS_DEBUG) + string(TIMESTAMP timestamp) + message(STATUS "[hunter *** DEBUG *** ${timestamp}] ${print_message}") + endif() + endforeach() +endfunction() + +function(hunter_gate_wiki wiki_page) + message("------------------------------ WIKI -------------------------------") + message(" ${HUNTER_WIKI}/${wiki_page}") + message("-------------------------------------------------------------------") + message("") + message(FATAL_ERROR "") +endfunction() + +function(hunter_gate_internal_error) + message("") + foreach(print_message ${ARGV}) + message("[hunter ** INTERNAL **] ${print_message}") + endforeach() + message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]") + message("") + hunter_gate_wiki("error.internal") +endfunction() + +function(hunter_gate_fatal_error) + cmake_parse_arguments(hunter "" "WIKI" "" "${ARGV}") + string(COMPARE EQUAL "${hunter_WIKI}" "" have_no_wiki) + if(have_no_wiki) + hunter_gate_internal_error("Expected wiki") + endif() + message("") + foreach(x ${hunter_UNPARSED_ARGUMENTS}) + message("[hunter ** FATAL ERROR **] ${x}") + endforeach() + message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]") + message("") + hunter_gate_wiki("${hunter_WIKI}") +endfunction() + +function(hunter_gate_user_error) + hunter_gate_fatal_error(${ARGV} WIKI "error.incorrect.input.data") +endfunction() + +function(hunter_gate_self root version sha1 result) + string(COMPARE EQUAL "${root}" "" is_bad) + if(is_bad) + hunter_gate_internal_error("root is empty") + endif() + + string(COMPARE EQUAL "${version}" "" is_bad) + if(is_bad) + hunter_gate_internal_error("version is empty") + endif() + + string(COMPARE EQUAL "${sha1}" "" is_bad) + if(is_bad) + hunter_gate_internal_error("sha1 is empty") + endif() + + string(SUBSTRING "${sha1}" 0 7 archive_id) + + if(EXISTS "${root}/cmake/Hunter") + set(hunter_self "${root}") + else() + set( + hunter_self + "${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked" + ) + endif() + + set("${result}" "${hunter_self}" PARENT_SCOPE) +endfunction() + +# Set HUNTER_GATE_ROOT cmake variable to suitable value. +function(hunter_gate_detect_root) + # Check CMake variable + string(COMPARE NOTEQUAL "${HUNTER_ROOT}" "" not_empty) + if(not_empty) + set(HUNTER_GATE_ROOT "${HUNTER_ROOT}" PARENT_SCOPE) + hunter_gate_status_debug("HUNTER_ROOT detected by cmake variable") + return() + endif() + + # Check environment variable + string(COMPARE NOTEQUAL "$ENV{HUNTER_ROOT}" "" not_empty) + if(not_empty) + set(HUNTER_GATE_ROOT "$ENV{HUNTER_ROOT}" PARENT_SCOPE) + hunter_gate_status_debug("HUNTER_ROOT detected by environment variable") + return() + endif() + + # Check HOME environment variable + string(COMPARE NOTEQUAL "$ENV{HOME}" "" result) + if(result) + set(HUNTER_GATE_ROOT "$ENV{HOME}/.hunter" PARENT_SCOPE) + hunter_gate_status_debug("HUNTER_ROOT set using HOME environment variable") + return() + endif() + + # Check SYSTEMDRIVE and USERPROFILE environment variable (windows only) + if(WIN32) + string(COMPARE NOTEQUAL "$ENV{SYSTEMDRIVE}" "" result) + if(result) + set(HUNTER_GATE_ROOT "$ENV{SYSTEMDRIVE}/.hunter" PARENT_SCOPE) + hunter_gate_status_debug( + "HUNTER_ROOT set using SYSTEMDRIVE environment variable" + ) + return() + endif() + + string(COMPARE NOTEQUAL "$ENV{USERPROFILE}" "" result) + if(result) + set(HUNTER_GATE_ROOT "$ENV{USERPROFILE}/.hunter" PARENT_SCOPE) + hunter_gate_status_debug( + "HUNTER_ROOT set using USERPROFILE environment variable" + ) + return() + endif() + endif() + + hunter_gate_fatal_error( + "Can't detect HUNTER_ROOT" + WIKI "error.detect.hunter.root" + ) +endfunction() + +macro(hunter_gate_lock dir) + if(NOT HUNTER_SKIP_LOCK) + if("${CMAKE_VERSION}" VERSION_LESS "3.2") + hunter_gate_fatal_error( + "Can't lock, upgrade to CMake 3.2 or use HUNTER_SKIP_LOCK" + WIKI "error.can.not.lock" + ) + endif() + hunter_gate_status_debug("Locking directory: ${dir}") + file(LOCK "${dir}" DIRECTORY GUARD FUNCTION) + hunter_gate_status_debug("Lock done") + endif() +endmacro() + +function(hunter_gate_download dir) + string( + COMPARE + NOTEQUAL + "$ENV{HUNTER_DISABLE_AUTOINSTALL}" + "" + disable_autoinstall + ) + if(disable_autoinstall AND NOT HUNTER_RUN_INSTALL) + hunter_gate_fatal_error( + "Hunter not found in '${dir}'" + "Set HUNTER_RUN_INSTALL=ON to auto-install it from '${HUNTER_GATE_URL}'" + "Settings:" + " HUNTER_ROOT: ${HUNTER_GATE_ROOT}" + " HUNTER_SHA1: ${HUNTER_GATE_SHA1}" + WIKI "error.run.install" + ) + endif() + string(COMPARE EQUAL "${dir}" "" is_bad) + if(is_bad) + hunter_gate_internal_error("Empty 'dir' argument") + endif() + + string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" is_bad) + if(is_bad) + hunter_gate_internal_error("HUNTER_GATE_SHA1 empty") + endif() + + string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" is_bad) + if(is_bad) + hunter_gate_internal_error("HUNTER_GATE_URL empty") + endif() + + set(done_location "${dir}/DONE") + set(sha1_location "${dir}/SHA1") + + set(build_dir "${dir}/Build") + set(cmakelists "${dir}/CMakeLists.txt") + + hunter_gate_lock("${dir}") + if(EXISTS "${done_location}") + # while waiting for lock other instance can do all the job + hunter_gate_status_debug("File '${done_location}' found, skip install") + return() + endif() + + file(REMOVE_RECURSE "${build_dir}") + file(REMOVE_RECURSE "${cmakelists}") + + file(MAKE_DIRECTORY "${build_dir}") # check directory permissions + + # Disabling languages speeds up a little bit, reduces noise in the output + # and avoids path too long windows error + file( + WRITE + "${cmakelists}" + "cmake_minimum_required(VERSION 3.0)\n" + "project(HunterDownload LANGUAGES NONE)\n" + "include(ExternalProject)\n" + "ExternalProject_Add(\n" + " Hunter\n" + " URL\n" + " \"${HUNTER_GATE_URL}\"\n" + " URL_HASH\n" + " SHA1=${HUNTER_GATE_SHA1}\n" + " DOWNLOAD_DIR\n" + " \"${dir}\"\n" + " SOURCE_DIR\n" + " \"${dir}/Unpacked\"\n" + " CONFIGURE_COMMAND\n" + " \"\"\n" + " BUILD_COMMAND\n" + " \"\"\n" + " INSTALL_COMMAND\n" + " \"\"\n" + ")\n" + ) + + if(HUNTER_STATUS_DEBUG) + set(logging_params "") + else() + set(logging_params OUTPUT_QUIET) + endif() + + hunter_gate_status_debug("Run generate") + + # Need to add toolchain file too. + # Otherwise on Visual Studio + MDD this will fail with error: + # "Could not find an appropriate version of the Windows 10 SDK installed on this machine" + if(EXISTS "${CMAKE_TOOLCHAIN_FILE}") + get_filename_component(absolute_CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE) + set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=${absolute_CMAKE_TOOLCHAIN_FILE}") + else() + # 'toolchain_arg' can't be empty + set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=") + endif() + + string(COMPARE EQUAL "${CMAKE_MAKE_PROGRAM}" "" no_make) + if(no_make) + set(make_arg "") + else() + # Test case: remove Ninja from PATH but set it via CMAKE_MAKE_PROGRAM + set(make_arg "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}") + endif() + + execute_process( + COMMAND + "${CMAKE_COMMAND}" + "-H${dir}" + "-B${build_dir}" + "-G${CMAKE_GENERATOR}" + "${toolchain_arg}" + ${make_arg} + WORKING_DIRECTORY "${dir}" + RESULT_VARIABLE download_result + ${logging_params} + ) + + if(NOT download_result EQUAL 0) + hunter_gate_internal_error("Configure project failed") + endif() + + hunter_gate_status_print( + "Initializing Hunter workspace (${HUNTER_GATE_SHA1})" + " ${HUNTER_GATE_URL}" + " -> ${dir}" + ) + execute_process( + COMMAND "${CMAKE_COMMAND}" --build "${build_dir}" + WORKING_DIRECTORY "${dir}" + RESULT_VARIABLE download_result + ${logging_params} + ) + + if(NOT download_result EQUAL 0) + hunter_gate_internal_error("Build project failed") + endif() + + file(REMOVE_RECURSE "${build_dir}") + file(REMOVE_RECURSE "${cmakelists}") + + file(WRITE "${sha1_location}" "${HUNTER_GATE_SHA1}") + file(WRITE "${done_location}" "DONE") + + hunter_gate_status_debug("Finished") +endfunction() + +# Must be a macro so master file 'cmake/Hunter' can +# apply all variables easily just by 'include' command +# (otherwise PARENT_SCOPE magic needed) +macro(HunterGate) + if(HUNTER_GATE_DONE) + # variable HUNTER_GATE_DONE set explicitly for external project + # (see `hunter_download`) + set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES) + endif() + + # First HunterGate command will init Hunter, others will be ignored + get_property(_hunter_gate_done GLOBAL PROPERTY HUNTER_GATE_DONE SET) + + if(NOT HUNTER_ENABLED) + # Empty function to avoid error "unknown function" + function(hunter_add_package) + endfunction() + elseif(_hunter_gate_done) + hunter_gate_status_debug("Secondary HunterGate (use old settings)") + hunter_gate_self( + "${HUNTER_CACHED_ROOT}" + "${HUNTER_VERSION}" + "${HUNTER_SHA1}" + _hunter_self + ) + include("${_hunter_self}/cmake/Hunter") + else() + set(HUNTER_GATE_LOCATION "${CMAKE_CURRENT_LIST_DIR}") + + string(COMPARE NOTEQUAL "${PROJECT_NAME}" "" _have_project_name) + if(_have_project_name) + hunter_gate_fatal_error( + "Please set HunterGate *before* 'project' command. " + "Detected project: ${PROJECT_NAME}" + WIKI "error.huntergate.before.project" + ) + endif() + + cmake_parse_arguments( + HUNTER_GATE "LOCAL" "URL;SHA1;GLOBAL;FILEPATH" "" ${ARGV} + ) + + string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" _empty_sha1) + string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" _empty_url) + string( + COMPARE + NOTEQUAL + "${HUNTER_GATE_UNPARSED_ARGUMENTS}" + "" + _have_unparsed + ) + string(COMPARE NOTEQUAL "${HUNTER_GATE_GLOBAL}" "" _have_global) + string(COMPARE NOTEQUAL "${HUNTER_GATE_FILEPATH}" "" _have_filepath) + + if(_have_unparsed) + hunter_gate_user_error( + "HunterGate unparsed arguments: ${HUNTER_GATE_UNPARSED_ARGUMENTS}" + ) + endif() + if(_empty_sha1) + hunter_gate_user_error("SHA1 suboption of HunterGate is mandatory") + endif() + if(_empty_url) + hunter_gate_user_error("URL suboption of HunterGate is mandatory") + endif() + if(_have_global) + if(HUNTER_GATE_LOCAL) + hunter_gate_user_error("Unexpected LOCAL (already has GLOBAL)") + endif() + if(_have_filepath) + hunter_gate_user_error("Unexpected FILEPATH (already has GLOBAL)") + endif() + endif() + if(HUNTER_GATE_LOCAL) + if(_have_global) + hunter_gate_user_error("Unexpected GLOBAL (already has LOCAL)") + endif() + if(_have_filepath) + hunter_gate_user_error("Unexpected FILEPATH (already has LOCAL)") + endif() + endif() + if(_have_filepath) + if(_have_global) + hunter_gate_user_error("Unexpected GLOBAL (already has FILEPATH)") + endif() + if(HUNTER_GATE_LOCAL) + hunter_gate_user_error("Unexpected LOCAL (already has FILEPATH)") + endif() + endif() + + hunter_gate_detect_root() # set HUNTER_GATE_ROOT + + # Beautify path, fix probable problems with windows path slashes + get_filename_component( + HUNTER_GATE_ROOT "${HUNTER_GATE_ROOT}" ABSOLUTE + ) + hunter_gate_status_debug("HUNTER_ROOT: ${HUNTER_GATE_ROOT}") + if(NOT HUNTER_ALLOW_SPACES_IN_PATH) + string(FIND "${HUNTER_GATE_ROOT}" " " _contain_spaces) + if(NOT _contain_spaces EQUAL -1) + hunter_gate_fatal_error( + "HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces." + "Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error" + "(Use at your own risk!)" + WIKI "error.spaces.in.hunter.root" + ) + endif() + endif() + + string( + REGEX + MATCH + "[0-9]+\\.[0-9]+\\.[0-9]+[-_a-z0-9]*" + HUNTER_GATE_VERSION + "${HUNTER_GATE_URL}" + ) + string(COMPARE EQUAL "${HUNTER_GATE_VERSION}" "" _is_empty) + if(_is_empty) + set(HUNTER_GATE_VERSION "unknown") + endif() + + hunter_gate_self( + "${HUNTER_GATE_ROOT}" + "${HUNTER_GATE_VERSION}" + "${HUNTER_GATE_SHA1}" + _hunter_self + ) + + set(_master_location "${_hunter_self}/cmake/Hunter") + if(EXISTS "${HUNTER_GATE_ROOT}/cmake/Hunter") + # Hunter downloaded manually (e.g. by 'git clone') + set(_unused "xxxxxxxxxx") + set(HUNTER_GATE_SHA1 "${_unused}") + set(HUNTER_GATE_VERSION "${_unused}") + else() + get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE) + set(_done_location "${_archive_id_location}/DONE") + set(_sha1_location "${_archive_id_location}/SHA1") + + # Check Hunter already downloaded by HunterGate + if(NOT EXISTS "${_done_location}") + hunter_gate_download("${_archive_id_location}") + endif() + + if(NOT EXISTS "${_done_location}") + hunter_gate_internal_error("hunter_gate_download failed") + endif() + + if(NOT EXISTS "${_sha1_location}") + hunter_gate_internal_error("${_sha1_location} not found") + endif() + file(READ "${_sha1_location}" _sha1_value) + string(COMPARE EQUAL "${_sha1_value}" "${HUNTER_GATE_SHA1}" _is_equal) + if(NOT _is_equal) + hunter_gate_internal_error( + "Short SHA1 collision:" + " ${_sha1_value} (from ${_sha1_location})" + " ${HUNTER_GATE_SHA1} (HunterGate)" + ) + endif() + if(NOT EXISTS "${_master_location}") + hunter_gate_user_error( + "Master file not found:" + " ${_master_location}" + "try to update Hunter/HunterGate" + ) + endif() + endif() + include("${_master_location}") + set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES) + endif() +endmacro() \ No newline at end of file diff --git a/cmake/toolchain.cmake b/cmake/toolchain.cmake new file mode 100644 index 000000000..0ac730b5f --- /dev/null +++ b/cmake/toolchain.cmake @@ -0,0 +1,4 @@ +# Require C++11. +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) +set(CMAKE_CXX_EXTENSIONS Off) \ No newline at end of file diff --git a/cpp-ethereum b/cpp-ethereum new file mode 160000 index 000000000..2b552430d --- /dev/null +++ b/cpp-ethereum @@ -0,0 +1 @@ +Subproject commit 2b552430d57c247d526394cf0075ebb7a680d725 diff --git a/crypto777/CMakeLists.txt b/crypto777/CMakeLists.txt new file mode 100644 index 000000000..ac2316e04 --- /dev/null +++ b/crypto777/CMakeLists.txt @@ -0,0 +1,11 @@ +file(GLOB sources "*.c") +file(GLOB headers "*.h") +add_library(libcrypto777 ${sources} ${headers}) +target_compile_definitions(libcrypto777 PRIVATE USE_STATIC_NANOMSG) +target_link_libraries(libcrypto777 PUBLIC curl ${NANOMSG_LIBRARY}) +if(WIN32) +add_definitions(-DNATIVE_WINDOWS) +add_definitions(-DIGUANA_LOG2PACKETSIZE=20) +add_definitions(-DIGUANA_MAXPACKETSIZE=1572864) +include_directories("${CMAKE_SOURCE_DIR}/includes") +endif() diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 8c109e5d0..03120f2ef 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -31,6 +31,7 @@ #include #include #include +#include #define HAVE_STRUCT_TIMESPEC #include #include @@ -285,6 +286,8 @@ void *iguana_memalloc(struct OS_memspace *mem,long size,int32_t clearflag); int64_t iguana_memfree(struct OS_memspace *mem,void *ptr,int32_t size); // generic functions +bits256 iguana_merkle(char *symbol,bits256 *tree,int32_t txn_count); +bits256 bits256_calctxid(char *symbol,uint8_t *serialized,int32_t len); int32_t unhex(char c); void touppercase(char *str); uint32_t is_ipaddr(char *str); diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 775ec5f66..4a38e90b3 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -73,8 +73,8 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * long i,j,len; char *retstr = 0; cJSON *json,*result,*error; -#ifdef FROM_MARKETMAKER - //usleep(500); +#ifndef FROM_MARKETMAKER + 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 ) @@ -164,7 +164,11 @@ char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char * if ( url[0] == 0 ) strcpy(url,"http://127.0.0.1:7776"); if ( specialcase != 0 && (0) ) + { + //int32_t zeroval(); printf("<<<<<<<<<<< bitcoind_RPC: userpass.(%s) url.(%s) command.(%s) params.(%s)\n",userpass,url,command,params); + //printf("die.%d\n",1/zeroval()); + } try_again: if ( retstrp != 0 ) *retstrp = 0; diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index 5f978e305..36c2e03a4 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -557,7 +557,7 @@ int _increasing_uint64(const void *a,const void *b) #undef uint64_b } -static int _decreasing_uint64(const void *a,const void *b) +int _decreasing_uint64(const void *a,const void *b) { #define uint64_a (*(uint64_t *)a) #define uint64_b (*(uint64_t *)b) @@ -570,7 +570,7 @@ static int _decreasing_uint64(const void *a,const void *b) #undef uint64_b } -static int _decreasing_uint32(const void *a,const void *b) +int _decreasing_uint32(const void *a,const void *b) { #define uint32_a (*(uint32_t *)a) #define uint32_b (*(uint32_t *)b) @@ -799,23 +799,23 @@ int32_t nn_base64_decode (const char *in, size_t in_len,uint8_t *out, size_t out 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - + for (io = 0, ii = 0, v = 0, rem = 0; ii < in_len; ii++) { if (isspace ((uint32_t)in [ii])) continue; - + if (in [ii] == '=') break; - + ch = DECODEMAP [(uint32_t)in [ii]]; - + // Discard invalid characters as per RFC 2045. if (ch == 0xFF) break; - + v = (v << 6) | ch; rem += 6; - + if (rem >= 8) { rem -= 8; if (io >= out_len) @@ -839,7 +839,7 @@ int32_t nn_base64_encode (const uint8_t *in, size_t in_len,char *out, size_t out "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; - + for (io = 0, ii = 0, v = 0, rem = 0; ii < in_len; ii++) { ch = in [ii]; v = (v << 8) | ch; @@ -851,26 +851,26 @@ int32_t nn_base64_encode (const uint8_t *in, size_t in_len,char *out, size_t out out [io++] = ENCODEMAP [(v >> rem) & 63]; } } - + if (rem) { v <<= (6 - rem); if (io >= out_len) return -ENOBUFS; out [io++] = ENCODEMAP [v & 63]; } - + // Pad to a multiple of 3 while (io & 3) { if (io >= out_len) return -ENOBUFS; out [io++] = '='; } - + if (io >= out_len) return -ENOBUFS; - + out [io] = '\0'; - + return io; } @@ -1285,3 +1285,40 @@ double get_theoretical(double *avebidp,double *aveaskp,double *highbidp,double * return(theoretical); } +bits256 bits256_calctxid(char *symbol,uint8_t *serialized,int32_t len) +{ + bits256 txid,revtxid; int32_t i; + memset(txid.bytes,0,sizeof(txid)); + if ( strcmp(symbol,"GRS") != 0 && strcmp(symbol,"SMART") != 0 ) + txid = bits256_doublesha256(0,serialized,len); + else + { + vcalc_sha256(0,revtxid.bytes,serialized,len); + for (i=0; i<32; i++) + txid.bytes[i] = revtxid.bytes[31 - i]; + } + return(txid); +} + +bits256 iguana_merkle(char *symbol,bits256 *tree,int32_t txn_count) +{ + int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; + if ( txn_count == 1 ) + return(tree[0]); + prev = 0; + while ( txn_count > 1 ) + { + if ( (txn_count & 1) != 0 ) + tree[prev + txn_count] = tree[prev + txn_count-1], txn_count++; + n += txn_count; + for (i=0; i> 1)] = bits256_calctxid(symbol,serialized,sizeof(serialized)); + } + prev = n; + txn_count >>= 1; + } + return(tree[n]); +} diff --git a/crypto777/inet.c b/crypto777/inet.c index 0809b96c6..6d3555e89 100755 --- a/crypto777/inet.c +++ b/crypto777/inet.c @@ -605,7 +605,10 @@ uint16_t parse_endpoint(int32_t *ip6flagp,char *transport,char *ipbuf,char *retb ipbits = calc_ipbits(ipaddr); expand_ipbits(tmp,ipbits); if ( strcmp(tmp,ipaddr) != 0 ) - ipaddr = 0, sprintf(retbuf,"{\"result\":\"illegal ipaddr\",\"endpoint\":\"%s\",\"ipaddr\":\"%s\",\"checkaddr\":\"%s\"}",endpoint,ipaddr,tmp); + { + sprintf(retbuf,"{\"result\":\"illegal ipaddr\",\"endpoint\":\"%s\",\"ipaddr\":\"%s\",\"checkaddr\":\"%s\"}",endpoint,ipaddr,tmp); + ipaddr = 0; + } } if ( inet != 0 && ipaddr != 0 && port != 0 ) { diff --git a/crypto777/jpeg/CMakeLists.txt b/crypto777/jpeg/CMakeLists.txt new file mode 100644 index 000000000..aec626b74 --- /dev/null +++ b/crypto777/jpeg/CMakeLists.txt @@ -0,0 +1,4 @@ +file(GLOB sources "*.c") +file(GLOB headers "*.h") +add_library(libjpeg ${sources} ${headers}) +target_sources(libjpeg PRIVATE "unix/jmemname.c") diff --git a/crypto777/pnacl_libs/libcrypto.a b/crypto777/pnacl_libs/libcrypto.a deleted file mode 100755 index f1e059cab..000000000 Binary files a/crypto777/pnacl_libs/libcrypto.a and /dev/null differ diff --git a/crypto777/pnacl_libs/libcurl.a b/crypto777/pnacl_libs/libcurl.a deleted file mode 100755 index 34d79989c..000000000 Binary files a/crypto777/pnacl_libs/libcurl.a and /dev/null differ diff --git a/crypto777/pnacl_libs/libnanomsg.a b/crypto777/pnacl_libs/libnanomsg.a deleted file mode 100755 index c1fc4973c..000000000 Binary files a/crypto777/pnacl_libs/libnanomsg.a and /dev/null differ diff --git a/crypto777/pnacl_libs/libssl.a b/crypto777/pnacl_libs/libssl.a deleted file mode 100755 index 7685bb725..000000000 Binary files a/crypto777/pnacl_libs/libssl.a and /dev/null differ diff --git a/crypto777/pnacl_libs/libz.a b/crypto777/pnacl_libs/libz.a deleted file mode 100755 index e02de65d8..000000000 Binary files a/crypto777/pnacl_libs/libz.a and /dev/null differ diff --git a/datachain/datachain.c b/datachain/datachain.c index 4ce46416d..f1fec3094 100755 --- a/datachain/datachain.c +++ b/datachain/datachain.c @@ -88,7 +88,7 @@ int32_t datachain_checkpoint_update(struct supernet_info *myinfo,struct iguana_i } if ( n > 0 && lastheight >= 0 && bits256_nonz(lasthash2) != 0 ) { - merkle = iguana_merkle(tree,num); + merkle = iguana_merkle(coin->symbol,tree,num); coin->lastcheckpoint = datachain_checkpoint(myinfo,coin,coin->lastcheckpoint,timestamp,merkle,lastheight,lasthash2); } } diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h deleted file mode 100755 index 754c54f9c..000000000 --- a/deprecated/obsolete.h +++ /dev/null @@ -1,20490 +0,0 @@ -// -// obsolete.h -// pnacl -// -// Created by jimbo laptop on 10/27/15. -// Copyright (c) 2015 jl777. All rights reserved. -// - -#ifndef pnacl_obsolete_h -#define pnacl_obsolete_h - -if ( 0 ) -{ - sleep(3); - char *str,*jsonstr = clonestr("{\"plugin\":\"relay\",\"method\":\"busdata\"}"); uint32_t nonce; - if ( (str= busdata_sync(&nonce,jsonstr,"allnodes",0)) != 0 ) - { - fprintf(stderr,"busdata.(%s)\n",str); - free(str); - } else printf("null return from busdata sync.(%s)\n",jsonstr); - getchar();exit(1); - } - -int32_t nn_stripctrl(int32_t *clenp,uint8_t *ctrl,int32_t ctrlsize,uint8_t *buf) -{ - int32_t clen,offset; - offset = 1; - if ( (clen= buf[0]) > 0 ) - { - if ( clen == 0xfd ) - { - clen = buf[1] | (buf[2] << 8); - offset += 2; - } - printf("nn_stripctrl: clen.%d offset.%d\n",clen,offset); - if ( clen > ctrlsize ) - { - printf("too much control data.%d vs %d, truncate\n",clen,(int32_t)sizeof(ctrl)); - memcpy(ctrl,&buf[offset],ctrlsize); - *clenp = ctrlsize; - errno = MSG_CTRUNC; - } - else - { - memcpy(ctrl,&buf[offset],clen); - *clenp = clen; - } - //printf("copied (%d).%d bytes of control from nbytes.%d\n",clen,offset-clen,(int32_t)nbytes); - } else *clenp = 0; - offset += clen; - return(offset); -} - -static bool nc_conn_ip_active(struct net_child_info *nci,const unsigned char *ip) -{ - unsigned int i; - for (i = 0; i < nci->conns->len; i++) - { - struct nc_conn *conn; - conn = parr_idx(nci->conns, i); - if (!memcmp(conn->peer.addr.ip, ip, 16)) - return true; - } - return false; -} - -static bool nc_conn_group_active(struct net_child_info *nci,const struct peer *peer) -{ - // FIXME - return false; - unsigned int group_len = peer->group_len; - unsigned int i; - for (i = 0; i < nci->conns->len; i++) - { - struct nc_conn *conn; - conn = parr_idx(nci->conns, i); - if ((group_len == conn->peer.group_len) && !memcmp(peer->group, conn->peer.group, group_len)) - return true; - } - return false; -} - -static struct nc_conn *nc_conn_new(const struct peer *peer) -{ - struct nc_conn *conn; - conn = calloc(1, sizeof(*conn)); - if (!conn) - return NULL; - conn->fd = -1; - peer_copy(&conn->peer, peer); - bn_address_str(conn->addr_str, sizeof(conn->addr_str), conn->peer.addr.ip); - return conn; -} - -static void nc_conn_kill(struct net_child_info *nci,struct nc_conn *conn) -{ - assert(conn->dead == false); - conn->dead = true; - event_base_loopbreak(conn->nci->eb); -} - -static void nc_conn_free(struct net_child_info *nci,struct nc_conn *conn) -{ - if (!conn) - return; - if (conn->write_q) - { - clist *tmp = conn->write_q; - while (tmp) - { - struct buffer *buf; - buf = tmp->data; - tmp = tmp->next; - free(buf->p); - free(buf); - } - clist_free(conn->write_q); - } - if (conn->ev) - { - event_del(conn->ev); - event_free(conn->ev); - } - if (conn->write_ev) - { - event_del(conn->write_ev); - event_free(conn->write_ev); - } - if (conn->fd >= 0) - close(conn->fd); - free(conn->msg.data); - memset(conn, 0, sizeof(*conn)); - free(conn); -} - -static bool nc_conn_start(struct net_child_info *nci,struct nc_conn *conn) -{ - char errpfx[64]; - /* create socket */ - printf("start connection.(%s)\n",conn->addr_str); - conn->ipv4 = is_ipv4_mapped(conn->peer.addr.ip); - conn->fd = socket(conn->ipv4 ? AF_INET : AF_INET6,SOCK_STREAM,IPPROTO_TCP); - if ( conn->fd < 0 ) - { - sprintf(errpfx, "socket %s", conn->addr_str); - perror(errpfx); - return false; - } - /* set non-blocking */ - int flags = fcntl(conn->fd,F_GETFL,0); - if ( (flags < 0) || (fcntl(conn->fd,F_SETFL,flags | O_NONBLOCK) < 0) ) - { - sprintf(errpfx, "socket fcntl %s", conn->addr_str); - perror(errpfx); - return false; - } - struct sockaddr *saddr; - struct sockaddr_in6 saddr6; - struct sockaddr_in saddr4; - socklen_t saddr_len; - /* fill out connect(2) address */ - if (conn->ipv4) - { - memset(&saddr4, 0, sizeof(saddr4)); - saddr4.sin_family = AF_INET; - memcpy(&saddr4.sin_addr.s_addr,&conn->peer.addr.ip[12],4); - saddr4.sin_port = htons(conn->peer.addr.port); - saddr = (struct sockaddr *) &saddr4; - saddr_len = sizeof(saddr4); - } - else - { - memset(&saddr6, 0, sizeof(saddr6)); - saddr6.sin6_family = AF_INET6; - memcpy(&saddr6.sin6_addr.s6_addr,&conn->peer.addr.ip[0], 16); - saddr6.sin6_port = htons(conn->peer.addr.port); - saddr = (struct sockaddr *) &saddr6; - saddr_len = sizeof(saddr6); - } - // initiate TCP connection - if ( connect(conn->fd,saddr,saddr_len) < 0 ) - { - if ( errno != EINPROGRESS ) - { - sprintf(errpfx, "socket connect %s", conn->addr_str); - perror(errpfx); - return false; - } - } - return true; -} - -static bool nc_conn_got_header(struct net_child_info *nci,struct nc_conn *conn) -{ - parse_message_hdr(&conn->msg.hdr, conn->hdrbuf); - unsigned int data_len = conn->msg.hdr.data_len; - if (data_len > (16 * 1024 * 1024)) - { - free(conn->msg.data); - conn->msg.data = NULL; - return false; - } - conn->msg.data = malloc(data_len); - /* switch to read-body state */ - conn->msg_p = conn->msg.data; - conn->expected = data_len; - conn->reading_hdr = false; - return true; -} - -static bool nc_conn_got_msg(struct net_child_info *nci,struct nc_conn *conn) -{ - if (!message_valid(&conn->msg)) { - fprintf(nci->plog, "llnet: %s invalid message\n",conn->addr_str); - return false; - } - if (!nc_conn_message(nci,conn)) - return false; - free(conn->msg.data); - conn->msg.data = NULL; - /* switch to read-header state */ - conn->msg_p = conn->hdrbuf; - conn->expected = P2P_HDR_SZ; - conn->reading_hdr = true; - return true; -} - -static void nc_conn_read_evt(int fd, short events, void *priv) -{ - struct nc_conn *conn = priv; - struct net_child_info *nci = conn->nci; - ssize_t rrc = read(fd, conn->msg_p, conn->expected); - if (rrc <= 0) - { - if (rrc < 0) - fprintf(nci->plog, "llnet: %s read: %s\n",conn->addr_str,strerror(errno)); - else fprintf(nci->plog, "llnet: %s read EOF\n", conn->addr_str); - goto err_out; - } - conn->msg_p += rrc; - conn->expected -= rrc; - /* execute our state machine at most twice */ - unsigned int i; - for (i = 0; i < 2; i++) - { - if (conn->expected == 0) - { - if (conn->reading_hdr) - { - if (!nc_conn_got_header(nci,conn)) - goto err_out; - } - else - { - if (!nc_conn_got_msg(nci,conn)) - goto err_out; - } - } - } - return; -err_out: - nc_conn_kill(nci,conn); -} - -static cstring *nc_version_build(struct net_child_info *nci) -{ - struct msg_version mv; - msg_version_init(&mv); - mv.nVersion = PROTO_VERSION; - mv.nServices = nci->blocks_fp != 0 ? NODE_NETWORK : 0; - mv.nTime = (int64_t)time(NULL); - mv.nonce = nci->instance_nonce; - sprintf(mv.strSubVer,"/nano/"); - mv.nStartingHeight = nci->db.best_chain ? nci->db.best_chain->height : 0; - cstring *rs = ser_msg_version(&mv); - msg_version_free(&mv); - return rs; -} - -static bool nc_conn_read_enable(struct net_child_info *nci,struct nc_conn *conn) -{ - if (conn->ev) - return true; - conn->ev = event_new(conn->nci->eb, conn->fd, EV_READ | EV_PERSIST,(void *)nc_conn_read_evt, conn); - if (!conn->ev) - return false; - if (event_add(conn->ev, NULL) != 0) - { - event_free(conn->ev); - conn->ev = NULL; - return false; - } - return true; -} - -static bool nc_conn_read_disable(struct net_child_info *nci,struct nc_conn *conn) -{ - if (!conn->ev) - return true; - event_del(conn->ev); - event_free(conn->ev); - conn->ev = NULL; - return true; -} - -static bool nc_conn_write_enable(struct net_child_info *nci,struct nc_conn *conn) -{ - if (conn->write_ev) - return true; - conn->write_ev = event_new(conn->nci->eb, conn->fd,EV_WRITE | EV_PERSIST,(void *)nc_conn_write_evt, conn); - if (!conn->write_ev) - return false; - if (event_add(conn->write_ev, NULL) != 0) - { - event_free(conn->write_ev); - conn->write_ev = NULL; - return false; - } - return true; -} - -static bool nc_conn_write_disable(struct net_child_info *nci,struct nc_conn *conn) -{ - if (!conn->write_ev) - return true; - event_del(conn->write_ev); - event_free(conn->write_ev); - conn->write_ev = NULL; - return true; -} - -static void nc_conn_evt_connected(int fd, short events, void *priv) -{ - struct nc_conn *conn = priv; - struct net_child_info *nci = conn->nci; - if ((events & EV_WRITE) == 0) { - fprintf(nci->plog, "net: %s connection timeout\n", conn->addr_str); - goto err_out; - } - int err = 0; - socklen_t len = sizeof(err); - /* check success of connect(2) */ - if ((getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0) || (err != 0)) - { - fprintf(nci->plog, "net: connect %s failed: %s\n",conn->addr_str, strerror(err)); - goto err_out; - } - if (nci->debugging) - fprintf(nci->plog, "net: connected to %s\n", conn->addr_str); - conn->connected = true; - /* clear event used for watching connect(2) */ - event_free(conn->ev); - conn->ev = NULL; - /* build and send "version" message */ - cstring *msg_data = nc_version_build(nci); - bool rc = nc_conn_send(nci,conn, "version", msg_data->str, msg_data->len); - cstr_free(msg_data, true); - if (!rc) - { - fprintf(nci->plog, "net: %s !conn_send\n", conn->addr_str); - goto err_out; - } - /* switch to read-header state */ - conn->msg_p = conn->hdrbuf; - conn->expected = P2P_HDR_SZ; - conn->reading_hdr = true; - if (!nc_conn_read_enable(nci,conn)) - { - fprintf(nci->plog, "net: %s read not enabled\n", conn->addr_str); - goto err_out; - } - return; -err_out: - nc_conn_kill(nci,conn); -} - -static void nc_conns_gc(struct net_child_info *nci, bool free_all) -{ - clist *dead = NULL; - unsigned int n_gc = 0; - /* build list of dead connections */ - unsigned int i; - for (i = 0; i < nci->conns->len; i++) - { - struct nc_conn *conn = parr_idx(nci->conns, i); - if (free_all || conn->dead) - dead = clist_prepend(dead, conn); - } - /* remove and free dead connections */ - clist *tmp = dead; - while (tmp) - { - struct nc_conn *conn = tmp->data; - tmp = tmp->next; - - parr_remove(nci->conns, conn); - nc_conn_free(nci,conn); - n_gc++; - } - clist_free(dead); - if (nci->debugging) - fprintf(nci->plog, "net: gc'd %u connections\n", n_gc); -} - -static void nc_conns_open(struct net_child_info *nci) -{ - if (nci->debugging) - fprintf(nci->plog, "net: open connections (have %zu, want %zu more)\n",nci->conns->len,NC_MAX_CONN - nci->conns->len); - printf("nc_conns_open\n"); - while ((bp_hashtab_size(nci->peers->map_addr) > 0) && (nci->conns->len < NC_MAX_CONN)) - { - // delete peer from front of address list. it will be re-added before writing peer file, if successful - struct peer *peer = peerman_pop(nci->peers); - struct nc_conn *conn = nc_conn_new(peer); - conn->nci = nci; - peer_free(peer); - free(peer); - fprintf(stderr, "net: connecting to [%s]\n",conn->addr_str); - if (nc_conn_ip_active(nci, conn->peer.addr.ip)) // are we already connected to this IP? - { - fprintf(nci->plog, "net: already connected to %s\n",conn->addr_str); - goto err_loop; - } - if (nc_conn_group_active(nci, &conn->peer)) // are we already connected to this network group? - { - fprintf(nci->plog, "net: already grouped to %s\n",conn->addr_str); - goto err_loop; - } - if (!nc_conn_start(nci,conn)) // initiate non-blocking connect(2) - { - fprintf(nci->plog, "net: failed to start connection to %s\n",conn->addr_str); - goto err_loop; - } - // add to our list of monitored event sources - conn->ev = event_new(nci->eb, conn->fd, EV_WRITE,(void *)nc_conn_evt_connected, conn); - if ( !conn->ev ) - { - fprintf(nci->plog, "net: event_new failed on %s\n",conn->addr_str); - goto err_loop; - } - struct timeval timeout = { net_conn_timeout, }; - if (event_add(conn->ev, &timeout) != 0) - { - fprintf(nci->plog, "net: event_add failed on %s\n",conn->addr_str); - goto err_loop; - } - parr_add(nci->conns, conn); // add to our list of active connections - continue; - err_loop: - nc_conn_kill(nci,conn); - } -} - -static void nc_conns_process(struct net_child_info *nci) -{ - nc_conns_gc(nci, false); - nc_conns_open(nci); -} - -static bool parse_kvstr(const char *s, char **key, char **value) -{ - char *eql; - eql = strchr(s, '='); - if (eql) - { - uint32_t keylen = (uint32_t)((long)eql - (long)s); - *key = strndup(s, keylen); - *value = strdup(s + keylen + 1); - } - else - { - *key = strdup(s); - *value = strdup(""); - } - /* blank keys forbidden; blank values permitted */ - if (!strlen(*key)) - { - free(*key); - free(*value); - *key = NULL; - *value = NULL; - return false; - } - return true; -} - -static bool read_config_file(struct net_child_info *nci,const char *cfg_fn) -{ - FILE *cfg = fopen(cfg_fn, "r"); - if (!cfg) - return false; - bool rc = false; - char line[1024]; - while (fgets(line, sizeof(line), cfg) != NULL) - { - char *key, *value; - if (line[0] == '#') - continue; - while (line[0] && (isspace(line[strlen(line) - 1]))) - line[strlen(line) - 1] = 0; - if (!parse_kvstr(line, &key, &value)) - continue; - - bp_hashtab_put(nci->settings, key, value); - } - rc = ferror(cfg) == 0; - fclose(cfg); - return rc; -} - -static bool do_setting(struct net_child_info *nci,const char *arg) -{ - char *key, *value; - if (!parse_kvstr(arg, &key, &value)) - return false; - bp_hashtab_put(nci->settings, key, value); - // trigger special setting-specific behaviors - if (!strcmp(key, "debug")) - nci->debugging = true; - else if (!strcmp(key, "config") || !strcmp(key, "c")) - return read_config_file(nci,value); - return true; -} - -static bool preload_settings(struct net_child_info *nci) -{ - unsigned int i; - /* preload static settings */ - for (i = 0; i < ARRAY_SIZE(const_settings); i++) - if (!do_setting(nci,const_settings[i])) - return false; - return true; -} -/*unsigned int arg; - for (arg = 1; arg < argc; arg++) - { - const char *argstr = argv[arg]; - if ( do_setting(nci,argstr) == 0 ) - return 1; - }*/ -/* - * properly capture TERM and other signals - */ - -static void nc_conn_write_evt(int fd, short events, void *priv) -{ - struct nc_conn *conn = priv; - - struct iovec *iov = NULL; - unsigned int iov_len = 0; - struct net_child_info *nci = conn->nci; - /* build list of outgoing data buffers */ - nc_conn_build_iov(conn->write_q, conn->write_partial, &iov, &iov_len); - printf("send data to network\n"); - /* send data to network */ - ssize_t wrc = mywritev(conn->fd, iov, iov_len); - free(iov); - if (wrc < 0) - { - if (errno != EAGAIN && errno != EWOULDBLOCK) - goto err_out; - return; - } - /* handle partially and fully completed buffers */ - nc_conn_written(conn, wrc); - /* thaw read, if write fully drained */ - if (!conn->write_q) - { - nc_conn_write_disable(nci,conn); - nc_conn_read_enable(nci,conn); - } - return; -err_out: - nc_conn_kill(nci,conn); -} - -static void nc_conn_build_iov(clist *write_q, unsigned int partial,struct iovec **iov_, unsigned int *iov_len_) -{ - *iov_ = NULL; - *iov_len_ = 0; - unsigned int i, iov_len = (uint32_t)clist_length(write_q); - struct iovec *iov = calloc(iov_len, sizeof(struct iovec)); - clist *tmp = write_q; - i = 0; - while (tmp) - { - struct buffer *buf = tmp->data; - - iov[i].iov_base = buf->p; - iov[i].iov_len = buf->len; - if (i == 0) - { - iov[0].iov_base += partial; - iov[0].iov_len -= partial; - } - tmp = tmp->next; - i++; - } - *iov_ = iov; - *iov_len_ = iov_len; -} - -static void nc_conn_written(struct nc_conn *conn, size_t bytes) -{ - while (bytes > 0) - { - clist *tmp; - struct buffer *buf; - uint32_t left; - tmp = conn->write_q; - buf = tmp->data; - left = (uint32_t)(buf->len - conn->write_partial); - /* buffer fully written; free */ - if (bytes >= left) - { - free(buf->p); - free(buf); - conn->write_partial = 0; - conn->write_q = clist_delete(tmp, tmp); - bytes -= left; - } - /* buffer partially written; store state */ - else - { - conn->write_partial += bytes; - break; - } - } -} - -ssize_t mywritev(int fildes, const struct iovec *iov, int iovcnt) -{ - int i; - int32_t bytes_written = 0; - for (i = 0; i < iovcnt; i++) - { - int len = (int32_t)send(fildes,iov[i].iov_base,iov[i].iov_len,0); - if (len < 0) - { - //DWORD err = GetLastError(); - //errno = ewin_to_posix_error(err); - bytes_written = -1; - break; - } - bytes_written += len; - } - return bytes_written; -} - -static bool nc_msg_version(struct net_child_info *nci,struct nc_conn *conn) -{ - if (conn->seen_version) - return false; - conn->seen_version = true; - struct const_buffer buf = { conn->msg.data, conn->msg.hdr.data_len }; - struct msg_version mv; - bool rc = false; - msg_version_init(&mv); - if (!deser_msg_version(&mv, &buf)) - goto out; - if (nci->debugging) - { - char fromstr[64], tostr[64]; - bn_address_str(fromstr, sizeof(fromstr), mv.addrFrom.ip); - bn_address_str(tostr, sizeof(tostr), mv.addrTo.ip); - fprintf(nci->plog, "net: %s version(%u, 0x%llx, %lld, To:%s, From:%s, %s, %u)\n", - conn->addr_str, - mv.nVersion, - (unsigned long long) mv.nServices, - (long long) mv.nTime, - tostr, - fromstr, - mv.strSubVer, - mv.nStartingHeight); - } - if (!(mv.nServices & NODE_NETWORK)) /* require NODE_NETWORK */ - goto out; - if (mv.nonce == nci->instance_nonce) /* connected to ourselves? */ - goto out; - conn->protover = (mv.nVersion < PROTO_VERSION) ? mv.nVersion : PROTO_VERSION; - /* acknowledge version receipt */ - if (!nc_conn_send(nci,conn, "verack", NULL, 0)) - goto out; - rc = true; - out: - msg_version_free(&mv); - return rc; -} - -static bool nc_conn_send(struct net_child_info *nci,struct nc_conn *conn, const char *command,const void *data, size_t data_len) -{ - /* build wire message */ - cstring *msg = message_str(nci->chain->netmagic, command, data, (uint32_t)data_len); - if (!msg) - return false; - /* buffer now owns message data */ - struct buffer *buf = calloc(1, sizeof(struct buffer)); - buf->p = msg->str; - buf->len = msg->len; - cstr_free(msg, false); - /* if write q exists, write_evt will handle output */ - if (conn->write_q) - { - conn->write_q = clist_append(conn->write_q, buf); - return true; - } - /* attempt optimistic write */ - ssize_t wrc = write(conn->fd, buf->p, buf->len); - if (wrc < 0) - { - if (errno != EAGAIN && errno != EWOULDBLOCK) - { - free(buf->p); - free(buf); - return false; - } - conn->write_q = clist_append(conn->write_q, buf); - goto out_wrstart; - } - /* message fully sent */ - if (wrc == buf->len) - { - free(buf->p); - free(buf); - return true; - } - /* message partially sent; pause read; poll for writable */ - conn->write_q = clist_append(conn->write_q, buf); - conn->write_partial = (uint32_t)wrc; -out_wrstart: - nc_conn_read_disable(nci,conn); - nc_conn_write_enable(nci,conn); - return true; -} - - -static void init_daemon(struct net_child_info *nci,char *coin) -{ - strcpy(nci->coin,coin); - //init_log(nci); - //init_blkdb(nci); - //printf("utxo\n"); - //bp_utxo_set_init(&nci->uset); - //printf("init_blocks\n"); - //init_blocks(nci); - //printf("init_orphans\n"); - init_orphans(nci); - //readprep_blocks_file(nci); - init_nci(nci); -} - -int32_t iguana_verack(struct net_child_info *nci,struct bp_address *addr) -{ - struct msg_getblocks gb; int32_t rc,numsent; time_t now,cutoff; cstring *s,*msg; - if ( addr->seen_verack ) - { - printf("addr->seen_verack %d\n",addr->seen_verack); - return(-1); - } - addr->seen_verack = 1; - addr->nTime = (uint32_t)time(NULL); - addr->n_ok++; - //peerman_add(conn->nci->peers, &conn->peer,true); - if ( addr->protover >= CADDR_TIME_VERSION ) - { - msg = message_str(nci->chain->netmagic,"getaddr",NULL,0); - if ( (numsent= (int32_t)send(addr->usock,msg->str,msg->len,0)) != msg->len ) - { - cstr_free(msg,true); - return -1; - } - cstr_free(msg,true); - } else printf("protover.%d vs %d CADDR_TIME_VERSION\n",addr->protover,CADDR_TIME_VERSION); - rc = 0; - now = time(NULL); - cutoff = now - (24 * 60 * 60); - if ( nci->last_getblocks < cutoff ) - { - msg_getblocks_init(&gb); - blkdb_locator(&nci->db,NULL,&gb.locator); - s = ser_msg_getblocks(&gb); - oldsend_getblocks(nci); - msg = message_str(nci->chain->netmagic,"getblocks",s->str,(uint32_t)s->len); - cstr_free(s,true); - msg_getblocks_free(&gb); - nci->last_getblocks = now; - } - return(rc); -} - - -static void init_peers(struct net_child_info *nci) -{ - struct peer_manager *peers = 0; - peers = peerman_read(setting(nci,"peers")); - printf("init_peers.%p\n",peers); - if (!peers) - { - PostMessage( "net: initializing empty peer list\n"); - peers = peerman_seed(nci->chain->default_port,1,1);//setting(nci,"dns") != 0 ? true : false,nci->debugging); - if ( !peerman_write(nci->chain,peers,setting(nci,"peers"),nci->debugging) ) - { - PostMessage( "net: failed to write peer list\n"); - exit(1); - } - } - char *addnode = setting(nci,"addnode"); - if (addnode) - peerman_addstr(nci->chain->default_port,peers,addnode,nci->debugging); - peerman_sort(peers); - if (nci->debugging) - PostMessage( "net: have %u/%zu peers\n",bp_hashtab_size(peers->map_addr),clist_length(peers->addrlist)); - nci->peers = peers; -} - -static void init_nci(struct net_child_info *nci) -{ - nci->read_fd = -1; - nci->write_fd = -1; - //nci->blocks_fd = -1; - //init_peers(nci); - nci->conns = parr_new(NC_MAX_CONN, NULL); - //nci->eb = event_base_new(); - nci->daemon_running = true; -} - -void oldsend_getblocks(struct net_child_info *nci) -{ - struct msg_getblocks gb; - msg_getblocks_init(&gb); - blkdb_locator(&nci->db, NULL, &gb.locator); - cstring *s = ser_msg_getblocks(&gb); - printf("oldsend_getblocks\n"); - nc_conn_send(nci,0, "getblocks", s->str, s->len); - cstr_free(s, true); - msg_getblocks_free(&gb); -} - - -static bool nc_msg_inv(struct net_child_info *nci,struct nc_conn *conn) -{ - struct const_buffer buf = { conn->msg.data, conn->msg.hdr.data_len }; - struct msg_vinv mv, mv_out; - bool rc = false; - msg_vinv_init(&mv); - msg_vinv_init(&mv_out); - if (!deser_msg_vinv(&mv, &buf)) - goto out; - if (nci->debugging && mv.invs && mv.invs->len == 1) - { - struct bp_inv *inv = parr_idx(mv.invs, 0); - char hexstr[BU256_STRSZ]; - bu256_hex(hexstr, &inv->hash); - char typestr[32]; - switch (inv->type) - { - case MSG_TX: strcpy(typestr, "tx"); break; - case MSG_BLOCK: strcpy(typestr, "block"); break; - default: sprintf(typestr, "unknown 0x%x", inv->type); break; - } - PostMessage( "net: %s inv %s %s\n",conn->addr_str, typestr, hexstr); - } - else if (nci->debugging && mv.invs) - PostMessage( "net: %s inv (%zu sz)\n",conn->addr_str, mv.invs->len); - if (!mv.invs || !mv.invs->len) - goto out_ok; - /* scan incoming inv's for interesting material */ - unsigned int i; - for (i = 0; i < mv.invs->len; i++) - { - struct bp_inv *inv = parr_idx(mv.invs, i); - switch (inv->type) - { - case MSG_BLOCK: - if (!blkdb_lookup(&nci->db, &inv->hash) && !have_orphan(nci,&inv->hash)) - msg_vinv_push(&mv_out, MSG_BLOCK, &inv->hash); - break; - case MSG_TX: - default: - break; - } - } - /* send getdata, if they have anything we want */ - if (mv_out.invs && mv_out.invs->len) - { - cstring *s = ser_msg_vinv(&mv_out); - rc = nc_conn_send(nci,conn, "getdata", s->str, s->len); - cstr_free(s, true); - } -out_ok: - rc = true; - out: - msg_vinv_free(&mv); - msg_vinv_free(&mv_out); - return rc; -} - -ssize_t fwritev(FILE *fp,const struct iovec *iov,int iovcnt) -{ - int i; int32_t bytes_written = 0; - fprintf(stderr,"fwritev.%d from %ld: ",iovcnt,(long)ftell(fp)); - for (i = 0; i < iovcnt; i++) - { - int len = (int32_t)fwrite(iov[i].iov_base,1,iov[i].iov_len,fp); - if ( len != iov[i].iov_len ) - { - printf("len.%d != %d iov[i].iov_len\n",len,(int32_t)iov[i].iov_len); - //DWORD err = GetLastError(); - //errno = ewin_to_posix_error(err); - bytes_written = -1; - break; - } - bytes_written += len; - } - fprintf(stderr,"%d bytes\n",bytes_written); - return bytes_written; -} - -static bool nc_msg_verack(struct net_child_info *nci,struct nc_conn *conn) -{ - if (conn->seen_verack) - return false; - conn->seen_verack = true; - if (nci->debugging) - PostMessage( "net: %s verack\n",conn->addr_str); - /* - * When a connection attempt is made, the peer is deleted - * from the peer list. When we successfully connect, - * the peer is re-added. Thus, peers are immediately - * forgotten if they fail, on the first try. - */ - conn->peer.last_ok = time(NULL); - conn->peer.n_ok++; - conn->peer.addr.nTime = (uint32_t) conn->peer.last_ok; - peerman_add(conn->nci->peers, &conn->peer, true); - /* request peer addresses */ - if ((conn->protover >= CADDR_TIME_VERSION) && (!nc_conn_send(nci,conn, "getaddr", NULL, 0))) - return false; - /* request blocks */ - bool rc = true; - time_t now = time(NULL); - time_t cutoff = now - (24 * 60 * 60); - if (conn->nci->last_getblocks < cutoff) - { - struct msg_getblocks gb; - msg_getblocks_init(&gb); - blkdb_locator(&nci->db, NULL, &gb.locator); - cstring *s = ser_msg_getblocks(&gb); - rc = nc_conn_send(nci,conn, "getblocks", s->str, s->len); - cstr_free(s, true); - msg_getblocks_free(&gb); - conn->nci->last_getblocks = now; - } - return rc; -} -static bool nc_conn_send(struct net_child_info *nci,struct nc_conn *conn, const char *command,const void *data, size_t data_len) -{ - int32_t i; - cstring *msg = message_str(nci->chain->netmagic, command, data, (uint32_t)data_len); - for (i=0; ilen; i++) - printf("%02x ",msg->str[i] & 0xff); - printf("nc_conn_send cmd.(%s) len.%d\n",command,(int32_t)msg->len); - return(0); -} - -static bool nc_msg_addr(struct net_child_info *nci,struct nc_conn *conn) -{ - struct const_buffer buf = { conn->msg.data, conn->msg.hdr.data_len }; - struct msg_addr ma; - bool rc = false; - msg_addr_init(&ma); - if (!deser_msg_addr(conn->protover, &ma, &buf)) - goto out; - unsigned int i; - time_t cutoff = time(NULL) - (7 * 24 * 60 * 60); - if (nci->debugging) - { - unsigned int old = 0; - for (i = 0; i < ma.addrs->len; i++) - { - struct bp_address *addr = parr_idx(ma.addrs, i); - if (addr->nTime < cutoff) - old++; - } - PostMessage( "net: %s addr(%zu addresses, %u old)\n",conn->addr_str, ma.addrs->len, old); - } - /* ignore ancient addresses */ - if (conn->protover < CADDR_TIME_VERSION) - goto out_ok; - /* feed addresses to peer manager */ - for (i = 0; i < ma.addrs->len; i++) { - struct bp_address *addr = parr_idx(ma.addrs, i); - if (addr->nTime > cutoff) - peerman_add_addr(conn->nci->peers, addr, false); - } -out_ok: - rc = true; - out: - msg_addr_free(&ma); - return rc; -} -/*libevent stubs - #define EV_READ 1 - #define EV_WRITE 2 - #define EV_PERSIST 4 - struct event *event_new(struct event_base *evbase,int32_t fd,int32_t flags,void *funcp,void *conn) { return(0); } - void event_base_loopbreak(struct event_base *evbase) {} - void event_base_dispatch(struct event_base *evbase) {} - void event_base_free(struct event_base *evbase) {} - - struct event_base *event_base_new() { return(0); } - void event_del(struct event *ev) {} - void event_free(struct event *ev) {} - int32_t event_add(struct event *ev,struct timeval *tval) { return(-1); } - // end stubs */ - -enum { NC_MAX_CONN = 8, }; - -//static unsigned int net_conn_timeout = 11; -/* - static void nc_conn_kill(struct net_child_info *nci,struct nc_conn *conn); - static bool nc_conn_read_enable(struct net_child_info *nci,struct nc_conn *conn); - static bool nc_conn_read_disable(struct net_child_info *nci,struct nc_conn *conn); - static bool nc_conn_write_enable(struct net_child_info *nci,struct nc_conn *conn); - static bool nc_conn_write_disable(struct net_child_info *nci,struct nc_conn *conn);*/ - -static bool nc_conn_message(struct net_child_info *nci,struct nc_conn *conn) -{ - char *command = conn->msg.hdr.command; - /* verify correct network */ - printf("got message.(%s)\n",command); - if (memcmp(conn->msg.hdr.netmagic, nci->chain->netmagic, 4)) - { - PostMessage( "net: %s invalid network\n",conn->addr_str); - return false; - } - /* incoming message: version */ - //if ( !strncmp(command,"version",12) ) - // return nc_msg_version(nci,conn); - /* "version" must be first message */ - if (!conn->seen_version) - { - PostMessage( "net: %s 'version' not first\n",conn->addr_str); - return false; - } - /* incoming message: verack */ - if (!strncmp(command,"verack",12)) - return nc_msg_verack(nci,conn); - /* "verack" must be second message */ - if (!conn->seen_verack) - { - PostMessage( "net: %s 'verack' not second\n",conn->addr_str); - return false; - } - /* incoming message: addr */ - if (!strncmp(command, "addr", 12)) - return nc_msg_addr(nci,conn); - /* incoming message: inv */ - else if (!strncmp(command, "inv", 12)) - return nc_msg_inv(nci,conn); - /* incoming message: block */ - else if (!strncmp(command, "block", 12)) - return nc_msg_block(nci,conn); - if (nci->debugging) - PostMessage( "net: %s unknown message %s\n",conn->addr_str,command); - /* ignore unknown messages */ - return true; -} - -static void init_log(struct net_child_info *nci) -{ - char *log_fn = setting(nci,"log"); - if (!log_fn || !strcmp(log_fn, "-")) - nci->plog = stdout; - else { - nci->plog = fopen(log_fn, "a"); - if (!nci->plog) { - perror(log_fn); - exit(1); - } - } - setvbuf(nci->plog, NULL, _IONBF, BUFSIZ); -} - -static void init_blkdb(struct net_child_info *nci) -{ - if (!blkdb_init(&nci->db, nci->chain->netmagic, &nci->chain_genesis)) - { - PostMessage( "blkdb init failed\n"); - exit(1); - } - - char *blkdb_fn = 0;//setting(nci,"blkdb"); - if (!blkdb_fn) - return; - if ((access(blkdb_fn, F_OK) == 0) && !blkdb_read(nci->chain->hastimestamp,&nci->db, blkdb_fn)) - { - PostMessage( "blkdb read failed\n"); - exit(1); - } - if ( (nci->db.fp= fopen(blkdb_fn,"rb+")) == 0 ) - nci->db.fp= fopen(blkdb_fn,"wb+"); - if ( nci->db.fp == 0 ) - { - PostMessage( "blkdb file open failed: %s\n", strerror(errno)); - exit(1); - } - //nci->db.fd = open(blkdb_fn,O_WRONLY | O_APPEND | O_CREAT | O_LARGEFILE, 0666); - //if (nci->db.fd < 0) { - // PostMessage( "blkdb file open failed: %s\n", strerror(errno)); - // exit(1); - //} -} - -static void init_blocks(struct net_child_info *nci) -{ - char blocks_fn[512]; - sprintf(blocks_fn,"%s.blocks",nci->coin); - if ( (nci->blocks_fp= fopen(blocks_fn,"rb+")) == 0 )// O_RDWR | O_CREAT | O_LARGEFILE, 0666); - nci->blocks_fp = fopen(blocks_fn,"wb+"); - if ( nci->blocks_fp == 0 ) - { - PostMessage( "blocks file open failed: %s\n", strerror(errno)); - exit(1); - } - fseek(nci->blocks_fp,0,SEEK_END); - off64_t flen = ftell(nci->blocks_fp); - printf("opened.(%s) flen.%llu\n",blocks_fn,(long long)flen); - if ( flen == (off64_t)-1 ) - { - PostMessage( "blocks file lseek64 failed: %s\n", strerror(errno)); - exit(1); - } - if ( flen == 0 ) - init_block0(nci); -} - -static void shutdown_daemon(struct net_child_info *nci) -{ - if ( nci->blocks_fp != 0 ) - fclose(nci->blocks_fp); - bool rc = peerman_write(nci->chain,nci->peers,setting(nci,"peers"),nci->debugging); - PostMessage( "net: %s %u/%zu peers\n",rc ? "wrote" : "failed to write",bp_hashtab_size(nci->peers->map_addr),clist_length(nci->peers->addrlist)); - if ( nci->plog != stdout && nci->plog != stderr ) - { - fclose(nci->plog); - nci->plog = NULL; - } - if ( setting(nci,"free") ) - { - shutdown_nci(nci); - bp_hashtab_unref(nci->orphans); - bp_hashtab_unref(nci->settings); - blkdb_free(&nci->db); - bp_utxo_set_free(&nci->uset); - } -} - - -static bool nc_msg_block(struct net_child_info *nci,struct nc_conn *conn) -{ - struct const_buffer buf = { conn->msg.data, conn->msg.hdr.data_len }; - struct iovec iov[2]; char hexstr[BU256_STRSZ]; struct bp_block block; bool rc = false; - bp_block_init(&block); - if ( !deser_bp_block(nci->chain->hastimestamp,&block,&buf) ) - goto out; - bp_block_calc_sha256(&block); - bu256_hex(hexstr,&block.sha256); - if ( nci->debugging ) - PostMessage("net: %s block %s\n",conn->addr_str,hexstr); - if ( !bp_block_valid(&block) ) - { - PostMessage("net: %s invalid block %s\n",conn->addr_str,hexstr); - goto out; - } - if ( blkdb_lookup(&nci->db,&block.sha256) || have_orphan(nci,&block.sha256) ) - goto out_ok; - iov[0].iov_base = &conn->msg.hdr; - iov[0].iov_len = sizeof(conn->msg.hdr); - iov[1].iov_base = (void *)buf.p; - iov[1].iov_len = conn->msg.hdr.data_len; - printf("hdr.%d len.%d\n",(int32_t)sizeof(conn->msg.hdr),(int32_t)buf.len); - size_t total_write = iov[0].iov_len + iov[1].iov_len; - //off64_t fpos64 = lseek64(nci->blocks_fd, 0, SEEK_CUR); - //fseek(nci->blocks_fp, 0, SEEK_CUR); - off64_t fpos64 = ftell(nci->blocks_fp); - if ( fpos64 == (off64_t)-1 ) - { - PostMessage( "blocks: lseek64 failed %s\n", - strerror(errno)); - goto out; - } - //errno = 0; - ssize_t bwritten = fwritev(nci->blocks_fp,iov,ARRAY_SIZE(iov)); - if ( bwritten != total_write ) - { - PostMessage( "blocks: write failed %s\n",strerror(errno)); - goto out; - } - if ( !process_block(nci,&block,fpos64) ) - { - PostMessage( "blocks: process-block failed\n"); - goto out; - } -out_ok: - rc = true; - out: - bp_block_free(&block); - return rc; -} - -static bool spend_tx(bool script_verf,struct bp_utxo_set *uset, const struct bp_tx *tx,unsigned int tx_idx, unsigned int height) -{ - bool is_coinbase = (tx_idx == 0); - struct bp_utxo *coin; - int64_t total_in = 0, total_out = 0; - unsigned int i; - /* verify and spend this transaction's inputs */ - if (!is_coinbase) - { - for (i = 0; i < tx->vin->len; i++) - { - struct bp_txin *txin; - struct bp_txout *txout; - txin = parr_idx(tx->vin, i); - coin = bp_utxo_lookup(uset, &txin->prevout.hash); - if (!coin || !coin->vout) - return false; - if (coin->is_coinbase && ((coin->height + COINBASE_MATURITY) > height)) - return false; - txout = NULL; - if (txin->prevout.n >= coin->vout->len) - return false; - txout = parr_idx(coin->vout, txin->prevout.n); - total_in += txout->nValue; - if (script_verf && !bp_verify_sig(coin, tx, i, /* SCRIPT_VERIFY_P2SH */ 0, 0)) - return false; - if (!bp_utxo_spend(uset, &txin->prevout)) - return false; - } - } - for (i = 0; i < tx->vout->len; i++) - { - struct bp_txout *txout; - txout = parr_idx(tx->vout, i); - total_out += txout->nValue; - } - if (!is_coinbase) - { - if (total_out > total_in) - return false; - } - /* copy-and-convert a tx into a UTXO */ - coin = calloc(1, sizeof(*coin)); - bp_utxo_init(coin); - if (!bp_utxo_from_tx(coin, tx, is_coinbase, height)) - return false; - /* add unspent outputs to set */ - bp_utxo_set_add(uset, coin); - return true; -} - -static bool spend_block(struct net_child_info *nci,const struct bp_block *block,unsigned int height) -{ - struct bp_tx *tx; - unsigned int i; - for (i = 0; i < block->vtx->len; i++) - { - tx = parr_idx(block->vtx, i); - if (!spend_tx(nci->script_verf,&nci->uset, tx, i, height)) - { - char hexstr[BU256_STRSZ]; - bu256_hex(hexstr, &tx->sha256); - PostMessage( "brd: spent_block tx fail %s\n", hexstr); - return false; - } - } - return true; -} - -static bool process_block(struct net_child_info *nci,const struct bp_block *block,int64_t fpos) -{ - struct blkdb_reorg reorg; struct blkinfo *bi = bi_new(); - fprintf(stderr,"process_block sha256 %llx\n",*(long long *)&block->sha256); - bu256_copy(&bi->hash, &block->sha256); - bp_block_copy_hdr(&bi->hdr, block); - bi->n_file = 0; - bi->n_pos = fpos; - if ( blkdb_add(&nci->db,bi,&reorg) == 0 ) - { - PostMessage( "brd: blkdb add fail fpos.%ld\n",(long)fpos); - goto err_out; - } - /* FIXME: support reorg */ - assert(reorg.conn == 1); - assert(reorg.disconn == 0); - if ( bu256_equal(&nci->db.best_chain->hash,&bi->hdr.sha256) ) // if best chain, mark TX's as spent - { - if ( spend_block(nci,block,bi->height) == 0 ) - { - char hexstr[BU256_STRSZ]; - bu256_hex(hexstr, &bi->hdr.sha256); - PostMessage("brd: block spend fail %u %s\n",bi->height, hexstr); - // FIXME: bad record is now in blkdb - goto err_out; - } - } - return true; -err_out: - bi_free(bi); - return false; -} - -static bool read_block_msg(struct net_child_info *nci,struct p2p_message *msg, int64_t fpos) -{ - struct const_buffer buf = { msg->data, msg->hdr.data_len }; - struct bp_block block; bool rc = false; - // unknown records are invalid - printf("read_block_msg\n"); - if ( strncmp(msg->hdr.command,"block",sizeof(msg->hdr.command)) ) - { - printf("invalid cmd.(%s) != block\n",msg->hdr.command); - return false; - } - bp_block_init(&block); - if ( deser_bp_block(nci->chain->hastimestamp,&block,&buf) == 0 ) - { - PostMessage( "brd: block deser fail\n"); - goto out; - } - bp_block_calc_sha256(&block); - if (!bp_block_valid(&block)) - { - PostMessage( "brd: block not valid\n"); - goto out; - } - printf("call process_block\n"); - rc = process_block(nci,&block,fpos); - out: - bp_block_free(&block); - return rc; -} - -static void read_blocks(struct net_child_info *nci) -{ - //int fd = nci->blocks_fd; - int32_t n = 0; FILE *fp = nci->blocks_fp; - struct p2p_message msg = {}; - bool read_ok = true; - int64_t fpos = 0; - printf("read_blocks from pos %ld\n",(long)ftell(fp)); - while ( fread_message(fp,&msg,&read_ok) ) - { - printf("iter.%d netmagic.%x\n",n++,*(int32_t *)nci->chain->netmagic); - if ( memcmp(msg.hdr.netmagic,nci->chain->netmagic,4) ) - { - PostMessage("blocks file: invalid network magic\n"); - exit(1); - } - //strcpy(msg.hdr.command,"block"); - if ( !read_block_msg(nci,&msg,fpos) ) - exit(1); - fpos += P2P_HDR_SZ; - fpos += msg.hdr.data_len; - fpos = ftell(fp); - } - printf("read_blocks finished loop\n"); - if ( !read_ok ) - { - PostMessage("blocks file: read failed\n"); - exit(1); - } - free(msg.data); -} - -static void readprep_blocks_file(struct net_child_info *nci) -{ - // if no blk index, but blocks are present, read and index all block data (several gigabytes) - if ( nci->blocks_fp != 0 ) - { - rewind(nci->blocks_fp); - if ( nci->db.fp == 0 ) - read_blocks(nci); - else - { - printf("seek to end\n"); - // TODO: verify that blocks file offsets are present in blkdb - //if ( lseek(nci->blocks_fd, 0, SEEK_END) == (off_t)-1 ) - if ( fseek(nci->blocks_fp,0,SEEK_END) == (off_t)-1 ) - { - PostMessage( "blocks file: seek failed: %s\n",strerror(errno)); - exit(1); - } - } - } -} - -static void init_orphans(struct net_child_info *nci) -{ - nci->orphans = bp_hashtab_new_ext(bu256_hash, bu256_equal_,(bp_freefunc) bu256_free, (bp_freefunc) buffer_free); -} - -static bool have_orphan(struct net_child_info *nci,const bu256_t *v) -{ - return bp_hashtab_get(nci->orphans, v); -} - -bool add_orphan(struct net_child_info *nci,const bu256_t *hash_in, struct const_buffer *buf_in) -{ - if (have_orphan(nci,hash_in)) - return false; - bu256_t *hash = bu256_new(hash_in); - if (!hash) { - PostMessage( "OOM\n"); - return false; - } - struct buffer *buf = buffer_copy(buf_in->p, buf_in->len); - if (!buf) { - bu256_free(hash); - PostMessage( "OOM\n"); - return false; - } - bp_hashtab_put(nci->orphans, hash, buf); - return true; -} - -struct nc_conn -{ - bool dead; - int fd; - struct peer peer; - char addr_str[64]; - bool ipv4; - bool connected; - struct event *ev; - struct net_child_info *nci; - struct event *write_ev; - clist *write_q; /* of struct buffer */ - unsigned int write_partial; - struct p2p_message msg; - void *msg_p; - unsigned int expected; - bool reading_hdr; - unsigned char hdrbuf[P2P_HDR_SZ]; - bool seen_version; - bool seen_verack; - uint32_t protover; -}; - -static bool process_block(struct net_child_info *nci,const struct bp_block *block, int64_t fpos); -static bool have_orphan(struct net_child_info *nci,const bu256_t *v); -static bool add_orphan(struct net_child_info *nci,const bu256_t *hash_in, struct const_buffer *buf_in); - -/*struct bp_hashtab *settings; - //const struct chain_info *chain = NULL; - bu256_t chain_genesis; - uint64_t instance_nonce; - bool debugging = false; - FILE *plog = NULL; - - static const char *const_settings[] = - { - "net.connect.timeout=11", - "addnode=127.0.0.1", - "peers=brd.peers", - "dns=1", - //"blkdb=brd.blkdb", - "blocks=brd.blocks", - //"log=brd.log", - };*/ - -static void init_block0(struct net_child_info *nci) -{ - if ( nci->blocks_fp != 0 ) - { - cstring *msg0 = message_str(nci->chain->netmagic,"block",nci->chain->genesis_hashdata,(int32_t)sizeof(nci->chain->genesis_hashdata)); - ssize_t bwritten = fwrite(msg0->str,1,msg0->len,nci->blocks_fp); - if ( bwritten != msg0->len ) - { - PostMessage( "blocks write0 failed: %s\n", strerror(errno)); - exit(1); - } - cstr_free(msg0,true); - off64_t fpos64 = ftell(nci->blocks_fp); - if ( fpos64 == (off64_t)-1 ) - { - PostMessage( "blocks lseek0 failed: %s\n", strerror(errno)); - exit(1); - } - PostMessage("blocks: genesis block written\n"); - } -} - -static void shutdown_nci(struct net_child_info *nci) -{ - peerman_free(nci->peers); - //nc_conns_gc(nci, true); - assert(nci->conns->len == 0); - //parr_free(nci->conns, true); - //event_base_free(nci->eb); -}int32_t iguana_send(struct iguana_info *coin,void *_conn,uint8_t *serialized,char *cmd,int32_t len) -{ - return(nc_conn_send(coin,_conn,cmd,&serialized[sizeof(struct iguana_msghdr)],len)); - int32_t numsent; struct nc_conn *conn = _conn; - len = iguana_sethdr((void *)serialized,coin->chain->netmagic,cmd,&serialized[sizeof(struct iguana_msghdr)],len); - if ( (numsent= (int32_t)send(conn->addr.usock,serialized,len,0)) < 0 ) - { - printf("%s: numsent.%d vs len.%d errno.%d usock.%d\n",cmd,numsent,len,errno,conn->addr.usock); - if (errno != EAGAIN && errno != EWOULDBLOCK) - { - printf("bad errno.%d\n",errno); - return(-errno); - } - if ( 0 ) - { - /*struct buffer *buf = calloc(1, sizeof(struct buffer)); - buf->p = malloc(len), memcpy(buf->p,serialized,len); - buf->len = len; - conn->write_q = clist_append(conn->write_q,buf); - nc_conn_read_disable(coin,conn); - nc_conn_write_enable(coin,conn);*/ - } - } - else if ( numsent < len ) - { - if ( 0 ) - { - /*conn->write_q = clist_append(conn->write_q, buf); - conn->write_partial = (uint32_t)numsent; - buf->p = malloc(len), memcpy(buf->p,serialized,len); - buf->len = len; - conn->write_q = clist_append(conn->write_q,buf); - nc_conn_read_disable(coin,conn); - nc_conn_write_enable(coin,conn);*/ - } - //int32_t i; - //for (i=0; i 0 && bestheight > oldbestheight ) -{ - prevhash = iguana_prevblockhash(blocks,new_best); - if ( (prev= iguana_findblock(&space,blocks,prevhash)) != 0 && prev->height > 0 ) - { - new_best = prevhash; - bestheight = prev->height; - reorg_info->conn++; - printf("connect.%d: newbest.%s oldheight.%d newheight.%d\n",reorg_info->conn,bits256_str(new_best),oldbestheight,bestheight); - } else break; -} -// unlikely case: old best chain has greater height -while ( oldbestheight > 0 && bestheight > 0 && oldbestheight > bestheight ) -{ - old_best = iguana_prevblockhash(blocks,old_best); - if ( (prev= iguana_findblock(&space,blocks,prevhash)) != 0 && prev->height > 0 ) - { - oldbestheight = prev->height; - reorg_info->disconn++; - printf("unlikely case: disconn.%d %s\n",reorg_info->disconn,bits256_str(old_best)); - } else break; -} -// height matches, but we are still walking parallel chains -while ( oldbestheight > 0 && bestheight > 0 && memcmp(old_best.bytes,new_best.bytes,sizeof(old_best)) != 0 ) -{ - new_best = iguana_prevblockhash(blocks,new_best); - bestheight = iguana_height(blocks,new_best); - reorg_info->conn++; - old_best = iguana_prevblockhash(blocks,old_best); - oldbestheight = iguana_height(blocks,old_best); - reorg_info->disconn++; - printf("parallel case\n"); -} - -/*bits256 iguana_PoW(struct iguana_info *coin,int32_t height) - { - int32_t h; bits256 sum; struct iguana_block *ptr,space; - if ( height > 0 ) - { - h = (height / 1000); - sum = coin->blocks.PoW[h]; - h *= 1000; - while ( ++h <= height ) - { - if ( (ptr= iguana_block(&space,coin,h)) != 0 ) - sum = bits256_add(sum,bits256_from_compact(ptr->bits)); - else - { - printf("error getting block[%u]\n",h); - break; - } - } - } - else - { - iguana_block(&space,coin,0); - sum = bits256_from_compact(space.bits); - } - return(sum); - }*/ -/*BIGNUM cur_work,test; bits256 x,sum; char ystr[512],xstr[512]; - BN_init(&cur_work); - BN_init(&test); - u256_from_compact(&cur_work,0x1d00ffff); - PoW_str(ystr,sizeof(ystr),&cur_work); - printf("y.(%s) ",ystr); - BN_add(&test,&cur_work,&cur_work); - PoW_str(ystr,sizeof(ystr),&test); - printf("sum.(%s) ",ystr); - PoW_conv(&test,0x1d00ffff); - PoW_str(xstr,sizeof(xstr),&test); - x = bits256_from_compact(0x1d00ffff); - sum = bits256_add(x,x); - printf("xstr.(%s) x.(%s) sum.(%s)\n",xstr,bits256_str(x),bits256_lstr(sum)); - getchar();*/ -void u256_from_compact(BIGNUM *vo,uint32_t c); - -int32_t PoW_conv(BIGNUM *PoW,uint32_t nBits) -{ - BN_init(PoW); - u256_from_compact(PoW,nBits); - return(0); -} - -int32_t PoW_add(BIGNUM *sum,BIGNUM *a,BIGNUM *b) -{ - if ( BN_add(sum,a,b) == 0 ) - return(-1); - return(0); -} - -void PoW_free(BIGNUM *a) { BN_clear_free(a); } - -int32_t PoW_cmp(BIGNUM *test,BIGNUM *hwm) { return(BN_cmp(test,hwm)); } -void PoW_str(char *str,int32_t maxlen,BIGNUM *v); - -/*static void nc_conns_gc(struct parr *conns,bool free_all) - { - struct nc_conn *conn; clist *dead = NULL; uint32_t i,n_gc = 0; - // build list of dead connections - for (i=0; ilen; i++) - { - conn = parr_idx(conns,i); - if ( free_all || conn->dead ) - dead = clist_prepend(dead,conn); - } - // remove and free dead connections - clist *tmp = dead; - while ( tmp ) - { - struct nc_conn *conn = tmp->data; - tmp = tmp->next; - parr_remove(conns,conn); - nc_conn_free(conn); - n_gc++; - } - clist_free(dead); - fprintf(stderr,"net: gc'd %u connections\n",n_gc); - }*/ - -/*static struct nc_conn *nc_conn_new(const struct peer *peer) - { - struct nc_conn *conn; - conn = calloc(1, sizeof(*conn)); - if (!conn) - return NULL; - conn->fd = -1; - peer_copy(&conn->peer, peer); - bn_address_str(conn->addr_str, sizeof(conn->addr_str), conn->peer.addr.ip); - return conn; - }*/ - -/*static bool nc_conn_start(struct iguana_info *coin,struct nc_conn *conn) - { - char errpfx[64]; - printf("start connection.(%s)\n",conn->addr_str); - conn->ipv4 = 1;//is_ipv4_mapped(conn->peer.addr.ip); - conn->fd = socket(conn->ipv4 ? AF_INET : AF_INET6,SOCK_STREAM,IPPROTO_TCP); - if ( conn->fd < 0 ) - { - sprintf(errpfx, "socket %s", conn->addr_str); - perror(errpfx); - return false; - } - int flags = fcntl(conn->fd,F_GETFL,0); - if ( (flags < 0) || (fcntl(conn->fd,F_SETFL,flags | O_NONBLOCK) < 0) ) - { - sprintf(errpfx, "socket fcntl %s", conn->addr_str); - perror(errpfx); - return false; - } - struct sockaddr *saddr; - struct sockaddr_in6 saddr6; - struct sockaddr_in saddr4; - socklen_t saddr_len; - if (conn->ipv4) - { - memset(&saddr4, 0, sizeof(saddr4)); - saddr4.sin_family = AF_INET; - memcpy(&saddr4.sin_addr.s_addr,&conn->peer.addr.ip[12],4); - saddr4.sin_port = htons(conn->peer.addr.port); - saddr = (struct sockaddr *) &saddr4; - saddr_len = sizeof(saddr4); - } - else - { - memset(&saddr6, 0, sizeof(saddr6)); - saddr6.sin6_family = AF_INET6; - memcpy(&saddr6.sin6_addr.s6_addr,&conn->peer.addr.ip[0], 16); - saddr6.sin6_port = htons(conn->peer.addr.port); - saddr = (struct sockaddr *) &saddr6; - saddr_len = sizeof(saddr6); - } - // initiate TCP connection - if ( connect(conn->fd,saddr,saddr_len) < 0 ) - { - if ( errno != EINPROGRESS ) - { - sprintf(errpfx, "socket connect %s", conn->addr_str); - perror(errpfx); - return false; - } - } - return true; - }*/ -int32_t rc,lbsock=-1,timeout=1000,priority=1; uint8_t magic[4] = { 0xf9, 0xbe, 0xb4, 0xd9 }; -if ( 0 ) -{ - int32_t testsock,testsock2; char buf[512]; - testsock2 = nn_socket(AF_SP,NN_CRYPTO); - testsock = nn_socket(AF_SP,NN_CRYPTO); - rc = nn_setsockopt(testsock,NN_SOL_SOCKET,NN_CRYPTO_MAGIC,magic,4); - rc = nn_setsockopt(testsock2,NN_SOL_SOCKET,NN_CRYPTO_MAGIC,magic,4); - nn_bind(testsock2,"crypto://127.0.0.1:9999"); - nn_connect(testsock,"crypto://127.0.0.1:9999"); - nn_send(testsock,"hello",6,0); - nn_recv(testsock2,buf,sizeof(buf),0); - printf("bind side got.(%s)\n",buf); - nn_send(testsock2,"gotmsg",7,0); - nn_recv(testsock,buf,sizeof(buf),0); - printf("connect side got.(%s)\n",buf); - - getchar(); -} -//if ( (lbsock= nn_socket(AF_SP,NN_CRYPTO)) >= 0 ) -{ - rc = nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_CRYPTO_MAGIC,magic,4); - printf("rc.%d from NN_CRYPTO_MAGIC\n",rc); - rc = nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_SNDPRIO,&priority,sizeof(priority)); - rc = nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - rc = nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); - printf("rc.%d from NN_SNDPRIO\n",rc); - //if ( nn_connect(lbsock,"crypto://127.0.0.1:8883") >= 0 ) - //if ( nn_connect(lbsock,"tcp://127.0.0.1:50447") >= 0 ) - { - iguana_main("bitcoin","BTC",1); //NODE_NETWORK); - getchar(); - } -} - -/*struct iguana_kvitem *iguana_kvitemptr(struct iguanakv *kv,void *value) - { - struct iguana_kvitem *item = 0; - if ( kv != 0 && value != 0 ) - { - value = (void *)((long)value - (kv)->keysize); - item = (void *)((long)value - ((long)item->keyvalue - (long)item)); - } - return(item); - }*/ - -void iguana_savepeers(struct iguana_info *coin) -{ - uint32_t peerind,itemind; struct iguana_peer *addr,space; char ipaddr[64]; - for (peerind=1; peerind<=coin->latest.maxpeers; peerind++) - { - if ( iguana_RWmmap(0,&space,coin,coin->peers,peerind) == 0 ) - { - strcpy(ipaddr,space.ipaddr); - //printf("peerind.%d -> (%s)\n",peerind,ipaddr); - if ( (addr= iguana_kvread(coin,&space,&itemind,coin->peers,space.A.ip)) != 0 ) - { - if ( peerind == itemind ) - { - if ( iguana_RWmmap(1,addr,coin,coin->peers,peerind) != 0 ) - printf("error RWmap.1 peerind.%d -> (%s)\n",peerind,ipaddr); - } else printf("mismatched peerind.%d vs itemind.%d for (%s)\n",peerind,itemind,ipaddr); - } - } else printf("error reading peerind.%d\n",peerind); - } - iguana_syncmap(&coin->peers->state.M,0); -} -if ( strcmp("peers",kv->name) == 0 ) -{ - struct iguana_peer *addr = (void *)sp->space; - addr->seen_verack = 0; - checkip[0] = 0; - addr->peerind = itemind; - if ( addr->ipaddr[0] != 0 ) - { - ipbits = (uint32_t)calc_ipbits(addr->ipaddr); - expand_ipbits(checkip,ipbits); - } - if ( addr->ipaddr[0] == 0 || strcmp(checkip,addr->ipaddr) != 0 ) - { - printf("bad record.(%s) vs (%s) %d vs %d\n",checkip,addr->ipaddr,addr->peerind,itemind); - i = keysize; - } - else printf("add n.%d skipped.%d (%s) vs (%s).%x i.%d\n",n,skipped,addr->ipaddr,checkip,ipbits,i); - } - -void *iguana_kvsavepeer(struct iguana_info *coin,struct iguanakv *kv,struct iguana_kvitem *item,uint64_t args,void *key,void *value,int32_t valuesize) -{ - FILE *fp = (FILE *)args; struct iguana_peer *addr; uint32_t data[4],ipbits,flag = 0; - if ( args != 0 && (addr= value) != 0 ) - { - printf("%p %s iterarg.%d verack.%d killed.%d\n",addr,addr->ipaddr,kv->iterarg,addr->seen_verack,addr->dead); - if ( kv->iterarg == 0 && addr->seen_verack != 0 ) - flag = 1; - else if ( kv->iterarg == 1 && addr->dead != 0 ) - flag = 1; - else if ( kv->iterarg == 2 && (addr->seen_verack == 0 && addr->dead == 0) ) - flag = 1; - if ( flag != 0 ) - { - ipbits = (uint32_t)calc_ipbits(addr->ipaddr); - data[0] = ipbits; - data[1] = addr->lastcontact; - data[2] = addr->nStartingHeight; - data[3] = addr->pingtime; - if ( fwrite(data,1,sizeof(data),fp) != sizeof(data) ) - { - printf("Error saving key.[%x]\n",ipbits); - return(key); - } - } - } - return(0); -} - -long iguana_savepeers(struct iguana_info *coin) -{ - FILE *fp; long retval = -1; int32_t iter; char fname[512],*str = "good"; - for (iter=0; iter<3; iter++) - { - coin->peers->iterarg = iter; - sprintf(fname,"%s.%s",coin->peers->name,str); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( iguana_kviterate(coin,coin->peers,(uint64_t)fp,iguana_kvsavepeer) == 0 ) - { - printf("save %ld to HDD\n",ftell(fp)); - retval = ftell(fp); - } - else printf("error saving item at %ld\n",ftell(fp)); - fclose(fp); - } else printf("error creating(%s)\n",fname); - if ( iter == 0 ) - str = "errpeer"; - else str = "newpeer"; - } - coin->updatedpeers = 0; - return(retval); -} - -/*void iguana_open_connection(struct iguana_info *coin,char *ipaddr) - { - int32_t i,n; struct iguana_peer addrs[10]; - memset(addrs,0,sizeof(addrs)); - n = iguana_connect(addrs,(int32_t)(sizeof(addrs)/sizeof(*addrs)),ipaddr,coin->chain->default_port); - if ( n > 0 ) - { - for (i=0; iipaddr,coin->numpeers,coin->numrelayers); - iguana_kvwrite(coin,coin->peers,addr->A.ip,addr,sizeof(*addr),(uint32_t *)&addr->peerind); - coin->updatedpeers++; -} - - -void *iguana_kvpurgepeer(struct iguana_info *coin,struct iguanakv *kv,struct iguana_kvitem *item,uint64_t args,void *key,void *value,int32_t valuesize) -{ - struct iguana_peer *addr; int32_t lag; - if ( args != 0 && (addr= value) != 0 && addr->sendtime != 0 ) - { - if ( (lag= (kv->iteruarg - addr->sendtime)) == 0 ) - lag = 1; - if ( kv->iterarg == 0 || lag > kv->iterarg ) - { - kv->iterarg = lag; - strcpy((char *)args,addr->ipaddr); - } - } - return(0); -} - -void *iguana_loop(void *_coin) -{ - struct iguana_info *coin = _coin; - while ( 1 ) - { - /*if ( 1 && (ipaddr= queue_dequeue(&coin->newpeersQ,1)) != 0 ) - { - iguana_open_connection(coin,ipaddr); - printf("check newpeer.(%s)\n",ipaddr); - free_queueitem(ipaddr); - }*/ - sleep(1); - } - return(0); -} - -void shutdown_daemon(struct iguana_info *coin) -{ - if ( coin->blocks.db != 0 ) - { - //iguana_kvsave(coin->blocks.db); - iguana_kvfree(coin,coin->blocks.db); - } -} - -/*if ( coin->numpeers > 16 ) - { - coin->peers->iteruarg = (uint32_t)time(NULL); - coin->peers->iterarg = 0; - if ( iguana_kviterate(coin,coin->peers,(uint64_t)ipaddr,iguana_kvpurgepeer) == 0 ) - printf("lag.%d (%s) peer purged\n",coin->peers->iterarg,ipaddr); - else printf("error: lag.%d (%s) peer purged\n",coin->peers->iterarg,ipaddr); - } - */ -//for (iter=0; iter<2; iter++) -{ - fpos = n = m = fixed = skipped = 0; - if ( (fp= fopen(sp->fname,"rb")) != 0 ) - { - fseek(fp,fpos,SEEK_SET); - while ( fread(sp->space,2,valuesize,fp) == valuesize ) - { - //printf("m.%d\n",m); - itemind = m++; - for (i=0; ispace)[kv->keyoffset + i] != 0 ) - break; - if ( i != keysize ) - { - if ( itemind != n ) - { - fseek(fp,fpos,SEEK_SET); - memset((void *)((long)sp->space + valuesize),0,valuesize); - fwrite((void *)((long)sp->space + valuesize),1,valuesize,fp); - fseek(fp,(long)n * valuesize,SEEK_SET); - fwrite(sp->space,1,valuesize,fp); - fixed++; - //printf("itemind.%d vs n.%d skipped.%d\n",itemind,n,skipped); - itemind = n; - } - if ( iter == 1 ) - { - iguana_kvwrite(coin,kv,(void *)((long)sp->space + kv->keyoffset),sp->space,valuesize,&itemind); - } - n++; - } skipped++; - fseek(fp,(long)m * valuesize,SEEK_SET); - } - printf("iter.%d fixed.%d %s added %d items, skipped.%d keysize.%d keyoffset.%d valuesize.%d\n",iter,fixed,kv->name,n,skipped,kv->keysize,kv->keyoffset,kv->valuesize); - fclose(fp); - //getchar(); - } -} -void iguana_killpeer(struct iguana_info *coin,struct iguana_peer *addr) -{ - if ( addr->seen_verack != 0 ) - { - addr->dead = 1; - addr->seen_verack = 0; - coin->numrelayers -= addr->relayflag; - coin->numpeers--; - printf("KILL PEER.(%s) peerind.%u total.%d relayers.%d\n",addr->ipaddr,addr->peerind,coin->numpeers,coin->numrelayers); - iguana_kvwrite(coin,coin->peers,addr->A.ip,addr,sizeof(*addr),(uint32_t *)&addr->peerind); - coin->updatedpeers++; - } -} - -/*for (j=0; jnumreferrals; j++) - if ( ipbits == addr->referrals[j] ) - break; - if ( j == addr->numreferrals ) - { - if ( addr->numreferrals < sizeof(addr->referrals)/sizeof(*addr->referrals) ) - addr->referrals[addr->numreferrals++] = ipbits; - iguana_possible_peer(coin,ipaddr); - }*/ - -int32_t iguana_blockchain(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgblock *blk,uint8_t *serialized,bits256 hash2,int32_t checkpointi) -{ - struct iguana_blocks *blocks; double PoW; struct iguana_block *prev,*check,space; int32_t i,height,firsttxidind; - blocks = &coin->blocks; - /*if ( (check= iguana_findblock(coin,&space,hash2)) != 0 ) - { - if ( checkpointi >= 0 && check->height == coin->checktip_heights[checkpointi]+1 ) - { - coin->checkpointips[checkpointi] = hash2; - coin->checktip_heights[checkpointi]++; - coin->rawblocks++; - printf("iguana_blockchain: duplicate block height.%d checkpointi.%d tipheight.%d rawblocks.%d\n",check->height,checkpointi,coin->checktip_heights[checkpointi],coin->rawblocks); - } - return(check->height); - } - for (i=0; ichain->numcheckpoints; i++) - { - if ( memcmp(coin->chain->checkpoints_data[i].bytes,hash2.bytes,sizeof(hash2)) == 0 ) - { - height = coin->chain->checkblocks[i]; - coin->checktip_heights[i] = height; - printf("checkpointi.%d height.%d rawblocks.%d\n",i,height,coin->rawblocks); - iguana_addblock(coin,hash2,blk,height,-1,0.); // add to block map, orphans and all - return(0); - } - if ( memcmp(coin->chain->checkpoints_data[i].bytes,blk->H.prev_block.bytes,sizeof(blk->H.prev_block)) == 0 ) - { - height = coin->chain->checkblocks[i] + 1; - coin->checktip_heights[i] = height; - coin->checkpointips[i] = hash2; - coin->rawblocks++; - printf("checkpointi.%d height.%d <- (%s) rawblocks.%d\n",i,height,bits256_str(hash2),coin->rawblocks); - iguana_addblock(coin,hash2,blk,height,-1,0.); // add to block map, orphans and all - return(0); - } - if ( memcmp(coin->checkpointips[i].bytes,blk->H.prev_block.bytes,sizeof(blk->H.prev_block)) == 0 ) - { - height = ++coin->checktip_heights[i]; - coin->checkpointips[i] = hash2; - coin->rawblocks++; - printf("checkpointi.%d height.%d rawblocks.%d\n",i,height,coin->rawblocks); - iguana_addblock(coin,hash2,blk,height,-1,0.); // add to block map, orphans and all - return(0); - } - }*/ - if ( (prev= iguana_findblock(coin,&space,blk->H.prev_block)) == 0 ) - { - fprintf(stderr,"iguana_blockchain no prev block.(%s)\n",bits256_str(blk->H.prev_block)); - return(-1); - } - else - { - height = prev->height + 1; - PoW = (PoW_from_compact(blk->H.bits) + prev->PoW); - firsttxidind = (prev->firsttxidind + prev->txn_count); - if ( PoW <= coin->blocks.best_chain_work ) - height = 0; - } - //printf("NEWHT.%d (%s) PoW %.15f prev.%d prevPoW %.15f\n",height,bits256_str(hash2),blk->PoW,prev->height,prev->PoW); - iguana_addblock(coin,addr,hash2,blk,height,firsttxidind,PoW); // add to block map, orphans and all - if ( height == 0 ) - { - printf("%s chain not best\n",bits256_str(hash2)); - return(-1); - } - if ( memcmp(blocks->best_chain.bytes,blk->H.prev_block.bytes,sizeof(blocks->best_chain)) != 0 ) - { - printf("prev.(%s) doesnt connect to previous bestchain\n",bits256_str(blk->H.prev_block)); - printf("mark as orphans from old bestchain.(%s) till it connects to mainchain\n",bits256_str(blocks->best_chain)); - getchar(); - } - return(height); -} - -int32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) -{ - struct iguana_peer *space,*addr,addrs[8]; uint32_t i,n,peerind = (uint32_t)-1; - if ( strncmp("0.0.0",ipaddr,5) != 0 && strcmp("0.0.255.255",ipaddr) != 0 && strcmp("1.0.0.0",ipaddr) != 0 ) - { - memset(addrs,0,sizeof(addrs)); - n = iguana_connect(addrs,(int32_t)(sizeof(addrs)/sizeof(*addrs)),ipaddr,coin->chain->default_port,0); - if ( n > 0 ) - { - for (i=0; i<1; i++) // n is almost always 1 - { - strcpy(addrs[i].coinstr,coin->name); - space = calloc(1,sizeof(*space)); - peerind = -1; - //portable_mutex_lock(&coin->netmutex); - if ( (addr= iguana_kvread(coin,space,(uint32_t *)&peerind,coin->peers,ipaddr)) == 0 ) - memcpy(space,&addrs[i],sizeof(*space)); - else if ( addr->usock >= 0 || addr->pending != 0 ) - break; - peerind = -1; - if ( iguana_kvwrite(coin,coin->peers,ipaddr,space,sizeof(*space),(uint32_t *)&peerind) != 0 ) - { - //portable_mutex_unlock(&coin->netmutex); - //printf("%p %s ADD PEER.(%s) peerind.%u max.%u total.%d relayers.%d numkeys.%d\n",&addrs[i],space->coinstr,space->ipaddr,peerind,coin->latest.maxpeers,coin->numpeers,coin->numrelayers,coin->peers->numkeys); - space->coin = coin; - if ( coin->numthreads < 3 || (coin->numthreads < IGUANA_MAXPEERS/2 && iguana_metric(space) > coin->avemetric) || (coin->numthreads >= IGUANA_MAXPEERS/2 && coin->numthreads < IGUANA_MAXPEERS) ) - { - peerind = -1; - //portable_mutex_lock(&coin->netmutex); - if ( (addr= iguana_kvread(coin,space,(uint32_t *)&peerind,coin->peers,ipaddr)) != 0 ) - { - coin->numthreads++; - //portable_mutex_unlock(&coin->netmutex); - addr->coin = coin; - if ( coin->chain->numcheckpoints > 0 ) - addr->checkpointi = (coin->nextcheckpointi++ % coin->chain->numcheckpoints); - else addr->checkpointi = -1; - portable_thread_create(iguana_startconnection,addr); - } //else portable_mutex_unlock(&coin->netmutex); - } - //printf("possible.(%s)\n",ipaddr); - } - else - { - //portable_mutex_unlock(&coin->netmutex); - printf("error writing?\n"); - } - } - } - } - return(0); -} -/*iguana_send_version(coin,addr,coin->myservices); - if ( addr->dead == 0 && addr->usock >= 0 ) - { - printf("connected and version sent to usock.%d (%s) numpings.%d\n",addr->usock,addr->ipaddr,addr->numpings); - if ( coin->chain->numcheckpoints > 0 ) - addr->checkpointi = (coin->nextcheckpointi++ % coin->chain->numcheckpoints); - printf("%s uses checkpointi.%d\n",addr->ipaddr,addr->checkpointi); - //nexti = (coin->chain->numcheckpoints/IGUANA_MAXPEERS) * addr->checkpointi; - iguana_advancechain(coin,addr,addr->checkpointi);//nexti++ % coin->chain->numcheckpoints); - }*/ - -/*iguana_send_version(coin,addr,coin->myservices); - if ( addr->dead == 0 && addr->usock >= 0 ) - { - printf("connected and version sent to usock.%d (%s) numpings.%d\n",addr->usock,addr->ipaddr,addr->numpings); - if ( coin->chain->numcheckpoints > 0 ) - addr->checkpointi = (coin->nextcheckpointi++ % coin->chain->numcheckpoints); - printf("%s uses checkpointi.%d\n",addr->ipaddr,addr->checkpointi); - //nexti = (coin->chain->numcheckpoints/IGUANA_MAXPEERS) * addr->checkpointi; - iguana_advancechain(coin,addr,addr->checkpointi);//nexti++ % coin->chain->numcheckpoints); - }*/ - - -void iguana_pollconnection(struct iguana_info *coin,struct iguana_peer *addr) -{ - /*if ( addr->last_getblocks < time(NULL) - (24 * 60 * 60) ) - { - memset(stophash.bytes,0,sizeof(stophash)); - n = iguana_locator(coin,hashes,(int32_t)(sizeof(hashes)/sizeof(*hashes))); - iguana_send_hashes(coin,addr->protover < GETHEADERS_VERSION ? "getblocks" : "getheaders",addr,stophash,hashes,n); - printf("send %s to %s\n",addr->protover < GETHEADERS_VERSION ? "getblocks" : "getheaders",addr->ipaddr); - addr->last_getblocks = time(NULL); - }*/ -} - -void iguana_checkpoint(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,int32_t height) -{ - struct iguana_block block; - memset(&block,0,sizeof(block)); - block.prev_block = hash2; - block.height = (height + 1); - //printf("write (%s) to %d\n",bits256_str(hash2),height+1); - iguana_RWmmap(1,&block,coin,coin->blocks.db,height+1); - //iguana_syncmap(coin->blocks.db,0); -} - -int32_t iguana_addblockhash(struct iguana_info *coin,struct iguana_peer *addr,int32_t *heightp,bits256 hash2,bits256 nexthash) -{ - struct iguana_block *block,*next,space,nextspace; - *heightp = -1; - if ( (block= iguana_findblock(coin,&space,hash2)) != 0 ) - { - *heightp = block->height; - if ( (next= iguana_findblock(coin,&nextspace,nexthash)) == 0 ) - { - iguana_checkpoint(coin,addr,nexthash,block->height + 1); - //iguana_audit(coin); - return(0); - } - else if ( next->height != block->height + 1 ) - { - printf("iguana_addblockhash: mismatched next height.%d vs height.%d+1\n",next->height,block->height); - //iguana_audit(coin); - return(-1); - } - else - { - //iguana_audit(coin); - return(iguana_blockdata(coin,block)); - } - } - //iguana_audit(coin); - return(0); -} - - -int32_t iguana_advancecmp(bits256 hashes[2],int32_t n,int32_t cmpa,int32_t cmpb) -{ - //printf("n.%d cmpa.%d cmpb.%d\n",n,cmpa,cmpb); - if ( bits256_nonz(hashes[0]) != 0 && bits256_nonz(hashes[1]) == 0 && (cmpa == 0 || n < cmpa) && (cmpb == 0 || n < cmpb) ) - return(1); - //printf("failed cmp %d %d %d %d\n",bits256_nonz(hashes[0]) != 0,bits256_nonz(hashes[1]) == 0,(cmpa == 0 || n < cmpa),(cmpb == 0 || n < cmpb)); - return(0); -} - -/*void iguana_advancechain(struct iguana_info *coin,struct iguana_peer *addr,int32_t checkpointi) - { - bits256 stophash,hashes[10]; int32_t islocal,n = 0; char *cmd = ""; - memset(stophash.bytes,0,sizeof(stophash)); - islocal = (strcmp("127.0.0.1",addr->ipaddr) == 0); - //printf("blockhash %d, blockhdr.%d block.%d height.%d\n",addr->maxblockhash_height,addr->maxblockhdr_height,addr->maxblock_height,addr->height); - if ( (islocal != 0 || addr->protover < GETHEADERS_VERSION) && iguana_advancecmp(addr->maxblockhash,addr->maxblockhash_height,addr->maxblockhdr_height+500,addr->height+2000) != 0 ) - { - printf("request blockhashes islocal.%d\n",islocal); - cmd = "getblocks"; - addr->maxblockhash[1] = hashes[n++] = coin->blocks.hwmchain;//addr->maxblockhash[0]; - } - else if ( islocal != 0 && addr->protover >= GETHEADERS_VERSION && iguana_advancecmp(addr->maxblockhdr,addr->maxblockhdr_height,addr->maxblock_height+500,0) != 0 ) - { - cmd = "getheaders"; - printf("request headers islocal.%d\n",islocal); - addr->maxblockhdr[1] = hashes[n++] = addr->maxblockhdr[0]; - } - else if ( memcmp(coin->blocks.hwmchain.bytes,addr->maxblock[1].bytes,sizeof(bits256)) != 0 ) //if ( iguana_advancecmp(addr->maxblock,addr->maxblock_height,addr->height,0) != 0 ) - { - printf("request data\n"); - addr->maxblock[0] = addr->maxblock[1] = coin->blocks.hwmchain; - iguana_request_data(coin,addr,coin->blocks.hwmchain,MSG_BLOCK); - return; - } - else - { - //printf("nothing to advance %s\n",addr->ipaddr); - return; - } - n = iguana_locator(coin,hashes,(int32_t)(sizeof(hashes)/sizeof(*hashes))-1,checkpointi); - iguana_send_hashes(coin,cmd,addr,stophash,hashes,n); - }*/ - - -// got functions - -void iguana_gotblockhash(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,bits256 nexthash,int32_t i,int32_t n) -{ - int32_t height; struct iguana_block space; bits256 hashes[2001]; - /*if ( iguana_addblockhash(coin,addr,&height,hash2,nexthash) == 0 ) - { - //if ( height > (coin->blocks.hwmheight-10) ) - // iguana_request_data(coin,addr,nexthash,MSG_BLOCK); - } - if ( height > addr->maxblockhash_height ) - { - addr->maxblockhash_height = height; - addr->maxblockhash[0] = hash2; - memset(addr->maxblockhash[1].bytes,0,sizeof(hash2)); - }*/ - //if ( i > 0 ) - //hashes[i-1] = hash2; - iguana_request_data(coin,addr,&hash2,1,MSG_BLOCK); - if ( i == n-1 ) - { - hashes[i] = nexthash; - iguana_request_data(coin,addr,&nexthash,1,MSG_BLOCK); - //iguana_request_data(coin,addr,hashes,n,MSG_BLOCK); - bits256 stophash; - memset(stophash.bytes,0,sizeof(stophash)); - iguana_send_hashes(coin,"getblocks",addr,stophash,&nexthash,1); - } - height = iguana_height(coin,hash2); - //printf("set gotblockhash.%s %d ht.%d -> %s from %s\n",bits256_str(hash2),height,iguana_height(coin,hash2),bits256_str2(nexthash),addr->ipaddr); - //iguana_audit(coin); -} - -int32_t iguana_gotblockhdr(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgblock *msg,uint8_t *serialized,int32_t len,bits256 hash2,int32_t checkpointi) -{ - int32_t n = 0,height = -1; struct iguana_block space,*block; - //printf("got gotblockhdr.%s from %s, checkpointi.%d\n",bits256_str(hash2),addr->ipaddr,checkpointi); - - if ( (block= iguana_findblock(coin,&space,hash2)) != 0 && block->height < coin->blocks.hwmheight ) - return(block->height - coin->blocks.hwmheight); - iguana_convblock(&space,msg,-1,0,0.); - if ( (height= iguana_addblock(coin,addr,hash2,&space)) > 0 ) - { - n = iguana_lookahead(coin,addr,&hash2,height + 1); - //printf("lookahead.%d\n",n); - } - /*if ( height+1+n > addr->maxblockhdr_height ) - { - printf("set new maxblockhdr.%d\n",height+1+n); - addr->maxblockhdr_height = height+1+n; - addr->maxblockhdr[0] = hash2; - memset(addr->maxblockhdr[1].bytes,0,sizeof(hash2)); - }*/ - //iguana_audit(coin); - return(height); -} -int32_t iguana_queue_ramchain(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,int32_t txind,int32_t numtx,struct iguana_msgtx *tx,bits256 txid) -{ - int32_t height; - addr->getdatamillis = 0; - if ( addr != 0 && txind == 0 && (height= iguana_height(coin,hash2)) >= 0 )//&& height >= addr->maxblock_height ) - { - //printf("got ramchain tx.%s from %s height.%d txind.%d\n",bits256_str(txid),addr!=0?addr->ipaddr:"local",height,txind); - /*printf("set new maxblock.%d\n",height); - addr->maxblock_height = height; - addr->maxblock[0] = hash2; - memset(addr->maxblock[1].bytes,0,sizeof(hash2));*/ - } - return(0); -} -void iguana_gottxid(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2) -{ -} - -int32_t iguana_addblock(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,struct iguana_block *newblock) -{ - int32_t h; - //,firsttxidind,txn_count,hwm=0,equivalent = 0; - //double PoW; struct iguana_block *block,space,prevspace; - //height = newblock->height, firsttxidind = newblock->firsttxidind, PoW = newblock->PoW; - //printf("iguana_addblock nBits.%x\n",newblock->bits); - /*if ( (block= iguana_findblock(coin,&space,hash2)) != 0 ) - { - if ( height >= 0 ) - { - if ( height != block->height ) - printf("iguana_addblockhdr: height.%d mismatch vs %d\n",height,block->height); - } else height = block->height; - if ( firsttxidind > 0 ) - { - if ( firsttxidind != block->firsttxidind ) - printf("iguana_addblockhdr: firsttxidind.%d mismatch vs %d\n",firsttxidind,block->firsttxidind); - } else firsttxidind = block->firsttxidind; - if ( PoW > SMALLVAL ) - { - if ( fabs(PoW - block->PoW) > SMALLVAL ) - printf("iguana_addblockhdr: PoW.%.15f mismatch vs %.15f\n",PoW,block->PoW); - } else PoW = block->PoW; - if ( (flag= iguana_blockdata(coin,block)) == 0 ) - { - printf("write out block.(%s) to %d\n",bits256_str(hash2),height); - iguana_kvwrite(coin,coin->blocks.db,hash2.bytes,newblock,sizeof(*newblock),(uint32_t *)&height); - } - else if ( flag > 0 ) - { - space2 = *block; - space2.height = newblock->height; - if ( memcmp(block,&space2,sizeof(*block)) != 0 ) - printf("newblock is different from oldblock (%d %d %f) vs (%d %d %f)\n",newblock->height,newblock->firsttxidind,newblock->PoW,block->height,block->firsttxidind,block->PoW); - else - { - equivalent = 1; - } - } - //printf("newblock (%d %d %f) vs old (%d %d %f)\n",newblock->height,newblock->firsttxidind,newblock->PoW,block->height,block->firsttxidind,block->PoW); - //iguana_audit(coin); - } - if ( memcmp(coin->chain->genesis_hashdata,hash2.bytes,sizeof(hash2)) == 0 ) - { - PoW = height = txn_count = 0; - prev = 0; - firsttxidind = 1; - hwm = 1; - block = newblock; - printf("adding genesis\n"); - } - else if ( (prev= iguana_findblock(coin,&prevspace,newblock->prev_block)) == 0 ) - { - printf("hash2.(%s) ",bits256_str(hash2)); - fprintf(stderr,"iguana_blockchain no prev block.(%s)\n",bits256_str(newblock->prev_block)); - getchar(); - return(-1); - } - else - { - if ( height >= 0 && height != prev->height + 1 ) - printf("iguana_addblock: height.%d != prev.%d+1\n",height,prev->height); - height = prev->height + 1; - PoW = prev->PoW; - firsttxidind = prev->firsttxidind; - txn_count = prev->txn_count; - }*/ - if ( (newblock->height= iguana_setchainvars(coin,addr,&newblock->firsttxidind,&newblock->PoW,hash2,newblock->prev_block,newblock->bits,newblock->txn_count)) != (uint32_t)-1 ) - { - if ( newblock->PoW > coin->blocks.hwmPoW ) - { - if ( newblock->height+1 > coin->blocks.maxblocks ) - coin->blocks.maxblocks = (newblock->height + 1); - h = newblock->height; - iguana_kvwrite(coin,coin->blocks.db,hash2.bytes,newblock,(uint32_t *)&h); - if ( addr != 0 && newblock->height > addr->height ) - addr->height = newblock->height; - coin->blocks.hwmheight = newblock->height; - coin->blocks.hwmPoW = newblock->PoW; - coin->blocks.hwmchain = hash2; - coin->latest.blockhash = hash2; - coin->latest.merkleroot = newblock->merkle_root; - coin->latest.timestamp = newblock->timestamp; - coin->latest.numblocks = coin->blocks.hwmheight+1; - coin->latest.numtxidind = newblock->firsttxidind + newblock->txn_count; - //iguana_syncmap(coin->blocks.db,0); - //printf("%s height.%d PoW %f\n",bits256_str(hash2),block->height,block->PoW); - if ( coin->initblocks != 0 ) - printf("ADD %d:%d:%d <- (%s) n.%u max.%u PoW %f\n",h,iguana_height(coin,coin->blocks.hwmchain),newblock->height,bits256_str(coin->blocks.hwmchain),coin->blocks.hwmheight+1,coin->blocks.maxblocks,newblock->PoW); - } - } - if ( memcmp(hash2.bytes,coin->blocks.hwmchain.bytes,sizeof(hash2)) != 0 ) - { - printf("ORPHAN.%s height.%d PoW %f vs best %f\n",bits256_str(hash2),newblock->height,newblock->PoW,coin->blocks.hwmPoW); - newblock->height = -1; - } - //iguana_audit(coin); - return(newblock->height); -} - -/*int32_t iguana_locator(struct iguana_info *coin,bits256 *hashes,int32_t max) - { - int32_t i,n = 0; bits256 prevhash; - hashes[n++] = coin->blocks.hwmchain; - for (i=0; iblocks.db->keyoffset + coin->blocks.db->keysize) / sizeof(struct iguana_block)); - if ( n > sizeof(blocks)/sizeof(*blocks) || coin->blocks.db->keysize != sizeof(bits256) ) - return(hash2); - for (i=0; iheight+i) == 0 ) - return(hash2); - memcpy(hash2.bytes,(void *)((long)&blocks[0] + coin->blocks.db->keyoffset),coin->blocks.db->keysize); - return(hash2); - }*/ - -int32_t iguana_blockdata(struct iguana_info *coin,struct iguana_block *block) -{ - bits256 key = iguana_blockkey(coin,block); - if ( block->height+1 >= (coin->blocks.db->state.M.allocsize / sizeof(*block)) || bits256_nonz(key) == 0 ) - return(-1); - else if ( block->height > 0 && (bits256_nonz(block->prev_block) == 0 || fabs(block->PoW) < SMALLVAL) ) - { - printf("iguana_blockdata height.%d \n",block->height); - return(0); - } - if ( block->firsttxidind > 0 ) - return(1); - return(-1); -} -/*space = mycalloc(1,sizeof(*space)); - if ( (addr= iguana_kvread(coin,space,(uint32_t *)&peerind,coin->peers,ipaddr)) == 0 ) - { - memcpy(space,&addrs[i],sizeof(*space)); - addr = space; - iguana_clear_addrstate(coin,addr); - } - else if ( addr->usock >= 0 || addr->pending != 0 || addr->dead != 0 ) - { - printf("%s usock.%d pending.%u dead.%d\n",addr->ipaddr,addr->usock,addr->pending,addr->dead); - break; - } - addr->lastcontact = (uint32_t)time(NULL); - if ( coin->numthreads < IGUANA_MAXTHREADS )//&& (coin->numactive < 3 || (coin->numactive < IGUANA_MAXPEERS/2 && iguana_metric(space) > coin->avemetric) || (coin->numactive >= IGUANA_MAXPEERS/2 && coin->numactive < IGUANA_MAXPEERS)) ) - { - addr->pending = (uint32_t)time(NULL); - addr->coin = coin; - peerind = -1; - iguana_kvwrite(coin,coin->peers,ipaddr,addr,(uint32_t *)&peerind); - portable_thread_create(iguana_startconnection,addr); - } else*/ - -{ - int32_t valuesize; void *checkptr; - valuesize = iguana_valuesize(coin,kv); - memset(kv->state.space,0,kv->RAMvaluesize); - checkptr = kv->state.space; - if ( (kv->flags & IGUANA_MAPPED_ITEM) != 0 ) - { - value = (void *)((long)value + sizeof(UT_hash_handle)); - checkptr = (void *)((long)checkptr + sizeof(UT_hash_handle)); - } - if ( iguana_RWmmap(0,kv->state.space,coin,kv,*itemindp) != 0 || memcmp(value,checkptr,valuesize) != 0 ) - { - printf("iguana_RWmmap data mismatch after kvwrite\n"); - getchar(); - } - -} -/*init_hexbytes_noT(hexstr,pk_script+1,pk_script[0]); - //printf("(%s).%02x ",hexstr,pk_script[pk_script[0]]); - if ( 1 && pk_script[1] == 4 ) - { - pk[0] = 2 + (pk_script[pk_script[0]] & 1); - memcpy(pk+1,pk_script+2,32); - init_hexbytes_noT(hexstr,pk,33); - printf("data.(%s).%d ",hexstr,pk_script[0]); - vcalc_sha256(0,sha256,pk,33); - calc_rmd160(0,rmd160,sha256,sizeof(sha256)); - init_hexbytes_noT(hexstr,rmd160,20); - printf("rmd.(%s) ",hexstr); - //decode_hex(rmd160,20,"e34498597d0d4d4be05db1bb7501da985e15aaa5"); - btc_convrmd160(coinaddr,coin->chain->addr_pubkey,rmd160); - printf("(%s)\n",coinaddr); - }*/ -/*int32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) - { - struct iguana_peer *addr=0,addrs[8]; uint32_t i,n; - #ifdef IGUANA_DISABLEPEERS - if ( strcmp(ipaddr,"127.0.0.1") != 0 ) - return(0); - #endif - if ( strncmp("0.0.0",ipaddr,5) != 0 && strcmp("0.0.255.255",ipaddr) != 0 && strcmp("1.0.0.0",ipaddr) != 0 ) - { - //printf("possible peer.(%s)\n",ipaddr); - memset(addrs,0,sizeof(addrs)); - n = iguana_connect(addrs,(int32_t)(sizeof(addrs)/sizeof(*addrs)),ipaddr,coin->chain->default_port,0); - if ( n > 0 ) - { - for (i=0; i<1; i++) // n is almost always 1 - { - strcpy(addrs[i].coinstr,coin->name); - addr = mycalloc('p',1,sizeof(*addr)); - *addr = addrs[i]; - iguana_clear_peerstate(coin,addr); - queue_enqueue("connectionQ",&coin->peers.connectionQ,&addr->DL); - return(0); - } - } - } - if ( addr != 0 ) - myfree(addr,sizeof(*addr)); - return(0); - }*/ -/*{ - for (i=0; iname); - //if ( addr->ipv6 != 0 ) - // err = iguana_connectsocket(1,addr,(struct sockaddr *)&addr->saddr6,sizeof(addr->saddr6)); - //else err = iguana_connectsocket(1,addr,(struct sockaddr *)&addr->saddr4,sizeof(addr->saddr4)); - if ( err < 0 ) - { - fprintf(stderr,"close connect %s: %s numpings.%d\n",addr->ipaddr,strerror(-err),addr->numpings); - iguana_iAkill(coin,addr); - } - else - { - iguana_iAconnected(coin,addr); - addr->ready = (uint32_t)time(NULL); - } - } - }*/ -void iguana_clear_peerstate(struct iguana_info *coin,struct iguana_peer *addr) -{ - addr->usock = -1; - addr->pingnonce = 0; - addr->ready = addr->dead = addr->pending = 0; - addr->startsend = addr->startrecv = 0; - addr->bufsize = 0; addr->buf = 0; - strcpy(addr->symbol,coin->symbol); - strcpy(addr->coinstr,coin->name); - //memset(&addr->DL,0,sizeof(addr->DL)); - //memset(&addr->sendQ,0,sizeof(addr->sendQ)); - //memset(&addr->msgcounts,0,sizeof(addr->msgcounts)); -} - -/**/ -/* - void iguana_activate(struct iguana_info *coin,struct iguana_peer *addr) - { - int32_t i;//,peerind = -1; - if ( coin->peers.numactive > 0 ) - { - for (i=0; ipeers.numactive; i++) - if ( strcmp(coin->peers.active[i].ipaddr,addr->ipaddr) == 0 ) - break; - if ( i != coin->peers.numactive ) - { - printf("duplicate activation.%s rejected\n",addr->ipaddr); - return; - } - } - coin->peers.active[coin->peers.numactive] = *addr; - myfree(addr,sizeof(*addr)); - addr = &coin->peers.active[coin->peers.numactive++]; - iguana_send_version(coin,addr,coin->myservices); - printf("ACTIVE.%d peer.(%s) numthreads.%d\n",coin->peers.numactive,addr->ipaddr,coin->numthreads); - //if ( strcmp(addr->ipaddr,"127.0.0.1") == 0 ) - // portable_thread_create(iguana_localhost,addr); - } - - void iguana_connections(struct iguana_info *coin) - { - int32_t i,j,firsti,peerind; uint32_t ipbits; struct iguana_peer *addr; - if ( coin->numthreads < IGUANA_MAXTHREADS && (addr= queue_dequeue(&coin->peers.connectionQ,0)) != 0 ) - { - if ( addr->pending == 0 ) - { - for (i=0; ipeers.active)/sizeof(*coin->peers.active); i++) - if ( strcmp(coin->peers.active[i].ipaddr,addr->ipaddr) == 0 ) - break; - if ( i == coin->peers.numactive ) - { - if ( coin->peers.numpending < sizeof(coin->peers.pending)/sizeof(*coin->peers.pending) ) - { - ipbits = (uint32_t)calc_ipbits(addr->ipaddr); - firsti = -1; - for (i=0; ipeers.pending)/sizeof(*coin->peers.pending); i++) - { - if ( coin->peers.pending[i] == 0 ) - firsti = i; - else if ( coin->peers.pending[i] == ipbits ) - break; - } - if ( i == sizeof(coin->peers.pending)/sizeof(*coin->peers.pending) ) - { - printf("PENDING.%-16s pending.%u ready.%u numpending.%d\n",addr->ipaddr,addr->pending,addr->ready,coin->numiAddrs); - coin->peers.pending[firsti] = ipbits; - addr->pending = (uint32_t)time(NULL); - strcpy(addr->symbol,coin->symbol); - iguana_launch(coin,"connection",iguana_startconnection,addr,0); - } - } - queue_enqueue("retryQ",&coin->peers.retryQ,&addr->DL); - } - } - else - { - if ( addr->ready != 0 ) - iguana_activate(coin,addr); - else if ( addr->dead == 0 ) - queue_enqueue("retryQ",&coin->peers.retryQ,&addr->DL); - } - } - }*/ - -//printf("parsed.%d firstvout.%d+%d firstvin.%d+%d: %s got.%d %s v %d\n",coin->blocks.parsedblocks,block->firstvout,block->numvouts,block->firstvin,block->numvins,addr->ipaddr,block->height,bits256_str(block->hash2),coin->blocks.hwmheight); -/*if ( block->height == coin->blocks.parsedblocks ) - iguana_parseblock(coin,block,tx,numtx); - else - { - printf("height.%d vs parsed.%d hwm.%d\n",block->height,coin->blocks.parsedblocks,coin->blocks.hwmheight); - iguana_addpending(coin,addr->ipbits,block,tx,numtx); - }*/ - -int32_t iguana_polliter(struct iguana_info *coin) -{ - struct pollfd fds[IGUANA_MAXPEERS]; - struct iguana_peer *addr,*addrs[IGUANA_MAXPEERS]; - int32_t i,n,nonz,flag,timeout=10; - memset(fds,0,sizeof(*fds)); - memset(addrs,0,sizeof(*addrs)); - flag = 0; - for (i=n=nonz=0; ipeers.active[i]; - fds[i].fd = -1; - if ( addr->usock < 0 || addr->dead != 0 || addr->ready == 0 ) - { - if ( addr->pending == 0 ) - addrs[n++] = addr; - continue; - } - if ( addr->startrecv == 0 ) - { - fds[i].fd = addr->usock; - fds[i].events |= POLLIN; - nonz++; - } - } - if ( nonz != 0 && poll(fds,IGUANA_MAXPEERS,timeout) > 0 ) - { - for (i=0; ipeers.active[i]; - if ( addr->usock < 0 || addr->dead != 0 || addr->ready == 0 ) - continue; - //if ( addr->usock >= 0 && addr->ready > 0 ) - // printf("%d/%d %d/%d startrecv.%u usock.%d dead.%d ready.%u\n",fds[i].events,fds[i].fd,POLLIN,POLLOUT,addr->startrecv,addr->usock,addr->dead,addr->ready); - if ( addr->startrecv == 0 && (fds[i].revents & POLLIN) != 0 ) - { - void iguana_processmsg(void *ptr); - flag++; - strcpy(addr->symbol,coin->symbol); - if ( 0 ) - { - addr->startrecv = (uint32_t)time(NULL); - iguana_launch("processmsg",iguana_processmsg,addr,0); - } else iguana_processmsg(addr); - } - } - } - return(flag); -} - -int32_t oldiguana_getdata(struct iguana_info *coin,struct iguana_peer *addr) -{ - struct iguana_overlap *ov = &addr->OV; - int32_t height,flag,elapsed,j,n = 0; bits256 hash2; double reqpsec,kbpsec; - //printf("iguana_getdata.(%s) ov.%p %p\n",addr->ipaddr,ov,addr); - //printf("addr height.%d vs parsed.%d\n",addr->height,coin->blocks.parsedblocks); - if ( ov->overlap == 0 ) - { - if ( strcmp("127.0.0.1",addr->ipaddr) == 0 ) - ov->overlap = IGUANA_MAXOVERLAP/2; - else ov->overlap = IGUANA_MAXOVERLAP/8; - iguana_teststart(coin,addr); - } - if ( addr != 0 && addr->dead == 0 && addr->usock >= 0 && addr->height >= coin->blocks.parsedblocks ) - { - for (flag=0; flagoverlap; flag++) - { - if ( addr->waiting[flag] == 0 ) - { - for (height=coin->blocks.parsedblocks; heightlongestchain&&heightblocks.parsedblocks+IGUANA_MAXPENDING; height++) - { - if ( coin->recvblocks != 0 && coin->recvblocks[height] != 0 ) - continue; - if ( strcmp("127.0.0.1",addr->ipaddr) == 0 ) - { - if ( height > coin->blocks.parsedblocks+IGUANA_MAXPENDING/2 ) - { - if ( n == 0 ) - { - hash2 = iguana_blockhash(coin,coin->blocks.parsedblocks); - iguana_request_data(coin,addr,&hash2,1,MSG_BLOCK); - } - return(n); - } - } - else - { - if ( height < coin->blocks.parsedblocks+IGUANA_MAXPENDING/2 ) - continue; - } - hash2 = iguana_blockhash(coin,height); - for (j=0; jwaitinghash[j].bytes,hash2.bytes,sizeof(hash2)) == 0 ) - break; - if ( j != sizeof(addr->waitinghash)/sizeof(*addr->waitinghash) ) - continue; - if ( height < coin->numwaitingbits && GETBIT(coin->waitingbits,height) == 0 ) - { - if ( bits256_nonz(hash2) != 0 ) - { - addr->waiting[flag] = (uint32_t)time(NULL); - addr->waitinghash[flag] = hash2; - if ( ov->numreqs++ >= ov->overlap ) - { - if ( ov->numreqs == ov->overlap ) - ov->numreqs = ov->overlap; - elapsed = (uint32_t)(time(NULL) - ov->teststart) + 1; - reqpsec = (double)ov->numreqs / elapsed; - kbpsec = (double)ov->reqrecv / (1024 * elapsed); - dxblend(&ov->Rsec,reqpsec,0.99); - dxblend(&ov->KBsec,kbpsec,0.99); - if ( kbpsec*reqpsec >= (ov->Rsec * ov->KBsec) ) - ov->faster++; - else ov->slower++; - if ( ((ov->faster + ov->slower) % 1000) == 0 ) - printf("OV.%-2d i.%-2d +%-4d -%-4d | h.%d %u | %5.1f/sec %5.3f/kB vs %5.1f/sec %5.3f/kB %5.1f %s\n",ov->overlap,flag,ov->faster,ov->slower,height,addr->waiting[flag],ov->Rsec,ov->KBsec,reqpsec,kbpsec,reqpsec*kbpsec-ov->Rsec*ov->KBsec,addr->ipaddr); - if ( time(NULL) > ov->teststart+60 || (ov->faster+ov->slower > ov->overlap*2 && ov->faster > 10*ov->slower) ) - iguana_teststart(coin,addr); - elapsed = (uint32_t)(time(NULL) - coin->starttime) + 1; - reqpsec = (double)coin->totalpackets / elapsed; - kbpsec = (double)coin->totalrecv / (1024 * elapsed); - dxblend(&coin->Rsec,reqpsec,0.99); - dxblend(&coin->KBsec,kbpsec,0.99); - } - n++; - //printf("request.%d bit.%d\n",height,GETBIT(coin->waitingbits,height)); - iguana_request_data(coin,addr,&hash2,1,MSG_BLOCK); - SETBIT(coin->waitingbits,height); - break; - } - } - } - } - } - } - if ( strcmp(addr->ipaddr,"127.0.0.1") == 0 && n == 0 && coin->recvblocks != 0 && coin->recvblocks[height] == 0 ) - { - hash2 = iguana_blockhash(coin,coin->blocks.parsedblocks); - iguana_request_data(coin,addr,&hash2,1,MSG_BLOCK); - } - return(n); - //printf("full.%d numactive.%d hwm.%d\n",coin->fullblocks,coin->numactive,coin->blocks.hwmheight); -} - -void iguana_teststart(struct iguana_info *coin,struct iguana_peer *addr) -{ - static uint32_t lastdisp; - int32_t dir; struct iguana_overlap *ov = &addr->OV; - dir = (ov->overlap - ov->prevoverlap); - ov->prevoverlap = ov->overlap; - if ( dir != 0 ) - { - if ( time(NULL) > lastdisp+60 ) - { - lastdisp = (uint32_t)time(NULL); - printf("ov.%-2d M%4.1f-> %5.1f/sec %6.2f/kb M%4.1f |fast.%-3d vs slow.%-3d d.%-2d | ",ov->overlap,ov->prevmetric,ov->Rsec,ov->KBsec,ov->Rsec*ov->KBsec,ov->faster,ov->slower,dir); - printf("all %5.1f/sec, %6.2fKB %s\n",coin->Rsec,coin->KBsec,addr->ipaddr); - } - if ( ov->faster > ov->slower ) - { - if ( (dir > 0 && ov->overlap < IGUANA_MAXOVERLAP) || (dir < 0 && ov->overlap > 1) ) - ov->overlap += dir; - //else printf("max overlap\n"); - //printf("increase by dir.%d -> overlap.%d\n",dir,addr->overlap); - } - else if ( dir > 0 && ov->overlap > 1 ) - { - ov->overlap--; - //printf("since slower, reduce overlap to overlap.%d\n",addr->overlap); - } - else if ( dir < 0 && ov->overlap < IGUANA_MAXOVERLAP ) - { - ov->overlap++; - //printf("since faster, increase overlap to overlap.%d\n",addr->overlap); - } - //else printf("at lowest overlap, cant change\n"); - ov->prevmetric = (ov->Rsec * ov->KBsec); - ov->reqrecv = 0; - ov->numreqs = -ov->overlap; - ov->faster = ov->slower = 0; - } - else ov->overlap = 1; - ov->teststart = (uint32_t)time(NULL); -} - -void iguana_localhost(void *ptr) -{ - struct iguana_info *coin; struct iguana_peer *addr = ptr; - if ( addr != 0 && (coin= iguana_coin(addr->symbol)) != 0 ) - { - while ( addr->dead == 0 ) - _iguana_processmsg(coin,addr); - } -} -if ( (num= iguana_available(coin,availables)) > 0 ) -{ - if ( (addr= availables[0]) != 0 ) - { - m = iguana_needed(coin,coin->need[0],IGUANA_MAXPENDING/2,0); - n = iguana_needed(coin,coin->need[1],IGUANA_MAXPENDING/2,IGUANA_MAXPENDING/2); - if ( strcmp(addr->ipaddr,"127.0.0.1") == 0 || num == 1 ) - { - //printf("m.%d n.%d num.%d\n",m,n,num); - for (i=0; ineed[0][i]; - //printf("%d ",height); - hash2 = iguana_blockhash(coin,height); - iguana_request_data(coin,addr,&hash2,1,MSG_BLOCK); - SETBIT(coin->waitingbits,height); - } - if ( num > 1 ) - { - for (i=0; ineed[1][i]; - //printf("%d ",height); - hash2 = iguana_blockhash(coin,height); - iguana_request_data(coin,availables[(i+1) % (num-1)],&hash2,1,MSG_BLOCK); - SETBIT(coin->waitingbits,height); - } - } - } - else - { - for (i=0; ineed[0][i]; - //printf("%d ",height); - hash2 = iguana_blockhash(coin,height); - iguana_request_data(coin,availables[i % num],&hash2,1,MSG_BLOCK); - SETBIT(coin->waitingbits,height); - } - } - if ( 0 && m+n > 0 ) - printf("requests\n"); - /*if ( m == 0 ) - sleep(3); - if ( m+n == 0 ) - sleep(10);*/ - return(m+n); - } else printf("null available[0]\n"); - } - -int32_t iguana_needed(struct iguana_info *coin,int32_t *need,int32_t max,int32_t offset) -{ - int32_t nonz,m,height; - if ( coin->recvblocks == 0 ) - return(0); - nonz = m = 0; - memset(need,0,sizeof(*need) * max); - if ( (time(NULL) - coin->parsetime) > 3 ) - need[m++] = coin->blocks.parsedblocks; - for (height=coin->blocks.parsedblocks+offset; heightlongestchain&&heightblocks.parsedblocks+max+offset; height++) - { - if ( coin->recvblocks[height] != 0 ) - nonz++; - else if ( GETBIT(coin->waitingbits,height) == 0 ) - need[m++] = height; - } - return(m); -} - -int32_t iguana_available(struct iguana_info *coin,struct iguana_peer *availables[IGUANA_MAXPEERS]) -{ - int32_t j,n; struct iguana_peer *addr; - memset(availables,0,sizeof(*availables) * IGUANA_MAXPEERS); - for (j=n=0; jpeers.active[j]; - if ( addr->height < coin->blocks.parsedblocks || addr == coin->localaddr ) - continue; - if ( addr->usock >= 0 && addr->dead == 0 && addr->ready > 0 && iguana_updatewaiting(coin,addr) > 0 ) - availables[n++] = addr; - } - return(n); -} - -/*int32_t iguana_loadtx(struct iguana_info *coin,struct iguana_peer *addr,bits256 *blockhashp,int32_t txind,int32_t numtx,struct iguana_msgtx *tx,uint8_t *data,int32_t maxsize) - { - int32_t len; bits256 txid; - memset(tx,0,sizeof(*tx)); - len = iguana_rwtx(0,data,tx,maxsize,&txid); - if ( blockhashp != 0 ) - { - //printf("parse.(%s)\n",bits256_str(*blockhashp)); - //if ( (blocknum= iguana_height(coin,*blockhashp)) >= 0 ) - if ( iguana_queue_ramchain(coin,addr,*blockhashp,txind,numtx,tx,txid) > 0 ) - return(len); - //else printf("cant find blockhash.(%s)\n",bits256_str(*blockhashp)); - } - iguana_purgetx(tx,0); - return(len); - }*/ -/*for (i=0; iwaiting)/sizeof(*addr->waiting); i++) - { - if ( addr->waiting[i] != 0 && time(NULL) > (addr->waiting[i] + 60) ) - { - if ( (height= iguana_height(coin,addr->waitinghash[i])) >= 0 ) - { - printf("i.%d of %ld ipbits.%x timeout.%s height.%d\n",i,sizeof(addr->waiting)/sizeof(*addr->waiting),addr->ipbits,addr->ipaddr,height); - CLEARBIT(coin->waitingbits,height); - } - addr->waiting[i] = 0; - addr->waitinghash[i] = bits256_zero; - } - if ( addr->waiting[i] == 0 ) - n++; - }*/ - -void *iguana_kvmetriciterator(struct iguana_info *coin,struct iguanakv *kv,struct iguana_kvitem *item,uint64_t args,void *key,void *value,int32_t valuesize) -{ - struct iguana_peer *addr = value; double *sortbuf = (double *)args; - if ( addr->numpings > 0 && addr->pingsum > SMALLVAL && item->hh.itemind < kv->numkeys ) - { - //printf("%p (%s).%d ind.%d msgs.%d pings.%d %.0fms [%.3f] last.%u lag.%d S.%llu R.%llu\n",sortbuf,addr->ipaddr,addr->usock,item->itemind,addr->numpackets,addr->numpings,addr->pingtime,addr->pingsum/addr->numpings,addr->lastcontact,kv->iteruarg - addr->lastcontact,(long long)addr->totalsent,(long long)addr->totalrecv); - sortbuf = &sortbuf[item->hh.itemind << 1]; - sortbuf[0] = iguana_metric(addr); - sortbuf[1] = item->hh.itemind; - } - return(0); -} - -int32_t iguana_sendrequests(struct iguana_info *coin,struct iguana_peer *addrs[],int32_t n,int32_t *blocks,int32_t m) -{ - int32_t i,height; bits256 hash2; - if ( n > 0 && m > 0 ) - { - for (i=0; iwaitingbits,height); - } - return(m); - } - return(0); -} -int32_t iguana_getdata(struct iguana_info *coin) -{ - int32_t reqs[IGUANA_READAHEAD],height,i,j,m,readahead,offset,numpeers,limit,n = 0; struct iguana_peer *addr,*addrs[IGUANA_MAXPEERS]; - if ( coin->R.waitingbits == 0 || coin->R.recvblocks == 0 ) - return(0); - capacity = iguana_capacity(coin,&numpeers,addrs); - if ( numpeers == 0 ) - return(0); - if ( capacity < numpeers ) - capacity = numpeers; - else if ( capacity > IGUANA_READAHEAD ) - capacity = IGUANA_READAHEAD; - readahead = (coin->longestchain - coin->blocks.parsedblocks) / numpeers; - for (j=m=0; jnumwaiting > IGUANA_MAXWAITING ) makes it worse - // break; - if ( coin->peers.numranked == 0 ) - addr = &coin->peers.active[j]; - else - { - if ( j >= coin->peers.numranked ) - break; - if ( (addr= coin->peers.ranked[j]) == 0 ) - continue; - } - if ( addr->recvblocks == 0 ) - limit = 1; - else - { - if ( addr == coin->peers.localaddr ) - limit = IGUANA_BUNDLESIZE; - else limit = addr->rank <= 0 ? 1 : (IGUANA_BUNDLESIZE / sqrt(addr->rank)); - if ( limit < 1 ) - limit = 1; - } - height = coin->blocks.parsedblocks; - if ( readahead < 1 ) - readahead = 1; - if ( readahead > IGUANA_READAHEAD ) - readahead = IGUANA_READAHEAD; - if ( addr->rank >= 0 && addr->ready > 0 && addr->usock >= 0 && addr->dead == 0 && addr->height > 0 ) - { - m++; - //printf("%s: addrht.%d %s p.%d getbit.%d rank.%d\n",addr->ipaddr,addr->height,addr->ipaddr,height,GETBIT(coin->waitingbits,height),addr->rank); - for (i=n=0; i<100000&&nrank > 0) ? addr->rank-1 : m)) * readahead; - height = (coin->blocks.parsedblocks + offset + i); - if ( height > coin->blocks.hwmheight || height > addr->height ) - { - //printf("%s: height.%d > hwm.%d || addr %d\n",addr->ipaddr,height,coin->blocks.hwmheight,addr->height); - break; - } - if ( coin->R.numwaiting > IGUANA_MAXWAITING && height > coin->blocks.parsedblocks+100 ) - break; - if ( iguana_waitstart(coin,height,addr) == 0 ) - { - //printf("%-15s request block.%-6d parsed.%-6d offset.%-4d rank.%-3d numpeers.%d numwaiting.%d\n",addr->ipaddr,height,coin->blocks.parsedblocks,offset,addr->rank,numpeers,coin->R.numwaiting); - n++; - } - } - } - } - return(n); -} - -/*else if ( time(NULL) > coin->parsetime+1 ) - { - coin->parsetime = (uint32_t)time(NULL); - printf("backstop.%d %s\n",coin->blocks.parsedblocks,bits256_str(iguana_blockhash(coin,coin->blocks.parsedblocks))); - iguana_waitclear(coin,coin->blocks.parsedblocks); - iguana_waitstart(coin,coin->blocks.parsedblocks,0); - iguana_updatewaiting(coin,coin->blocks.parsedblocks+1,100); - } - //else printf("ptr.%p height.%d\n",ptr,height);*/ - - -/*if ( coin->blocks.parsedblocks > initialheight ) - initialheight = coin->blocks.parsedblocks; - if ( coin->longestchain > initialheight ) - initialheight = coin->longestchain; - iguana_recvinit(coin,coin->R.numwaitingbits);*/ -//height = (coin->blocks.hwmheight / IGUANA_HDRSCOUNT) * IGUANA_HDRSCOUNT; -//iguana_queuehdrs(coin,height,iguana_blockhash(coin,height)); - -int32_t iguana_rwunspentind(struct iguana_info *coin,int32_t rwflag,struct iguana_unspent *U,uint32_t unspentind) -{ - if ( rwflag == 0 ) - { - memset(U,0,sizeof(*U)); - if ( iguana_kvread(coin,coin->unspents,0,U,&unspentind) != 0 ) - return(0); - else printf("error getting unspents[%u] when %d\n",unspentind,coin->latest.numunspents); - } - else if ( iguana_kvwrite(coin,coin->unspents,0,U,&unspentind) != 0 ) - return(0); - return(-1); -} -void iguana_requests(void *arg) -{ - int32_t flag,i,j,n; double sum; struct iguana_peer *addr; struct iguana_info *coin,**coins = arg; - n = (int32_t)coins[0]; - coins++; - printf("iguana_requests N.%d\n",n); - while ( 1 ) - { - for (i=0; iblocks.mutex); - //if ( iguana_avail(coin,coin->blocks.parsedblocks,10000) < 10000 ) - else printf("skip getting data max packets allocated %s\n",mbstr(sum)); - //portable_mutex_unlock(&coin->blocks.mutex); - } - } - if ( flag == 0 ) - usleep((uint32_t)coin->sleeptime + 1); - } -} -else -{ - if ( coin->peers.numranked > 0 && time(NULL) > coin->backstop ) - { - int32_t i; bits256 hash2; struct iguana_peer *addr; - i = (rand() % coin->peers.numranked); - hash2 = iguana_blockhash(coin,coin->blocks.parsedblocks); - addr = coin->peers.ranked[i]; - if ( addr != 0 && memcmp(hash2.bytes,addr->backstop.bytes,sizeof(hash2)) != 0 ) - { - iguana_waitclear(coin,coin->blocks.parsedblocks); - if ( addr != 0 ) - { - iguana_waitstart(coin,coin->blocks.parsedblocks,addr); - printf("%s BACKSTOP.%d\n",addr->ipaddr,coin->blocks.parsedblocks); - coin->backstop = (uint32_t)time(NULL); - } - } - } - /*if ( iguana_waitstart(coin,coin->blocks.parsedblocks,addr) == 0 ) - { - printf("backstop request.%d to %s\n",coin->blocks.parsedblocks,addr->ipaddr); - addr->backstop = hash2; - }*/ - //printf("%s skip %d vs %d ptr.%p\n",addr->ipaddr,coin->blocks.parsedblocks,coin->numwaitingbits,ptr); -} - -bits256 iguana_histo(struct iguana_info *coin) -{ - double sum = 0.; int32_t i; bits256 seed; - for (i=0; i<0x100; i++) - sum += coin->R.histo[i]; - sum /= i; - memset(seed.bytes,0,sizeof(seed)); - if ( sum > 0. ) - { - for (i=0; i<0x100; i++) - { - printf("%.2f ",coin->R.histo[i]/sum); - if ( coin->R.histo[i] > sum ) - SETBIT(seed.bytes,i); - } - } - printf("histo.(%s)\n",bits256_str(seed)); - return(seed); -} -struct iguana_state -{ - //char name[16]; - uint8_t sha256[256 >> 3]; struct sha256_vstate state; - //struct iguana_mappedptr M; struct iguana_space MEM; //queue_t writeQ; portable_mutex_t ; - void *table; - //FILE *fp; uint8_t *space; - //uint64_t maxitems; //uint32_t itemsize,flags; -}; -/*struct iguana_overlap - { - double KBsec,Rsec,prevmetric; - uint64_t reqrecv; - uint32_t teststart; - int32_t numreqs,overlap,faster,slower,prevoverlap; - };*/ - - -int32_t iguana_capacity(struct iguana_info *coin,int32_t *nump,struct iguana_peer *addrs[IGUANA_MAXPEERS]) -{ - struct iguana_peer *addr; int32_t i,n,capacity = 0; - for (i=n=0; ipeers.active[i]; - //if ( addr->usock >= 0 ) - // printf("%s ht.%d\n",addr->ipaddr,addr->height); - if ( addr->ready > 0 && addr->dead == 0 && addr->usock >= 0 && addr->height > coin->blocks.parsedblocks ) - { - capacity += addr->capacity; - addrs[n++] = addr; - } - } - *nump = n; - return(capacity); -} - -int32_t iguana_getdata(struct iguana_info *coin) -{ - int32_t reqs[IGUANA_READAHEAD],height,i,j,m,readahead,offset,numpeers,limit,n = 0; struct iguana_peer *addr,*addrs[IGUANA_MAXPEERS]; - if ( coin->R.waitingbits == 0 || coin->R.recvblocks == 0 ) - return(0); - for (i=numpeers=0; ipeers.active[i].usock < 0 ) - numpeers++; - if ( numpeers == 0 ) - return(0); - readahead = (coin->longestchain - coin->blocks.parsedblocks) / numpeers; - for (j=m=0; jnumwaiting > IGUANA_MAXWAITING ) makes it worse - // break; - if ( coin->peers.numranked == 0 ) - addr = &coin->peers.active[j]; - else - { - if ( j >= coin->peers.numranked ) - break; - if ( (addr= coin->peers.ranked[j]) == 0 ) - continue; - } - if ( addr->recvblocks == 0 ) - limit = 1; - else - { - if ( addr == coin->peers.localaddr ) - limit = IGUANA_EXPIREWINDOW; - else limit = addr->rank <= 0 ? 1 : (IGUANA_EXPIREWINDOW / sqrt(addr->rank)); - if ( limit < 1 ) - limit = 1; - } - height = coin->blocks.parsedblocks; - if ( readahead < 1 ) - readahead = 1; - if ( readahead > IGUANA_EXPIREWINDOW ) - readahead = IGUANA_EXPIREWINDOW; - if ( addr->rank >= 0 && addr->ready > 0 && addr->usock >= 0 && addr->dead == 0 && addr->height > 0 ) - { - m++; - //printf("%s: addrht.%d %s p.%d getbit.%d rank.%d\n",addr->ipaddr,addr->height,addr->ipaddr,height,GETBIT(coin->waitingbits,height),addr->rank); - for (i=n=0; i<100000&&nrank > 0) ? addr->rank-1 : m)) * readahead; - height = (coin->blocks.parsedblocks + offset + i); - if ( height > coin->blocks.hwmheight || height > addr->height ) - { - //printf("%s: height.%d > hwm.%d || addr %d\n",addr->ipaddr,height,coin->blocks.hwmheight,addr->height); - break; - } - //if ( coin->R.numwaiting > IGUANA_MAXWAITING && height > coin->blocks.parsedblocks+100 ) - // break; - if ( iguana_waitstart(coin,height,addr) != 0 ) - { - addr->capacity--; - //printf("%-15s request block.%-6d parsed.%-6d offset.%-4d rank.%-3d numpeers.%d numwaiting.%d\n",addr->ipaddr,height,coin->blocks.parsedblocks,offset,addr->rank,numpeers,coin->R.numwaiting); - n++; - } - } - } - } - return(n); -} - -int32_t newiguana_getdata(struct iguana_info *coin) -{ - int32_t reqs[IGUANA_READAHEAD],height,i,j,count,capacity,numpeers,n = 0; struct iguana_peer *addr,*addrs[IGUANA_MAXPEERS]; - if ( coin->R.waitingbits == 0 || coin->R.recvblocks == 0 ) - return(0); - capacity = iguana_capacity(coin,&numpeers,addrs); - if ( numpeers == 0 ) - return(0); - if ( capacity < numpeers ) - capacity = numpeers; - else if ( capacity > IGUANA_READAHEAD ) - capacity = IGUANA_READAHEAD; - if ( iguana_avail(coin,coin->blocks.parsedblocks,IGUANA_READAHEAD) == IGUANA_READAHEAD ) - n = iguana_updatewaiting(coin,reqs,capacity,coin->blocks.parsedblocks + (coin->longestchain - coin->blocks.parsedblocks)/2); - else n = iguana_updatewaiting(coin,reqs,IGUANA_READAHEAD,coin->blocks.parsedblocks); - count = 0; - height = coin->blocks.parsedblocks; - //printf("capacity.%d reqs.%d numpeers.%d\n",capacity,n,numpeers); - if ( n > 0 ) - { - for (i=0; iR.numwaiting > IGUANA_MAXWAITING )//&& height > coin->blocks.parsedblocks+100 ) - break; - for (j=0; jcapacity > 0 && addr->height >= height ) - { - count += iguana_waitstart(coin,height,addr); - break; - } - } - if ( j == numpeers ) - { - //printf("leftover.%d n.%d\n",i,n); - if ( (addr= addrs[(i+j) % numpeers]) != 0 && addr->height >= height ) - count += iguana_waitstart(coin,height,addr); - break; - } - } - } - //for (i=0; i= 0 ) - { - if ( flag == 0 ) - { - - } - printf("gotheaders flag.%d n.%d (%s) %d vs %d \n",flag,n,bits256_str(blocks[n-1].hash2),iguana_height(coin,blocks[n-1].hash2),coin->blocks.hwmheight); - if ( n > 0 && iguana_height(coin,blocks[n-1].hash2) > coin->blocks.hwmheight-1000 ) - iguana_send_hashes(coin,strcmp(coin->name,"bitcoin") != 0 ? "getblocks" : "getheaders",addr,bits256_zero,&blocks[n-1].hash2,1); - } - printf("%s gotheaders.%d height.%d flag.%d\n",addr->ipaddr,n,coin->blocks.hwmheight,flag); - //portable_mutex_unlock(&coin->blocks.mutex); - }*/ - - -//#define IGUANA_OVERLAP 64 -//#define IGUANA_MAXWAITING (2 * IGUANA_MAXPEERS * IGUANA_OVERLAP) -//#define IGUANA_EXPIREWINDOW 1000 -//#define IGUANA_READAHEAD (IGUANA_EXPIREWINDOW) - -#ifndef IGUANA_DEDICATED_THREADS -limit = 1; -if ( addr->ipbits != 0 && addr->pendhdrs < limit && (hashstr= queue_dequeue(&coin->R.hdrsQ,1)) != 0 ) -{ - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - iguana_send_hashes(coin,strcmp(coin->name,"bitcoin") != 0 ? "getblocks" : "getheaders",addr,bits256_zero,&hash2,1); - queue_enqueue("pendinghdrsQ",&coin->R.pendinghdrsQ[0],(void *)((long)hashstr - sizeof(struct queueitem)),0); - //printf("dequeue hdrsQ.(%s) -> %s pendinghdrsQ\n",hashstr,addr->ipaddr); - addr->hdrmillis = milliseconds(); - addr->pendhdrs++; - flag++; -} -if ( addr->recvblocks == 0 ) -limit = 1; -else limit = IGUANA_MAXPENDING; -if ( addr->ipbits != 0 && addr->pendblocks < limit && (hashstr= queue_dequeue(&coin->blocksQ,1)) != 0 ) -{ - //printf("dequeued.(%s) for %s\n",hashstr,addr->ipaddr); - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - if ( memcmp(hash2.bytes,coin->chain->genesis_hashdata,sizeof(hash2)) != 0 ) - { - iguana_request_data(coin,addr,&hash2,1,MSG_BLOCK,0); - addr->pendblocks++; - flag++; - } - free_queueitem(hashstr); -} -#endif - -void newiguana_updatehdrs(struct iguana_info *coin) -{ - int32_t i,j,hdri,flag,iter; char *hashstr; struct iguana_hdrs *hdrs; bits256 hash2; - portable_mutex_lock(&coin->R.hdrsmutex); - if ( iguana_needhdrs(coin) == 0 ) - return; - iguana_requesthdrs(coin,0); - return; - hdri = (coin->blocks.hwmheight / IGUANA_HDRSCOUNT); - hdrs = &coin->R.hdrs[hdri]; - if ( time(NULL) > coin->R.lasthdrtime+3 && coin->blocks.hwmheight < coin->longestchain-500 ) - { - for (iter=flag=0; iter<2; iter++) - { - while ( flag == 0 && (hashstr= queue_dequeue(&coin->R.pendinghdrsQ[iter],1)) != 0 ) - { - //printf("timeout found pending.(%s)\n",hashstr); - flag++; - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - for (j=0; j<2; j++) - iguana_send_hashes(coin,strcmp(coin->name,"bitcoin") != 0 ? "getblocks" : "getheaders",0,bits256_zero,&hash2,1); - //queue_enqueue("resubmit",&coin->R.pendinghdrsQ[iter ^ 1],(void *)((long)hashstr - sizeof(struct queueitem)),0); - coin->R.lasthdrtime = (uint32_t)time(NULL); - break; - } - } - if ( hdrs->blocks == 0 && coin->peers.numranked > 2 ) - { - hash2 = iguana_blockhash(coin,hdri * IGUANA_HDRSCOUNT); - printf("hdrs backstop %d %s\n",hdri * IGUANA_HDRSCOUNT,bits256_str(hash2)); - for (j=0; j<3; j++) - iguana_send_hashes(coin,strcmp(coin->name,"bitcoin") != 0 ? "getblocks" : "getheaders",coin->peers.ranked[j],bits256_zero,&hash2,1); - coin->R.lasthdrtime = (uint32_t)time(NULL); - } - } - if ( coin->blocks.hwmheight > 100000 && coin->R.savedhdrs < coin->blocks.hwmheight-501 ) - coin->R.savedhdrs = iguana_savehdrs(coin); - //printf("hdri.%d height.%d n.%d %p coin->R.savedhdrs.%u\n",hdri,hdrs->height,hdrs->n,hdrs->blocks,coin->R.savedhdrs); - if ( hdrs->blocks != 0 && (hdrs->height + hdrs->n) > coin->blocks.hwmheight ) - iguana_processhdrs(coin,hdrs->blocks,hdrs->n); - for (i=0; iR.hdrs[i]; - if ( coin->blocks.hwmheight >= (hdrs->height + hdrs->n) ) - { - if ( hdrs->blocks != 0 ) - { - myfree(hdrs->blocks,hdrs->n * sizeof(*hdrs->blocks)); - hdrs->blocks = 0; - } - if ( hdrs->conflictblocks != 0 ) - { - myfree(hdrs->conflictblocks,hdrs->n * sizeof(*hdrs->conflictblocks)); - hdrs->conflictblocks = 0; - } - } - } - portable_mutex_unlock(&coin->R.hdrsmutex); -} -void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n) -{ - int32_t i,iter,flag; char hexstr[65],*hashstr; - addr->lastrequest = bits256_zero; - addr->recvhdrs++; - if ( addr->pendhdrs > 0 ) - addr->pendhdrs--; - coin->R.lasthdrtime = (uint32_t)time(NULL); - iguana_processhdrs(coin,blocks,n); - return; - //printf("hdrs.(%s) n.%d from %s\n",bits256_str(blocks[0].hash2),n,addr->ipaddr); - portable_mutex_lock(&coin->R.hdrsmutex); - for (i=0; iR.numhdrs; i++) - { - if ( memcmp(coin->R.hdrs[i].hash2.bytes,blocks[0].prev_block.bytes,sizeof(bits256)) == 0 ) - { - init_hexbytes_noT(hexstr,blocks[0].prev_block.bytes,sizeof(bits256)); - for (iter=flag=0; iter<2; iter++) - { - while ( flag == 0 && (hashstr= queue_dequeue(&coin->R.pendinghdrsQ[iter],1)) != 0 ) - { - if( strcmp(hashstr,hexstr) == 0 ) - { - free_queueitem(hashstr); - //printf("found pending.(%s) hdri.%d\n",hexstr,(coin->blocks.hwmheight / IGUANA_HDRSCOUNT)); - flag++; - break; - } - queue_enqueue("requeue",&coin->R.pendinghdrsQ[iter ^ 1],(void *)((long)hashstr - sizeof(struct queueitem)),0); - } - } - if ( coin->R.hdrs[i].blocks == 0 ) - { - coin->R.hdrs[i].blocks = blocks; - coin->R.hdrs[i].n = n; - printf("got headers for %d[%d] from %s\n",coin->R.hdrs[i].height,n,addr->ipaddr); - if ( addr != 0 && coin->R.hdrs[i].height+n > addr->height ) - addr->height = coin->R.hdrs[i].height+n; - } - else if ( coin->R.hdrs[i].n == n && memcmp(coin->R.hdrs[i].blocks,blocks,n*sizeof(*blocks)) == 0 ) - { - coin->R.hdrs[i].duplicates++; - printf("duplicate.%d blocks for height.%d n.%d\n",coin->R.hdrs[i].duplicates,coin->R.hdrs[i].height,n); - myfree(blocks,sizeof(*blocks) * n); - } - else - { - if ( coin->R.hdrs[i].conflictblocks != 0 ) - { - myfree(coin->R.hdrs[i].conflictblocks,coin->R.hdrs[i].conflictblocksn * sizeof(struct iguana_block)); - } - coin->R.hdrs[i].conflicts++; - printf("conflict.%d blocks for height.%d n.%d\n",coin->R.hdrs[i].conflicts,coin->R.hdrs[i].height,n); - coin->R.hdrs[i].conflictblocks = blocks; - coin->R.hdrs[i].conflictblocksn = n; - } - portable_mutex_unlock(&coin->R.hdrsmutex); - return; - } - } - printf("got unexpected hdrs[%d] prev %s\n",n,bits256_str(blocks[0].prev_block)); - myfree(blocks,sizeof(*blocks) * n); - portable_mutex_unlock(&coin->R.hdrsmutex); -} -void iguana_connections(void *arg) -{ - FILE *fp; uint8_t serialized[sizeof(struct iguana_msghdr)]; struct iguana_info *coin,**coins = arg; - int32_t i,j,r,n,iter,flag; uint32_t now,lastrank; char fname[512]; - struct iguana_peer *addr; - n = (int32_t)coins[0]; - lastrank = (uint32_t)time(NULL); - coins++; - for (i=0; isymbol,(iter == 0) ? "peers" : "hdrs"); - if ( (fp= fopen(fname,"r")) != 0 ) - iguana_parseline(coin,iter,fp); - fclose(fp); - } - //iguana_recvinit(coin,coin->R.numwaitingbits); - } - while ( 1 ) - { - if ( time(NULL) > lastrank+60 ) - { - for (i=0; ipeers.mutex); - iguana_peermetrics(coins[i]); - portable_mutex_unlock(&coin->peers.mutex); - } - lastrank = (uint32_t)time(NULL); - } - now = (uint32_t)time(NULL); - for (i=flag=0; ipeers.active[(j + r) % IGUANA_MAXPEERS]; - if ( addr->usock >= 0 && addr->ipbits != 0 ) - { - if ( addr->dead == 0 && addr->ready > 0 ) - { - if ( now > addr->lastblockrecv+60 && addr->pendblocks > 0 ) - addr->pendblocks--; - if ( now > coin->peers.lastpeer+300 ) - iguana_queue_send(coin,addr,serialized,"getaddr",0,0,0); - } - //printf("%s pend.(%d %d) dead.%u ready.%u relay.%d millis.%.0f hwm.%d\n",addr->ipaddr,addr->pendhdrs,addr->pendblocks,addr->dead,addr->ready,addr->relayflag,addr->hdrmillis,coin->blocks.hwmheight); - } - } - if ( now > coin->peers.lastpeer+300 ) - { - printf("lastpeer %u vs now.%u, startpeers\n",coin->peers.lastpeer,now); - coin->peers.lastpeer = now; - } - } - iguana_shutdownpeers(coin,0); // closes dead peers to free up open spots - } - if ( flag == 0 ) - usleep(10000); - } -} -&& ((packet= queue_dequeue(&addr->sendQ,0)) != 0 || (packet= queue_dequeue(&coin->sendQ,0)) != 0) ) -{ - //printf("%d %s: usock.%d dead.%u ready.%u\n",i,addr->ipaddr,addr->usock,addr->dead,addr->ready); - flag++; - if ( (packet->addr != 0 && packet->addr != addr) || (packet->getdatablock > 0 && packet->getdatablock < coin->blocks.parsedblocks) || coin->R.recvblocks[packet->getdatablock] != 0 ) - { - if ( coin->R.recvblocks[packet->getdatablock] == 0 ) - printf("peerloop: (%s).%d packetaddr.%p != %p || packet->getdatablock %d < %d coin->blocks.parsedblocks recv[%p]\n",packet->serialized+4,packet->datalen,packet->addr,addr,packet->getdatablock,coin->blocks.parsedblocks,coin->R.recvblocks[packet->getdatablock]); - myfree(packet,sizeof(*packet) + packet->datalen); - } - else - { - if ( 1 && addr != coin->peers.localaddr ) - { - if ( ) - { - addr->startsend = (uint32_t)time(NULL); - strcpy(addr->symbol,coin->symbol); - strcpy(addr->coinstr,coin->name); - iguana_launch("send_data",iguana_issue,packet,IGUANA_SENDTHREAD); - } else printf("need to wait for pending sends %d\n",iguana_numthreads(1<serialized,packet->datalen); - if ( packet->getdatablock > 0 ) - iguana_setwaitstart(coin,packet->getdatablock); - myfree(packet,sizeof(*packet) + packet->datalen); - } - } - void iguana_queuehdrs(struct iguana_info *coin,int32_t height,bits256 hash2) - { - char hashstr[65]; //int32_t hdrsi; - init_hexbytes_noT(hashstr,hash2.bytes,sizeof(hash2)); - queue_enqueue("hdrsQ",&coin->R.hdrsQ,queueitem(hashstr),1); - //printf("try to queue hdr.(%s) height.%d vs %d\n",hashstr,height,coin->blocks.hwmheight); - /*if ( (height % IGUANA_HDRSCOUNT) == 0 && height+1 >= coin->blocks.hwmheight ) - { - hdrsi = (height / IGUANA_HDRSCOUNT); - if ( (height == 0 || coin->R.hdrs[hdrsi].height == 0) && coin->R.hdrs[hdrsi].duplicates == 0 ) - { - coin->R.hdrs[hdrsi].hash2 = hash2; - coin->R.hdrs[hdrsi].height = height; - if ( hdrsi >= coin->R.numhdrs ) - coin->R.numhdrs = hdrsi + 1; - //printf("queued hdr.(%s)\n",hashstr); - queue_enqueue("hdrsQ",&coin->R.hdrsQ,queueitem(hashstr),1); - } - }*/ - } - - int32_t iguana_queue_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,char *cmd,int32_t len,int32_t getdatablock,int32_t forceflag) - { - struct iguana_packet *packet; int32_t datalen; - if ( addr == 0 ) - { - printf("iguana_queue_send null addr\n"); - getchar(); - return(-1); - } - datalen = iguana_sethdr((void *)serialized,coin->chain->netmagic,cmd,&serialized[sizeof(struct iguana_msghdr)],len); - if ( strcmp("getaddr",cmd) == 0 && time(NULL) < addr->lastgotaddr+300 ) - return(0); - if ( strcmp("version",cmd) == 0 ) - return(iguana_send(coin,addr,serialized,datalen)); - packet = mycalloc('S',1,sizeof(struct iguana_packet) + datalen); - packet->datalen = datalen; - packet->addr = addr; - if ( 1 && (packet->getdatablock = getdatablock) == 0 && strcmp((char *)&serialized[4],"getdata") == 0 ) - { - printf("no need to request genesis\n"); - getchar(); - } - memcpy(packet->serialized,serialized,datalen); - //printf("%p queue send.(%s) %d to (%s) %x\n",packet,serialized+4,datalen,addr->ipaddr,addr->ipbits); - queue_enqueue("sendQ",addr != 0 ? &addr->sendQ : &coin->sendQ,&packet->DL,0); - //printf("queue send.(%s) datalen.%d addr.%p %s [%d]\n",cmd,len,addr,addr!=0?addr->ipaddr:"",getdatablock); - if ( addr == 0 || (addr->dead == 0 && addr->ipbits != 0) ) - { - if ( addr == 0 && getdatablock == 0 ) - addr = iguana_choosepeer(coin); - if ( addr == coin->peers.localaddr || (getdatablock == 0 && strcmp(cmd,"getdata") != 0) ) - forceflag = 1; - if ( forceflag != 0 ) - { - if ( getdatablock >= coin->blocks.parsedblocks ) - len = iguana_send(coin,addr!=0?addr:iguana_choosepeer(coin),serialized,datalen); - else len = -1; - } - else - { - packet = mycalloc('S',1,sizeof(struct iguana_packet) + datalen); - packet->datalen = datalen; - packet->addr = addr; - if ( 1 && (packet->getdatablock = getdatablock) == 0 && strcmp((char *)&serialized[4],"getdata") == 0 ) - { - printf("no need to request genesis\n"); - getchar(); - } - memcpy(packet->serialized,serialized,datalen); - //printf("%p queue send.(%s) %d to (%s) %x\n",packet,serialized+4,datalen,addr->ipaddr,addr->ipbits); - queue_enqueue("sendQ",addr != 0 ? &addr->sendQ : &coin->sendQ,&packet->DL,0); - } - } else printf("cant send.(%s) len.%d datalen.%d to null addr or dead.%u\n",&serialized[4],len,datalen,addr->dead); - return(len); - } - while ( (packet= queue_dequeue(&addr->sendQ,0)) != 0 ) - { - if ( packet->getdatablock > 0 && packet->getdatablock < coin->blocks.parsedblocks ) - { - packet->addr = 0; - printf("recycle pending sendQ block.%d\n",packet->getdatablock); - queue_enqueue("shutdown_sendQ",&coin->blocksQ,&packet->DL,0); - } else myfree(packet,sizeof(*packet) + packet->datalen); - } - -void iguana_dedicatedrecv(void *arg) -{ - struct iguana_info *coin = 0; uint8_t *buf; int32_t bufsize; struct iguana_peer *addr = arg; - if ( addr == 0 || (coin= iguana_coin(addr->symbol)) == 0 ) - { - printf("iguana_dedicatedrecv nullptrs addr.%p coin.%p\n",addr,coin); - return; - } - printf("DEDICATED RECV %s\n",addr->ipaddr); - bufsize = IGUANA_MAXPACKETSIZE; - buf = mycalloc('r',1,bufsize); - while ( addr->usock >= 0 && addr->dead == 0 && coin->peers.shuttingdown == 0 ) - _iguana_processmsg(coin,addr,buf,bufsize); - myfree(buf,bufsize); -} - if ( packet->getdatablock > 0 && (packet->getdatablock < coin->blocks.parsedblocks || coin->R.recvblocks[packet->getdatablock] != 0) ) - { - printf("discard sendQ for getdatablock.%d parsed.%d\n",packet->getdatablock,coin->blocks.parsedblocks); - myfree(packet,sizeof(*packet) + packet->datalen); - return(1); - - void iguana_issue(void *ptr) - { - uint32_t ipbits; char ipaddr[64]; struct iguana_peer *addr; struct iguana_info *coin=0; struct iguana_packet *packet = ptr; - if ( (addr= packet->addr) == 0 || (coin= iguana_coin(addr->symbol)) == 0 || addr->dead != 0 ) - { - printf("iguana_issue: addr %p coin.%p dead.%u\n",addr,coin,addr->dead); - return; - } - ipbits = (uint32_t)calc_ipbits(addr->ipaddr); - expand_ipbits(ipaddr,ipbits); - if ( strcmp(ipaddr,addr->ipaddr) == 0 ) - { - if ( packet->getdatablock == 0 ) - iguana_send(coin,addr,packet->serialized,packet->datalen); - else if ( packet->getdatablock > 0 && packet->getdatablock >= coin->blocks.parsedblocks ) - { - //printf("req block.%d to (%s) numthreads.%d\n",packet->getdatablock,packet->addr->ipaddr,iguana_numthreads(1 << IGUANA_SENDTHREAD)); - iguana_send(coin,addr,packet->serialized,packet->datalen); - iguana_setwaitstart(coin,packet->getdatablock); - } - } - else printf("iguana_issue: ipaddr mismatch.(%s) != (%s)\n",ipaddr,addr->ipaddr), getchar(); - //printf("finished sending %d to (%s) numthreads.%d\n",packet->datalen,packet->addr->ipaddr,iguana_numthreads(-1)); - addr->startsend = 0; - myfree(packet,sizeof(*packet) + packet->datalen); - } - - uint64_t iguana_validaterecv(struct iguana_info *coin,int32_t *nump,char *fname) - { - struct iguana_pending *ptr; struct iguana_block space; struct iguana_msgtx *tx; - int32_t n = 0; struct iguana_mappedptr M; struct iguana_memspace RSPACE; uint64_t allocated = 0; - memset(&M,0,sizeof(M)); - memset(&RSPACE,0,sizeof(RSPACE)); - if ( (ptr= iguana_mappedptr(0,&M,0,0,fname)) != 0 ) - { - RSPACE.ptr = M.fileptr; - RSPACE.used = 0; - RSPACE.size = M.allocsize; - printf("process.(%s) %ld\n",fname,(long)M.allocsize); - n = 0; - while ( ptr != 0 && ((long)ptr - (long)RSPACE.ptr)+ptr->next < (RSPACE.size - sizeof(*ptr)) ) - { - //printf("ptr diff.%d next.%d\n",(int32_t)((long)ptr - (long)RSPACE.ptr),ptr->next); - if ( (tx= iguana_validpending(coin,ptr,&space)) != 0 ) - { - //printf("%d: ht.%-6d size.%d next.%d\n",n,ptr->block.height,ptr->allocsize,ptr->next); - iguana_freetx(tx,ptr->numtx); - allocated += ptr->allocsize; - n++; - coin->R.recvblocks[ptr->block.height] = ptr; - } - else - { - printf("n.%d ht.%d: tx doesnt validate\n",n,ptr->block.height); - } - if ( ptr->next != 0 ) - ptr = (void *)((long)ptr + ptr->next); - else break; - } - if ( n == 0 ) - iguana_closemap(&M); - } - *nump = n; - return(allocated); - } - for (i=maxi=skipped=total=0; skipped<10; i++) - { - if ( coin->R.maprecvdata == 0 ) - break; - sprintf(fname,"tmp/%s/recv.%d",coin->symbol,i), iguana_compatible_path(fname); - if ( (allocated= iguana_validaterecv(coin,&n,fname)) != 0 ) - combined += allocated, total += n, skipped = 0, maxi = i; - else if ( skipped++ > 10 ) - break; - } - - /*for (i=0; isymbol); - ensure_directory(dirname); - sprintf(dirname,"tmp/%s",coin->symbol); - ensure_directory(dirname); - }*/ - //iguana_launch("peers",iguana_connections,coins,IGUANA_PERMTHREAD); - //iguana_launch("requests",iguana_requests,coins,IGUANA_PERMTHREAD); - - //portable_mutex_t hdrsmutex; struct iguana_hdrs *hdrs; uint32_t savedhdrs,lasthdrtime,numhdrs; - struct iguana_hdrs - { - bits256 hash2; - struct iguana_block *blocks,*conflictblocks; - int32_t n,conflictblocksn,height,conflicts,duplicates; - }; - - - bits256 iguana_unspentmap(struct iguana_info *coin,uint32_t *spendindp,uint32_t *txidindp,char *txidstr,uint32_t unspentind) - { - struct iguana_unspent U; - memset(&U,0,sizeof(U)); - if ( iguana_rwunspentind(coin,0,&U,unspentind) == 0 ) - { - *txidindp = U.txidind; - *spendindp = U.spendind; - if ( txidstr != 0 ) - return(iguana_txidstr(coin,0,0,txidstr,U.txidind)); - } - else printf("error getting unspents[%u] when %d\n",unspentind,coin->latest.numunspents), getchar(); - return(bits256_zero); - } - - int32_t iguana_inittxid(struct iguana_info *coin,struct iguanakv *kv,void *key,void *value,int32_t itemind,int32_t itemsize,int32_t numitems) - { - char txidstr[513]; bits256 checktxid; uint32_t txidind,spendind; struct iguana_txid *tx = value; - if ( key != 0 && value != 0 && itemind > 0 ) - { - //printf("inittxid.(%s) itemind.%d (%d %d)\n",bits256_str(tx->txid),itemind,tx->firstvout,tx->firstvin); - checktxid = iguana_unspentmap(coin,&spendind,&txidind,txidstr,tx->firstvout); - if ( memcmp(checktxid.bytes,key,sizeof(checktxid)) != 0 || txidind != itemind ) - { - printf("checktxid.%s miscompares to %s, txidind.%d vs itemind.%d\n",txidstr,bits256_str(tx->txid),txidind,itemind); - getchar(); - return(-1); - } - if ( spendind >= coin->latest.numspends ) - { - //struct iguana_unspent U; - //iguana_rwunspentind(coin,0,&U,tx->firstvout); - //U.spendind = 0; - //iguana_rwunspentind(coin,1,&U,tx->firstvout); - printf("spendind.%d vs %d overflow in txid.%s txidind.%d U%d autocleared\n",spendind,coin->latest.numspends,txidstr,tx->firstvout,tx->firstvout); - } - //printf("txidind.%d: 1st.(%d %d)\n",txidind,tx->firstvout,tx->firstvin); - } - return(0); - } - - /*if ( flag != 0 && height > 0 ) - { - if ( coin->latest.numtxids != lastblock.L.firsttxidind + lastblock.txn_count && iguana_kvtruncate(coin,coin->txids,lastblock.L.firsttxidind + lastblock.txn_count) < 0 ) - err |= 1; - if ( coin->latest.numunspents != lastblock.L.firstvout + lastblock.numvouts && iguana_kvtruncate(coin,coin->unspents,lastblock.L.firstvout + lastblock.numvouts) < 0 ) - err |= 2; - if ( coin->latest.numspends != lastblock.L.firstvin + lastblock.numvins && iguana_kvtruncate(coin,coin->spends,lastblock.L.firstvin + lastblock.numvins) < 0 ) - err |= 4; - if ( coin->latest.numpkhashes != lastblock.L.numpkinds && iguana_kvtruncate(coin,coin->pkhashes,lastblock.L.numpkinds) < 0 ) - err |= 8; - } - else - { - printf("reset counters flag.%d height.%d\n",flag,height); //getchar(); - } - if ( err != 0 ) - return(-err);*/ - checktxid = iguana_txidstr(coin,0,0,txidstr,txidind); - if ( memcmp(checktxid.bytes,txid.bytes,sizeof(txid)) != 0 ) - { - int32_t i; - printf("error kvwrite/read of txid.%s vs %s txidind.%d\n",bits256_str(txid),bits256_str2(checktxid),txidind); - for (i=-10; i<10; i++) - { - iguana_rwtxidind(coin,0,&tx,txidind+i); - printf("txidind.%d %s\n",txidind+i,bits256_str(tx.txid)); - } - getchar(); - return(0); - } - checkind = iguana_txidind(coin,&checkfirstvout,&checkfirstvin,txid); - if ( checkind != txidind || checkfirstvout != firstvout || checkfirstvin != firstvin ) - { - printf("error kvwrite/read of txidind.%d:%d %s firstvout.%d vs %d firstvin.%d vs %d\n",txidind,checkind,bits256_str(txid),firstvout,checkfirstvout,checkfirstvin,firstvin); - getchar(); - return(0); - } - - int32_t iguana_recvinit(struct iguana_info *coin,int32_t initialheight) - { - //int32_t maxi,total; uint64_t allocated,combined = 0; - //portable_mutex_init(&coin->R.RSPACE.mutex); - //memset(&coin->R.RSPACE,0,sizeof(coin->R.RSPACE)); - //coin->R.RSPACE.size = 1024*1024*128; - //coin->R.RSPACE.counter = total != 0 ? maxi+1 : 0; - return(0); - } - - int32_t iguana_initpkhash(struct iguana_info *coin,struct iguanakv *kv,void *key,void *value,int32_t itemind,int32_t itemsize,int32_t numitems) - { - int64_t balance; uint64_t credits,debits; int32_t numutxo; uint32_t unspents[64]; struct iguana_pkhash *P = value; - if ( key != 0 && value != 0 && itemind > 0 ) - { - if ( (balance= iguana_balance(coin,&credits,&debits,&numutxo,unspents,sizeof(unspents)/sizeof(*unspents),P,itemind)) < 0 ) - { - printf("iguana_balance error pkind.%d %.8f vs %.8f\n",itemind,dstr(balance),dstr(P->balance)); - getchar(); - return(-1); - } - coin->latest.credits += credits; - coin->latest.debits += debits; - } - return(0); - } - /* - - int64_t iguana_balance(struct iguana_info *coin,uint64_t *creditsp,uint64_t *debitsp,int32_t *nump,uint32_t *unspents,long max,struct iguana_pkhash *P,uint32_t pkind) - { - uint32_t unspentind,spendind,lastunspentind,lastspendind,flag,n = 0; int64_t credits,debits,net = 0; - struct iguana_unspent U; struct iguana_spend S; - *creditsp = *debitsp = net = credits = debits = lastunspentind = lastspendind = flag = 0; - unspentind = P->firstunspentind; - while ( unspentind > 0 ) - { - lastunspentind = unspentind; - if ( iguana_rwunspentind(coin,0,&U,unspentind) == 0 ) - { - credits += U.value; - if ( U.spendind == 0 ) - { - net += U.value; - if ( n < max && unspents != 0 ) - unspents[n] = unspentind; - } - n++; - if ( unspentind != P->lastunspentind && U.nextunspentind > 0 && U.nextunspentind > unspentind && U.nextunspentind < coin->latest.numunspents ) - unspentind = U.nextunspentind; - else - { - if ( U.nextunspentind == 0 ) // cleared during unspents init - { - P->lastunspentind = unspentind = lastunspentind; - flag++; - } - break; - } - } else return(-1); - } - if ( unspentind == P->lastunspentind ) - { - if ( (spendind= P->firstspendind) >= coin->latest.numspends ) - { - P->firstspendind = P->lastspendind = spendind = 0; - flag++; - } - while ( spendind > 0 ) - { - lastspendind = spendind; - if ( iguana_rwspendind(coin,0,&S,spendind) == 0 ) - { - if ( S.unspentind > 0 && S.unspentind < coin->latest.numunspents && iguana_rwunspentind(coin,0,&U,S.unspentind) == 0 ) - { - debits += U.value; - if ( spendind != P->lastspendind && S.nextspendind > 0 && S.nextspendind > spendind && S.nextspendind < coin->latest.numspends ) - spendind = S.nextspendind; - } else S.nextspendind = 0; - if ( S.nextspendind == 0 ) // cleared during spends init - { - P->lastspendind = spendind = lastspendind; - flag++; - break; - } - } else return(-1); - } - if ( flag != 0 ) - { - if ( iguana_rwpkind(coin,1,P,pkind) < 0 ) - printf("error "); - printf("pkind.%d autofix\n",pkind); - P->balance = (credits - debits); - } - if ( net != (credits - debits) ) - printf("iguana_balance: total mismatch %.8f != %.8f (%.8f - %.8f)\n",dstr(net),dstr(credits)-dstr(debits),dstr(credits),dstr(debits)); - *nump = n; - *creditsp = credits; - *debitsp = debits; - return(net); - } else printf("iguana_balance error: unspentind.%u != last.%u\n",unspentind,P->lastunspentind); - *nump = 0; - return(-1); - }*/ - - int32_t iguana_processhdrs(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n) - { - bits256 hash2; int32_t i,flag=0,startheight = -1,height = -1; struct iguana_block space,*block; - if ( startheight >= 0 ) - { - printf("%s received headers %d [%d] %s\n",addr->ipaddr,startheight,n,bits256_str(blocks[0].hash2)); - if ( startheight+n < coin->blocks.hwmheight ) - return(-1); - for (i=0; iblocks.hwmheight ) - continue; - if ( (block= iguana_findblock(coin,&space,blocks[i].hash2)) == 0 || height > coin->blocks.hwmheight ) - { - if ( (height= iguana_addblock(coin,blocks[i].hash2,&blocks[i])) > 0 ) - { - iguana_gotdata(coin,0,blocks[i].height,blocks[i].hash2); - flag++; - } - } else printf("height.%d:%d %s block.%p flag.%d\n",height,blocks[i].height,bits256_str(blocks[i].hash2),block,flag); - } - if ( flag != 0 ) - { - //iguana_queuehdrs(coin,blocks[n-1].height,blocks[n-1].hash2,1); - //iguana_lookahead(coin,&hash2,coin->blocks.hwmheight + 1); - } - } - iguana_lookahead(coin,&hash2,coin->blocks.hwmheight + 1); - return(flag); - } - - /*int32_t iguana_updatewaiting(struct iguana_info *coin,int32_t starti,int32_t max) - { - int32_t i,height,gap,n = 0; uint32_t now; - now = (uint32_t)time(NULL); - height = starti; - for (i=0; iblocks.parsedblocks); - if ( gap >= 0 ) - gap = sqrt(gap); - if ( gap < 1 ) - gap = 1; - if ( height < coin->R.numwaitingbits && coin->R.recvblocks[height] == 0 && now > (coin->R.waitstart[height] + gap) ) - { - //printf("restart height.%d width.%d widthready.%d %s\n",height,coin->width,coin->widthready,bits256_str(iguana_blockhash(coin,height))); - iguana_waitclear(coin,height); - iguana_waitstart(coin,height); - } //else printf("%d %d %p %u\n",height,coin->R.numwaitingbits,coin->R.recvblocks[height],coin->R.waitstart[height]); - } - //printf("height.%d max.%d\n",starti,max); - height = starti; - for (i=0; iR.recvblocks[height] != 0 ) - n++; - return(n); - }*/ - - /*void iguana_queuehdrs(struct iguana_info *coin,int32_t height,bits256 hash2,int32_t forceflag) - { - char hashstr[65]; - if ( memcmp(bits256_zero.bytes,hash2.bytes,sizeof(hash2)) == 0 ) - { - printf("trying to queue null hash\n"); - getchar(); - } - if ( height < 0 ) - forceflag = 1; - if ( (forceflag != 0 && height > coin->blocks.hwmheight-coin->chain->bundlesize) || (height/coin->chain->bundlesize) > (coin->R.topheight/coin->chain->bundlesize) ) - { - printf("queue hdrs height.%d %s\n",height,bits256_str(hash2)); - coin->R.pendingtopheight = coin->R.topheight; - coin->R.pendingtopstart = (uint32_t)time(NULL); - init_hexbytes_noT(hashstr,hash2.bytes,sizeof(hash2)); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - } - }*/ - /*if ( block->height >= coin->blocks.parsedblocks ) - { - memset(&space,0,sizeof(space)); - if ( iguana_kvread(coin,coin->blocks.db,0,&space,(uint32_t *)&block->height) != 0 ) - iguana_mergeblock(&space,block); - else printf("iguana_gotblock: cant read block.%d\n",block->height); - iguana_recvblock(coin,addr,&space,txarray,numtx,data,datalen); - iguana_kvwrite(coin,coin->blocks.db,0,&space,(uint32_t *)&space.height); - } // else printf("orphan %d block.%s from gotblockM\n",block->height,bits256_str(block->hash2)); - iguana_waitclear(coin,block->height);*/ - //portable_mutex_unlock(&coin->blocks.mutex); - - /*if ( 1 && coin->R.pendingtopheight == 0 ) - { - for (checkpointi=coin->blocks.hwmheight/coin->chain->bundlesize; checkpointiR.numcheckpoints; checkpointi++) - if ( memcmp(bits256_zero.bytes,coin->R.checkpoints[checkpointi].prevhash2.bytes,sizeof(coin->R.checkpoints[checkpointi])) != 0 ) - iguana_queuehdrs(coin,coin->R.checkpoints[checkpointi].height,coin->R.checkpoints[checkpointi].prevhash2,1); - coin->R.pendingtopheight = 1; - printf("issued initial gethdrs from %d\n",(coin->blocks.hwmheight/coin->chain->bundlesize)*coin->chain->bundlesize); //getchar(); - } - if ( coin->R.topheight < 0 ) - coin->R.topheight = 0; - if ( coin->blocks.hwmheight < 0 ) - coin->blocks.hwmheight = 0; - if ( coin->R.topheight < coin->blocks.hwmheight ) - coin->R.topheight = coin->blocks.hwmheight; - if ( coin->R.topheight == 0 || coin->R.topheight >= coin->R.pendingtopheight+coin->chain->bundlesize || time(NULL) > (coin->R.lasthdrtime + 60) ) - { - memset(hash2.bytes,0,sizeof(hash2)); - if ( coin->R.pendingtopheight != coin->R.topheight ) - { - height = (coin->R.topheight/coin->chain->bundlesize) * coin->chain->bundlesize; - hash2 = coin->R.checkpoints[height / coin->chain->bundlesize].prevhash2; - printf("request new header %d vs %d %u %s\n",height,coin->R.topheight,coin->R.pendingtopstart,bits256_str(hash2)); - if ( memcmp(bits256_zero.bytes,hash2.bytes,sizeof(hash2)) == 0 ) - hash2 = iguana_blockhash(coin,height); - } - if ( memcmp(bits256_zero.bytes,hash2.bytes,sizeof(hash2)) == 0 ) - { - iguana_lookahead(coin,&hash2,1); - if ( coin->blocks.hwmheight < coin->blocks.parsedblocks ) - coin->blocks.parsedblocks = coin->blocks.hwmheight; - height = coin->blocks.parsedblocks; - hash2 = iguana_blockhash(coin,height); - if ( iguana_choosepeer(coin) != 0 ) - printf("hwmchain request new header %d vs %d %u\n",coin->R.pendingtopheight,coin->R.topheight,coin->R.pendingtopstart); - } - coin->R.lasthdrtime = (uint32_t)time(NULL); - if ( memcmp(bits256_zero.bytes,hash2.bytes,sizeof(hash2)) != 0 ) - { - iguana_queuehdrs(coin,height,hash2,1); - return(1); - } - } - if ( coin->newhdrs != 0 ) - { - coin->newhdrs = 0; - height = coin->blocks.hwmheight; - iguana_lookahead(coin,&hash2,height + 1); - if ( coin->blocks.hwmheight > height ) - return(1); - }*/ - /*for (iter=0; iter<2; iter++) - { - while ( (req= queue_dequeue(&addr->pendblocksQ[iter ^ 1],0)) != 0 ) - { - if ( memcmp(&req->hash2,hash2.bytes,sizeof(hash2)) == 0 ) - { - if ( (*heightp= req->height) >= 0 && req->checkpointi >= 0 ) - { - printf("FOUND.(%s) height.%d\n",bits256_str(req->hash2),req->height); - if ( deleteflag == 0 ) - queue_enqueue("pendblocksQ",&addr->pendblocksQ[iter ^ 1],&req->DL,0); - return(&coin->R.checkpoints[req->checkpointi]); - } else printf("height.%d checkpointi.%d\n",req->height,req->checkpointi); - } - printf("requeue.%p\n",req); - queue_enqueue("pendblocksQ",&addr->pendblocksQ[iter ^ 1],&req->DL,0); - } - } - return(0);*/ - - void iguana_queuebundle(struct iguana_info *coin,struct iguana_bundle *bundle) - { - int32_t i; - printf("queue bundle.%p %s height.%d num.%d waitingbits.%d\n",bundle,bits256_str(bundle->prevhash2),bundle->height,bundle->num,coin->R.numwaitingbits); - for (i=0; inum; i++) - { - //printf("bundle[i.%d] %d %s\n",i,bundle->height + 1 + i,bits256_str(bundle->blocks[i].hash2)); - if ( iguana_recvblock(coin,bundle->height + 1 + i) == 0 ) - { - coin->R.blockhashes[bundle->height + 1 + i] = bundle->blocks[i].hash2; - //iguana_queueblock(coin,bundle->height + 1 + i,bundle->blocks[i].hash2,0); - } - } - } - - struct iguana_bundle *iguana_bundleheight(struct iguana_info *coin,int32_t *heightp,bits256 hash2,bits256 prev_block,int32_t deleteflag) - { - //int32_t i,j,miscompare = 0; struct iguana_bundle *bundle; - *heightp = -1; - /* for (i=0; iR.numbundles; i++) - { - if ( i*coin->chain->bundlesize > coin->longestchain ) - { - // printf("i.%d %d < longestchain.%d\n",i,i*coin->chain->bundlesize,coin->longestchain); - break; - } - bundle = &coin->R.bundles[i]; - if ( bundle->height >= 0 && bundle->blocks != 0 ) - { - if ( bundle->recvstart == 0 ) - continue; - // printf("bundlei.%d recvstart.%u finish.%u\n",i,bundle->recvstart,bundle->recvfinish); - if ( memcmp(bundle->prevhash2.bytes,prev_block.bytes,sizeof(prev_block)) == 0 ) - { - *heightp = bundle->height + 1; - return(bundle); - } - for (j=0; jnum; j++) - { - if ( memcmp(bundle->blocks[j].hash2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) - { - *heightp = bundle->height + 1 + j; - //printf("height.%d j.%d (%s) vs (%s) bundle.%d\n",*heightp,j,bits256_str(bundle->blocks[j].hash2),bits256_str2(hash2),bundle->height); - return(bundle); - } else miscompare++;//, printf("%x ",(uint32_t)bundle->blocks[j].hash2.uints[7]); - } - } //else printf("skip bundle.%d %p\n",bundle->height,bundle->blocks); - } - printf("cant find.(%s) miscompares.%d %x\n",bits256_str(hash2),miscompare,(uint32_t)hash2.uints[7]);*/ - return(0); - } - /* - static bits256 lasthash2; - struct iguana_blockreq *req; int32_t height; - addr->lastrequest = bits256_zero; - addr->recvhdrs++; - if ( addr->pendhdrs > 0 ) - addr->pendhdrs--; - coin->R.lasthdrtime = (uint32_t)time(NULL); - if ( memcmp(lasthash2.bytes,blockhashes[0].bytes,sizeof(lasthash2)) != 0 ) - { - if ( n <= 2 ) - { - printf("gotblockhashes[%d] %s pend.%d\n",n,bits256_str(blockhashes[0]),addr->pendhdrs); - lasthash2 = blockhashes[0]; - } - } - if ( n > 2 ) - { - if ( n > coin->chain->bundlesize ) - printf("warning: %s gotheaders.%d is too many vs. %d\n",coin->symbol,n,coin->chain->bundlesize); - req = mycalloc('r',1,sizeof(*req)); - req->hash2 = blockhashes[0]; - req->blockhashes = blockhashes; - req->n = n; - iguana_bundleheight(coin,&height,blockhashes[0],bits256_zero,0); - if ( req->height >= 0 ) - { - req->bundlei = (req->height / coin->chain->bundlesize); - //printf("blocksQ.%s height.%d\n",bits256_str(blockhashes[0]),height); - //queue_enqueue("blocksQ",&coin->blocksQ,&req->DL,0); - } - else - { - req->bundlei = -1; - //printf("priorityQ.%s height.%d\n",bits256_str(blockhashes[0]),height); - //queue_enqueue("priorityQ",&coin->priorityQ,&req->DL,0); - } - printf("blocksQ.%s height.%d req->height.%d\n",bits256_str(blockhashes[0]),height,req->height); - queue_enqueue("blocksQ",&coin->blocksQ,&req->DL,0); - } else myfree(blockhashes,n * sizeof(*blockhashes)); - } - - - int32_t h,i,height; uint32_t now; bits256 prevhash2; //char hashstr[65]; - struct iguana_blockreq *req; struct iguana_bundle *bundle; - - iguana_gotdata(coin,addr,block->height,block->hash2); - now = (uint32_t)time(NULL); - bundle = iguana_bundleheight(coin,&height,block->hash2,block->prev_block,1); - //printf("%s got block.%d height.%d\n",addr!=0?addr->ipaddr:"local",block->height,height); - if ( (req= queue_dequeue(&addr->pendingQ,0)) != 0 ) // should only have depth 1! - { - if ( memcmp(req->hash2.bytes,block->hash2.bytes,sizeof(req->hash2)) == 0 ) - { - if ( req->blockhashes != 0 ) - { - iguana_gotdata(coin,addr,block->height,block->hash2); - iguana_bundleinit(coin,block->height-1,block->prev_block); - if ( (bundle= iguana_bundle(coin,block->prev_block)) != 0 ) - { - portable_mutex_lock(&bundle->mutex); - if ( bundle->blocks == 0 ) - { - bundle->blockhashes = req->blockhashes; - bundle->num = req->n; - bundle->bundlei = (block->height / coin->chain->bundlesize); - bundle->firsthash2 = block->hash2; - bundle->lasthash2 = req->blockhashes[req->n-1]; - bundle->height = block->height - 1; - bundle->blocks = mycalloc('B',req->n,sizeof(*bundle->blocks)); - bundle->blocks[0] = *block; - prevhash2 = block->prev_block; - for (i=0; in; i++) - { - height = (bundle->height + 1 + i); - bundle->blocks[i].prev_block = prevhash2; - bundle->blocks[i].hash2 = req->blockhashes[i]; - prevhash2 = req->blockhashes[i]; - if ( (height % coin->chain->bundlesize) == 0 ) - iguana_bundleinit(coin,height,req->blockhashes[i]); - } - printf("initialized bundlei.%d %d\n",bundle->bundlei,bundle->height); - } - portable_mutex_unlock(&bundle->mutex); - } else printf("couldnt find matching bundle for %s\n",bits256_str(block->prev_block)); - myfree(req->blockhashes,req->n * sizeof(*req->blockhashes)); - myfree(req,sizeof(*req)); - } else printf("unexpected missing blockhashes.%p\n",req->blockhashes); - } else printf("unexpected hash2 mismatch with height.%d\n",block->height); - } - else - { - if ( bundle == 0 ) - { - printf("cant find bundle.(%s)\n",bits256_str(block->hash2)); - return; - } - if ( height > bundle->height && height <= bundle->height+bundle->num ) - { - h = height - bundle->height - 1; - portable_mutex_lock(&bundle->mutex); - if ( bundle->numvalid < bundle->num && bundle->txdata[h] == 0 ) - { - bundle->blocks[h] = *block; - if ( iguana_recvblockptr(coin,height) == &bundle->txdata[h] && bundle->txdata[h] == 0 ) - { - bundle->txdata[h] = txarray, bundle->numtxs[h] = numtx; - coin->blocks.numblocks++; - //if ( (rand() % 100) == 0 ) - printf("GOT.%d | received.%d total.%d | %.2f minutes\n",height,coin->blocks.recvblocks,coin->blocks.numblocks,(double)(now - coin->starttime)/60.); - txarray = 0; - if ( ++bundle->numvalid == bundle->num ) - { - bundle->recvfinish = now; - bundle->lastduration = (bundle->recvfinish - bundle->recvstart); - dxblend(&coin->R.avetime,bundle->lastduration,.9); - if ( bundle->lastduration < coin->R.avetime ) - coin->R.faster++; - else coin->R.slower++; - if ( coin->R.faster > 3*coin->R.slower || coin->R.slower > 3*coin->R.faster ) - { - dir = (coin->R.maxrecvbundles - coin->R.prevmaxrecvbundles); - if ( coin->R.slower >= coin->R.faster ) - dir = -dir; - if ( dir > 0 ) - dir = 1; - else if ( coin->R.maxrecvbundles > 2 ) - dir = -1; - else dir = 0; - printf("(%d vs %f) faster.%d slower.%d -> dir.%d apply -> %d\n",bundle->lastduration,coin->R.avetime,coin->R.faster,coin->R.slower,dir,coin->R.maxrecvbundles + dir); - coin->R.prevmaxrecvbundles = coin->R.maxrecvbundles; - coin->R.maxrecvbundles += dir; - coin->R.slower = coin->R.faster = 0; - } - coin->R.finishedbundles++; - printf("submit emit.%d height.%d\n",bundle->bundlei,bundle->height); - queue_enqueue("emitQ",&coin->emitQ,&bundle->DL,0); - } - else - { - if ( coin->R.waitstart[height] > 0 ) - { - if ( bundle->firstblocktime == 0 ) - bundle->firstblocktime = now; - bundle->durationsum += (now - coin->R.waitstart[height] + 1); - bundle->aveduration = (bundle->durationsum / bundle->numvalid); - } - } - } else printf("recvblockptr error? height.%d %p %p h.%d\n",height,iguana_recvblockptr(coin,height),&bundle->txdata[h],h); - } else if ( (rand() % 1000) == 0 ) - printf("interloper! already have txs[%d] for bundlei.%d\n",h,bundle!=0?bundle->height:-1); - portable_mutex_unlock(&bundle->mutex); - } else printf("height.%d outside range of bundlei.%d %d\n",height,bundle!=0?bundle->height:-1,bundle!=0?bundle->height:-1); - } - //iguana_waitclear(coin,block->height); - if ( 1 && (rand() % 1000) == 0 ) - printf("%-15s pend.(%d %d) got block.%-6d recvblocks %-8.0f recvtotal %-10.0f\n",addr->ipaddr,addr->pendhdrs,addr->pendblocks,block->height,addr->recvblocks,addr->recvtotal); - } - if ( txarray != 0 ) - iguana_freetx(txarray,numtx); - myfree(block,sizeof(*block)); - }*/ - - - /* - if ( (bp= iguana_bundleinit(coin,-1,blocks[0].prev_block)) != 0 ) - { - if ( n > coin->chain->bundlesize ) - printf("warning: %s gotheaders.%d is too many vs. %d\n",coin->symbol,n,coin->chain->bundlesize); - portable_mutex_lock(&bundle->mutex); - if ( bundle->blocks == 0 ) - { - bundle->num = n; - bundle->blocks = blocks; - bundle->firsthash2 = blocks[0].hash2; - bundle->lasthash2 = blocks[n-1].hash2; - for (i=0; iheight + i + 1); - iguana_gotdata(coin,addr,blocks[i].height,blocks[i].hash2); - if ( (blocks[i].height % coin->chain->bundlesize) == 0 ) - iguana_bundleinit(coin,blocks[i].height,blocks[i].hash2); - } - printf("%s set bundle.%d %s\n",addr->ipaddr,bundle->height,bits256_str(blocks[0].prev_block)); - } - portable_mutex_unlock(&bundle->mutex); - } else printf("ERROR iguana_gotheaders got bundle.(%s) n.%d that cant be found?\n",bits256_str(blocks[0].prev_block),n); - }*/ - - int32_t iguana_updatehdrs(struct iguana_info *coin) - { - int32_t flag = 0; - int32_t i,j,m,height,run,flag = 0; uint32_t now; struct iguana_bundle *bundle; - if ( iguana_needhdrs(coin) == 0 ) - return(flag); - now = (uint32_t)time(NULL); - run = -1; - for (i=0; iR.numbundles; i++) - { - if ( i*coin->chain->bundlesize > coin->longestchain ) - break; - bundle = &coin->R.bundles[i]; - if ( bundle->blocks != 0 ) - { - if ( bundle->recvstart == 0 ) - { - if ( (coin->R.startedbundles - coin->R.finishedbundles) < coin->R.maxrecvbundles ) - { - iguana_queuebundle(coin,bundle); - bundle->recvstart = now; - coin->R.startedbundles++; - printf("startbundle.%d (%d - %d)\n",bundle->height,coin->R.startedbundles,coin->R.finishedbundles); - flag++; - } - } - else if ( bundle->recvfinish == 0 ) - { - for (j=m=0; jnum; j++) - { - height = bundle->height+j+1; - if ( iguana_recvblock(coin,height) != 0 ) - m++; - else if ( coin->R.waitstart[height] > 0 ) - { - duration = (now - coin->R.waitstart[height]); - if ( duration > 60 || (duration > 10 && bundle->numvalid > 13 && duration > 3.*bundle->aveduration) ) - { - if ( now > bundle->lastdisp+15 ) - printf("height.%d in bundle.%d duration.%d vs ave %.3f\n",height,bundle->height,duration,bundle->aveduration); - iguana_waitclear(coin,height); - iguana_waitstart(coin,height,bundle->blocks[j].hash2,1); - } - } - else if ( bundle->firstblocktime > 0 && (now - bundle->firstblocktime) > 60 ) - { - if ( now > bundle->lastdisp+15 ) - printf("height.%d in bundle.%d ave %.3f\n",height,bundle->height,bundle->aveduration); - iguana_waitclear(coin,height); - iguana_waitstart(coin,height,bundle->blocks[j].hash2,1); - bundle->firstblocktime = now; - } - } - if ( 0 && now > bundle->lastdisp+15 ) - { - printf("bundle.%d (%d %d) elapsed.%d (%d - %d) %d | %.2f minutes\n",bundle->bundlei,bundle->height,m,(int32_t)(now - bundle->recvstart),coin->R.startedbundles,coin->R.finishedbundles,coin->R.maxrecvbundles,(double)(now - coin->starttime)/60.); - bundle->lastdisp = now; - } - } - else if ( run == i-1 ) - run++; - } - } - //iguana_lookahead(coin,&hash2,0); - return(flag); - }*/ - - /*struct iguana_block *iguana_block(struct iguana_info *coin,struct iguana_block *space,int32_t height) - { - if ( height <= coin->blocks.hwmheight ) - { - if ( iguana_kvread(coin,coin->blocks.db,0,space,(uint32_t *)&height) != 0 ) - { - if ( bits256_nonz(space->hash2) != 0 ) - return(space); - if ( height < coin->blocks.hwmheight ) - { - printf("height.%d null blockhash? prev.%s\n",height,bits256_str(space->prev_block)); - getchar(); - } - return(0); - } else printf("error doing RWmmap\n"); - } - //printf("iguana_block hwmheight.%d vs height.%d\n",coin->blocks.hwmheight,height); - return(0); - } - - struct iguana_block *iguana_findblock(struct iguana_info *coin,struct iguana_block *space,bits256 hash2) - { - struct iguana_block *block = 0; uint32_t itemind; - if ( bits256_nonz(hash2) != 0 ) - { - block = iguana_kvread(coin,coin->blocks.db,hash2.bytes,space,&itemind); - //printf("iguana_findblock block.%p itemind.%d\n",block,itemind); - if ( block == 0 || itemind != block->height ) - { - if ( block != 0 && block->height != itemind ) - { - printf("iguana_findblock (%s) error itemind.%d vs %d block.%p\n",bits256_str(hash2),itemind,block!=0?block->height:-1,block); - getchar(); - } - return(0); - } - } - return(block); - }*/ - struct iguana_bundle *iguana_bundlefindprev(struct iguana_info *coin,int32_t *heightp,bits256 prevhash2) - { - struct iguana_block *block; - *heightp = -1; - if ( (block= iguana_blockfind(coin,prevhash2)) != 0 ) - { - *heightp = block->hh.itemind; - if ( block->bundle == 0 ) - { - if ( *heightp == 0 ) - block->bundle = coin->B[0]; - else block->bundle = coin->B[(block->hh.itemind - 1) / coin->chain->bundlesize]; - } - return(block->bundle); - } - else return(0); - } - - /*int32_t iguana_bundleset(struct iguana_info *coin,int32_t origheight,bits256 hash2) - { - int32_t bundlei,blocki,height = origheight; struct iguana_bundle *bp = 0; - //printf("bundleset.(%d %s)\n",height,bits256_str(hash2)); - if ( (height % coin->chain->bundlesize) == 0 && height > 0 ) - { - iguana_blockhashset(coin,origheight,hash2,0); - return(0); - } - if ( (bundlei= iguana_bundlei(coin,&blocki,height)) >= 0 && bundlei >= 0 && (bp= coin->B[bundlei]) != 0 ) - { - if ( height > bp->height && height < bp->height+bp->num ) - { - if ( iguana_blockhashset(coin,origheight,hash2,bp) != 0 ) - { - return(0); - } - printf("iguana_bundleset error setting bundle height.%d %s\n",height,bits256_str(hash2)); - } else printf("iguana_bundleset illegal height.%d for bundle.%d\n",height,bp->height); - } else printf("iguana_bundleset illegal height.%d bundlei.%d blocki.%d bp.%p\n",height,bundlei,blocki,bp); - return(-1); - }*/ - - /*int32_t iguana_bundlei(struct iguana_info *coin,int32_t *blockip,int32_t height) - { - int32_t bundlei; - *blockip = -1; - if ( height <= 0 || height > coin->R.numwaitingbits ) - return(-1); - height--; - *blockip = (height % coin->chain->bundlesize); - if ( (bundlei= (height / coin->chain->bundlesize)) < IGUANA_MAXBUNDLES ) - return(bundlei); - else return(-1); - } - - void **iguana_recvblockptr(struct iguana_info *coin,int32_t *blockip,int32_t height) - { - int32_t bundlei; struct iguana_bundle *bp; - if ( (bundlei= iguana_bundlei(coin,blockip,height)) >= 0 ) - { - if ( (bp= coin->B[bundlei]) != 0 ) - return(&bp->txdata[*blockip]); - } - return(0); - }*/ - - /*struct iguana_bundle *iguana_bundleinit(struct iguana_info *coin,int32_t height,bits256 hash2) - { - int32_t bundlei,blocki; struct iguana_bundle *bp = 0; - if ( height < 0 || (height % coin->chain->bundlesize) != 0 ) - { - printf("bundleinit error: height.%d %s\n",height,bits256_str(hash2)); - return(bp); - } - portable_mutex_lock(&coin->bundles_mutex); - if ( (bundlei= iguana_bundlei(coin,&blocki,height+1)) >= 0 ) - { - if ( (bp= coin->B[bundlei]) != 0 ) - { - if ( memcmp(hash2.bytes,bp->prevhash2.bytes,sizeof(hash2)) != 0 ) - { - if ( bits256_nonz(hash2) > 0 ) - { - if ( bits256_nonz(bp->prevhash2) > 0 ) - { - printf("bundleinit[%d]: %d hash conflict have %s, got %s\n",bp->bundlei,bp->height,bits256_str(bp->prevhash2),bits256_str2(hash2)); - //getchar(); - portable_mutex_unlock(&coin->bundles_mutex); - return(0); - } - bp->prevhash2 = hash2; - iguana_blockhashset(coin,height,hash2,1); - printf("bundleinit: set starting hash.(%s) for %d\n",bits256_str(hash2),bp->height); - } - } - } - else - { - bp = mycalloc('b',1,sizeof(*bp)); - coin->B[bundlei] = bp; // cant change values once set to nonzero - bp->prevhash2 = hash2; - bp->bundlei = bundlei; - bp->hasheaders = coin->chain->hasheaders; - bp->num = coin->chain->bundlesize; - bp->height = (bundlei * coin->chain->bundlesize); - bp->starttime = (uint32_t)time(NULL); - if ( bits256_nonz(hash2) > 0 ) - { - iguana_blockhashset(coin,height,hash2,1); - printf("created bundle.%d: %s coin->B[%d] <- %p\n",height,bits256_str(hash2),bundlei,bp); - } - } - } - portable_mutex_unlock(&coin->bundles_mutex); - return(bp); - }*/ - int32_t iguana_waitstart(struct iguana_info *coin,int32_t height,bits256 hash2,int32_t priority) - { - if ( height < 0 || iguana_recvblock(coin,height) == 0 ) - return(iguana_queueblock(coin,height,hash2,priority)); - else if ( height < coin->maxblockbits ) - printf("iguana_waitstart ignore height.%d < %d, %p GETBIT.%d\n",height,coin->maxblockbits,iguana_recvblock(coin,height),GETBIT(coin->R.waitingbits,height)); - return(0); - } - - int32_t iguana_waitclear(struct iguana_info *coin,int32_t height) - { - if ( height < coin->maxblockbits ) - { - //printf("%d waitclear.%d parsed.%d\n",coin->R.numwaiting,height,coin->blocks.recvblocks); - if ( coin->R.numwaiting > 0 ) - coin->R.numwaiting--; - coin->R.waitstart[height] = 0; - CLEARBIT(coin->R.waitingbits,height); - return(0); - } - return(-1); - } - - int32_t iguana_updatewaiting(struct iguana_info *coin,int32_t starti,int32_t max) - { - int32_t i,height,gap,n = 0; uint32_t now; - now = (uint32_t)time(NULL); - height = starti; - iguana_waitclear(coin,height); - iguana_waitstart(coin,height,coin->R.blockhashes[height],1); - for (i=0; iblocks.recvblocks); - if ( gap >= 0 ) - gap = sqrt(gap); - if ( gap < 13 ) - gap = 13; - if ( height < coin->maxblockbits && iguana_recvblock(coin,height) == 0 && now > (coin->R.waitstart[height] + gap) && memcmp(bits256_zero.bytes,coin->R.blockhashes[height].bytes,sizeof(bits256)) != 0 ) - { - //printf("restart height.%d width.%d widthready.%d %s\n",height,coin->width,coin->widthready,bits256_str(coin->R.blockhashes[height])); - iguana_waitclear(coin,height); - iguana_waitstart(coin,height,coin->R.blockhashes[height],0); - } //else printf("%d %d %p %u\n",height,coin->maxblockbits,coin->R.recvblocks[height],coin->R.waitstart[height]); - } - //printf("height.%d max.%d\n",starti,max); - height = starti; - for (i=0; iwidth = width = 4*sqrt(coin->longestchain - coin->blocks.recvblocks); - if ( coin->width < 0 ) - width = 500; - coin->widthready = 0; - coin->width = 5000; - //printf("width.%d\n",width); - while ( iguana_recvblock(coin,coin->blocks.recvblocks) != 0 ) - { - coin->blocks.recvblocks++; - //printf("RECV.%d\n",coin->blocks.recvblocks); - } - while ( width < (coin->longestchain - coin->blocks.recvblocks) ) - { - w = iguana_updatewaiting(coin,coin->blocks.recvblocks,width); - //printf("w%d ",w); - if ( width == coin->width ) - coin->widthready = w; - //else - break; - width <<= 1; - if ( width >= coin->longestchain-coin->blocks.recvblocks ) - width = coin->longestchain-coin->blocks.recvblocks-1; - if ( (rand() % 100) == 0 && width > (coin->width<<2) ) - printf("coin->width.%d higher width.%d all there, w.%d\n",coin->width,width,w); - } - return((uint32_t)time(NULL)); - } - int32_t iguana_connectsocket(int32_t blockflag,struct iguana_peer *A,struct sockaddr *addr,socklen_t addr_len) - { - int32_t opt,flags; struct timeval timeout; //,val = 65536*2 - if ( A->usock >= 0 ) - { - printf("iguana_connectsocket: (%s) already has usock.%d\n",A->ipaddr,A->usock); - return(-1); - } - if ( A->ipv6 != 0 ) - A->usock = socket(AF_INET6,SOCK_STREAM,IPPROTO_TCP); - else A->usock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); - if ( A->usock >= 0 ) - { - //setsockopt(A->usock,SOL_SOCKET,SO_SNDBUF,&val,sizeof(val)); - //setsockopt(A->usock,SOL_SOCKET,SO_RCVBUF,&val,sizeof(val)); - timeout.tv_sec = 0; - timeout.tv_usec = 1000; - setsockopt(A->usock,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout)); - setsockopt(A->usock,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout)); - opt = 1; - setsockopt(A->usock,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(opt)); - //retval = setsockopt(A->usock,SOL_SOCKET,SO_NOSIGPIPE,&opt,sizeof(opt)); - //printf("nosigpipe retval.%d\n",retval); - if ( blockflag != 0 || ((flags= fcntl(A->usock,F_GETFL,0)) >= 0 && fcntl(A->usock,F_SETFL,flags|O_NONBLOCK) >= 0) ) - { - if ( connect(A->usock,addr,addr_len) >= 0 || errno == EINPROGRESS ) - return(A->usock); - else fprintf(stderr,"usock %s connect -> errno.%d\n",A->ipaddr,errno); - }// else fprintf(stderr,"usock %s fcntl -> flags.%d errno.%d",ipaddr,flags,errno); - } else fprintf(stderr,"usock %s -> errno.%d\n",A->ipaddr,errno); - return(-errno); - } - - int32_t iguana_connect(struct iguana_info *coin,struct iguana_peer *addrs,int32_t maxaddrs,char *ipaddr,uint16_t default_port,int32_t connectflag) - { - struct sockaddr *addr; struct sockaddr_in6 saddr6; struct sockaddr_in saddr4; uint32_t ipbits; - struct addrinfo hints,*res; socklen_t addr_len; struct addrinfo *ai; int32_t retval = -1,status,n = 0; - addrs[n].usock = -1; - memset(&hints,0,sizeof(hints)); - memset(&saddr6,0,sizeof(saddr6)); - memset(&saddr4,0,sizeof(saddr4)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - //printf("getaddrinfo\n"); - if ( getaddrinfo(ipaddr,NULL,&hints,&res)) - { - printf("cant get addrinfo for (%s)\n",ipaddr); - return(-1); - } - for (ai=res; ai!=NULL&&nai_next) - { - if ( ai->ai_family == AF_INET6 ) - { - struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)ai->ai_addr; - memcpy(&addrs[n].A.ip,&saddr->sin6_addr,16); - memset(&saddr6,0,sizeof(saddr6)); - saddr6.sin6_family = AF_INET6; - memcpy(&saddr6.sin6_addr.s6_addr,&addrs[n].A.ip[0],16); - saddr6.sin6_port = htons(default_port); - addrs[n].ipv6 = 1; - addr = (struct sockaddr *)&saddr6; - addr_len = sizeof(saddr6); - } - else if ( ai->ai_family == AF_INET ) - { - struct sockaddr_in *saddr = (struct sockaddr_in *)ai->ai_addr; - memset(&addrs[n].A.ip[0],0,10); - memset(&addrs[n].A.ip[10],0xff,2); - memcpy(&addrs[n].A.ip[12],&saddr->sin_addr,4); - memset(&saddr4,0,sizeof(saddr4)); - saddr4.sin_family = AF_INET; - memcpy(&saddr4.sin_addr.s_addr,&addrs[n].A.ip[12],4); - saddr4.sin_port = htons(default_port); - addrs[n].ipv6 = 0; - addr = (struct sockaddr *)&saddr4; - addr_len = sizeof(saddr4); - } else return(-1); - addrs[n].A.nTime = (uint32_t)(time(NULL) - (24 * 60 * 60)); - addrs[n].A.port = default_port; - strcpy(addrs[n].ipaddr,ipaddr); - addrs[n].A.nServices = 0; - n++; - if ( connectflag != 0 ) - { - ipbits = (uint32_t)calc_ipbits(ipaddr); - addrs[n].usock = -1; - addrs[n].ipbits = ipbits; - strcpy(addrs[n].ipaddr,ipaddr); - //printf("call connectsocket\n"); - if ( (addrs[n].usock= iguana_connectsocket(connectflag > 1,&addrs[n],addr,addr_len)) < 0 ) - { - status = IGUANA_PEER_KILLED; - printf("refused PEER STATUS.%d for %s usock.%d\n",status,ipaddr,retval); - iguana_iAkill(coin,&addrs[n],1); - if ( iguana_rwipbits_status(coin,1,ipbits,&status) == 0 ) - printf("error updating status.%d for %s\n",status,ipaddr); - } - else - { - status = IGUANA_PEER_READY; - printf("CONNECTED! PEER STATUS.%d for %s usock.%d\n",status,ipaddr,addrs[n].usock); - iguana_iAconnected(coin,&addrs[n]); - if ( iguana_rwipbits_status(coin,1,ipbits,&status) == 0 ) - printf("error updating status.%d for %s\n",status,ipaddr); - else retval = addrs[n].usock; - } - break; - } - } - freeaddrinfo(res); - return(retval); - } - - /*if ( (fp= fopen(fname,"r")) != 0 ) - { - if ( fgets(line,sizeof(line),fp) > 0 ) - { - line[strlen(line)-1] = 0; - if ( atoi(line) > coin->blocks.hashblocks ) - { - //printf("skip save since %s has %d\n",fname,atoi(line)); - fclose(fp); - return(0); - } - } - fclose(fp); - }*/ - - /*struct iguana_bundle - { - struct queueitem DL; portable_mutex_t mutex; - char fname[512]; struct iguana_mappedptr M; - void *txdata[_IGUANA_HDRSCOUNT]; int32_t numtxs[_IGUANA_HDRSCOUNT]; - struct iguana_counts presnapshot,postsnapshot; - int32_t bundlei,height,num,hasheaders,numvalid,havehashes; - uint32_t starttime,emitstart,emitfinish,lastdisp; - bits256 prevhash2,firsthash2,lasthash2; - //double durationsum,aveduration; - //struct iguana_block *blocks; - };*/ - - /*struct iguana_recv - { - //uint8_t compressed[IGUANA_MAXPACKETSIZE],decompressed[IGUANA_MAXPACKETSIZE],checkbuf[IGUANA_MAXPACKETSIZE]; - long srcdatalen,compressedtotal; //uint64_t histo[0x100]; - struct iguana_memspace RSPACE,*oldRSPACE; int32_t numold; - int64_t packetsallocated,packetsfreed; int32_t numwaiting,maprecvdata; - uint8_t *waitingbits; uint32_t numwaitingbits,*waitstart; //struct iguana_pending **recvblocks; - int32_t topheight,pendingtopheight; - uint32_t pendingtopstart,numbundles,lasthdrtime,startedbundles,finishedbundles; - bits256 tophash2; - //int32_t prevmaxrecvbundles,maxrecvbundles,faster,slower; double avetime; - }; - - struct iguana_pending - { - int32_t next,numtx,datalen,origdatalen; struct iguana_block block; uint32_t allocsize,ipbits; uint8_t data[]; - };*/ - //struct iguana_recv R; - //struct iguana_bundle *B[IGUANA_MAXBUNDLES]; - //struct iguana_blockhashes pendings[1024]; - /* int32_t height; - height = iguana_blockheight(coin,blockhashes[0]); - if ( n > 2 && iguana_needhdrs(coin) > 0 ) - { - //printf("got blockhashes[%d] %s height.%d\n",n,bits256_str(blockhashes[0]),height); - if ( height >= 0 ) - { - for (j=0; jchain->bundlesize && height+jlongestchain; j++) - { - iguana_bundleset(coin,height+j,blockhashes[j]); - iguana_gotdata(coin,0,height+j,blockhashes[j],j,n); - } - } - else - { - iguana_queueblock(coin,-1,blockhashes[0],1); - for (i=0; inumpendings; i++) - if ( memcmp(coin->pendings[i].blockhashes[0].bytes,blockhashes[0].bytes,sizeof(bits256)) == 0 ) - break; - if ( i == coin->numpendings ) - { - if ( coin->numpendings < sizeof(coin->pendings)/sizeof(*coin->pendings) ) - { - coin->pendings[coin->numpendings].blockhashes = blockhashes; - coin->pendings[coin->numpendings].n = n; - coin->pendings[coin->numpendings].starttime = (uint32_t)time(NULL); - coin->numpendings++; - printf("ADD to numpendings.%d priority.(%s) n.%d\n",coin->numpendings,bits256_str(blockhashes[0]),n); - blockhashes = 0; - } else printf("updatebundles: overflowed pendings\n"); - } - } - }*/ - - /* if ( iguana_bundlefindprev(coin,&height,blocks[0].prev_block) != 0 && height >= 0 ) - { - //printf(">>>>>> found %s height.%d n.%d\n",bits256_str(blocks[0].prev_block),height,n); - height++; - for (i=0; ichain->bundlesize && heightlongestchain; i++,height++) - { - //printf("i.%d height.%d\n",i,height); - iguana_bundleset(coin,height,blocks[i].hash2); - iguana_gotdata(coin,req->addr,height,blocks[i].hash2,i,n); - if ( height >= coin->blocks.hwmheight ) - { - if ( height == coin->blocks.hwmheight ) - (*newhwmp)++; - if ( (block= iguana_block(coin,height)) != 0 ) - iguana_mergeblock(block,&blocks[i]); - else printf("unexpected null block at height.%d\n",height), getchar(); - } - else - { - // verify it doesnt trigger reorg (and is recent enough!) - } - } - } else printf("unexpected bundlefind error %s height.%d\n",bits256_str(blocks[0].prev_block),height), getchar(); - */ - - /* int32_t height; - //printf("%s got block.(%s) height.%d\n",req->addr!=0?req->addr->ipaddr:"local",bits256_str(block->hash2),height); - if ( (height= iguana_bundleheight(coin,block)) > 0 ) - { - if ( (ptrp= iguana_blockptrptr(coin,&blocki,height)) != 0 ) - { - if ( (*ptrp) == 0 ) - { - //printf("height.%d tx.%p blocki.%d txarray.%p[%d] (%p[%d] %p[%d])\n",height,&txarray[0],blocki,txarray,numtx,txarray[0].vouts,txarray[0].tx_out,txarray[0].vins,txarray[0].tx_in); - (*ptrp) = (void *)txarray; - bp->numtxs[blocki] = numtx; - if ( bp->emitstart == 0 && ++bp->numvalid >= bp->num ) - { - bp->emitstart = (uint32_t)time(NULL); - iguana_emittxdata(coin,bp); - //printf("queue txarray.%p[%d]\n",txarray,numtx); - //queue_enqueue("emitQ",&coin->emitQ,&bp->DL,0); - } - //txarray = 0; - } - } - else printf("cant get ptrp.%d\n",height), getchar(); - iguana_gotdata(coin,req->addr,height,block->hash2,0,0); - if ( bp != 0 && iguana_bundleready(coin,height-1) <= 0 ) - { - printf("check for pendings.%d height.%d\n",coin->numpendings,height); - if ( height == coin->blocks.hwmheight ) - (*newhwmp)++; - for (i=0; inumpendings; i++) - if ( memcmp(coin->pendings[i].blockhashes[0].bytes,block->hash2.bytes,sizeof(block->hash2)) == 0 ) - { - blockhashes = coin->pendings[i].blockhashes; - n = coin->pendings[i].n; - printf("pending[%d].%d bundlesets[%d] %d %s\n",i,coin->numpendings,n,height,bits256_str(blockhashes[0])); - for (j=0; jchain->bundlesize && height+jlongestchain; j++) - { - iguana_bundleset(coin,height+j,blockhashes[j]); - iguana_gotdata(coin,0,height+j,blockhashes[j],j,n); - } - myfree(blockhashes,n * sizeof(*blockhashes)); - coin->pendings[i] = coin->pendings[--coin->numpendings]; - break; - } - // queue tx for processing - } - else - { - // probably new block - //printf("couldnt find.(%s)\n",bits256_str(block->hash2)); - } - }*/ - //if ( height >= 0 ) - // coin->blocks.ptrs[height] = block; - //printf("found.%s -> %s %d %p inputht.%d\n",bits256_str(hash2),bits256_str(block->hash2),block->hh.itemind,block,height); - if ( height < 0 || block->hh.itemind == height ) - { - if ( (int32_t)block->hh.itemind < 0 ) - { - //printf("found.%s -> %d %p set height.%d matches.%d\n",bits256_str(hash2),block->hh.itemind,block,height,block->matches); - if ( height >= 0 && block->matches == 0 ) - block->hh.itemind = height, block->matches = 1; - else block = 0; - } - if ( block != 0 ) - { - if ( block->matches < 100 ) - block->matches++; - //_iguana_blocklink(coin,block); - } - } - else if ( block->matches == 0 && block->hh.itemind == (uint32_t)-1 ) - { - if ( height >= 0 ) - { - if ( (rand() % 10000) == 0 ) - printf("set %s.itemind <- %d\n",bits256_str(hash2),height); - block->hh.itemind = height; - block->matches = 1; - } - else - { - printf("matches.%d itemind.%d when height.%d\n",block->matches,block->hh.itemind,height); - block = 0; - } - } - else - { - /*if ( block->matches < 100 ) - { - block->matches >>= 1; - if ( block->matches == 0 ) - { - //printf("collision with (%s) itemind.%d vs %d | matches.%d\n",bits256_str(hash2),block->hh.itemind,height,block->matches); - block->hh.itemind = -1; - for (i=0; i<1; i++) - iguana_queueblock(coin,-1,block->hash2,1); - block = 0; - //coin->blocks.recvblocks = 0; - } - } else block = 0;*/ - } - - /*int32_t iguana_blockheight(struct iguana_info *coin,struct iguana_block *block) - { - int32_t height; - if ( (height= iguana_itemheight(coin,block->hash2)) < 0 ) - { - if ( (height= iguana_itemheight(coin,block->prev_block)) < 0 ) - { - iguana_blockhashset(coin,-1,block->hash2,1); - iguana_blockhashset(coin,-1,block->prev_block,1); - } - else - { - height++; - iguana_blockhashset(coin,height,block->hash2,1); - } - } else iguana_blockhashset(coin,height,block->hash2,1); // increments matches - return(height); - }*/ - if ( (height= iguana_itemheight(coin,blockhashes[0])) >= 0 ) - { - if ( iguana_needhdrs(coin) > 0 && iguana_havetxdata(coin,h) == 0 ) - iguana_queueblock(coin,height,blockhashes[0],1); - } - else if ( iguana_needhdrs(coin) > 0 && iguana_havetxdata(coin,h) == 0 ) - iguana_queueblock(coin,-1,blockhashes[0],1); - //printf("check.%s height.%d\n",bits256_str(blockhashes[0]),height); - for (i=0; i= 0 ) - h = height++; - permblock = iguana_blockhashset(coin,h,blockhashes[i],1); - if ( h >= 0 && permblock != 0 ) - { - if ( iguana_blockptr(coin,h) == 0 ) - { - coin->blocks.ptrs[h] = permblock; - { - int32_t j,m; - for (j=m=0; jlongestchain; j++) - if ( iguana_blockptr(coin,j) != 0 ) - m++; - printf("set (%s) <- %d %p m.%d\n",bits256_str(blockhashes[i]),h,permblock,m); - } - } - if ( permblock->hh.itemind != h ) - permblock->hh.itemind = h; - } - if ( i == coin->chain->bundlesize-1 ) - { - init_hexbytes_noT(hashstr,blockhashes[i].bytes,sizeof(blockhashes[i])); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - } - //else //if ( h >= 0 ) printf("unexpected missing permblock for h.%d\n",h); - // iguana_queueblock(coin,-1,blockhashes[i],0); - } - for (i=m=run=0; i= 0 ) - { - if ( run == i && (i == 0 || height == height0+i) ) - run++; - if ( (block= iguana_blockfind(coin,blockhashes[i])) != 0 && block == blocks[i] && block->mainchain == 0 ) - { - if ( block->hh.itemind != height && wt > block->matches ) - { - printf("%p[%d] <- %d matches.%d wt.%d vs matches.%d\n",block,block->hh.itemind,height,block->matches,wt,block->matches); - if ( block->matches < 100 ) - { - block->matches = 1; - block->hh.itemind = height; - } - else printf("height conflict for %s\n",bits256_str(blockhashes[i])); - } - } else blocks[i] = 0; - if ( i == 0 ) - height0 = height; - height -= i; - if ( m > 0 ) - { - for (j=0; j %d\n",j,m,wt,heightwts[j][1]); - break; - } - } - } else j = 0; - if ( j == m ) - { - heightwts[m][0] = height; - heightwts[m][1] = wt; - m++; - } - } - printf("i.%d j.%d m.%d height.%d wt.%d %s\n",i,j,m,height,wt,bits256_str(blockhashes[0])); - } - nlinks = plinks = 0; - if ( m > 0 ) - { - if ( m == 1 && height0 >= 0 ) - { - wt = (heightwts[0][1] / num) + 2; - for (i=0; ihh.next == 0 || prev->matches < wt ) - prev->hh.next = blocks[0]; - } - for (i=plinks=nlinks=0; ihh.itemind < 0 || block->matches < wt ) - { - block->hh.itemind = height0 + i; - block->matches = (wt < 100) ? wt : 100; - SETBIT(coin->havehash,height0 + i); - //iguana_blockhashset(coin,height0 + i,blockhashes[i],(wt < 100) ? wt : 100); - } - if ( (block->hh.prev == 0 || block->matches < wt) && block->hh.prev != prev ) - block->hh.prev = prev, plinks++; - if ( (block->hh.next == 0 || block->matches < wt) && block->hh.next != next ) - block->hh.next = next, nlinks++; - if ( block->matches < 100 ) - block->matches++; - } else printf("recvblockhashes: blocks[%d] null\n",i); - prev = block; - } - if ( next != 0 && (next->hh.prev == 0 || next->matches < wt) ) - next->hh.prev = prev; - } else printf("recvblockhashes: i.%d != num.%d\n",i,num); - } - if ( height0 >= 0 && 0 ) - { - for (i=0; i= 0 ) - { - if ( i == 0 ) - height0 = height, block0 = block; - m++; - //printf("height %d, wt %d itemind.%d matches.%d\n",height,wt,block->hh.itemind,block->matches); - if ( (int32_t)block->hh.itemind < 0 || block->matches*3 < wt ) - { - SETBIT(coin->havehash,height); - block->hh.itemind = height; - block->matches = (wt/3) + 1; - } - if ( prev != 0 && ((int32_t)prev->hh.itemind < 0 || prev->matches*3 < wt) ) - { - SETBIT(coin->havehash,height - 1); - prev->hh.itemind = height - 1; - prev->matches = (wt/3) + 1; - } - if ( next != 0 && ((int32_t)next->hh.itemind < 0 || next->matches*3 < wt) ) - { - SETBIT(coin->havehash,height + 1); - next->hh.itemind = height + 1; - next->matches = (wt/3) + 1; - } - } - } - prev = block; - } - if ( m >= coin->chain->bundlesize && height0 >= 0 && block != 0 ) - { - printf("gothdr.%d oldgothdr.%d %p %d <- %p\n",height0,block->gothdrs,coin->blocks.ptrs[height0],coin->blocks.ptrs[height0]!=0?coin->blocks.ptrs[height0]->hh.itemind:0,block); - coin->blocks.ptrs[height0] = block; - block->gothdrs = 1; - } - int32_t i,m,height,wt,height0 = -1; struct iguana_block *block,*next,*prev,*block0 = 0; - - int32_t iguana_blockmetric(struct iguana_info *coin,int32_t *wtp,struct iguana_block *block) - { - int32_t height = -1; int64_t wt; - if ( block->mainchain != 0 && block->height >= 0 ) - { - height = block->height; - wt = ((int64_t)coin->blocks.hwmheight - block->height) * 10000; - if ( wt > (1 << 28)/_IGUANA_HDRSCOUNT ) - wt = (1 << 28) / _IGUANA_HDRSCOUNT; - (*wtp) += (int32_t)wt; - } - else if ( block->height >= 0 ) - { - height = block->height; - (*wtp) += 10; - } - else if ( (int32_t)block->hh.itemind >= 0 ) - { - height = block->hh.itemind; - (*wtp) += block->matches; - } - return(height); - } - - int32_t iguana_heightwt(struct iguana_info *coin,int32_t *wtp,struct iguana_block *prev,struct iguana_block *block,struct iguana_block *next) - { - int32_t heightwts[3][2],height,i,n = 0; - *wtp = 0; - height = -1; - memset(heightwts,0,sizeof(heightwts)); - if ( block != 0 ) - { - if ( (heightwts[1][0]= iguana_blockmetric(coin,&heightwts[1][1],block)) >= 0 ) - n++; - //printf("%s itemind.%d matches.%d ht.%d metric.%d n.%d\n",bits256_str(hash2),block->hh.itemind,block->matches,heightwts[1][0],heightwts[1][1],n); - if ( prev != 0 )//|| (prev= block->hh.prev) != 0 ) - { - if ( (heightwts[0][0]= iguana_blockmetric(coin,&heightwts[0][1],prev)) >= 0 ) - { - //printf("heightwts(%d + 1) vs %d\n",heightwts[0][0],heightwts[1][0]); - if ( heightwts[0][0]+1 == heightwts[1][0] ) - n++; - else n--, heightwts[0][0] = -1; - } - //printf("%s itemind.%d matches.%d ht.%d metric.%d n.%d\n",bits256_str(prev->hash2),prev->hh.itemind,prev->matches,heightwts[0][0],heightwts[0][1],n); - } - if ( next != 0 )//(next= block->hh.prev) != 0 && next != block ) - { - if ( (heightwts[2][0]= iguana_blockmetric(coin,&heightwts[2][1],next)) >= 0 ) - { - if ( heightwts[2][0]-1 == heightwts[1][0] ) - n++; - else n--, heightwts[2][0] = -1; - } - //printf("%s itemind.%d matches.%d ht.%d metric.%d n.%d\n",bits256_str(next->hash2),next->hh.itemind,next->matches,heightwts[2][0],heightwts[2][1],n); - } - if ( n > 0 ) - { - for (i=0; i<3; i++) - if ( heightwts[i][0] >= 0 ) - (*wtp) += heightwts[i][1]; - (*wtp) *= n; - height = heightwts[1][0]; - } - } //else printf("cant find.(%s)\n",bits256_str(hash2)); - return(height); - } - /*n = 0; - if ( 0 && n == 0 && time(NULL) > coin->hdrstime+30 ) - { - height = (coin->blocks.hashblocks / coin->chain->bundlesize) * coin->chain->bundlesize; - while ( height < (coin->longestchain - coin->chain->bundlesize - 1) ) - { - if ( (hdrs= iguana_addhdr(coin,block->hash2,bits256_zero)) != 0 && hdrs->block.gothdrs == 0 ) - { - flag++; - //printf("REQ HDR.(%s) %d\n",bits256_str(block->hash2),height); - printf("%d ",height); - n++; - init_hexbytes_noT(hashstr,hdrs->bundlehash2.bytes,sizeof(bits256)); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - } - height += coin->chain->bundlesize; - } - coin->hdrstime = (uint32_t)time(NULL); - } - if ( n > 0 ) - printf("REQ EXTRA HDRS\n");*/ - if ( offset == 0 ) - printf("unhandled case offset.0\n"); - else - { - struct iguana_block *block; - if ( bits256_nonz(hdrs->bundlehash2) == 0 ) - { - if ( (block= iguana_blockfind(coin,blockhashes[0])) != 0 ) - hdrs->bundlehash2 = block->prev_block; - } - } - - struct iguana_block *iguana_updatehdrs(struct iguana_info *coin,int32_t *newhwmp,struct iguana_block *block,bits256 prevhash2,bits256 hash2) - { - struct iguana_bundlereq *hdrs; int32_t i,offset,height; - if ( (hdrs= iguana_addhdr(coin,&offset,0,prevhash2,hash2)) != 0 && hdrs->bundleheight >= 0 ) - { - iguana_blockset(coin,hdrs->bundleheight,hdrs->bundlehash2); - height = (hdrs->bundleheight + offset); - if ( block != 0 ) - { - block->hh.itemind = height; - hdrs->block = *block; - prevhash2 = block->prev_block, hash2 = block->hash2; - if ( height > 0 ) - iguana_blockset(coin,height - 1,prevhash2); - if ( height <= coin->blocks.hwmheight ) - { - if ( height < coin->blocks.hwmheight || coin->blocks.dirty == 0 ) - coin->blocks.dirty = height; - (*newhwmp)++; - } - } - if ( hdrs->hashes != 0 ) - { - for (i=0; in; i++) - if ( memcmp(block->hash2.bytes,hdrs->hashes[i].bytes,sizeof(bits256)) == 0 ) - break; - printf("got block.(%s) height.%d i.%d\n",bits256_str(block->hash2),height,i); - for (; in; i++,height++) - iguana_blockset(coin,height,hdrs->hashes[i]); - } else printf("no blockhashes.%d\n",hdrs->bundleheight); - } else printf("cant find hdrs.%s %s %d\n",bits256_str(prevhash2),bits256_str2(hash2),hdrs==0?-1:hdrs->bundleheight), getchar(); - return(iguana_blockfind(coin,hash2)); - } - - struct iguana_block *iguana_blockset(struct iguana_info *coin,int32_t height,bits256 hash2) - { - struct iguana_block *block; int32_t offset,h,flag; struct iguana_bundlereq *hdrs; - //printf("blockset.%d %s\n",height,bits256_str(hash2)); - if ( height < 0 ) - getchar(); - iguana_blockhashset(coin,height,hash2,100); - if ( (block= iguana_blockfind(coin,hash2)) != 0 ) - { - SETBIT(coin->havehash,height); - block->hh.itemind = height; - coin->blocks.ptrs[height] = block; - //printf("SETBIT.%d %s %p\n",hdrs->bundleheight,bits256_str(hdrs->bundlehash2),permblock); - } - if ( (height % coin->chain->bundlesize) == 0 ) - { - if ( 0 && (hdrs= iguana_addhdr(coin,&offset,1,hash2,bits256_zero)) != 0 ) - { - if ( hdrs->bundleheight != height && hdrs->bundleheight >= 0 ) - { - printf("bundleheight.%d -> EXTENDED HDRS.%d %s\n",hdrs->bundleheight,height,bits256_str(hash2)); - hdrs->bundleheight = height; - } - } - } - if ( height >= 0 && bits256_nonz(hash2) > 0 ) - { - if ( coin->chain->hasheaders == 0 && (height % coin->chain->bundlesize) == 1 && iguana_havetxdata(coin,height) == 0 ) - iguana_queueblock(coin,height,hash2,1); - } - return(block); - } - //tmp = iguana_updatehdrs(coin,newhwmp,block,block->prev_block,block->hash2); - if ( (prev= iguana_blockfind(coin,block->prev_block)) != 0 && (int32_t)prev->hh.itemind >= 0 ) - { - //printf("recv blockset.%s %d\n",bits256_str(block->hash2),prev->hh.itemind+1); - permblock = iguana_blockset(coin,prev->hh.itemind+1,block->hash2); - //permblock = iguana_blockhashset(coin,prev->hh.itemind+1,block->hash2,1); - } - else if ( (permblock= iguana_blockfind(coin,block->hash2)) == 0 ) - printf("cant find block prev.%s\n",bits256_str(block->prev_block)); - if ( tmp != 0 && permblock == 0 ) - permblock = tmp; - /*struct iguana_block *block; int32_t flag = 0; - while ( coin->blocks.issuedblocks < coin->blocks.hashblocks && coin->blocks.issuedblocks < coin->blocks.recvblocks+coin->chain->bundlesize*IGUANA_INITIALBUNDLES ) - { - if ( (block= iguana_blockptr(coin,coin->blocks.issuedblocks)) != 0 && bits256_nonz(block->hash2) != 0 ) - iguana_queueblock(coin,coin->blocks.issuedblocks,block->hash2,0); - coin->blocks.issuedblocks++; - flag++; - } - return(flag);*/ - - /*int32_t iguana_reqblocks(struct iguana_info *coin) - { - int32_t n,height,flag = 0; struct iguana_block *block; - if ( queue_size(&coin->priorityQ) == 0 ) - { - coin->pcount++; - if ( coin->pcount > 1 && (block= iguana_blockptr(coin,coin->blocks.recvblocks)) != 0 && coin->blocks.recvblocks < coin->blocks.issuedblocks && bits256_nonz(block->hash2) > 0 ) - flag += (iguana_queueblock(coin,coin->blocks.recvblocks,block->hash2,1) > 0); - } else coin->pcount = 0; - if ( queue_size(&coin->blocksQ) == 0 ) - { - coin->bcount++; - n = 0; - if ( coin->bcount > 100 && time(NULL) > coin->recvtime+3 ) - { - for (height=coin->blocks.recvblocks+1; heightblocks.issuedblocks&&nchain->bundlesize; height++) - { - if ( (block= iguana_blockptr(coin,coin->blocks.recvblocks)) != 0 && bits256_nonz(block->hash2) > 0 ) - { - //if ( (height % 100) == 0 ) - printf("RETRY BLOCK.%d\n",height); - flag += (iguana_queueblock(coin,height,block->hash2,0) > 0); - n++; - } - } - //coin->recvtime = (uint32_t)time(NULL); - } - } else coin->bcount = 0; - return(flag); - } - - { - bundlei = (height / coin->chain->bundlesize); - if ( GETBIT(coin->emitbits,bundlei) == 0 && iguana_bundleready(coin,height) > 0 ) - { - req->bundleheight = bundlei * coin->chain->bundlesize; - SETBIT(coin->emitbits,bundlei); - req->type = 'E'; - printf("Q emit.%d\n",req->bundleheight); - queue_enqueue("emitQ",&coin->emitQ,&req->DL,0); - } - }*/ - hash2 = iguana_bundleihash2(coin,bp,bundlei); - if ( memcmp(hash2.bytes,block->hash2.bytes,sizeof(hash2)) == 0 ) - { - *hdrsp = bp; - *bundleip = bundlei; - if ( bundlei == 0 ) - { - if ( (prevbp= iguana_bundlesearch(coin,&prevbundlei,block->bundlehash2,block->prev_block,IGUANA_SEARCHNEXT)) != 0 ) - { - if ( prevbundlei == prevbp->n+1 ) - { - bp->prevbundlehash2 = prevbp->bundlehash2; - prevbp->nextbundlehash2 = block->hash2; - //printf("prev BUNDLES LINKED! (%d <-> %d) (%s <-> %s)\n",prevbp->bundleheight,bp->bundleheight,bits256_str(prevbp->bundlehash2),bits256_str2(bp->bundlehash2)); - if ( prevbp->bundleheight != bp->bundleheight-coin->chain->bundlesize ) - printf("WARNING gap in bundleheight %d != %d bundlesize\n",prevbp->bundleheight,bp->bundleheight-coin->chain->bundlesize); - } else printf("prevbundlei.%d != prevhdrs->n %d\n",prevbundlei,prevbp->n+1); - } - } - else if ( bundlei == bp->n ) - { - if ( (nextbp= iguana_bundlesearch(coin,&nextbundlei,block->bundlehash2,block->hash2,IGUANA_SEARCHPREV)) != 0 ) - { - if ( nextbundlei == 0 ) - { - bp->nextbundlehash2 = nextbp->bundlehash2; - nextbp->prevbundlehash2 = block->hash2; - //printf("next BUNDLES LINKED! (%d <-> %d) (%s <-> %s)\n",nextbp->bundleheight,bp->bundleheight,bits256_str(nextbp->bundlehash2),bits256_str2(bp->bundlehash2)); - if ( nextbp->bundleheight != bp->bundleheight+coin->chain->bundlesize ) - printf("WARNING gap in bundleheight != bundlesize\n"); - } else printf("nextbundlei.%d != nextbp->n %d\n",nextbundlei,nextbp->n); - } - } - } else printf("hdrs.%d [%d] unexpected hash2 mismatch for %s != %s\n",bp->bundleheight,bundlei,bits256_str(block->hash2),bits256_str2(hash2)); - - - /*int32_t iguana_havehash(struct iguana_info *coin,int32_t height) - { - return(GETBIT(coin->havehash,height) != 0); - }*/ - - if ( (bp= iguana_bundlefind(coin,bundleip,block->hash2)) == 0 ) - { - if ( (prevbp= iguana_bundlefind(coin,&prevbundlei,block->prev_block)) == 0 ) - { - for (j=0; jbundlescount; j++) - { - if ( (bp= coin->bundles[j]) != 0 ) - { - if ( bp->blockhashes != 0 && bp->n > 0 && (bp= iguana_bundlescan(coin,bundleip,bp,block->hash2,IGUANA_SEARCHBUNDLE)) != 0 ) - { - return(bp); - } - } - } - return(0); - } - else if ( prevbundlei == prevbp->n ) - { - printf("prev AUTOCREATE.%s\n",bits256_str(block->hash2)); - iguana_bundlecreate(coin,block->hash2,bits256_zero); - } - } - || (bp= iguana_bundlefind(coin,bundleip,hash2)) != 0 ) - { - if ( (bp= iguana_bundlescan(coin,bundleip,bp,hash2,searchmask)) != 0 ) - return(bp); - } - if ( (bp= iguana_bundlefind(coin,bundleip,hash2)) != 0 ) - return(bp); - if ( (block= iguana_blockfind(coin,hash2)) == 0 ) - iguana_blockhashset(coin,-1,hash2,1); - if ( (block= iguana_blockfind(coin,hash2)) != 0 ) - { - if ( bits256_nonz(block->bundlehash2) > 0 ) - { - if ( (bp= iguana_bundlefind(coin,&tmp,block->bundlehash2)) != 0 ) - return(iguana_bundlescan(coin,bundleip,bp,hash2,searchmask)); - } - } - - for (i=0; ichain->bundlesize+1 && iguana_bundlefind(coin,&bundlei,blocks[n - 1].hash2,0) == 0 ) - { - printf("AUTO EXTEND3.%s[%d]\n",bits256_str(blocks[n - 1].hash2),n); - iguana_bundlecreate(coin,blocks[n - 1].hash2,bits256_zero); - } - - //struct iguana_blockhashes { bits256 *blockhashes; int32_t n; uint32_t starttime; }; - - void iguana_freetx(struct iguana_msgtx *tx,int32_t n) - { - int32_t i,j; struct iguana_msgtx *origtx = tx; - return; - for (j=0; jallocsize; - if ( tx->vins != 0 ) - { - for (i=0; itx_in; i++) - if ( tx->vins[i].script != 0 ) - myfree(tx->vins[i].script,tx->vins[i].scriptlen); - myfree(tx->vins,tx->tx_in * sizeof(*tx->vins)); - } - if ( tx->vouts != 0 ) - { - for (i=0; itx_out; i++) - if ( tx->vouts[i].pk_script != 0 ) - myfree(tx->vouts[i].pk_script,tx->vouts[i].pk_scriptlen); - myfree(tx->vouts,tx->tx_out * sizeof(*tx->vouts)); - } - } - myfree(origtx,sizeof(*origtx) * n); - } - - /* - struct iguana_rawtx { bits256 txid; uint16_t numvouts,numvins; uint8_t rmd160[20]; }; - - int32_t iguana_emittx(struct iguana_info *coin,FILE *fp,struct iguana_block *block,struct iguana_msgtx *tx,int32_t txi,uint32_t *numvoutsp,uint32_t *numvinsp,int64_t *outputp) - { - int32_t blocknum,i; int64_t reward; uint16_t s; struct iguana_rawtx rawtx; uint8_t rmd160[20],buf[64]; - struct iguana_msgvin *vin; - blocknum = block->hh.itemind; - memset(&rawtx,0,sizeof(rawtx)); - rawtx.txid = tx->txid; - rawtx.numvouts = tx->tx_out, rawtx.numvins = tx->tx_in; - if ( (blocknum == 91842 || blocknum == 91880) && txi == 0 && strcmp(coin->name,"bitcoin") == 0 ) - rawtx.txid.ulongs[0] ^= blocknum; - //printf("%d: tx.%p %p[numvouts.%d] %p[numvins.%d]\n",block->hh.itemind,tx,tx->vouts,tx->tx_out,tx->vins,tx->tx_in); - if ( fwrite(&rawtx,1,sizeof(rawtx),fp) == sizeof(rawtx) ) - { - for (i=0; ivouts[i].pk_script,tx->vouts[i].pk_scriptlen,rawtx.txid); - memcpy(buf,&tx->vouts[i].value,sizeof(tx->vouts[i].value)); - memcpy(&buf[sizeof(tx->vouts[i].value)],rmd160,sizeof(rmd160)); - if ( fwrite(buf,1,sizeof(rmd160)+sizeof(tx->vouts[i].value),fp) == sizeof(rmd160)+sizeof(tx->vouts[i].value) ) - { - (*numvoutsp)++; - (*outputp) += tx->vouts[i].value; - } else printf("error writing txi.%d vout.%d\n",txi,i); - } - for (i=0; ivins[i]; - if ( bits256_nonz(vin->prev_hash) == 0 ) - { - if ( i == 0 && (int32_t)vin->prev_vout < 0 ) - { - reward = iguana_miningreward(coin,blocknum); - //printf("reward %.8f\n",dstr(reward)); - (*outputp) += reward; - } else printf("unexpected prevout.%d\n",vin->prev_vout), getchar(); - continue; - } - memcpy(buf,vin->prev_hash.bytes,sizeof(vin->prev_hash)); - s = vin->prev_vout; - memcpy(&buf[sizeof(vin->prev_hash)],&s,sizeof(s)); - //printf("do spend.%s\n",bits256_str(vin->prev_hash)); - if ( fwrite(buf,1,sizeof(bits256)+sizeof(s),fp) == sizeof(bits256)+sizeof(s) ) - (*numvinsp)++; - else printf("error writing txi.%d vin.%d\n",txi,i); - } - return(0); - } - else printf("error writing txi.%d blocknum.%d\n",txi,blocknum); - return(-1); - } - - void iguana_emittxarray(struct iguana_info *coin,FILE *fp,struct iguana_block *block,struct iguana_msgtx *txarray,int32_t numtx) - { - uint32_t i,numvouts,numvins; int64_t credits; long fpos,endpos; - if ( fp != 0 && block != 0 ) - { - //printf("%d/%d: txarray.%p, numtx.%d bp.%p\n",block->hh.itemind,block->hh.itemind,txarray,numtx,bp); - fpos = ftell(fp); - credits = numvouts = numvins = 0; - for (i=0; iL.supply = credits; - block->txn_count = numtx; - block->numvouts = numvouts, block->numvins = numvins; - block->L.numtxids = numtx, block->L.numunspents = numvouts, block->L.numspends = numvins; - if ( fwrite(block,1,sizeof(*block),fp) != sizeof(*block) ) - printf("iguana_emittxarray: error writing block.%d\n",block->height); - fseek(fp,endpos,SEEK_SET); - } - } - - int32_t iguana_maptxdata(struct iguana_info *coin,struct iguana_mappedptr *M,struct iguana_bundle *bp,char *fname) - { - void *fileptr = 0; int32_t i; uint32_t *offsets; struct iguana_block *block; - if ( (fileptr= iguana_mappedptr(0,M,0,0,fname)) != 0 ) - { - offsets = fileptr; - for (i=0; in; i++) - { - if ( (block= bp->blocks[i]) != 0 ) - { - if ( block->txdata != 0 ) - { - if ( block->mapped == 0 ) - { - printf("[%d].%d free txdata.%d %p\n",bp->hdrsi,i,((struct iguana_bundlereq *)block->txdata)->allocsize,block->txdata); - myfree(block->txdata,((struct iguana_bundlereq *)block->txdata)->allocsize); - block->txdata = 0; - block->mapped = 0; - } - } - if ( i < coin->chain->bundlesize ) - { - block->txdata = (void *)((long)fileptr + offsets[i]); - block->mapped = 1; - } - } - else if ( i < coin->chain->bundlesize ) - printf("iguana_maptxdata cant find block[%d]\n",i); - } - return(i < coin->chain->bundlesize ? i : coin->chain->bundlesize); - } - printf("error mapping (%s)\n",fname); - return(-1); - } - - void iguana_emittxdata(struct iguana_info *coin,struct iguana_bundle *emitbp) - { - FILE *fp; char fname[512];uint32_t offsets[_IGUANA_HDRSCOUNT+1]; - //uint8_t extra[256]; struct iguana_msgtx *txarray,*tx; - struct iguana_bundlereq *req; struct iguana_mappedptr M; - int32_t i,bundleheight,height,numtx,n; long len; struct iguana_block *block; - return; - if ( emitbp == 0 ) - return; - sprintf(fname,"tmp/%s/txdata.%d",coin->symbol,emitbp->bundleheight); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - bundleheight = emitbp->bundleheight; - for (i=n=0; in&&ichain->bundlesize; i++) - if ( (block= emitbp->blocks[i]) != 0 && block->txdata != 0 && block->mapped == 0 ) - n++; - if ( n != emitbp->n && n != coin->chain->bundlesize ) - printf("iguana_emittxdata: WARNING n.%d != bundlesize.%d bundlesize.%d\n",n,emitbp->n,coin->chain->bundlesize); - memset(offsets,0,sizeof(offsets)); - if ( (len= fwrite(offsets,sizeof(*offsets),n+1,fp)) != n+1 ) - printf("%s: error writing blank offsets len.%ld != %d\n",fname,len,n+1); - for (i=0; iblocks[i]) != 0 ) - { - if ( (req= block->txdata) != 0 && (numtx= block->txn_count) > 0 ) - { - if ( 0 && fwrite(req->serialized,1,req->n,fp) != req->n ) - printf("error writing serialized data.%d\n",req->n); - if ( 0 && (txarray= iguana_gentxarray(coin,&len2,block,req->serialized,req->n,extra)) != 0 ) - { - tx = txarray; - for (j=0; jvouts,tx->tx_out,tx->vins,tx->tx_in); - printf("emit.%d txarray.%p[%d]\n",i,txarray,numtx); - iguana_emittxarray(coin,fp,block,txarray,numtx); - iguana_freetx(txarray,numtx); - } - } else printf("emittxdata: unexpected missing txarray[%d]\n",i); - } else printf("emittxdata: error with recvblockptr[%d]\n",emitbp->bundleheight + i); - } - offsets[i] = (uint32_t)ftell(fp); - rewind(fp); - if ( (len= fwrite(offsets,sizeof(*offsets),n+1,fp)) != n+1 ) - printf("%s: error writing offsets len.%ld != %d\n",fname,len,n+1); - fclose(fp), fp = 0; - memset(&M,0,sizeof(M)); - //if ( iguana_maptxdata(coin,&M,emitbp,fname) != n ) - // printf("emit error mapping n.%d height.%d\n",n,bundleheight); - //else - { - //if ( emitbp->blockhashes != 0 ) - // myfree(emitbp->blockhashes,sizeof(*emitbp->blockhashes) * emitbp->n); - //emitbp->blockhashes = 0; - } - } - }*/ - //static uint64_t Tx_allocated,Tx_allocsize,Tx_freed,Tx_freesize; - - /*int64_t iguana_MEMallocated(struct iguana_info *coin) - { - int64_t total = coin->TMPallocated; - if ( Tx_allocsize > Tx_freesize ) - total += (Tx_allocsize - Tx_freesize); - //total += coin->R.RSPACE.openfiles * coin->R.RSPACE.size; - //total += iguana_packetsallocated(coin); - return(total); - }*/ - - static int32_t _sort_by_bits256(struct iguana_kvitem *a,struct iguana_kvitem *b) - { - return(bits256_cmp(*(bits256 *)a->keyvalue,*(bits256 *)b->keyvalue)); - } - - static int32_t _sort_by_revbits256(struct iguana_kvitem *a,struct iguana_kvitem *b) - { - return(bits256_revcmp(*(bits256 *)a->keyvalue,*(bits256 *)b->keyvalue)); - } - - static int32_t _sort_by_rmd160(struct iguana_kvitem *a,struct iguana_kvitem *b) - { - return(rmd160_cmp(a->keyvalue,b->keyvalue)); - } - - static int32_t _sort_by_revrmd160(struct iguana_kvitem *a,struct iguana_kvitem *b) - { - return(rmd160_revcmp(a->keyvalue,b->keyvalue)); - } - - // HASH_SORT(coin->blocks.hash,_sort_by_txid); - /* if ( bp->type == 'Q' ) - { - req = (struct iguana_bundlereq *)ptr; - //printf("START.%p save tmp txdata %p [%d].%d datalen.%d %p\n",req,req->argbp,req->argbp!=0?req->argbp->hdrsi:-1,req->argbundlei,req->datalen,req->data); - if ( fp != 0 ) - { - if ( fwrite(req->data,1,req->datalen,fp) != req->datalen ) - printf("error writing [%d].%d datalen.%d\n",req->argbp!=0?req->argbp->hdrsi:-1,req->argbundlei,req->datalen); - } - //Tx_freed++; - //Tx_freesize += req->allocsize; - if ( req->data != 0 ) - myfree(req->data,req->datalen); - if ( req->blocks != 0 ) - myfree(req->blocks,sizeof(*req->blocks)); - myfree(req,req->allocsize); - } - else if ( bp->type == 'E' ) - { - fflush(fp); - //myallocated(0,0); - //iguana_emittxdata(bp->coin,bp); - //myallocated(0,0); - } - else - { - printf("iguana_helper: unsupported type.%c %d %p\n",bp->type,bp->type,bp); - }*/ - for (j=0; jhdrsi,bundlei,itembp->emitfinish); - if ( itembp->emitfinish != 0 ) - finished++; - } - } - if ( finished == num ) - iguana_peerfilecloseHT(coin,inds[j][0],inds[j][1]); - else printf("peerdir.(%d %d) finished.%d of %d\n",inds[j][0],inds[j][1],finished,num); - } else printf("cant get peerdirptr.(%d %d)\n",inds[j][0],inds[j][1]); - } - - int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct iguana_memspace *mem,struct iguana_memspace *memB,struct iguana_bundle *bp) // helper thread - { - void *ptrs[IGUANA_MAXBUNDLESIZE]; uint32_t inds[IGUANA_MAXBUNDLESIZE][2]; struct iguana_fileitem *dir; - struct iguana_bundle *itembp; int32_t addrind,bundlei,finished,fileind,i,j,maxrecv,num,flag,numdirs=0; - struct iguana_txdatabits txdatabits; struct iguana_ramchain *ramchain; uint64_t estimatedsize = 0; - struct iguana_block *block; - memset(ptrs,0,sizeof(ptrs)), memset(inds,0,sizeof(inds)); - flag = maxrecv = 0; - for (i=0; in && ichain->bundlesize; i++) - { - if ( (block= bp->blocks[i]) != 0 ) - { - txdatabits = block->txdatabits; - if ( memcmp(block->hash2.bytes,coin->chain->genesis_hashdata,sizeof(bits256)) == 0 ) - ptrs[i] = coin->chain->genesis_hashdata, flag++; - else if ( (ptrs[i]= iguana_peerfileptrHT(coin,txdatabits,1)) != 0 ) - { - if ( block->recvlen > maxrecv ) - maxrecv = block->recvlen; - estimatedsize += block->recvlen; - flag++; - } - else - { - printf("peerfileptr[%d] (%d %d %d %d) null bp.%p %d\n",i,txdatabits.addrind,txdatabits.filecount,txdatabits.fpos,txdatabits.datalen,bp,bp->hdrsi); - if ( 1 ) - { - CLEARBIT(bp->recv,i); - bp->issued[i] = 0; - memset(&block->txdatabits,0,sizeof(block->txdatabits)); - block = 0; - } - } - addrind = txdatabits.addrind, fileind = txdatabits.filecount; - if ( numdirs > 0 ) - { - for (j=0; j>>>>>>>> start MERGE.(%ld %ld) numdirs.%d i.%d flag.%d estimated.%ld maxrecv.%d\n",(long)mem->totalsize,(long)memB->totalsize,numdirs,i,flag,(long)estimatedsize,maxrecv); - if ( (ramchain= iguana_bundlemergeHT(coin,mem,memB,ptrs,i,bp)) != 0 ) - { - iguana_ramchainsave(coin,mem,ramchain); - iguana_ramchainfree(coin,mem,ramchain); - bp->emitfinish = (uint32_t)time(NULL); - } else bp->emitfinish = 0; - iguana_mempurge(mem); - iguana_mempurge(memB); - } - else - { - printf(">>>>> bundlesaveHT error: numdirs.%d i.%d flag.%d\n",numdirs,i,flag); - bp->emitfinish = 0; - } - return(flag); - } - - int32_t iguana_peerfilecloseHT(struct iguana_info *coin,uint32_t addrind,uint32_t filecount) - { - char fname[512]; int32_t i,n = 0; struct iguana_mappedptr *M; - return(0); - iguana_peerfilename(coin,fname,addrind,filecount); - printf("PEERFILECLOSE.%s\n",fname); - //portable_mutex_lock(&coin->peers.filesM_mutex); - if ( coin->peers.filesM != 0 ) - { - for (i=0; ipeers.numfilesM; i++) - { - M = &coin->peers.filesM[i]; - if ( strcmp(fname,M->fname) == 0 && M->fileptr != 0 ) - { - printf("[%d] closemap.(%s)\n",i,fname); - iguana_closemap(M); - M->closetime = (uint32_t)time(NULL); - n++; - } - } - } - //portable_mutex_unlock(&coin->peers.filesM_mutex); - return(n); - } - - void *_iguana_txdataptrHT(struct iguana_info *coin,struct iguana_mappedptr *M,char *fname,struct iguana_txdatabits txdatabits) - { - int32_t len; uint8_t *rawptr; uint32_t starttime = (uint32_t)time(NULL); - if ( M->fileptr != 0 ) - { - while ( M->allocsize < (txdatabits.fpos + txdatabits.datalen + sizeof(uint32_t)) ) - { - iguana_closemap(M); - if ( iguana_mappedptr(0,M,0,0,fname) == 0 || M->allocsize < (txdatabits.fpos + txdatabits.datalen + sizeof(uint32_t)) ) - { - if ( time(NULL) > starttime+3 ) - { - printf("too small (%s) %llu vs %ld\n",fname,(long long)M->allocsize,(txdatabits.fpos + txdatabits.datalen + sizeof(uint32_t))); - return(0); - } else sleep(1); - } - } - rawptr = (void *)((long)M->fileptr + txdatabits.fpos); - memcpy(&len,rawptr,sizeof(len)); - if ( len == IGUANA_MARKER ) - { - memcpy(&len,&rawptr[sizeof(len)],sizeof(len)); - //printf("found marker %s[%u] numblocks.%d\n",fname,(int32_t)txdatabits.fpos,len); - if ( txdatabits.isdir != 0 ) - return(&rawptr[sizeof(uint32_t)*2]); - else printf("isdir notset with IGUANA_MARKER.%x\n",IGUANA_MARKER); - } - else if ( len == txdatabits.datalen && len < IGUANA_MAXPACKETSIZE ) - { - if ( txdatabits.isdir == 0 ) - return(&rawptr[sizeof(uint32_t)]); - else printf("isdir set without IGUANA_MARKER.%x\n",IGUANA_MARKER); - } else printf("txdataptr.%s: len.%d error [%d %d %d %d] (%d %d)\n",fname,len,txdatabits.datalen,txdatabits.addrind,txdatabits.fpos,txdatabits.filecount,len == txdatabits.datalen,len < IGUANA_MAXPACKETSIZE);//, getchar(); - } //else printf("txdataptr.%s %p %ld vs %ld\n",M->fname,M->fileptr,M->allocsize,(txdatabits.fpos + txdatabits.datalen + sizeof(uint32_t))); - return(0); - } -#define IGUANA_MARKER 0x07770777 - - void iguana_peerfilename(struct iguana_info *coin,char *fname,uint32_t addrind,uint32_t filecount) - { - sprintf(fname,"tmp/%s/peer%d.%d",coin->symbol,addrind,filecount); - } - - struct iguana_txdatabits iguana_calctxidbits(uint32_t addrind,uint32_t filecount,uint32_t fpos,uint32_t datalen) - { - struct iguana_txdatabits bits; - if ( (bits.addrind= addrind) != addrind ) - printf("iguana_calctxidbits: addrind overflow.%d\n",addrind), exit(-1); - if ( (bits.filecount= filecount) != filecount ) - printf("iguana_calctxidbits: filecount overflow.%d\n",filecount), exit(-1); - if ( (bits.fpos= fpos) != fpos ) - printf("iguana_calctxidbits: fpos overflow.%d\n",fpos), exit(-1); - if ( (bits.datalen= datalen) != datalen ) - printf("iguana_calctxidbits: datalen overflow.%d\n",datalen), exit(-1); - return(bits); - } - - void *iguana_peerfileptrHT(struct iguana_info *coin,struct iguana_txdatabits txdatabits,int32_t createflag) - { - char fname[512]; int32_t i,oldesti,oldest,duration,datalen; uint64_t fpos; struct iguana_mappedptr *M = 0; void *ptr = 0; - fpos = txdatabits.fpos, datalen = txdatabits.datalen; - oldesti = -1; - oldest = 0; - iguana_peerfilename(coin,fname,txdatabits.addrind,txdatabits.filecount); - //portable_mutex_lock(&coin->peers.filesM_mutex); - if ( coin->peers.filesM != 0 ) - { - for (i=0; ipeers.numfilesM; i++) - { - M = &coin->peers.filesM[i]; - if ( strcmp(fname,M->fname) == 0 ) - { - if ( M->fileptr != 0 && (ptr= _iguana_txdataptrHT(coin,M,fname,txdatabits)) != 0 ) - { - //portable_mutex_unlock(&coin->peers.filesM_mutex); - //printf("peerfileptr.(%s) %d %d -> %p\n",fname,txdatabits.addrind,txdatabits.filecount,ptr); - return(ptr); - } - else if ( M->closetime != 0 ) - { - duration = (uint32_t)(time(NULL) - M->closetime); - if ( duration > oldest ) - oldest = duration, oldesti = i; - } - } - } - M = 0; - } - if ( createflag != 0 ) - { - if ( oldesti >= 0 && oldest > 60 ) - { - M = &coin->peers.filesM[oldesti]; - printf("oldesti.%d oldest.%d remove.(%s) recycle slot.%d\n",oldesti,oldest,M->fname,i); - iguana_removefile(M->fname,0); - memset(M,0,sizeof(*M)); - } - if ( M == 0 ) - { - coin->peers.filesM = myrealloc('m',coin->peers.filesM,coin->peers.filesM==0?0:coin->peers.numfilesM * sizeof(*coin->peers.filesM),(coin->peers.numfilesM+1) * sizeof(*coin->peers.filesM)); - M = &coin->peers.filesM[coin->peers.numfilesM]; - coin->peers.numfilesM++; - //if ( (coin->peers.numfilesM % 10) == 0 ) - printf("iguana_peerfileptr realloc filesM.%d\n",coin->peers.numfilesM); - } - if ( iguana_mappedptr(0,M,0,0,fname) != 0 ) - { - ptr = _iguana_txdataptrHT(coin,M,fname,txdatabits); - printf("mapped.(%s) size.%ld %p\n",fname,(long)M->allocsize,ptr); - } else printf("iguana_peerfileptr error mapping.(%s)\n",fname); - } - //portable_mutex_unlock(&coin->peers.filesM_mutex); - return(ptr); - } - - struct iguana_fileitem *iguana_peerdirptrHT(struct iguana_info *coin,int32_t *nump,uint32_t addrind,uint32_t filecount,int32_t createflag) - { - char fname[512]; FILE *fp; uint32_t dirpos,marker; struct iguana_txdatabits txdatabits; - *nump = 0; - if ( filecount >= coin->peers.active[addrind].filecount ) - return(0); - iguana_peerfilename(coin,fname,addrind,filecount); - if ( (fp= fopen(fname,"rb")) != 0 ) - { - fseek(fp,-sizeof(int32_t) * 3,SEEK_END); - fread(nump,1,sizeof(*nump),fp); - fread(&dirpos,1,sizeof(dirpos),fp); - fread(&marker,1,sizeof(marker),fp); - if ( marker == IGUANA_MARKER && (dirpos + sizeof(uint32_t) * 5 + *nump * sizeof(struct iguana_fileitem)) == ftell(fp) ) - { - txdatabits = iguana_calctxidbits(addrind,filecount,dirpos,(int32_t)(*nump * sizeof(struct iguana_fileitem))); - fclose(fp); - txdatabits.isdir = 1; - return(iguana_peerfileptrHT(coin,txdatabits,1)); - } - else //if ( marker == IGUANA_MARKER ) - printf("marker.%x vs %x: dirpos.%d num.%d -> %ld vs %ld\n",marker,IGUANA_MARKER,dirpos,*nump,dirpos + sizeof(uint32_t) * 4 + *nump * sizeof(struct iguana_fileitem),ftell(fp)); - fclose(fp); - } else printf("cant open dir.(%s)\n",fname); - return(0); - } - struct iguana_txdatabits iguana_peerfilePT(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,struct iguana_txdatabits txdatabits,int32_t datalen) - { - char fname[512]; int32_t marker; uint32_t dirpos; - if ( bits256_nonz(hash2) == 0 || addr->fp == 0 || ftell(addr->fp)+datalen >= IGUANA_PEERFILESIZE-IGUANA_MAXPACKETSIZE || addr->numfilehash2 >= addr->maxfilehash2 ) - //if ( addr->fp == 0 ) - { - if ( addr->fp != 0 ) - { - dirpos = (uint32_t)ftell(addr->fp); - marker = IGUANA_MARKER; - fwrite(&marker,1,sizeof(marker),addr->fp); - fwrite(&addr->numfilehash2,1,sizeof(addr->numfilehash2),addr->fp); - fwrite(addr->filehash2,addr->numfilehash2,sizeof(*addr->filehash2),addr->fp); - fwrite(&addr->numfilehash2,1,sizeof(addr->numfilehash2),addr->fp); - fwrite(&dirpos,1,sizeof(dirpos),addr->fp); - fwrite(&marker,1,sizeof(marker),addr->fp); - fclose(addr->fp); - //iguana_flushQ(coin,addr); - //fflush(addr->fp); - } - iguana_peerfilename(coin,fname,addr->addrind,++addr->filecount); - txdatabits.filecount = addr->filecount; - addr->fp = fopen(fname,"wb"); - addr->numfilehash2 = 0; - } - if ( addr->fp == 0 ) - { - printf("error creating fileind.%d %s\n",addr->filecount,addr->ipaddr); - exit(1); - } - if ( addr->numfilehash2 < addr->maxfilehash2 ) - { - if ( addr->filehash2 == 0 ) - addr->filehash2 = mycalloc('f',addr->maxfilehash2,sizeof(*addr->filehash2)); - addr->filehash2[addr->numfilehash2].hash2 = hash2; - addr->filehash2[addr->numfilehash2].txdatabits = txdatabits; - addr->numfilehash2++; - } - return(txdatabits); - } - - - int32_t iguana_ramchainspend(struct iguana_info *coin,struct iguana_ramchain *ramchain,uint32_t spendind,uint32_t spent_txidind,uint16_t spent_vout,int32_t updateflag) - { - struct iguana_pkhash *p; struct iguana_unspent *u; struct iguana_account *acct; int32_t unspentind,pkind; - if ( spent_txidind < ramchain->numtxids ) - { - unspentind = (spent_txidind + spent_vout); - u = &ramchain->U[unspentind]; - if ( (pkind= u->pkind) < ramchain->numpkinds && pkind >= 0 ) - { - if ( updateflag != 0 ) - { - p = &ramchain->P[pkind]; - if ( ramchain->pkextras[pkind].firstspendind == 0 ) - ramchain->pkextras[pkind].firstspendind = spendind; - acct = &ramchain->accounts[pkind]; - ramchain->S[spendind].prevspendind = acct->lastspendind; - acct->lastspendind = spendind; - if ( ramchain->Uextras[unspentind].spendind != 0 ) - { - printf("double spend u.%d has spendind.%d when s.%d refers to it\n",unspentind,ramchain->Uextras[unspentind].spendind,spendind); - return(-1); - } - ramchain->Uextras[unspentind].spendind = spendind; - } - return(1); - } - } - return(0); - } - - int32_t iguana_ramchainspends(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t updateflag) - { - struct iguana_spend *s; int32_t j,spendind,retval,spent_txidind,spent_vout,needtxidinds = 0; - spendind = 0; - for (j=0; jnumspends; j++,spendind++) - { - s = &ramchain->S[spendind]; - spent_txidind = (s->unspentind >> 16) & 0xffff; - spent_vout = (s->unspentind & 0xffff); - if ( (retval= iguana_ramchainspend(coin,ramchain,spendind,spent_txidind,spent_vout,updateflag)) < 0 ) - return(-1); - needtxidinds += retval; - } - return(needtxidinds); - } - - int32_t iguana_ramchainload(struct iguana_info *coin,struct iguana_memspace *mem,struct iguana_ramchain *ramchain) - { - int32_t i,j; uint32_t unspentind,spendind,txidind,pkind,needtxidinds = 0; - struct iguana_txid *tx; struct iguana_pkhash *p; struct iguana_unspent *u; struct iguana_account *acct; - txidind = unspentind = spendind = pkind = 0; - for (pkind=0; pkindnumpkinds; pkind++) - { - p = &ramchain->P[pkind]; - iguana_hashsetHT(ramchain->pkhashes,0,p->rmd160,sizeof(p->rmd160),pkind); - } - for (i=0; inumtxids; i++,txidind++) - { - tx = &ramchain->T[txidind]; - iguana_hashsetHT(ramchain->txids,0,tx->txid.bytes,sizeof(bits256),txidind); - for (j=0; jnumvouts; j++,unspentind++) - { - u = &ramchain->U[unspentind]; - acct = &ramchain->accounts[u->pkind]; - u->prevunspentind = acct->lastunspentind; - acct->lastunspentind = unspentind; - if ( u->txidind != txidind ) - { - printf("txidind.%d u->txidind.%d mismatch\n",txidind,u->txidind); - return(-1); - } - acct->balance += u->value; - } - } - if ( (needtxidinds= iguana_ramchainspends(coin,ramchain,0)) == 0 ) - { - if ( (needtxidinds= iguana_ramchainspends(coin,ramchain,1)) != 0 ) - printf("ramchainspends unexpected error\n"); - } - return(needtxidinds); - } - - int32_t iguana_ramchainload(struct iguana_info *coin,struct iguana_memspace *mem,struct iguana_ramchain *ramchain) - { - int32_t i,j; uint32_t unspentind,spendind,txidind,pkind,needtxidinds = 0; - struct iguana_txid *tx; struct iguana_pkhash *p; struct iguana_unspent *u; struct iguana_account *acct; - txidind = unspentind = spendind = 0; - for (i=0; inumtxids; i++,txidind++) - { - tx = &ramchain->T[txidind]; - iguana_hashsetHT(ramchain->txids,0,tx->txid.bytes,sizeof(bits256),txidind); - for (j=0; jnumvouts; j++,unspentind++) - { - } - } - if ( (needtxidinds= iguana_ramchainspends(coin,ramchain,0)) == 0 ) - { - if ( (needtxidinds= iguana_ramchainspends(coin,ramchain,1)) != 0 ) - printf("ramchainspends unexpected error\n"); - } - return(needtxidinds); - } - - - int32_t iguana_ramchainspend(struct iguana_info *coin,struct iguana_ramchain *ramchain,uint32_t spendind,uint32_t spent_txidind,uint16_t spent_vout,int32_t updateflag) - { - struct iguana_pkhash *p; struct iguana_unspent *u; struct iguana_account *acct; int32_t unspentind,pkind; - if ( spent_txidind < ramchain->numtxids ) - { - unspentind = (spent_txidind + spent_vout); - u = &ramchain->U[unspentind]; - if ( (pkind= u->pkind) < ramchain->numpkinds && pkind >= 0 ) - { - if ( updateflag != 0 ) - { - p = &ramchain->P[pkind]; - if ( ramchain->pkextras[pkind].firstspendind == 0 ) - ramchain->pkextras[pkind].firstspendind = spendind; - acct = &ramchain->accounts[pkind]; - ramchain->S[spendind].prevspendind = acct->lastspendind; - acct->lastspendind = spendind; - if ( ramchain->Uextras[unspentind].spendind != 0 ) - { - printf("double spend u.%d has spendind.%d when s.%d refers to it\n",unspentind,ramchain->Uextras[unspentind].spendind,spendind); - return(-1); - } - ramchain->Uextras[unspentind].spendind = spendind; - } - return(1); - } - } - return(0); - } - uint32_t oldiguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana_iAddr *iA,uint32_t ind) - { - uint32_t tmpind; char ipaddr[64]; struct iguana_iAddr checkiA; - if ( rwflag == 0 ) - { - memset(iA,0,sizeof(*iA)); - if ( iguana_kvread(coin,coin->iAddrs,0,iA,&ind) != 0 ) - { - //printf("read[%d] %x -> status.%d\n",ind,iA->ipbits,iA->status); - return(ind); - } else printf("error getting pkhash[%u] when %d\n",ind,coin->numiAddrs); - } - else - { - expand_ipbits(ipaddr,iA->ipbits); - tmpind = ind; - if ( iguana_kvwrite(coin,coin->iAddrs,&iA->ipbits,iA,&tmpind) != 0 ) - { - if ( tmpind != ind ) - printf("warning: tmpind.%d != ind.%d for %s\n",tmpind,ind,ipaddr); - //printf("iA[%d] wrote status.%d\n",ind,iA->status); - if ( iguana_kvread(coin,coin->iAddrs,0,&checkiA,&tmpind) != 0 ) - { - if ( memcmp(&checkiA,iA,sizeof(checkiA)) != 0 ) - printf("compare error tmpind.%d != ind.%d\n",tmpind,ind); - } - return(iA->ipbits); - } else printf("error kvwrite (%s) ind.%d tmpind.%d\n",ipaddr,ind,tmpind); - } - printf("iA[%d] error rwflag.%d\n",ind,rwflag); - return(0); - } - struct iguana_peer *iguana_choosepeer(struct iguana_info *coin) - { - int32_t i,j,r,iter; struct iguana_peer *addr; - r = rand(); - portable_mutex_lock(&coin->peers_mutex); - if ( coin->MAXPEERS == 0 ) - coin->MAXPEERS = IGUANA_MAXPEERS; - if ( coin->peers.numranked > 0 ) - { - for (j=0; jpeers.numranked; j++) - { - i = (j + r) % coin->MAXPEERS; - if ( (addr= coin->peers.ranked[i]) != 0 && addr->pendblocks < coin->MAXPENDING && addr->dead == 0 && addr->usock >= 0 ) - { - portable_mutex_unlock(&coin->peers_mutex); - return(addr); - } - } - } - portable_mutex_unlock(&coin->peers_mutex); - for (iter=0; iter<2; iter++) - { - for (i=0; iMAXPEERS; i++) - { - addr = &coin->peers.active[(i + r) % coin->MAXPEERS]; - if ( addr->dead == 0 && addr->usock >= 0 && (iter == 1 || addr->pendblocks < coin->MAXPENDING) ) - return(addr); - } - } - return(0); - } - void iguana_shutdownpeers(struct iguana_info *coin,int32_t forceflag) - { -#ifndef IGUANA_DEDICATED_THREADS - int32_t i,skip,iter; struct iguana_peer *addr; - if ( forceflag != 0 ) - coin->peers.shuttingdown = (uint32_t)time(NULL); - for (iter=0; iter<60; iter++) - { - skip = 0; - for (i=0; iMAXPEERS; i++) - { - addr = &coin->peers.active[i]; - if ( addr->ipbits == 0 || addr->usock < 0 || (forceflag == 0 && addr->dead == 0) ) - continue; - if ( addr->startsend != 0 || addr->startrecv != 0 ) - { - skip++; - continue; - } - iguana_iAkill(coin,addr,0); - } - if ( skip == 0 ) - break; - sleep(1); - printf("iguana_shutdownpeers force.%d skipped.%d\n",forceflag,skip); - } - if ( forceflag != 0 ) - coin->peers.shuttingdown = 0; -#endif - } - - uint32_t iguana_ipbits2ind(struct iguana_info *coin,struct iguana_iAddr *iA,uint32_t ipbits,int32_t createflag) - { - char ipaddr[64]; struct iguana_kvitem *item; struct iguana_iAddr *tmp; - expand_ipbits(ipaddr,ipbits); - //printf("ipbits.%x %s to ind\n",ipbits,ipaddr); - memset(iA,0,sizeof(*iA)); - if ( (item= iguana_hashfind(coin->iAddrs,&ipbits,sizeof(ipbits))) == 0 ) - //if ( iguana_kvread(coin,coin->iAddrs,&ipbits,iA,&ind) == 0 ) - { - if ( createflag == 0 ) - return(0); - tmp = mycalloc('i',1,sizeof(*iA)); - *tmp = *iA; - iA->ind = coin->numiAddrs; - iA->ipbits = ipbits; - if ( (item= iguana_hashset(coin->iAddrs,0,&iA->ipbits,sizeof(iA->ipbits),iA->ind)) == 0 ) - { - printf("iguana_addr: cant save.(%s)\n",ipaddr); - return(0); - } - else - { - coin->numiAddrs++; - if ( iguana_rwiAddrind(coin,1,iA,iA->ind) == 0 ) - printf("error iAddr.%d: created %x %s\n",iA->ind,ipbits,ipaddr); - } - } - else *iA = *(struct iguana_iAddr *)item->keyvalue; - return(iA->ind); - } - - int32_t iguana_set_iAddrheight(struct iguana_info *coin,uint32_t ipbits,int32_t height) - { - struct iguana_iAddr iA; uint32_t ind; - if ( (ind= iguana_ipbits2ind(coin,&iA,ipbits,1)) > 0 ) - { - iA.ipbits = ipbits; - if ( (ind= iguana_rwiAddrind(coin,0,&iA,ind)) > 0 && height > iA.height ) - { - iA.height = height; - iA.ipbits = ipbits; - iguana_rwiAddrind(coin,1,&iA,ind); - } - } - return(iA.height); - } - - uint32_t iguana_rwipbits_status(struct iguana_info *coin,int32_t rwflag,uint32_t ipbits,int32_t *statusp) - { - struct iguana_iAddr iA; uint32_t ind; - if ( (ind= iguana_ipbits2ind(coin,&iA,ipbits,1)) > 0 ) - { - if ( (ind= iguana_rwiAddrind(coin,0,&iA,ind)) > 0 ) - { - if ( rwflag == 0 ) - *statusp = iA.status; - else - { - iA.status = *statusp; - iA.ipbits = ipbits; - printf("%p status.%d ipbits.%x iA.%d saved iA->ind.%d\n",&iA,iA.status,iA.ipbits,ind,iA.ind); - //printf("set status.%d for ind.%d\n",iA.status,ind); - if ( iguana_rwiAddrind(coin,1,&iA,ind) == 0 ) - { - printf("iguana_iAconnected (%x) save error\n",iA.ipbits); - return(0); - } - } - return(ind); - } else printf("iguana_rwiAstatus error getting iA[%d]\n",ind); - } else printf("error ipbits status\n"); - return(0); - } - - int32_t iguana_ramchainspends(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t updateflag) - { - struct iguana_spend *s; int32_t j,spendind,retval,needtxidinds = 0; - spendind = 0; - for (j=0; jnumspends; j++,spendind++) - { - s = &ramchain->S[spendind]; - if ( (retval= iguana_ramchainspend(coin,ramchain,spendind,s->spendtxidind,s->vout,updateflag)) < 0 ) - return(-1); - needtxidinds += retval; - } - return(needtxidinds); - } - if ( bundlei >= coin->chain->bundlesize ) - return(block); - if ( (block->bundlei= bundlei) == 0 ) - { - iguana_hash2set(coin,"bundlehash2",&bp->blockhashes[0],block->hash2); - //iguana_blockQ(coin,bp,0,bp->bundlehash2,1); - if ( bits256_nonz(block->prev_block) > 0 ) - { - //iguana_blockQ(coin,bp,-1,block->prev_block,1); - for (i=0; ibundlescount; i++) - { - if ( (prevbp= coin->bundles[i]) != 0 && prevbp->n >= coin->chain->bundlesize ) - { - cmphash2 = iguana_bundleihash2(coin,prevbp,coin->chain->bundlesize-1); - if ( memcmp(cmphash2.bytes,block->prev_block.bytes,sizeof(bits256)) == 0 ) - { - //printf("found prev_block\n"); - iguana_hash2set(coin,"bp setprev",&bp->prevbundlehash2,prevbp->blockhashes[0]); - iguana_hash2set(coin,"prevbp setnext",&prevbp->nextbundlehash2,bp->blockhashes[0]); - //printf("prev BUNDLES LINKED! (%d <-> %d) (%s <-> %s)\n",prevbp->bundleheight,bp->bundleheight,bits256_str(prevbp->bundlehash2),bits256_str2(bp->bundlehash2)); - if ( prevbp->bundleheight != bp->bundleheight-coin->chain->bundlesize ) - printf("WARNING gap in bundleheight %d != %d bundlesize\n",prevbp->bundleheight,bp->bundleheight-coin->chain->bundlesize); - break; - } - } - } - } - } - else if ( bundlei == 1 ) - { - if ( iguana_hash2set(coin,"firstblockhash2",&bp->blockhashes[1],block->hash2) < 0 ) - return(0); - if ( bp->blockhashes != 0 ) - { - if ( bits256_nonz(block->prev_block) > 0 ) - iguana_hash2set(coin,"b blockhashes[0]",&bp->blockhashes[0],block->prev_block); - iguana_hash2set(coin,"b blockhashes[1]",&bp->blockhashes[1],block->hash2); - } - } - else if ( bundlei == bp->n-1 ) - { - if ( (nextbp= iguana_bundlefind(coin,&nextbundlei,hash2,IGUANA_SEARCHBUNDLE)) != 0 ) - { - if ( nextbundlei == 0 ) - { - iguana_hash2set(coin,"bp setnext",&bp->nextbundlehash2,nextbp->blockhashes[0]); - iguana_hash2set(coin,"next setprev",&nextbp->prevbundlehash2,bp->blockhashes[0]); - char str[65],str2[65]; - bits256_str(str,bp->blockhashes[0]), bits256_str(str2,nextbp->blockhashes[0]); - printf("next BUNDLES LINKED! (%d <-> %d) (%s <-> %s)\n",bp->bundleheight,nextbp->bundleheight,str,str2); - if ( nextbp->bundleheight != bp->bundleheight+coin->chain->bundlesize ) - printf("WARNING gap in bundleheight %d != %d bundlesize\n",nextbp->bundleheight,bp->bundleheight+coin->chain->bundlesize); - } else printf("nextbundlei.%d != 0 nextbp->n %d\n",nextbundlei,nextbp->n); - } - //iguana_hash2set(coin,"lastblockhash2",&bp->lastblockhash2,block->hash2); - } - } - - - struct iguana_bundle *iguana_bundlescan(struct iguana_info *coin,int32_t *bundleip,struct iguana_bundle *bp,bits256 hash2,int32_t searchmask) - { - int32_t i; - *bundleip = -2; - if ( (searchmask & IGUANA_SEARCHBUNDLE) != 0 ) - { - // bloom filter here - //printf("%s vs %s: %d\n",bits256_str(hash2),bits256_str2(bp->bundlehash2),memcmp(hash2.bytes,bp->bundlehash2.bytes,sizeof(hash2))); - if ( memcmp(hash2.bytes,bp->blockhashes[0].bytes,sizeof(hash2)) == 0 ) - { - *bundleip = 0; - //printf("found blockhash[0]\n"); - return(bp); - } - if ( memcmp(hash2.bytes,bp->blockhashes[1].bytes,sizeof(hash2)) == 0 ) - { - *bundleip = 1; - //printf("found blockhash[1]\n"); - return(bp); - } - for (i=2; in && ichain->bundlesize; i++) - { - if ( memcmp(hash2.bytes,bp->blockhashes[i].bytes,sizeof(hash2)) == 0 ) - { - *bundleip = i; - return(bp); - } - } - } - if ( (searchmask & IGUANA_SEARCHPREV) != 0 && memcmp(hash2.bytes,bp->prevbundlehash2.bytes,sizeof(hash2)) == 0 ) - { - *bundleip = -1; - return(bp); - } - if ( (searchmask & IGUANA_SEARCHNEXT) != 0 && memcmp(hash2.bytes,bp->nextbundlehash2.bytes,sizeof(hash2)) == 0 ) - { - *bundleip = bp->n; - return(bp); - } - return(0); - } - - struct iguana_bundle *iguana_bundlefind(struct iguana_info *coin,int32_t *bundleip,bits256 hash2,int32_t adjust) - { - int32_t i,searchmask; struct iguana_bundle *bp = 0; // struct iguana_block *block; - *bundleip = -2; - if ( bits256_nonz(hash2) > 0 ) - { - if ( adjust == 0 ) - searchmask = IGUANA_SEARCHBUNDLE; - else searchmask = IGUANA_SEARCHNOLAST; - //if ( (block= iguana_blockfind(coin,hash2)) != 0 && (bp= block->bp) != 0 && (bp= iguana_bundlescan(coin,bundleip,bp,hash2,searchmask)) != 0 ) - // return(bp); - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - if ( (bp= iguana_bundlescan(coin,bundleip,bp,hash2,searchmask)) != 0 ) - return(bp); - } - } - } - //printf("iguana_hdrsfind: cant find %s\n",bits256_str(hash2)); - return(0); - } - - int32_t iguana_bundlecheck(struct iguana_info *coin,struct iguana_bundle *bp,int32_t priorityflag) - { - int32_t i,qsize,remains,incomplete,lasti,n = 0; struct iguana_block *block; - bits256 hash2; double threshold; uint64_t datasize =0; - //printf("bp.%p bundlecheck.%d emit.%d\n",bp,bp->ramchain.hdrsi,bp->emitfinish); - if ( bp != 0 && bp->emitfinish == 0 ) - { - remains = bp->n - bp->numrecv; - qsize = queue_size(&coin->priorityQ); - if ( bp->numrecv > coin->chain->bundlesize*.98 ) - { - priorityflag = 1; - if ( bp->numrecv > coin->chain->bundlesize-3 ) - threshold = bp->avetime; - else threshold = bp->avetime * 2; - } else threshold = bp->avetime * 5; - lasti = -1; - for (i=0; in && ichain->bundlesize; i++) - { - hash2 = iguana_bundleihash2(coin,bp,i); - if ( bits256_nonz(hash2) == 0 ) - continue; - if ( (block= bp->blocks[i]) == 0 ) - block = bp->blocks[i] = iguana_blockfind(coin,hash2); - if ( block != 0 && block->ipbits != 0 ) - { - //char str[65]; - if ( block->recvlen != 0 ) - datasize += block->recvlen; - if ( block->hdrsi != bp->ramchain.hdrsi ) - block->hdrsi = bp->ramchain.hdrsi; - if ( block->bundlei != i ) - block->bundlei = i; - /* printf("%s %d[%d] != %d[%d]\n",bits256_str(str,block->hash2),block->hdrsi,block->bundlei,bp->ramchain.hdrsi,i); - CLEARBIT(bp->recv,i); - //memset(&bp->blocks[i]->txdatabits,0,sizeof(bp->blocks[i]->txdatabits)); - bp->issued[i] = milliseconds(); - iguana_blockQ(coin,bp,i,bp->blocks[i]->hash2,1); - bp->blocks[i] = 0; - } - else if ( block->bundlei != i ) - { - printf("%s %d[%d] != %d[%d]\n",bits256_str(str,block->hash2),block->hdrsi,block->bundlei,bp->ramchain.hdrsi,i); - CLEARBIT(bp->recv,i); - //memset(&bp->blocks[i]->txdatabits,0,sizeof(bp->blocks[i]->txdatabits)); - bp->issued[i] = milliseconds(); - iguana_blockQ(coin,bp,i,bp->blocks[i]->hash2,1); - bp->blocks[i] = 0; - } else */ - n++; - } - else if ( priorityflag != 0 && qsize == 0 )//&& (bp->issued[i] == 0 || milliseconds() > (bp->issued[i] + threshold)) ) - { - //if ( (rand() % 1000) == 0 ) - // printf("priorityQ submit threshold %.3f [%d].%d\n",threshold,bp->ramchain.hdrsi,i); - if ( bp->blocks[i] == 0 || bp->blocks[i]->ipbits == 0 ) - { - //CLEARBIT(bp->recv,i); - bp->issued[i] = 0;//milliseconds(); - //if ( i < 2 ) - // iguana_blockQ(coin,bp,i,hash2,1); - //iguana_blockQ(coin,bp,i,hash2,1); - //bp->blocks[i] = 0; - } - lasti = i; - } else lasti = i; - } - //if ( n == coin->chain->bundlesize-1 ) - //if ( n > 490 ) - // printf("bp.%d %d %d n.%d\n",bp->ramchain.hdrsi,bp->ramchain.bundleheight,lasti,n); - bp->numrecv = n; - bp->datasize = datasize; - if ( n > 0 ) - { - bp->estsize = ((uint64_t)datasize * coin->chain->bundlesize) / n; - //printf("estsize %d datasize.%d hdrsi.%d numrecv.%d\n",(int32_t)bp->estsize,(int32_t)datasize,bp->ramchain.hdrsi,n); - } - if ( n == coin->chain->bundlesize ) - { - printf("check %d blocks in hdrs.%d\n",n,bp->ramchain.hdrsi); - for (i=incomplete=0; iblocks[i]->hash2.bytes,bp->blocks[i+1]->prev_block.bytes,sizeof(bits256)) != 0 ) - { - if ( bits256_nonz(bp->blocks[i]->prev_block) > 0 && bits256_nonz(bp->blocks[i+1]->prev_block) > 0 && bits256_nonz(bp->blocks[i+1]->hash2) > 0 ) - { - char str[65],str2[65],str3[65]; - bits256_str(str,bp->blocks[i]->hash2); - bits256_str(str2,bp->blocks[i+1]->prev_block); - bits256_str(str3,bp->blocks[i+1]->hash2); - printf("%s ->%d %d<- %s %s ",str,i,i+1,str2,str3); - printf("broken chain in hdrs.%d %d %p <-> %p %d\n",bp->ramchain.hdrsi,i,bp->blocks[i],bp->blocks[i+1],i+1); - CLEARBIT(bp->recv,i); - //memset(&bp->blocks[i]->txdatabits,0,sizeof(bp->blocks[i]->txdatabits)); - //memset(&bp->blocks[i+1]->txdatabits,0,sizeof(bp->blocks[i+1]->txdatabits)); - bp->issued[i] = bp->issued[i+1] = milliseconds(); - //iguana_blockQ(coin,bp,i,bp->blocks[i]->hash2,1); - //iguana_blockQ(coin,bp,i+1,bp->blocks[i+1]->hash2,1); - bp->blocks[i] = bp->blocks[i+1] = 0; - break; - } - else incomplete++; - } - } - printf("i.%d n.%d incomplete.%d\n",i,n,incomplete); - if ( i == n-1 && incomplete == 0 ) - { - //if ( bp->blockhashes != 0 ) - //{ - for (i=0; iblockhashes[i],bp->blocks[i]->hash2); - // iguana_hash2set(coin,"check blockhashes[0]",&bp->blockhashes[0],bp->bundlehash2); - // iguana_hash2set(coin,"check firsthash2",&bp->blockhashes[1],bp->firstblockhash2); - //} - iguana_bundleblockadd(coin,bp,0,iguana_bundleihash2(coin,bp,0)); - iguana_bundleblockadd(coin,bp,coin->chain->bundlesize-1,iguana_bundleihash2(coin,bp,coin->chain->bundlesize-1)); - if ( bp->emitfinish <= 1 ) - iguana_emitQ(coin,bp); - if ( bp->emitfinish == 0 ) - bp->emitfinish = 1; - coin->numpendings--; - return(1); - } - } - } - return(0); - } - /****************************************************************************** - * Copyright © 2014-2015 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. * - * * - ******************************************************************************/ - -#include "iguana777.h" - - // peer context, ie massively multithreaded -> bundlesQ - - struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana_peer *addr,int32_t type,int32_t datalen) - { - struct iguana_bundlereq *req; int32_t allocsize; - allocsize = (uint32_t)sizeof(*req) + datalen; - req = mycalloc(type,1,allocsize); - req->allocsize = allocsize; - req->datalen = datalen; - req->addr = addr; - req->coin = coin; - req->type = type; - return(req); - } - - void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *txdata,struct iguana_msgtx *txarray,uint8_t *data,int32_t recvlen) - { - struct iguana_bundlereq *req; int32_t i,z,fpos,bundlei; FILE *fp; char fname[1024]; - if ( 0 ) - { - for (i=0; ispace[0]; i++) - if ( txdata->space[i] != 0 ) - break; - if ( i != txdata->space[0] ) - { - for (i=0; ispace[0]; i++) - printf("%02x ",txdata->space[i]); - printf("extra\n"); - } - } - req = iguana_bundlereq(coin,addr,'B',0); - if ( addr != 0 ) - { - if ( addr->pendblocks > 0 ) - addr->pendblocks--; - addr->lastblockrecv = (uint32_t)time(NULL); - addr->recvblocks += 1.; - addr->recvtotal += recvlen; - if ( (txdata= iguana_blockramchainPT(coin,addr,txdata,txarray,txdata->block.txn_count,data,recvlen)) != 0 ) - { - //fpos = (addr->fp != 0) ? ftell(addr->fp) : 0; - //txdatabits = iguana_calctxidbits(addr->addrind,addr->filecount,(uint32_t)fpos,txdata->datalen); - //txdatabits = iguana_peerfilePT(coin,addr,txdata->block.hash2,txdatabits,txdata->datalen); - fpos = 0; - if ( (bundlei= iguana_peerfname(coin,fname,addr->ipbits,txdata->block.hash2)) < 0 ) - { - if ( (fp= fopen(fname,"wb")) != 0 ) - coin->peers.numfiles++; - } - else - { - if ( (fp= fopen(fname,"rb+")) == 0 ) - { - if ( (fp= fopen(fname,"wb")) != 0 ) - { - z = -1; - coin->peers.numfiles++; - for (i=0; ichain->bundlesize; i++) - fwrite(&z,1,sizeof(z),fp); - fclose(fp); - fp = fopen(fname,"rb+"); - } - } - if ( fp != 0 ) - { - fseek(fp,0,SEEK_END); - fpos = (int32_t)ftell(fp); - } - } - if ( fp != 0 ) - { - txdata->block.bundlei = bundlei; - //printf("fpos.%d: bundlei.%d datalen.%d\n",fpos,bundlei,txdata->datalen); - fwrite(&bundlei,1,sizeof(bundlei),fp); - fwrite(&txdata->block.hash2,1,sizeof(txdata->block.hash2),fp); - fwrite(&txdata->datalen,1,sizeof(txdata->datalen),fp); - fwrite(txdata,1,txdata->datalen,fp); - if ( bundlei >= 0 && bundlei < coin->chain->bundlesize ) - { - fseek(fp,bundlei * sizeof(bundlei),SEEK_SET); - //printf("bundlei[%d] <- fpos.%d\n",bundlei,fpos); - fwrite(&fpos,1,sizeof(fpos),fp); - } else printf("error saving with bundlei.%d vs %d\n",bundlei,coin->chain->bundlesize); - fclose(fp); - //for (i=0; inumpkinds; i++) - // printf("%016lx ",*(long *)((struct iguana_pkhash *)((long)txdata + txdata->pkoffset))[i].rmd160); - //printf("create.(%s) %d ",fname,bundlei,coin->peers.numfiles); - //printf("bundlei.%d datalen.%d T.%d U.%d S.%d P.%d X.%d\n",bundlei,txdata->datalen,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,txdata->numexternaltxids); - { - struct iguana_txblock *checktxdata; struct iguana_memspace checkmem; int32_t checkbundlei; - memset(&checkmem,0,sizeof(checkmem)); - iguana_meminit(&checkmem,"checkmem",0,txdata->block.recvlen + 4096,0); - if ( 0 && (checktxdata= iguana_peertxdata(coin,&checkbundlei,fname,&checkmem,addr->ipbits,txdata->block.hash2)) != 0 ) - { - printf("check datalen.%d bundlei.%d T.%d U.%d S.%d P.%d X.%d\n",checktxdata->datalen,checkbundlei,checktxdata->numtxids,checktxdata->numunspents,checktxdata->numspends,checktxdata->numpkinds,checktxdata->numexternaltxids); - } - } - } - req->datalen = txdata->datalen; - } - } - coin->recvcount++; - coin->recvtime = (uint32_t)time(NULL); - req->block = txdata->block; - req->addr = addr; - req->block.txn_count = req->numtx = txdata->block.txn_count; - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); - } - - void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *txids,int32_t n) - { - struct iguana_bundlereq *req; - printf("got %d txids from %s\n",n,addr->ipaddr); - req = iguana_bundlereq(coin,addr,'T',0); - req->hashes = txids, req->n = n; - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); - } - - void iguana_gotunconfirmedM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgtx *tx,uint8_t *data,int32_t datalen) - { - struct iguana_bundlereq *req; - char str[65]; bits256_str(str,tx->txid); - printf("%s unconfirmed.%s\n",addr->ipaddr,str); - req = iguana_bundlereq(coin,addr,'U',datalen); - req->datalen = datalen; - memcpy(req->serialized,data,datalen); - //iguana_freetx(tx,1); - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); - } - - void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n) - { - struct iguana_bundlereq *req; - if ( addr != 0 ) - { - addr->recvhdrs++; - if ( addr->pendhdrs > 0 ) - addr->pendhdrs--; - //printf("%s blocks[%d] ht.%d gotheaders pend.%d %.0f\n",addr->ipaddr,n,blocks[0].height,addr->pendhdrs,milliseconds()); - } - req = iguana_bundlereq(coin,addr,'H',0); - req->blocks = blocks, req->n = n; - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); - } - - void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *blockhashes,int32_t n) - { - struct iguana_bundlereq *req; - if ( addr != 0 ) - { - addr->recvhdrs++; - if ( addr->pendhdrs > 0 ) - addr->pendhdrs--; - } - req = iguana_bundlereq(coin,addr,'S',0); - req->hashes = blockhashes, req->n = n; - //printf("bundlesQ blockhashes.%p[%d]\n",blockhashes,n); - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); - } - - // main context, ie single threaded - - struct iguana_block *iguana_recvblockhdr(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,struct iguana_block *origblock,int32_t *newhwmp) - { - struct iguana_bundle *prevbp,*bp = 0; int32_t j,prevbundlei; struct iguana_block *block; char str[65]; - (*bpp) = 0; - *bundleip = -2; - if ( (block= iguana_blockhashset(coin,-1,origblock->hash2,1)) == 0 ) - { - printf("error getting block for %s\n",bits256_str(str,origblock->hash2)); - return(0); - } - block->prev_block = origblock->prev_block; - if ( (bp= iguana_bundlefind(coin,bundleip,block->hash2,IGUANA_SEARCHBUNDLE)) == 0 ) - { - if ( (prevbp= iguana_bundlefind(coin,&prevbundlei,block->prev_block,IGUANA_SEARCHBUNDLE)) == 0 ) - { - printf("cant find prev.%s either\n",bits256_str(str,block->prev_block)); - for (j=0; jbundlescount; j++) - { - if ( (bp= coin->bundles[j]) != 0 ) - { - if ( (bp= iguana_bundlescan(coin,bundleip,bp,block->hash2,IGUANA_SEARCHBUNDLE)) != 0 ) - { - (*bpp) = bp; - char str[65]; - bits256_str(str,block->hash2); - printf("FOUND.%s in bundle.[%d:%d] %d\n",str,bp->ramchain.hdrsi,*bundleip,bp->ramchain.bundleheight + *bundleip); - iguana_bundleblockadd(coin,bp,*bundleip,block->hash2); - return(block); - } - } - } - char str[65]; - bits256_str(str,block->hash2); - printf("CANTFIND.%s\n",str); - return(block); - } - else - { - (*bpp) = prevbp; - char str[65]; - //printf("found bp.%p prevbundlei.%d\n",prevbp,prevbundlei); - if ( prevbundlei >= 0 && prevbundlei < coin->chain->bundlesize-1 ) - { - *bundleip = prevbundlei + 1; - if ( prevbundlei == 0 ) - iguana_blockQ(coin,bp,0,block->prev_block,1); - if ( prevbp != 0 ) - { - //bits256_str(str,block->hash2); - //printf("prev FOUND.%s in bundle.[%d:%d] %d\n",str,prevbp->ramchain.hdrsi,*bundleip,prevbp->ramchain.bundleheight + *bundleip); - iguana_bundleblockadd(coin,prevbp,*bundleip,block->hash2); - } - } - if ( 0 && prevbundlei == coin->chain->bundlesize-1 ) - { - bits256 zero; - memset(zero.bytes,0,sizeof(zero)); - bits256_str(str,block->hash2); - printf("prev AUTOCREATE.%s\n",str); - iguana_bundlecreate(coin,block->hash2,zero); - } - return(block); - } - } - else - { - //char str[65],str2[65]; - (*bpp) = bp; - //printf("blockadd.%s %s %d\n",bits256_str(str,block->hash2),bits256_str(str2,origblock->hash2),*bundleip); - iguana_bundleblockadd(coin,bp,*bundleip,block->hash2); - if ( *bundleip > 0 && bits256_nonz(block->prev_block) > 0 ) - iguana_bundleblockadd(coin,bp,(*bundleip) - 1,block->prev_block); - } - return(block); - } - - struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *blockhashes,int32_t num) - { - struct iguana_bundle *bp,*newbp; bits256 zero; int32_t i,j,newbundlei,missing,bundlei = -2,bundleheight = -1; - memset(zero.bytes,0,sizeof(zero)); - if ( (bp= iguana_bundlefind(coin,&bundlei,blockhashes[1],IGUANA_SEARCHBUNDLE)) != 0 ) - { - if ( bp->blockhashes == 0 ) - { - //iguana_blockQ(coin,bp,0,bp->bundlehash2,1); - bundleheight = bp->ramchain.bundleheight; - if ( num > coin->chain->bundlesize+1 ) - num = coin->chain->bundlesize+1; - //printf("GOT blockhashes.%s[%d] %d %p hdrsi.%d bundlei.%d\n",bits256_str(str,blockhashes[1]),num,bundleheight,bp->blockhashes,bp->ramchain.hdrsi,bundlei); - memcpy(bp->blockhashes,blockhashes,num * sizeof(*blockhashes)); - bp->n = num; - bp->ramchain.bundleheight = bundleheight; - if ( bundlei >= 0 && bundlei < bp->n ) - { - j = 1; - if ( bundlei != 1 ) - { - /*if ( bundlei == 0 ) - { - for (i=1; i>>>>>>>> hdrsi.%d bundlei.%d j.%d\n",bp->ramchain.hdrsi,bundlei,j); - return(req); - } - for (; jn && bundlei<=coin->chain->bundlesize; bundlei++,j++) - { - //printf("%d: bundlei.%d %s j.%d\n",bundlei % coin->chain->bundlesize,bundlei,bits256_str(str,blockhashes[j]),j); - if ( bundlei == coin->chain->bundlesize ) - { - if ( (newbp= iguana_bundlefind(coin,&newbundlei,blockhashes[j],IGUANA_SEARCHBUNDLE)) == 0 ) - { - //iguana_blockQ(coin,newbp,0,blockhashes[j],1); - if ( j < bp->n-1 ) - { - newbp = iguana_bundlecreate(coin,blockhashes[j],blockhashes[j+1]); - //iguana_blockQ(coin,newbp,1,blockhashes[j+1],1); - } - else newbp = iguana_bundlecreate(coin,blockhashes[j],zero); - if ( newbp != 0 ) - { - char str[65]; - if ( bp->ramchain.bundleheight >= 0 ) - newbp->ramchain.bundleheight = (bp->ramchain.bundleheight + coin->chain->bundlesize); - init_hexbytes_noT(str,blockhashes[j].bytes,sizeof(bits256)); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); - } - } - } - else if ( 1 && iguana_bundleblockadd(coin,bp,bundlei,blockhashes[j]) == 0 ) - break; - } - } - //iguana_blockQ(coin,bp,1,blockhashes[1],1); - //if ( bp->n < coin->chain->bundlesize ) - // iguana_blockQ(coin,bp,bp->n-1,blockhashes[bp->n-1],1); - //else iguana_blockQ(coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],1); - } - else - { - if ( num > 2 ) - { - for (i=missing=0; in && ichain->bundlesize; i++) - { - if ( iguana_bundlescan(coin,&bundlei,bp,blockhashes[i],IGUANA_SEARCHBUNDLE) == 0 ) - { - missing++; - } - } - if ( missing != 0 ) - { - //printf("GOT MISMATCHED %d blockhashes.%s[%d] missing.%d of %d\n",bp->ramchain.bundleheight,bits256_str(blockhashes[1]),num,missing,bp->n); - return(req); - } - if ( num > bp->n && bp->n <= coin->chain->bundlesize ) - { - /*myfree(bp->blockhashes,sizeof(*bp->blockhashes) * bp->n); - bp->blockhashes = mycalloc('h',num,sizeof(*blockhashes)); - printf("replace blockhashes.%s[%d] %d %p\n",bits256_str(blockhashes[0]),num,bp->ramchain.bundleheight,bp->blockhashes); - memcpy(bp->blockhashes,blockhashes,num * sizeof(*blockhashes)); - i = bp->n, bp->n = num; - for (; iramchain.bundleheight >= 0 && (rand() % 1000) == 0 ) - printf("GOT duplicate.%s[%d] bheight.%d\n",str,num,bp->ramchain.bundleheight); - } - } - if ( (num= bp->n) > coin->chain->bundlesize ) - num = coin->chain->bundlesize; - } - else - { - if ( num > coin->chain->bundlesize+1 ) - num = coin->chain->bundlesize+1; - //for (i=1; i 2 ) - { - char str[65]; - bits256_str(str,blockhashes[1]); - //printf("recvblockhashes cant find %s num.%d\n",str,num); - //iguana_blockQ(coin,0,-1,blockhashes[1],1); - //iguana_bundlecreate(coin,blockhashes[1],blockhashes[2]); - if ( 0 && num == coin->chain->bundlesize+1 && iguana_bundlefind(coin,&bundlei,blockhashes[num - 1],IGUANA_SEARCHBUNDLE) == 0 ) - { - bits256 zero; - memset(zero.bytes,0,sizeof(zero)); - bits256_str(str,blockhashes[num - 1]); - printf("AUTO EXTEND2.%s[%d]\n",str,num); - iguana_bundlecreate(coin,blockhashes[num - 1],zero); - } - } - } - return(req); - } - - struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct iguana_bundlereq *req,struct iguana_block *blocks,int32_t n,int32_t *newhwmp) - { - int32_t i,j; struct iguana_block *block; struct iguana_bundle *bp; - if ( blocks == 0 ) - return(req); - if ( n > coin->chain->bundlesize+1 ) - n = coin->chain->bundlesize+1; - // blockhashes = mycalloc('h',n+1,sizeof(*blockhashes)); - // iguana_hash2set(coin,"recvhdrs0",&bp->blockhashes[0],blocks->prev_block); - //for (i=0; iblockhashes[i+1],blocks[i].hash2); - n++; - for (j=0; jbundlescount; j++) - { - if ( (bp= coin->bundles[j]) != 0 ) - { - if ( memcmp(blocks[0].prev_block.bytes,bp->blockhashes[0].bytes,sizeof(bits256)) == 0 ) - { - // iguana_hash2set(coin,"recvhdrs0",&bp->blockhashes[0],blocks->prev_block); - //for (i=0; iblockhashes[i+1],blocks[i].hash2); - if ( bp->blockhashes == 0 ) - { - bp->n = n < coin->chain->bundlesize ? n : coin->chain->bundlesize; - for (i=1; in; i++) - { - iguana_hash2set(coin,"blockhdrs[i]",&bp->blockhashes[i],blocks[i].hash2); - if ( (block= iguana_blockfind(coin,bp->blockhashes[i])) != 0 ) - iguana_copyblock(coin,block,&blocks[i-1]); - } - /*iguana_blockQ(coin,bp,0,bp->bundlehash2,1); - iguana_blockQ(coin,bp,1,blockhashes[1],1); - if ( bp->n < coin->chain->bundlesize ) - iguana_blockQ(coin,bp,n-1,blockhashes[n-1],1); - else iguana_blockQ(coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],1);*/ - break; - } - else - { - //printf("free duplicate blockhashes\n"); - // myfree(blockhashes,n*sizeof(*blockhashes)); - } - } - } - } - return(req); - } - - struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundlereq *req,struct iguana_block *origblock,int32_t numtx,int32_t datalen,int32_t *newhwmp) - { - struct iguana_bundle *bp; int32_t bundlei; struct iguana_block *block; double duration = 0.; - if ( (block= iguana_recvblockhdr(coin,&bp,&bundlei,origblock,newhwmp)) != 0 ) - { - iguana_copyblock(coin,block,origblock); - //printf("recvblock.(%s) bp.%p bundlei.%d\n",bits256_str(str,block->hash2),bp,bundlei); - if ( bp != 0 && datalen > 0 ) - { - //printf("iguana_recvblock (%s) %d[%d] bit.%d recv.%d %02x %02x\n",bits256_str(str,block->hash2),bp->ramchain.hdrsi,bundlei,GETBIT(bp->recv,bundlei),bp->numrecv,bp->recv[0],bp->recv[bp->n/8]); - SETBIT(bp->recv,bundlei); - if ( bp->issued[bundlei] > 0 ) - { - duration = (int32_t)(milliseconds() - bp->issued[bundlei]); - if ( duration < bp->avetime/10. ) - duration = bp->avetime/10.; - else if ( duration > bp->avetime*10. ) - duration = bp->avetime * 10.; - dxblend(&bp->avetime,duration,.9); - dxblend(&coin->avetime,bp->avetime,.9); - } - /*if ( bundlei < 3 ) - { - if ( bundlei > 0 ) - iguana_blockQ(coin,bp,bundlei-1,block->prev_block,1); - iguana_blockQ(coin,bp,bundlei,block->hash2,1); - } - if ( bundlei == 2 ) - { - bp->firstblockhash2 = bp->blockhashes[1] = block->prev_block; - iguana_blockQ(coin,bp,bundlei,block->prev_block,1); - }*/ - if ( bundlei >= 0 && bundlei < bp->n && bundlei < coin->chain->bundlesize ) - { - if ( 0 && bundlei == 1 ) - printf("iguana_recvblock %d[%d] bit.%d recv.%d %02x %02x\n",bp->ramchain.hdrsi,bundlei,GETBIT(bp->recv,bundlei),bp->numrecv,bp->recv[0],bp->recv[bp->n/8]); - if ( req->addr != 0 && req->addr->ipbits != 0 )//&& req->addr->addrind != 0 ) - block->ipbits = req->addr->ipbits; - else block->ipbits = 0xffff, printf("null addr\n"); - block->recvlen = datalen; - bp->blocks[bundlei] = block; - bp->numrecv++; - //iguana_txdataQ(coin,req,bp,bundlei); - } - - //printf("%s hdrsi.%d recv[%d] dur.%.0f avetimes.(%.2f %.2f) numpendinds.%d %f\n",bits256_str(block->hash2),hdrs->hdrsi,bundlei,duration,hdrs->avetime,coin->avetime,coin->numpendings,hdrs->issued[bundlei]); - } - } - else //if ( (rand() % 100) == 0 ) - printf("cant create block.%llx\n",(long long)origblock->hash2.txid); - return(req); - } - - struct iguana_bundlereq *iguana_recvtxids(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *txids,int32_t n) - { - return(req); - } - - struct iguana_bundlereq *iguana_recvunconfirmed(struct iguana_info *coin,struct iguana_bundlereq *req,uint8_t *data,int32_t datalen) - { - return(req); - } - - int32_t iguana_processbundlesQ(struct iguana_info *coin,int32_t *newhwmp) // single threaded - { - int32_t flag = 0; struct iguana_bundlereq *req; - *newhwmp = 0; - while ( flag < 10000 && (req= queue_dequeue(&coin->bundlesQ,0)) != 0 ) - { - //printf("%s bundlesQ.%p type.%c n.%d\n",req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n); - if ( req->type == 'B' ) // one block with all txdata - req = iguana_recvblock(coin,req->addr,req,&req->block,req->numtx,req->datalen,newhwmp); - else if ( req->type == 'H' ) // blockhdrs (doesnt have txn_count!) - { - if ( (req= iguana_recvblockhdrs(coin,req,req->blocks,req->n,newhwmp)) != 0 ) - { - if ( req->blocks != 0 ) - myfree(req->blocks,sizeof(*req->blocks) * req->n), req->blocks = 0; - } - } - else if ( req->type == 'S' ) // blockhashes - { - if ( (req= iguana_recvblockhashes(coin,req,req->hashes,req->n)) != 0 && req->hashes != 0 ) - myfree(req->hashes,sizeof(*req->hashes) * req->n), req->hashes = 0; - } - else if ( req->type == 'U' ) // unconfirmed tx - req = iguana_recvunconfirmed(coin,req,req->serialized,req->datalen); - else if ( req->type == 'T' ) // txids from inv - { - if ( (req= iguana_recvtxids(coin,req,req->hashes,req->n)) != 0 ) - myfree(req->hashes,(req->n+1) * sizeof(*req->hashes)), req->hashes = 0; - } - else printf("iguana_updatebundles unknown type.%c\n",req->type); - flag++; - if ( req != 0 ) - myfree(req,req->allocsize), req = 0; - } - return(flag); - } - - - int32_t iguana_issueloop(struct iguana_info *coin) - { - static uint32_t lastdisp; - int32_t i,closestbundle,bundlei,qsize,RTqsize,m,numactive,numwaiting,maxwaiting,lastbundle,n,dispflag = 0,flag = 0; - int64_t remaining,closest; struct iguana_bundle *bp,*prevbp,*nextbp; bits256 hash2; struct iguana_block *block; - if ( time(NULL) > lastdisp+13 ) - { - dispflag = 1; - lastdisp = (uint32_t)time(NULL); - } - qsize = queue_size(&coin->blocksQ); - if ( qsize == 0 ) - coin->bcount++; - else coin->bcount = 0; - maxwaiting = (coin->MAXBUNDLES * coin->chain->bundlesize); - numwaiting = 0; - numactive = 0; - prevbp = nextbp = 0; - lastbundle = -1; - for (i=coin->bundlescount-1; i>=0; i--) - if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 && bp->blockhashes != 0 ) - { - lastbundle = i; - break; - } - if ( lastbundle != coin->lastbundle ) - coin->lastbundletime = (uint32_t)time(NULL); - coin->lastbundle = lastbundle; - if ( 0 && time(NULL) < coin->starttime+60 ) - lastbundle = -1; - n = 0; - closest = closestbundle = -1; - for (i=0; ibundlescount; i++) - { - qsize = queue_size(&coin->blocksQ); - m = 0; - if ( (bp= coin->bundles[i]) != 0 ) - { - nextbp = (i < coin->bundlescount-1) ? coin->bundles[i+1] : 0; - if ( bp->emitfinish == 0 ) - { - //iguana_bundlecheck(coin,bp,numactive == 0 || i == coin->closestbundle || i == lastbundle); - iguana_bundlecheck(coin,bp,i == coin->closestbundle); - if ( bp->numrecv > 3 || numactive == 0 ) - { - numactive++; - remaining = (bp->estsize - bp->datasize) + (rand() % (1 + bp->estsize))/100; - if ( remaining > 0 && (closest < 0 || remaining < closest) ) - { - //printf("closest.[%d] %d -> R.%d (%d - %d)\n",closestbundle,(int)closest,(int)remaining,(int)bp->estsize,(int)bp->datasize); - closest = remaining; - closestbundle = i; - } - } - //if ( i < (coin->numemitted+coin->MAXPENDING) && numactive >= coin->MAXPENDING && i != coin->closestbundle && i != lastbundle ) - continue; - RTqsize = queue_size(&coin->blocksQ); - for (bundlei=0; bundlein && bundleichain->bundlesize; bundlei++) - { - if ( (block= bp->blocks[bundlei]) != 0 && block->ipbits != 0 ) - { - m++; - //printf("hashes.%p numrecv.%d hdrs->n.%d qsize.%d\n",bp->blockhashes,bp->numrecv,bp->n,qsize); - continue; - } - hash2 = iguana_bundleihash2(coin,bp,bundlei); - if ( bits256_nonz(hash2) > 0 ) - { - //printf("hdrsi.%d qsize.%d bcount.%d check bundlei.%d bit.%d %.3f lag %.3f ave %.3f\n",bp->ramchain.hdrsi,qsize,coin->bcount,bundlei,GETBIT(bp->recv,bundlei),bp->issued[bundlei],milliseconds() - bp->issued[bundlei],bp->avetime); - if ( (block= bp->blocks[bundlei]) == 0 || block->ipbits == 0 ) - //if ( GETBIT(bp->recv,bundlei) == 0 ) - { - if ( bp->issued[bundlei] > SMALLVAL ) - numwaiting++; - if ( numwaiting < maxwaiting && (bp->issued[bundlei] == 0 || (qsize == 0 && coin->bcount > 100 && milliseconds() > (bp->issued[bundlei] + bp->avetime*2))) )//()) ) - { - if ( RTqsize < maxwaiting && (i == lastbundle || i == coin->closestbundle) ) - { - char str[65]; - bits256_str(str,hash2); - if ( (rand() % 10000) == 0 && bp->issued[bundlei] > SMALLVAL ) - printf("issue.%d:%d of %d %s lag %f ave %f\n",bp->ramchain.hdrsi,bundlei,bp->n,str,milliseconds() - bp->issued[bundlei],bp->avetime); - bp->issued[bundlei] = milliseconds(); - n++; - flag += (iguana_blockQ(coin,bp,bundlei,hash2,0) > 0); - } - } - } - } //lse printf("skip.%d %s\n",numbundles,bits256_str(hash2)); - } - } else m = coin->chain->bundlesize; - } - prevbp = bp; - if ( dispflag != 0 && bp != 0 && bp->emitfinish == 0 && m > 0 ) - printf("%s",iguana_bundledisp(coin,prevbp,bp,nextbp,m)); - } - //if ( closestbundle >= 0 && (coin->closestbundle < 0 || coin->bundles[coin->closestbundle]->numrecv >= coin->chain->bundlesize) ) - coin->closestbundle = closestbundle; - char str[65]; - if ( dispflag != 0 ) - printf(" PENDINGBUNDLES lastbundle.%d closest.[%d] %s | %d\n",lastbundle,closestbundle,mbstr(str,closest),coin->closestbundle); - return(flag); - } - - int32_t iguana_reqhdrs(struct iguana_info *coin) - { - int32_t i,n = 0; struct iguana_bundle *bp; char hashstr[65]; - //printf("needhdrs.%d qsize.%d zcount.%d\n",iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); - if ( iguana_needhdrs(coin) > 0 && queue_size(&coin->hdrsQ) == 0 ) - { - if ( coin->zcount++ > 10 ) - { - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - if ( time(NULL) > bp->issuetime+7 )//&& coin->numpendings < coin->MAXBUNDLES ) - { - if ( bp->issuetime == 0 ) - coin->numpendings++; - if ( bp->blockhashes == 0 || bp->n < coin->chain->bundlesize ) - { - char str[65]; - bits256_str(str,bp->blockhashes[0]); - printf("(%s %d).%d ",str,bp->ramchain.bundleheight,i); - init_hexbytes_noT(hashstr,bp->blockhashes[0].bytes,sizeof(bits256)); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - n++; - } - bp->issuetime = (uint32_t)time(NULL); - } - } - } - if ( n > 0 ) - printf("REQ HDRS pending.%d\n",coin->numpendings); - coin->zcount = 0; - } - } else coin->zcount = 0; - return(n); - } - - int32_t iguana_updatecounts(struct iguana_info *coin) - { - int32_t h,flag = 0; - //SETBIT(coin->havehash,0); - //while ( iguana_havetxdata(coin,coin->blocks.recvblocks) != 0 ) - // coin->blocks.recvblocks++; - //if ( coin->blocks.recvblocks < 1 ) - // coin->blocks.recvblocks = 1; - //while ( GETBIT(coin->havehash,coin->blocks.hashblocks) > 0 ) - // coin->blocks.hashblocks++; - h = coin->blocks.hwmheight - coin->chain->bundlesize; - flag = 0; - while ( 0 && iguana_bundleready(coin,h) > 0 ) - { - h += coin->chain->bundlesize; - flag++; - } - if ( flag != 0 ) - iguana_savehdrs(coin); - return(flag); - } - - int32_t iguana_processrecv(struct iguana_info *coin) // single threaded - { - int32_t newhwm = 0,flag = 0; - //printf("process bundlesQ\n"); - flag += iguana_processbundlesQ(coin,&newhwm); - //printf("iguana_updatecounts\n"); - flag += iguana_updatecounts(coin); - //printf("iguana_reqhdrs\n"); - flag += iguana_reqhdrs(coin); - //printf("iguana_issueloop\n"); - flag += iguana_issueloop(coin); - //if ( newhwm != 0 ) - // flag += iguana_lookahead(coin,&hash2,coin->blocks.hwmheight); - return(flag); - } - - - struct iguana_block *iguana_recvblockhdr(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,struct iguana_block *origblock,int32_t *newhwmp) - { - struct iguana_bundle *prevbp,*bp = 0; int32_t j,prevbundlei; struct iguana_block *block; char str[65]; - (*bpp) = 0; - *bundleip = -2; - if ( (block= iguana_blockhashset(coin,-1,origblock->hash2,1)) == 0 ) - { - printf("error getting block for %s\n",bits256_str(str,origblock->hash2)); - return(0); - } - block->prev_block = origblock->prev_block; - if ( (bp= iguana_bundlefind(coin,bundleip,block->hash2,IGUANA_SEARCHBUNDLE)) == 0 ) - { - if ( (prevbp= iguana_bundlefind(coin,&prevbundlei,block->prev_block,IGUANA_SEARCHBUNDLE)) == 0 ) - { - printf("cant find prev.%s either\n",bits256_str(str,block->prev_block)); - for (j=0; jbundlescount; j++) - { - if ( (bp= coin->bundles[j]) != 0 ) - { - if ( (bp= iguana_bundlescan(coin,bundleip,bp,block->hash2,IGUANA_SEARCHBUNDLE)) != 0 ) - { - (*bpp) = bp; - char str[65]; - bits256_str(str,block->hash2); - printf("FOUND.%s in bundle.[%d:%d] %d\n",str,bp->ramchain.hdrsi,*bundleip,bp->ramchain.bundleheight + *bundleip); - iguana_bundleblockadd(coin,bp,*bundleip,block->hash2); - return(block); - } - } - } - char str[65]; - bits256_str(str,block->hash2); - printf("CANTFIND.%s\n",str); - return(block); - } - else - { - (*bpp) = prevbp; - char str[65]; - //printf("found bp.%p prevbundlei.%d\n",prevbp,prevbundlei); - if ( prevbundlei >= 0 && prevbundlei < coin->chain->bundlesize-1 ) - { - *bundleip = prevbundlei + 1; - if ( prevbundlei == 0 ) - iguana_blockQ(coin,bp,0,block->prev_block,1); - if ( prevbp != 0 ) - { - //bits256_str(str,block->hash2); - //printf("prev FOUND.%s in bundle.[%d:%d] %d\n",str,prevbp->ramchain.hdrsi,*bundleip,prevbp->ramchain.bundleheight + *bundleip); - iguana_bundleblockadd(coin,prevbp,*bundleip,block->hash2); - } - } - if ( 0 && prevbundlei == coin->chain->bundlesize-1 ) - { - bits256 zero; - memset(zero.bytes,0,sizeof(zero)); - bits256_str(str,block->hash2); - printf("prev AUTOCREATE.%s\n",str); - iguana_bundlecreate(coin,block->hash2,zero); - } - return(block); - } - } - else - { - //char str[65],str2[65]; - (*bpp) = bp; - //printf("blockadd.%s %s %d\n",bits256_str(str,block->hash2),bits256_str(str2,origblock->hash2),*bundleip); - iguana_bundleblockadd(coin,bp,*bundleip,block->hash2); - if ( *bundleip > 0 && bits256_nonz(block->prev_block) > 0 ) - iguana_bundleblockadd(coin,bp,(*bundleip) - 1,block->prev_block); - } - return(block); - } - - /*static int32_t _sort_by_itemind(struct iguana_block *a, struct iguana_block *b) - { - if (a->hh.itemind == b->hh.itemind) return 0; - return (a->hh.itemind < b->hh.itemind) ? -1 : 1; - }*/ - - int32_t _iguana_verifysort(struct iguana_info *coin) - { - int32_t height,prevheight = -1,i = 0,run = 0; struct iguana_block *block,*tmp; - HASH_ITER(hh,coin->blocks.hash,block,tmp) - { - if ( (height= block->hh.itemind) < 0 ) - printf("sortblocks error i.%d height.%d?\n",i,height), getchar(); - if ( height <= prevheight ) - printf("sortblocks error i.%d height.%d vs prevheight.%d\n",i,height,prevheight), getchar(); - if ( height == run ) - run++; - i++; - } - printf("_iguana_verifysort: n.%d run.%d\n",i,run); - return(run); - } - - /*int32_t iguana_blocksort(struct iguana_info *coin) - { - int32_t hashblocks; - portable_mutex_lock(&coin->blocks_mutex); - HASH_SORT(coin->blocks.hash,_sort_by_itemind); - hashblocks = _iguana_verifysort(coin); - portable_mutex_unlock(&coin->blocks_mutex); - return(hashblocks); - }*/ - - int32_t _iguana_blocklink(struct iguana_info *coin,struct iguana_block *block) - { - int32_t height,n = 0; struct iguana_block *prev,*next; - if ( block == 0 ) - printf("iguana_blockslink: illegal null block %p\n",block), getchar(); - block->hh.next = 0, block->hh.prev = 0; - if ( (height= (int32_t)block->hh.itemind) > 0 && (prev= iguana_block(coin,height-1)) != 0 ) - { - prev->hh.next = block; - block->hh.prev = prev; - n++; - } - if ( (next= iguana_block(coin,height+1)) != 0 ) - { - block->hh.next = next; - next->hh.prev = block; - n++; - } - return(n); - } - - /*bits256 iguana_prevblockhash(struct iguana_info *coin,bits256 hash2) - { - struct iguana_block *block; bits256 tmp; - if ( bits256_nonz(hash2) > 0 && (block= iguana_blockfind(coin,hash2)) != 0 ) - return(block->prev_block); - else - { - memset(tmp.bytes,0,sizeof(tmp)); - return(tmp); - } - }*/ - - int32_t iguana_hash2height(struct iguana_info *coin,bits256 hash2) - { - struct iguana_block *block; - if ( (block= iguana_blockfind(coin,hash2)) != 0 ) - { - if ( block->height >= 0 ) - return(block->height); - else return(block->hh.itemind); - } - else return(-1); - } - - int32_t iguana_blockheight(struct iguana_info *coin,struct iguana_block *block) - { - struct iguana_block *prev; int32_t height; - if ( (height= iguana_hash2height(coin,block->hash2)) < 0 ) - { - if ( (prev= iguana_blockfind(coin,block->prev_block)) != 0 ) - { - if ( prev->height >= 0 ) - return(prev->height+1); - else if ( (int32_t)prev->hh.itemind >= 0 ) - return(prev->hh.itemind + 1); - } - } - return(-1); - } - - int32_t iguana_chainheight(struct iguana_info *coin,struct iguana_block *block) - { - if ( block->mainchain != 0 && block->height >= 0 ) - return(block->height); - return(-1); - } - - void *iguana_blockptr(struct iguana_info *coin,int32_t height) - { - struct iguana_block *block; - if ( height < 0 || height >= coin->blocks.maxbits ) - { - //printf("iguana_blockptr height.%d vs maxbits.%d\n",height,coin->blocks.maxbits); - return(0); - } - if ( (block= coin->blocks.ptrs[height]) != 0 ) - return(block); - return(0); - } - - /*void *iguana_bundletxdata(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei) - { - struct iguana_block *block; void *txdata = 0; - if ( bp != 0 && bundlei >= 0 && bundlei < coin->chain->bundlesize && GETBIT(bp->recv,bundlei) != 0 && (block= bp->blocks[bundlei]) != 0 ) - { - txdata = block->txdata; - } - //printf("txdata.%p\n",txdata); - return(txdata); - }*/ - - int32_t iguana_avail(struct iguana_info *coin,int32_t height,int32_t n) - { - int32_t i,nonz = 0; - for (i=0; ichain->bundlesize; - if ( GETBIT(coin->bundleready,height/num) != 0 ) - return(1); - for (i=0; ibundleready,height/num); - return(1); - } - - int32_t iguana_fixblocks(struct iguana_info *coin,int32_t startheight,int32_t endheight) - { - struct iguana_block *block,space,origblock; int32_t height,n = 0; - for (height=startheight; height<=endheight; height++) - { - if ( (block= iguana_block(coin,&space,height)) != 0 ) - { - origblock = space; - iguana_setdependencies(coin,block); - if ( memcmp(&origblock,block,sizeof(origblock)) != 0 ) - { - printf("%d ",height); - n++; - iguana_kvwrite(coin,coin->blocks.db,0,block,(uint32_t *)&block->height); - } - } - } - iguana_syncmap(&coin->blocks.db->M,0); - return(n); - } - - int32_t iguana_blockcmp(struct iguana_info *coin,struct iguana_block *A,struct iguana_block *B,int32_t fastflag) - { - struct iguana_block tmpA,tmpB; - tmpA = *A, tmpB = *B; - memset(&tmpA.L,0,sizeof(tmpA.L)), memset(&tmpB.L,0,sizeof(tmpB.L)); - memset(&tmpA.hh,0,sizeof(tmpA.hh)), memset(&tmpB.hh,0,sizeof(tmpB.hh)); - tmpA.numvouts = tmpA.numvins = tmpA.tbd = tmpB.numvouts = tmpB.numvins = tmpB.tbd = 0; - if ( memcmp(&tmpA,&tmpB,sizeof(tmpA)) != 0 ) - return(-1); - if ( fastflag == 0 ) - { - if ( iguana_setdependencies(coin,&tmpA) != iguana_setdependencies(coin,&tmpB) || memcmp(&tmpA,&tmpB,sizeof(tmpA)) == 0 ) - return(-1); - } - return(0); - }*/ - - /* - int32_t iguana_checkblock(struct iguana_info *coin,int32_t dispflag,struct iguana_block *block,bits256 hash2) - { - struct iguana_block checkspace,prevspace,*checkblock,*prev; bits256 prevhash; int32_t retval = 0; - if ( block != 0 ) - { - if ( (checkblock= iguana_block(coin,&checkspace,block->height)) == 0 ) - { - if ( dispflag != 0 ) - printf("cant find checkblock %s at %d\n",bits256_str(hash2),block->height); - return(-2); - } - if ( memcmp(block,checkblock,sizeof(*block)) != 0 ) - { - if ( dispflag != 0 ) - printf("compare error %s block.%d vs checkblock.%d\n",bits256_str(hash2),block->height,checkblock->height); - return(-3); - } - prevhash = iguana_prevblockhash(coin,hash2); - if ( bits256_nonz(prevhash) != 0 ) - { - if ( memcmp(prevhash.bytes,block->prev_block.bytes,sizeof(prevhash)) != 0 ) - { - if ( dispflag != 0 ) - { - printf("height.%d block->prev %s vs ",block->height,bits256_str(block->prev_block)); - printf("prevhash mismatch %s\n",bits256_str(prevhash)); - } - return(-4); - } - } else prevhash = block->prev_block; - if ( block->height == 0 ) - { - //printf("reached genesis! numvalid.%d from %s\n",numvalid,bits256_str(coin->blocks.best_chain)); - return(0); - } - //printf("block.%d\n",block->height); - if ( (prev= iguana_blockfind(coin,&prevspace,prevhash)) == 0 ) - { - if ( dispflag != 0 ) - printf("cant find prevhash for (%s).%d\n",bits256_str(hash2),block->height); - return(-5); - } //else printf("block->height.%d prev height.%d %s\n",block->height,prev->height,bits256_str(prevhash)); - if ( fabs(block->L.PoW - (prev->L.PoW + PoW_from_compact(block->bits,coin->chain->unitval))) > SMALLVAL ) - { - if ( dispflag != 0 ) - printf("PoW mismatch: %s %.15f != %.15f (%.15f %.15f)\n",bits256_str(hash2),block->L.PoW,(prev->L.PoW + PoW_from_compact(block->bits,coin->chain->unitval)),prev->L.PoW,PoW_from_compact(block->bits,coin->chain->unitval)); - block->L.PoW = (prev->L.PoW + PoW_from_compact(block->bits,coin->chain->unitval)); - retval = -1000; - } - if ( block->txn_count != 0 && block->L.numtxids != (prev->L.numtxids + prev->txn_count) && block->L.numunspents != (prev->L.numunspents + prev->numvouts) && block->L.numspends != (prev->L.numspends + prev->numvins) ) - { - if ( dispflag != 0 ) - printf("firsttxidind mismatch %s T%d != %d (%d + %d) || U%d != %d (%d + %d) || S%d != %d (%d + %d)\n",bits256_str(hash2),block->L.numtxids,(prev->L.numtxids + prev->txn_count),prev->L.numtxids,prev->txn_count,block->L.numunspents,(prev->L.numunspents + prev->numvouts),prev->L.numunspents,prev->numvouts,block->L.numspends,(prev->L.numspends + prev->numvins),prev->L.numspends,prev->numvins); - block->L.numtxids = (prev->L.numtxids + prev->txn_count); - block->L.numunspents = (prev->L.numunspents + prev->numvouts); - block->L.numspends = (prev->L.numspends + prev->numvins); - return(retval - 10000); - } - return(retval); - } - if ( dispflag != 0 ) - printf("iguana_checkblock: null ptr\n"); - return(-8); - } - - int32_t _iguana_audit(struct iguana_info *coin) - { - bits256 hash2; struct iguana_block *block,space; int32_t numvalid = 0; - hash2 = coin->blocks.hwmchain; - while ( (block= iguana_blockfind(coin,&space,hash2)) != 0 ) - { - if ( iguana_checkblock(coin,1,block,hash2) == 0 ) - { - numvalid++; - if ( block->height == 0 ) - return(numvalid); - hash2 = block->prev_block; - } - } - printf("iguana_audit numvalid.%d vs %d\n",numvalid,coin->blocks.hwmheight); - return(numvalid); - } - - void iguana_audit(struct iguana_info *coin) - { - int32_t numvalid; - if ( (numvalid= _iguana_audit(coin)) < 0 || numvalid != coin->blocks.hwmheight ) - { - printf("iguana_audit error.%d\n",numvalid); - iguana_kvdisp(coin,coin->blocks.db); - } - }*/ - - - /*int32_t iguana_lookahead(struct iguana_info *coin,bits256 *hash2p,int32_t height) - { - struct iguana_block space,*block; bits256 hash2; int32_t err,h,n = 0; - while ( (block= iguana_block(coin,&space,height)) != 0 ) - { - *hash2p = hash2 = iguana_blockhash(coin,height); - if ( (err= iguana_checkblock(coin,1,block,hash2)) == 0 || err <= -1000 ) - { - if ( err < 0 ) - { - h = height; - printf("fixup height.%d\n",height); - iguana_kvwrite(coin,coin->blocks.db,hash2.bytes,block,(uint32_t *)&h); - //getchar(); - } - if ( (h= iguana_addblock(coin,hash2,block)) != height ) - { - printf("height.%d h.%d n.%d didnt work\n",height,h,n); - //getchar(); - break; - } - n++; - height++; - coin->blocks.hwmheight = height; - } - else - { - printf("height.%d %s error.%d\n",height,bits256_str(hash2),err); - break; - } - } - printf("lookahead stopped at height.%d\n",height); - return(n); - } - */ - - int32_t iguana_setchainvars(struct iguana_info *coin,struct iguana_prevdep *lp,bits256 hash2,uint32_t nBits,bits256 prevhash,int32_t txn_count) // uint32_t *firsttxidindp,uint32_t *firstvoutp,uint32_t *firstvinp,double *PoWp - { - int32_t height=-1,firstvout=0,firstvin=0,firsttxidind=0; double PoW; - struct iguana_prevdep *prevlp; struct iguana_block *prev; - memset(lp,0,sizeof(*lp)); - if ( memcmp(coin->chain->genesis_hashdata,hash2.bytes,sizeof(hash2)) == 0 ) - { - PoW = PoW_from_compact(nBits,coin->chain->unitval); - height = 0; - firsttxidind = firstvout = firstvin = 1; - printf("set genesis vars nBits.%x\n",nBits); - } - else - { - if ( (prev= iguana_blockfind(coin,prevhash)) == 0 ) - { - if ( iguana_needhdrs(coin) == 0 ) - { - char str[65],str2[65]; - bits256_str(str,hash2); - bits256_str(str2,prevhash); - printf("hash2.(%s) ",str); - fprintf(stderr,"iguana_blockchain no prev block.(%s)\n",str2); - //getchar(); - } - return(-1); - } - else - { - height = prev->height + 1; - if ( (prevlp= iguana_prevdepfind(coin,prev)) != 0 ) - { - PoW = (PoW_from_compact(nBits,coin->chain->unitval) + prevlp->PoW); - if ( txn_count > 0 && prevlp->numtxids > 0 && prev->numvouts > 0 && prevlp->numunspents > 0 && prevlp->numspends > 0 ) - { - firsttxidind = prevlp->numtxids + prev->txn_count; - firstvout = prevlp->numunspents + prev->numvouts; - firstvin = prevlp->numspends + prev->numvins; - //printf("PREV.%d firsttxidind.%d firstvout.%d+%d firstvin.%d+%d (%d %d %d)\n",prev->height,prev->L.numtxids,prev->L.numunspents,prev->numvouts,prev->L.numspends,prev->numvins,firsttxidind,firstvout,firstvin); - } - } - } - } - if ( lp != 0 ) - { - lp->PoW = PoW; - lp->numtxids = firsttxidind; - lp->numunspents = firstvout; - lp->numspends = firstvin; - } - //printf("set height.%d: %d %f firstvin.%d firstvout.%d\n",height,firsttxidind,PoW,firstvin,firstvout); - return(height); - } - - int32_t iguana_setdependencies(struct iguana_info *coin,struct iguana_block *block,struct iguana_prevdep *lp) - { - int32_t h,height; - if ( block == 0 ) - return(-1); - height = block->height; - if ( (h= iguana_setchainvars(coin,lp,block->hash2,block->bits,block->prev_block,block->txn_count)) == height ) - { - // place to make sure connected to ramchain - return(height); - } - if ( height < 0 ) - block->height = h; - //printf("dependencies returned %d vs %d\n",h,height); - return(-1); - } - - int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newblock) - { - int32_t h; - if ( (newblock->height= iguana_setdependencies(coin,newblock,lp)) >= 0 ) - { - if ( lp->PoW > coin->blocks.hwmPoW ) - { - if ( newblock->height+1 > coin->blocks.maxblocks ) - coin->blocks.maxblocks = (newblock->height + 1); - h = newblock->height; - iguana_kvwrite(coin,coin->blocks.db,hash2.bytes,newblock,(uint32_t *)&h); - coin->blocks.hwmheight = newblock->height; - coin->blocks.hwmPoW = lp->PoW; - coin->blocks.hwmchain = hash2; - coin->latest.blockhash = hash2; - coin->latest.merkle_root = newblock->merkle_root; - coin->latest.timestamp = newblock->timestamp; - coin->latest.height = coin->blocks.hwmheight; - char str[65],str2[65]; - bits256_str(str,newblock->hash2); - bits256_str(str2,coin->blocks.hwmchain); - printf("ADD %s %d:%d <- (%s) n.%u max.%u PoW %f 1st.%d numtx.%d\n",str,h,newblock->height,str2,coin->blocks.hwmheight+1,coin->blocks.maxblocks,lp->PoW,lp->numtxids,newblock->txn_count); - } - } else printf("error from setchain.%d\n",newblock->height); - if ( memcmp(hash2.bytes,coin->blocks.hwmchain.bytes,sizeof(hash2)) != 0 ) - { - char str[65]; - bits256_str(str,hash2); - if ( iguana_needhdrs(coin) == 0 ) - printf("ORPHAN.%s height.%d PoW %f vs best %f\n",str,newblock->height,lp->PoW,coin->blocks.hwmPoW); - newblock->height = -1; - } - return(newblock->height); - } - - else if ( strcmp(H->command,"headers") == 0 ) - { - struct iguana_msgblock msg; struct iguana_block *blocks; uint32_t n; struct iguana_prevdep L; - len = iguana_rwvarint32(0,data,&n); - if ( n <= IGUANA_MAXINV ) - { - blocks = mycalloc('i',1,sizeof(*blocks) * n); - height = -1; - memset(&L,0,sizeof(L)); - for (i=0; i 0 ) - { - height++; - L.numtxids += blocks[i].txn_count; - L.PoW += PoW_from_compact(blocks[i].bits,coin->chain->unitval); - } - } - //printf("GOT HEADERS n.%d len.%d\n",n,len); - iguana_gotheadersM(coin,addr,blocks,n); - //myfree(blocks,sizeof(*blocks) * n); - if ( len == datalen && addr != 0 ) - addr->msgcounts.headers++; - } else printf("got unexpected n.%d for headers\n",n); - } - - /*int32_t iguana_chainheight(struct iguana_info *coin,struct iguana_block *origblock) - { - static const bits256 zero; struct iguana_block *next,*block = origblock; - bits256 *blockhashes; char str[65]; int32_t i,max,toofar=0,height,n=0; - next = origblock; - iguana_memreset(&coin->blockMEM); - max = (int32_t)(coin->blockMEM.totalsize / sizeof(*blockhashes)); - blockhashes = iguana_memalloc(&coin->blockMEM,max*sizeof(*blockhashes),1); - while ( memcmp(block->prev_block.bytes,zero.bytes,sizeof(bits256)) != 0 ) - { - if ( n < max-1 ) - blockhashes[n++] = block->hash2; - else toofar = 1; - if ( (block= iguana_blockfind(coin,block->prev_block)) != 0 ) - { - //printf("i.%d %s chainheight.%d mainchain.%d\n",n,bits256_str(str,block->hash2),block->height,block->mainchain); - if ( block->mainchain != 0 && (height= block->height) >= 0 ) - { - iguana_chainextend(coin,next); - //printf("%s extend.%d from %d toofar.%d\n",bits256_str(str,block->hash2),n,height,toofar); - if ( toofar == 0 ) - { - for (i=0; iheight); - } - if ( iguana_chainextend(coin,next) < 0 ) - { - //printf("%d of %d: cant extend block.%s\n",i,n,bits256_str(str,blockhashes[n-1-i])); - return(origblock->height); - } - next = block; - } - return(origblock->height); - } - //printf("toofar means neg height\n"); - return(-1); - } - next = block; - } else break; - } // reached deadend or too far to link in - //printf("out of chainheight loop\n"); - return(origblock->height); - }*/ - - - /*int32_t iguana_issueloop(struct iguana_info *coin) - { - static uint32_t lastdisp; - int32_t i,closestbundle,qsize,m,numactive,numwaiting,maxwaiting,lastbundle,n,dispflag = 0,flag = 0; - int64_t remaining,closest; struct iguana_bundle *bp,*prevbp,*nextbp; - flag = iguana_reqhdrs(coin); - if ( time(NULL) > lastdisp+13 ) - { - dispflag = 1; - lastdisp = (uint32_t)time(NULL); - } - qsize = queue_size(&coin->blocksQ); - if ( qsize == 0 ) - coin->bcount++; - else coin->bcount = 0; - maxwaiting = (coin->MAXBUNDLES * coin->chain->bundlesize); - numwaiting = 0; - numactive = 0; - prevbp = nextbp = 0; - lastbundle = -1; - for (i=coin->bundlescount-1; i>=0; i--) - if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 && bp->blockhashes != 0 ) - { - lastbundle = i; - break; - } - if ( lastbundle != coin->lastbundle ) - coin->lastbundletime = (uint32_t)time(NULL); - coin->lastbundle = lastbundle; - if ( 0 && time(NULL) < coin->starttime+60 ) - lastbundle = -1; - n = 0; - closest = closestbundle = -1; - for (i=0; ibundlescount; i++) - { - qsize = queue_size(&coin->blocksQ); - m = 0; - if ( (bp= coin->bundles[i]) != 0 ) - { - nextbp = (i < coin->bundlescount-1) ? coin->bundles[i+1] : 0; - if ( bp->emitfinish == 0 ) - { - m = (bp->n - bp->numrecv); - if ( bp->numrecv > 3 || numactive == 0 ) - { - numactive++; - remaining = (bp->estsize - bp->datasize) + (rand() % (1 + bp->estsize))/100; - if ( remaining > 0 && (closest < 0 || remaining < closest) ) - { - //printf("closest.[%d] %d -> R.%d (%d - %d)\n",closestbundle,(int)closest,(int)remaining,(int)bp->estsize,(int)bp->datasize); - closest = remaining; - closestbundle = i; - } - } - if ( dispflag != 0 ) - printf("%s",iguana_bundledisp(coin,prevbp,bp,nextbp,m)); - } - } - prevbp = bp; - } - //if ( closestbundle >= 0 && (coin->closestbundle < 0 || coin->bundles[coin->closestbundle]->numrecv >= coin->chain->bundlesize) ) - coin->closestbundle = closestbundle; - char str[65]; - if ( dispflag != 0 ) - printf(" PENDINGBUNDLES lastbundle.%d closest.[%d] %s | %d\n",lastbundle,closestbundle,mbstr(str,closest),coin->closestbundle); - return(flag); - }*/ - int32_t iguana_updatecounts(struct iguana_info *coin) - { - int32_t flag = 0; - //SETBIT(coin->havehash,0); - //while ( iguana_havetxdata(coin,coin->blocks.recvblocks) != 0 ) - // coin->blocks.recvblocks++; - //if ( coin->blocks.recvblocks < 1 ) - // coin->blocks.recvblocks = 1; - //while ( GETBIT(coin->havehash,coin->blocks.hashblocks) > 0 ) - // coin->blocks.hashblocks++; - return(flag); - } - - //printf("iguana_issueloop\n"); - //flag += iguana_issueloop(coin); - //if ( newhwm != 0 ) - // flag += iguana_lookahead(coin,&hash2,coin->blocks.hwmheight); - - /*struct iguana_block *iguana_blockadd(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,struct iguana_block *origblock) - { - struct iguana_block *checkblock,*block = 0; char str[65]; struct iguana_bundle *bp = *bpp; - int32_t setval,checki,bundlei,bundleheight,bundlesize = coin->chain->bundlesize; - bundlei = *bundleip; - *bundleip = -2; - *bpp = 0; - if ( origblock == 0 ) - return(0); - //iguana_blockhashset(coin,-1,origblock->prev_block,1); - if ( bits256_nonz(origblock->hash2) > 0 && (block= iguana_blockhashset(coin,-1,origblock->hash2,1)) != 0 ) - { - //printf("blockadd.(%s) -> %d (%s)\n",bits256_str(str,origblock->prev_block),block->height,bits256_str(str2,origblock->hash2)); - if ( bits256_nonz(block->prev_block) == 0 ) - iguana_blockcopy(coin,block,origblock); - if ( (bp= *bpp) == 0 ) - { - if ( (bp= iguana_bundlefind(coin,bpp,&bundlei,block->hash2)) == 0 ) - { - *bpp = 0, bundlei = -2; - //printf("a bundlefind.(%s) -> bundlei.%d\n",bits256_str(str,block->hash2),*bundleip); - if ( (bp= iguana_bundlefind(coin,bpp,&bundlei,block->prev_block)) == 0 ) - { - //iguana_chainheight(coin,block); - //printf("a prev bundlefind.(%s) -> bundlei.%d ht.%d\n",bits256_str(str,block->prev_block),*bundleip,block->height); - *bpp = 0; - *bundleip = -2; - return(block); - } - else - { - if ( *bundleip == bundlesize-1 ) - { - printf("b prev bundlefind.(%s) -> bundlei.%d\n",bits256_str(str,block->prev_block),*bundleip); - bundleheight = (bp->ramchain.bundleheight >= 0) ? (bp->ramchain.bundleheight + bundlesize) : -1; - printf("autocreateA: bundleheight.%d\n",bundleheight); - bundlei = -2; - *bpp = bp = iguana_bundlecreate(coin,&bundlei,bundleheight,block->hash2); - *bpp = 0; - *bundleip = -2; - return(block); - } - else if ( bundlei < coin->chain->bundlesize-1 ) - { - bundlei++; - if ( bp->n <= bundlei ) - bp->n = bundlei+1; - iguana_hash2set(coin,"add",bp,bundlei,block->hash2); - //printf("found prev.%s -> bundlei.%d\n",bits256_str(str,block->prev_block),bundlei); - } - } - } - else - { - // printf("found bp.%p bundlei.%d\n",bp,bundlei); - } - } - else if ( bundlei < -1 ) - { - bp = iguana_bundlefind(coin,bpp,&bundlei,block->hash2); - printf("c bundlefind.(%s) -> bundlei.%d\n",bits256_str(str,block->hash2),bundlei); - } else printf("last case bundleip %d\n",bundlei); - *bpp = bp; - *bundleip = bundlei; - //printf("bundlei.%d for %s\n",bundlei,bits256_str(str,block->hash2)); - if ( memcmp(bp->hashes[bundlei].bytes,block->hash2.bytes,sizeof(bits256)) != 0 ) - printf("honk? find error %s\n",bits256_str(str,bp->hashes[bundlei])), getchar(); - if ( bp == 0 || bundlei < -1 ) - { - printf("%s null bp? %p or illegal bundlei.%d block.%p\n",bits256_str(str,block->hash2),bp,bundlei,block); - return(block); - } - if ( (setval= iguana_bundlehash2add(coin,&checkblock,bp,bundlei,block->hash2)) == 0 && checkblock == block ) - { - if ( bp->blocks[bundlei] != 0 ) - { - if ( bp->blocks[bundlei] != block ) - printf("blockadd: error blocks[%d] %p %d != %d %p\n",bundlei,bp->blocks[bundlei],bp->blocks[bundlei]->height,block->height,block); - } else bp->blocks[bundlei] = block; - //iguana_bundlehash2add(coin,0,bp,bundlei-1,block->prev_block); - //printf("setval.%d bp.%p bundlei.%d\n",setval,bp,bundlei); - } - else if ( setval > 0 ) - { - if ( bundlei == bundlesize ) - { - bundleheight = (bp->ramchain.bundleheight >= 0) ? (bp->ramchain.bundleheight + bundlesize) : -1; - printf("autocreate: bundleheight.%d\n",bundleheight); - iguana_bundlecreate(coin,&checki,bundleheight,block->hash2); - } - printf("setval.%d bundlei.%d\n",setval,bundlei); - } else printf("blockadd: error.%d adding hash2, checkblock.%p vs %p\n",setval,checkblock,block); - //printf("bundleblockadd.[%d] of %d <- %s setval.%d %p\n",bundlei,bp->n,bits256_str(str,block->hash2),setval,block); - } else printf("bundleblockadd: block.%p error\n",block); - return(block); - } - - struct iguana_block *iguana_bundleblockadd(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,struct iguana_block *origblock) - { - struct iguana_block *block,*retblock; int32_t i,oldhwm; struct iguana_bundle *bp; - bits256 *hash2p,hash2; char str[65]; struct iguana_bloominds bit; - oldhwm = coin->blocks.hwmchain.height; - *bpp = 0, *bundleip = -2; - if ( (retblock= iguana_blockadd(coin,bpp,bundleip,origblock)) != 0 ) - { - block = retblock; - //iguana_chainextend(coin,block); - if ( block->height >= 0 && (hash2p= iguana_blockhashptr(coin,coin->blocks.hashblocks)) != 0 ) - *hash2p = block->hash2; - if ( oldhwm != coin->blocks.hwmchain.height ) - { - if ( oldhwm < coin->blocks.hashblocks ) - coin->blocks.hashblocks = oldhwm; - while ( coin->blocks.hashblocks < coin->blocks.hwmchain.height && (hash2p= iguana_blockhashptr(coin,coin->blocks.hashblocks)) != 0 ) - { - hash2 = *hash2p; - if ( bits256_nonz(hash2) > 0 && (block= iguana_blockfind(coin,hash2)) != 0 ) - { - if ( hash2p == 0 ) - { - printf("iguana_bundleblockadd B cant find coin->blocks.hashblocks %d\n",coin->blocks.hashblocks); - break; - } - *hash2p = hash2; - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - if ( coin->blocks.hashblocks >= bp->ramchain.bundleheight && coin->blocks.hashblocks < bp->ramchain.bundleheight+bp->n ) - { - bit = iguana_calcbloom(block->hash2); - if ( iguana_bloomfind(coin,&bp->bloom,0,bit) < 0 ) - iguana_bloomset(coin,&bp->bloom,0,bit); - break; - } - } - } - //printf("ht.%d %s %p\n",block->height,bits256_str(str,hash2),hash2p); - bp = 0; - *bundleip = -2; - iguana_blockadd(coin,&bp,bundleip,block); - bp = 0; - *bundleip = -2; - if ( iguana_bundlefind(coin,&bp,bundleip,block->hash2) == 0 ) - { - printf("iguana_bundleblockadd A cant find just added.%s bundlei.%d\n",bits256_str(str,hash2),*bundleip); - bp = 0; - *bundleip = -2; - iguana_bundlefind(coin,&bp,bundleip,block->hash2); - break; - } - coin->blocks.hashblocks++; - block = 0; - } - else - { - //printf("break loop block.%p %s coin->blocks.hashblocks %d vs %d\n",block,bits256_str(str,hash2),coin->blocks.hashblocks,coin->blocks.hwmheight); - break; - } - } - } - } else printf("iguana_bundleblockadd returns null\n"); - return(retblock); - }*/ - int64_t iguana_ramchain_compact(struct iguana_ramchain *ramchain,int32_t numpkinds,int32_t numexternaltxids) - { - int32_t i,diff; int64_t offset; bits256 *src,*dest,tmp; - diff = (ramchain->data->numpkinds - numpkinds); - src = (bits256 *)((long)ramchain->mem->ptr + (long)ramchain->data->Xoffset); - offset = ramchain->data->Poffset + (sizeof(struct iguana_pkhash) * numpkinds); - ramchain->data->Xoffset = offset + ((sizeof(struct iguana_account)+sizeof(struct iguana_pkextra)) * numpkinds); - if ( numpkinds < ramchain->data->numpkinds ) - { - ramchain->data->numpkinds = numpkinds; - dest = (bits256 *)((long)ramchain->mem->ptr + (long)offset); - for (i=0; idata->numexternaltxids = numexternaltxids; - ramchain->mem->used = offset; - return(offset); - } - - long iguana_blockramchainPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,int32_t txn_count,uint8_t *data,int32_t recvlen) - { - RAMCHAIN_PTRS; struct iguana_ramchain *ramchain = &addr->ramchain; - struct iguana_msgtx *tx; int32_t i,j,err,bundlei = -2; struct iguana_bundle *bp = 0; - if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.hash2) == 0 ) - return(-1); - SETBIT(bp->recv,bundlei); - bp->fpos[bundlei] = -1; - bp->recvlens[bundlei] = recvlen; - if ( iguana_ramchain_init(ramchain,&addr->TXDATA,&addr->HASHMEM,0,txn_count,origtxdata->numunspents,origtxdata->numspends,0,0) == 0 ) - return(-1); - iguana_ramchain_link(ramchain,origtxdata->block.hash2,origtxdata->block.hash2,bp->hdrsi,bp->bundleheight+bundlei,1); - _iguana_ramchain_setptrs(ramchain,&T,&U,&U2,&S,&P,&P2,&A,&X); - if ( T == 0 || U == 0 || S == 0 || P == 0 || X == 0 ) - { - printf("fatal error getting txdataptrs\n"); - return(-1); - } - for (i=0; itxid,tx->tx_out,tx->tx_in); - for (j=0; jtx_out; j++) - iguana_ramchain_addunspent(ramchain,T,U,U2,S,P,P2,A,X,tx->vouts[j].value,tx->vouts[j].pk_script,tx->vouts[j].pk_scriptlen); - for (j=0; jtx_in; j++) - iguana_ramchain_addspend(ramchain,T,U,U2,S,P,P2,A,X,tx->vins[j].prev_hash,tx->vins[j].prev_vout,tx->vins[j].script,tx->vins[j].scriptlen,tx->vins[j].sequence); - } - ramchain->data->numpkinds = ramchain->pkind; - ramchain->data->numexternaltxids = ramchain->externalind; - ramchain->data->allocsize = iguana_ramchain_size(ramchain); - if ( (err= iguana_ramchainverify(ramchain)) == 0 ) - { - if ( (bp->fpos[bundlei]= iguana_ramchain_save(ramchain,addr->ipbits,bp->hashes[0],bundlei)) >= 0 ) - bp->ipbits[bundlei] = addr->ipbits; - } else printf("ramchain verification error.%d hdrsi.%d bundlei.%d\n",err,bp->hdrsi,bundlei); - iguana_ramchain_free(ramchain); - return(bp->fpos[bundlei]); - //iguana_hashfree(addr->txids,0); - //iguana_hashfree(addr->pkhashes,0); - - /*txidind = unspentind = spendind = pkind = 0; - for (i=numvouts=numpkinds=0; itxid = tx->txid, t->txidind = txidind, t->firstvout = unspentind, t->numvouts = tx->tx_out; - iguana_hashsetPT(ramchain,hashmem,'T',t->txid.bytes,txidind); - for (j=0; jtx_out; j++,numvouts++,unspentind++) - { - u = &U[unspentind]; - script = tx->vouts[j].pk_script, scriptlen = tx->vouts[j].pk_scriptlen; - iguana_calcrmd160(coin,rmd160,script,scriptlen,tx->txid); - //char str[65]; init_hexbytes_noT(str,rmd160,20), printf("pkhashes.%p %s %s new pkind.%d pkoffset.%d %d\n",addr->pkhashes,addr->ipaddr,str,numpkinds,txdata->pkoffset,(int32_t)((long)&P[numpkinds] - (long)txdata)); - if ( (ptr= iguana_hashfind(ramchain,'P',rmd160)) == 0 ) - { - memcpy(P[numpkinds].rmd160,rmd160,sizeof(rmd160)); - if ( (ptr= iguana_hashsetPT(ramchain,hashmem,'P',&P[numpkinds],numpkinds)) == 0 ) - printf("fatal error adding pkhash\n"), getchar(); - //printf("added ptr.%p\n",ptr); - numpkinds++; - } //else printf("found %p[%d] for (%s)\n",ptr,ptr->hh.itemind,str); - u->value = tx->vouts[j].value, u->txidind = txidind; - u->pkind = ptr->hh.itemind; - P[u->pkind].firstunspentind = unspentind; - // prevunspentind requires having accts, so that waits for third pass - } - } - //printf("reallocP.%p -> ",P); - if ( (txdata->numpkinds= numpkinds) > 0 ) - P = iguana_memalloc(txmem,sizeof(*P) * numpkinds,0); - //printf("%p\n",P); - externalT = iguana_memalloc(txmem,0,1); - txidind = 0; - for (i=numvins=numexternal=0; ifirstvin = spendind; - for (j=0; jtx_in; j++) - { - script = tx->vins[j].script, scriptlen = tx->vins[j].scriptlen; - s = &S[spendind]; - if ( (sequence= tx->vins[j].sequence) != (uint32_t)-1 ) - s->diffsequence = 1; - s->vout = tx->vins[j].prev_vout; - if ( s->vout != 0xffff ) - { - if ( (ptr= iguana_hashfind(ramchain,'T',tx->vins[j].prev_hash.bytes)) != 0 ) - { - if ( (s->spendtxidind= ptr->hh.itemind) >= txdata->numtxids ) - { - s->external = 1; - s->spendtxidind -= txdata->numtxids; - } - } - else - { - s->external = 1; - externalT[numexternal] = tx->vins[j].prev_hash; - iguana_hashsetPT(ramchain,hashmem,'T',externalT[numexternal].bytes,txdata->numtxids + numexternal); - s->spendtxidind = numexternal++; - } - spendind++; - numvins++; - //printf("spendind.%d\n",spendind); - } //else printf("vout.%x\n",s->vout); - // prevspendind requires having accts, so that waits for third pass - } - t->numvins = numvins; - } - if ( (txdata->numexternaltxids= numexternal) > 0 ) - externalT = iguana_memalloc(txmem,sizeof(*externalT) * numexternal,0); - txdata->datalen = (int32_t)txmem->used; - txdata->numspends = numvins; - txdata->numpkinds = numpkinds; - txdata->numtxids = txn_count; - //char str[65],buf[9999]; - //for (j=buf[0]=0; j %d\n",buf,bundlei,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,recvlen,txdata->datalen); - if ( numvouts != txdata->numunspents || i != txdata->numtxids ) - { - printf("counts mismatch: numvins %d != %d txdata->numvins || numvouts %d != %d txdata->numvouts || i %d != %d txdata->numtxids\n",numvins,txdata->numspends,numvouts,txdata->numunspents,i,txdata->numtxids); - getchar(); - exit(-1); - } - else - { - static int32_t maxrecvlen,maxdatalen,maxhashmem; static double recvsum,datasum; - recvsum += recvlen, datasum += txdata->datalen; - if ( recvlen > maxrecvlen ) - printf("[%.3f] %.0f/%.0f maxrecvlen %d -> %d\n",recvsum/datasum,recvsum,datasum,maxrecvlen,recvlen), maxrecvlen = recvlen; - if ( txdata->datalen > maxdatalen ) - printf("[%.3f] %.0f/%.0f maxdatalen %d -> %d\n",recvsum/datasum,recvsum,datasum,maxdatalen,txdata->datalen), maxdatalen = txdata->datalen; - if ( hashmem != 0 && hashmem->used > maxhashmem ) - printf("[%.3f] %.0f/%.0f maxhashmem %d -> %ld\n",recvsum/datasum,recvsum,datasum,maxhashmem,hashmem->used), maxhashmem = (int32_t)hashmem->used; - if ( (rand() % 10000) == 0 ) - printf("[%.3f] %.0f/%.0f recvlen vs datalen\n",recvsum/datasum,recvsum,datasum); - if ( origtxdata != 0 ) - { - origtxdata->numspends = txdata->numspends; - origtxdata->numpkinds = txdata->numpkinds; - origtxdata->numexternaltxids = txdata->numexternaltxids; - } - } - if ( iguana_peertxsave(coin,&hdrsi,&bundlei,fname,addr,txdata) == txdata ) - { - #ifdef __APPLE__ - int32_t checki; struct iguana_txblock *checktx; struct iguana_ramchain R,*ptr = &R; - if ( 1 && (checktx= iguana_peertxdata(coin,&checki,fname,txmem,addr->ipbits,txdata->block.hash2)) != 0 && checki == bundlei ) - { - if ( iguana_ramchainset(coin,ptr,checktx) == ptr ) - { - char str[65]; int32_t j,err; - ptr->txids = ramchain->txids; - ptr->pkhashes = ramchain->pkhashes; - if ( (err= iguana_ramchainverifyPT(coin,ptr)) != 0 ) - { - for (j=0; jnumpkinds; j++) - init_hexbytes_noT(str,ptr->P[j].rmd160,20), printf("[%d %s] ",j,str); - printf("check err.%d ramchain.%s bundlei.%d T.%d U.%d S.%d P.%d\n",err,bits256_str(str,ptr->hash2),bundlei,ptr->numtxids,ptr->numunspents,ptr->numspends,ptr->numpkinds); - } - } - } - #endif - }*/ - //printf("free addrtables %p %p\n",addr->txids,addr->pkhashes); - // printf("numpkinds.%d numspends.%d\n",txdata->numpkinds,txdata->numspends); - } - - - /*void iguana_flushQ(struct iguana_info *coin,struct iguana_peer *addr) - { - struct iguana_helper *ptr; - if ( time(NULL) > addr->lastflush+3 ) - { - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->addr = addr; - ptr->type = 'F'; - //printf("FLUSH.%s %u lag.%d\n",addr->ipaddr,addr->lastflush,(int32_t)(time(NULL)-addr->lastflush)); - addr->lastflush = (uint32_t)time(NULL); - queue_enqueue("helperQ",&helperQ,&ptr->DL,0); - } - }*/ - - struct iguana_txblock *iguana_peertxsave(struct iguana_info *coin,int32_t *hdrsip,int32_t *bundleip,char *fname,struct iguana_peer *addr,struct iguana_txblock *txdata) - { - int32_t fpos,bundlei,i,z; FILE *fp; - fpos = 0; - *bundleip = bundlei = iguana_peerfname(coin,hdrsip,fname,addr->ipbits,txdata->block.hash2); - if ( bundlei < 0 || bundlei >= coin->chain->bundlesize ) - { - printf(" wont save.(%s) bundlei.%d\n",fname,bundlei); - return(0); - } - txdata->block.hdrsi = *hdrsip; - txdata->block.bundlei = bundlei; - if ( (fp= fopen(fname,"rb+")) == 0 ) - { - if ( (fp= fopen(fname,"wb")) != 0 ) - { - z = -1; - coin->peers.numfiles++; - for (i=0; ichain->bundlesize; i++) - fwrite(&z,1,sizeof(z),fp); - fclose(fp); - fp = fopen(fname,"rb+"); - } - } - if ( fp != 0 ) - { - fseek(fp,0,SEEK_END); - fpos = (int32_t)ftell(fp); - //printf("%s fpos.%d: bundlei.%d datalen.%d\n",fname,fpos,bundlei,txdata->datalen); - fwrite(&bundlei,1,sizeof(bundlei),fp); - fwrite(&txdata->block.hash2,1,sizeof(txdata->block.hash2),fp); - fwrite(&txdata->datalen,1,sizeof(txdata->datalen),fp); - fwrite(txdata,1,txdata->datalen,fp); - fseek(fp,bundlei * sizeof(bundlei),SEEK_SET); - //printf("bundlei[%d] <- fpos.%d\n",bundlei,fpos); - fwrite(&fpos,1,sizeof(fpos),fp); - fclose(fp); - //for (i=0; inumpkinds; i++) - // printf("%016lx ",*(long *)((struct iguana_pkhash *)((long)txdata + txdata->pkoffset))[i].rmd160); - //printf("create.(%s) %d ",fname,bundlei,coin->peers.numfiles); - //printf("bundlei.%d datalen.%d T.%d U.%d S.%d P.%d X.%d\n",bundlei,txdata->datalen,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,txdata->numexternaltxids); - return(txdata); - } - return(0); - } - - /*if ( (n= ramchain->data->numtxids) > 0 ) - { - for (ramchain->txidind=ramchain->data->firsti; ramchain->txidindtxidind++) - { - tx = &T[ramchain->txidind]; - //printf("tx.%p (%d) %d txidind.%d\n",tx,(int32_t)((long)tx - (long)ramchain->mem->ptr),(int32_t)ramchain->mem->totalsize,ramchain->txidind); - iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->numvouts,tx->numvins); - //if ( (ptr= iguana_hashsetPT(ramchain,'T',&tx->txid.bytes,ramchain->txidind)) != 0 ) - { - for (j=0; jnumvouts; j++) - { - iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,U[ramchain->unspentind].value,P[U[ramchain->unspentind].pkind].rmd160,-20,tx->txid,j); - } - } - ramchain->spendind += tx->numvins; - } - ramchain->externalind = ramchain->data->numexternaltxids; - } - if ( (err= iguana_ramchainverify(coin,ramchain)) != 0 ) - { - printf("iguana_ramchain_map.(%s) err.%d verifying ramchain\n",fname,err); - iguana_ramchain_free(ramchain,hashmem == 0); - munmap(ptr,filesize); - }*/ - //printf("mapped ramchain verified\n"); - -#define iguana_hashfind(hashtable,key,keylen) iguana_hashsetHT(hashtable,0,key,keylen,-1) - - struct iguana_kvitem *iguana_hashsetHT(struct iguana_kvitem *hashtable,struct iguana_memspace *mem,void *key,int32_t keylen,int32_t itemind) - { - struct iguana_kvitem *ptr = 0; int32_t allocsize; - HASH_FIND(hh,hashtable,key,keylen,ptr); - if ( ptr == 0 && itemind >= 0 ) - { - allocsize = (int32_t)(sizeof(*ptr)); - if ( mem != 0 ) - ptr = iguana_memalloc(mem,allocsize,1); - else ptr = mycalloc('t',1,allocsize); - if ( ptr == 0 ) - printf("fatal alloc error in hashset\n"), exit(-1); - //printf("ptr.%p allocsize.%d key.%p keylen.%d itemind.%d\n",ptr,allocsize,key,keylen,itemind); - ptr->hh.itemind = itemind; - HASH_ADD_KEYPTR(hh,hashtable,key,keylen,ptr); - } - if ( ptr != 0 ) - { - struct iguana_kvitem *tmp; - HASH_FIND(hh,hashtable,key,keylen,tmp); - char str[65]; - init_hexbytes_noT(str,key,keylen); - if ( tmp != ptr ) - printf("%s itemind.%d search error %p != %p\n",str,itemind,ptr,tmp); - // else printf("added.(%s) height.%d %p\n",str,itemind,ptr); - } - return(ptr); - } - - int32_t iguana_parseblock(struct iguana_info *coin,struct iguana_block *block,struct iguana_msgtx *tx,int32_t numtx) - { -#ifdef oldway - int32_t txind,pkind,i; uint16_t numvouts,numvins; - pkind = block->L.numpkinds = coin->latest.dep.numpkinds; - block->L.supply = coin->latest.dep.supply; - if ( block->L.numtxids != coin->latest.dep.numtxids || block->L.numunspents != coin->latest.dep.numunspents || block->L.numspends != coin->latest.dep.numspends || block->L.numpkinds != coin->latest.dep.numpkinds ) - { - printf("Block.(h%d t%d u%d s%d p%d) vs coin.(h%d t%d u%d s%d p%d)\n",block->height,block->L.numtxids,block->L.numunspents,block->L.numspends,block->L.numpkinds,coin->blocks.parsedblocks,coin->latest.dep.numtxids,coin->latest.dep.numunspents,coin->latest.dep.numspends,coin->latest.dep.numpkinds); - block->L.numtxids = coin->latest.dep.numtxids; - block->L.numunspents = coin->latest.dep.numunspents; - block->L.numspends = coin->latest.dep.numspends; - block->L.numpkinds = coin->latest.dep.numpkinds; - iguana_kvwrite(coin,coin->blocks.db,0,block,(uint32_t *)&block->height); - //getchar(); - } - vcalc_sha256(0,coin->latest.ledgerhash.bytes,coin->latest.lhashes[0].bytes,sizeof(coin->latest.lhashes)); - coin->LEDGER.snapshot.dep = block->L; - memcpy(&coin->LEDGER.snapshot.ledgerhash,&coin->latest.ledgerhash,sizeof(coin->latest.ledgerhash)); - memcpy(coin->LEDGER.snapshot.lhashes,coin->latest.lhashes,sizeof(coin->latest.lhashes)); - memcpy(coin->LEDGER.snapshot.states,coin->latest.states,sizeof(coin->latest.states)); - //printf("%08x Block.(h%d t%d u%d s%d p%d) vs (h%d t%d u%d s%d p%d)\n",(uint32_t)coin->latest.ledgerhash.txid,block->height,block->L.numtxids,block->L.numunspents,block->L.numspends,block->L.numpkinds,coin->blocks.parsedblocks,coin->latest.dep.numtxids,coin->latest.dep.numunspents,coin->latest.dep.numspends,coin->latest.dep.numpkinds); - if ( (coin->blocks.parsedblocks % 1000) == 0 ) - { - for (i=0; iLEDGER.snapshot.lhashes[i].txid); - char str[65]; - bits256_str(str,coin->LEDGER.snapshot.ledgerhash); - printf("-> pre parse %s ledgerhashes.%d\n",str,coin->blocks.parsedblocks); - } - coin->LEDGER.snapshot.blockhash = block->hash2; - coin->LEDGER.snapshot.merkle_root = block->merkle_root; - coin->LEDGER.snapshot.timestamp = block->timestamp; - coin->LEDGER.snapshot.credits = coin->latest.credits; - coin->LEDGER.snapshot.debits = coin->latest.debits; - coin->LEDGER.snapshot.height = block->height; - //if ( coin->blocks.parsedblocks > 0 && (coin->blocks.parsedblocks % coin->chain->bundlesize) == 0 ) - // coin->R.bundles[coin->blocks.parsedblocks / coin->chain->bundlesize].presnapshot = coin->LEDGER.snapshot; - for (txind=block->numvouts=block->numvins=0; txindtxn_count; txind++) - { - //printf("block.%d txind.%d numvouts.%d numvins.%d block->(%d %d) U%d coin.%d\n",block->height,txind,numvouts,numvins,block->numvouts,block->numvins,block->L.numunspents,coin->latest.dep.numunspents); - //fprintf(stderr,"t"); - if ( ramchain_parsetx(coin,&coin->mining,&coin->totalfees,&numvouts,&numvins,block->height,txind,&tx[txind],block->L.numtxids+txind,block->L.numunspents + block->numvouts,block->L.numspends + block->numvins) < 0 ) - return(-1); - block->numvouts += numvouts; - block->numvins += numvins; - //printf("block.%d txind.%d numvouts.%d numvins.%d block->(%d %d) 1st.(%d %d)\n",block->height,txind,numvouts,numvins,block->numvouts,block->numvins,block->L.numunspents,block->L.numspends); - } - //printf(" Block.(h%d t%d u%d s%d p%d) vs coin.(h%d t%d u%d s%d p%d)\n",block->height,block->L.numtxids,block->L.numunspents,block->L.numspends,block->L.numpkinds,coin->blocks.parsedblocks,coin->latest.dep.numtxids,coin->latest.dep.numunspents,coin->latest.dep.numspends,coin->latest.dep.numpkinds); - if ( coin->latest.dep.supply != (coin->latest.credits - coin->latest.debits) ) - { - printf("height.%d supply %.8f != %.8f (%.8f - %.8f)\n",block->height,dstr(coin->latest.dep.supply),dstr(coin->latest.credits)-dstr(coin->latest.debits),dstr(coin->latest.credits),dstr(coin->latest.debits)); - getchar(); - } -#ifdef IGUANA_VERIFYFLAG - while ( pkind < coin->latest.dep.numpkinds ) - { - int64_t err; - if ( (err= iguana_verifyaccount(coin,&coin->accounts[pkind],pkind)) < 0 ) - printf("pkind.%d err.%lld %.8f last.(U%d S%d)\n",pkind,(long long)err,dstr(coin->accounts[pkind].balance),coin->accounts[pkind].lastunspentind,coin->accounts[pkind].lastspendind), getchar(); - pkind++; - } -#endif - coin->parsetime = (uint32_t)time(NULL); - coin->parsemillis = milliseconds(); - iguana_kvwrite(coin,coin->blocks.db,0,block,(uint32_t *)&block->height); - if ( (coin->blocks.parsedblocks > coin->longestchain-100000 && (coin->blocks.parsedblocks % 100) == 0) || (coin->blocks.parsedblocks > coin->longestchain-1000 && (coin->blocks.parsedblocks % 10) == 0) || coin->blocks.parsedblocks > coin->longestchain-100 || (coin->blocks.parsedblocks % 100) == 0 ) - { - printf("PARSED.%d T.%d U.%d+%d S.%d+%d P.%d hwm.%d longest.%d | %.8f - %.8f %.8f [%.8f] M %.8f F %.8f | %.02f minutes %.2f%% %.2f%% %.2f%% avail\n",coin->blocks.parsedblocks,coin->latest.dep.numtxids,block->L.numunspents,block->numvouts,block->L.numspends,block->numvins,block->L.numpkinds,coin->blocks.hwmheight,coin->longestchain,dstr(coin->latest.credits),dstr(coin->latest.debits),dstr(coin->latest.credits)-dstr(coin->latest.debits),(dstr(coin->latest.credits)-dstr(coin->latest.debits))/coin->blocks.parsedblocks,dstr(coin->mining),dstr(coin->totalfees),((double)time(NULL)-coin->starttime)/60.,(double)iguana_avail(coin,coin->blocks.parsedblocks+1,1000)/10.,(double)iguana_avail(coin,coin->blocks.parsedblocks+1,25000)/250.,100.*(double)iguana_avail(coin,coin->blocks.parsedblocks+1,coin->longestchain-coin->blocks.parsedblocks-1)/(coin->longestchain-coin->blocks.parsedblocks)); - myallocated(0,0); - } - if ( 0 && coin->loadedLEDGER.snapshot.height == coin->blocks.parsedblocks ) - { - memcpy(&coin->latest.ledgerhash,&coin->loadedLEDGER.snapshot.ledgerhash,sizeof(coin->loadedLEDGER.snapshot.ledgerhash)); - memcpy(coin->latest.lhashes,coin->loadedLEDGER.snapshot.lhashes,sizeof(coin->loadedLEDGER.snapshot.lhashes)); - printf("restore lhashes, special alignement case\n"); - } //else printf("loaded.%d vs parsed.%d\n",coin->loadedLEDGER.snapshot.height,coin->blocks.parsedblocks); - coin->blocks.parsedblocks++; -#endif - return(0); - } - - int32_t iguana_updateramchain(struct iguana_info *coin) - { - return(0); - } - - int32_t iguana_hashfree(struct iguana_kvitem *hashtable,int32_t delitem) - { - struct iguana_kvitem *item,*tmp; int32_t n = 0; - if ( hashtable != 0 ) - { - HASH_ITER(hh,hashtable,item,tmp) - { - //printf("hashdelete.%p allocsize.%d itemind.%d delitem.%d\n",item,item->allocsize,item->hh.itemind,delitem); - if ( delitem != 0 ) - { - HASH_DEL(hashtable,item); - //if ( delitem > 1 ) - // myfree(item,item->allocsize); - } - n++; - } - } - return(n); - } - - struct iguana_txblock *iguana_ramchainptrs(struct iguana_txid **Tptrp,struct iguana_unspent20 **Uptrp,struct iguana_spend256 **Sptrp,struct iguana_pkhash **Pptrp,bits256 **externalTptrp,struct iguana_memspace *mem,struct iguana_txblock *origtxdata) - { - char str[65]; struct iguana_txblock *txdata; int32_t allocsize,extralen,rwflag = (origtxdata != 0); - iguana_memreset(mem); - allocsize = (int32_t)(sizeof(*txdata) - sizeof(txdata->space) + ((origtxdata != 0) ? origtxdata->extralen : 0)); - mem->alignflag = sizeof(uint32_t); - if ( (txdata= iguana_memalloc(mem,allocsize,0)) == 0 ) - return(0); - //printf("ptr.%p alloctxdata.%p T.%d U.%d S.%d P.%d\n",mem->ptr,txdata,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds); - extralen = (origtxdata != 0) ? origtxdata->extralen : txdata->extralen; - if ( origtxdata != 0 ) - { - //printf("copy %d bytes from %p to %p extralen.%d size.%ld T.%d U.%d S.%d P.%d \n",allocsize,origtxdata,txdata,extralen,sizeof(*txdata),txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds); - memcpy(txdata,origtxdata,allocsize); - } else iguana_memalloc(mem,txdata->extralen,0); - *Tptrp = iguana_memalloc(mem,sizeof(**Tptrp) * txdata->numtxids,rwflag); - *Uptrp = iguana_memalloc(mem,sizeof(**Uptrp) * txdata->numunspents,rwflag); - *Sptrp = iguana_memalloc(mem,sizeof(**Sptrp) * txdata->numspends,rwflag); - //printf("rwflag.%d ptr.%p alloctxdata.%p T.%d U.%d S.%d P.%d pkoffset.%ld X.%d\n",rwflag,mem->ptr,txdata,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,mem->used,txdata->numexternaltxids); - if ( externalTptrp != 0 ) - { - if ( txdata->pkoffset < (int32_t)mem->used ) - printf("allocsize.%d size.%ld %p %s (T.%d U.%d S.%d P.%d X.%d) iguana_ramchainptrs pkoffset.%d != %ld numspends.%d\n",allocsize,sizeof(*txdata),txdata,bits256_str(str,txdata->block.hash2),txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,txdata->numexternaltxids,txdata->pkoffset,mem->used,txdata->numspends), getchar(); - mem->used = txdata->pkoffset; - *Pptrp = iguana_memalloc(mem,sizeof(**Pptrp) * txdata->numpkinds,rwflag); - *externalTptrp = iguana_memalloc(mem,txdata->numexternaltxids * sizeof(**externalTptrp),rwflag); - } - else - { - txdata->pkoffset = (int32_t)mem->used; - // printf("set pkoffset.%d\n",txdata->pkoffset); - *Pptrp = iguana_memalloc(mem,0,rwflag); - } - if ( 0 && rwflag == 0 ) - printf("datalen.%d rwflag.%d origtxdat.%p allocsize.%d extralen.%d T.%d U.%d S.%d P.%d X.%p[%d]\n",(int32_t)mem->totalsize,rwflag,origtxdata,allocsize,extralen,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,externalTptrp!=0?*externalTptrp:0,txdata->numexternaltxids); - return(txdata); - } - - int32_t iguana_ramchainsave(struct iguana_info *coin,struct iguana_ramchain *ramchain) - { - FILE *fp; char fname[1024],str[65]; - sprintf(fname,"DB/%s/%s.%d",coin->symbol,bits256_str(str,ramchain->H.data->firsthash2),ramchain->H.hdrsi); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - fwrite(ramchain,1,ramchain->H.data->allocsize,fp); - fclose(fp); - } - printf("ramchainsave.%s %d[%d] %s\n",coin->symbol,ramchain->H.hdrsi,ramchain->numblocks,mbstr(str,ramchain->H.data->allocsize)); - return(0); - } - - int32_t iguana_ramchainfree(struct iguana_info *coin,struct iguana_memspace *mem,struct iguana_ramchain *ramchain) - { - if ( ramchain->txids != 0 ) - iguana_hashfree(ramchain->txids,1); - if ( ramchain->pkhashes != 0 ) - iguana_hashfree(ramchain->pkhashes,1); - iguana_mempurge(mem); - return(0); - } - - /*struct iguana_ramchain *iguana_ramchainset(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_txblock *txdata) - { - struct iguana_memspace txmem; - memset(&txmem,0,sizeof(txmem)); - iguana_meminit(&txmem,"bramchain",txdata,txdata->datalen,0); - //printf("ramchainset <- txdata.%p memptr.%p T.%d U.%d S.%d P.%d X.%d\n",txdata,txmem.ptr,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,txdata->numexternaltxids); - if ( iguana_ramchainptrs(&ramchain->T,&ramchain->U,&ramchain->S,&ramchain->P,&ramchain->externalT,&txmem,0) != txdata || ramchain->T == 0 || ramchain->U == 0 || ramchain->S == 0 || ramchain->P == 0 ) - { - printf("iguana_ramchainset: cant set pointers txdata.%p\n",txdata); - return(0); - } - //int32_t i; - // for (i=0; i<344; i++) - // printf("%02x ",((uint8_t *)txdata)[i]); - //for (i=-1; i<2; i++) - // printf("%016lx ",*(long *)((struct iguana_pkhash *)((long)txdata + txdata->pkoffset))[i].rmd160); - //printf("datalen.%d T.%d U.%d S.%d P.%d X.%d | %d vs %d ramchain.%p txdata.%p\n",txdata->datalen,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,txdata->numexternaltxids,txdata->pkoffset,(int32_t)((long)ramchain->P - (long)txdata),ramchain,txdata); - ramchain->numtxids = txdata->numtxids; - ramchain->numunspents = txdata->numunspents; - ramchain->numspends = txdata->numspends; - ramchain->numpkinds = txdata->numpkinds; - ramchain->numexternaltxids = txdata->numexternaltxids; - //printf("ramchain T.%d U.%d S.%d P.%d X.%d %p\n",ramchain->numtxids,ramchain->numunspents,ramchain->numspends,ramchain->numpkinds,ramchain->numexternaltxids,ramchain->externalT); - if ( ramchain->numexternaltxids != 0 && ramchain->externalT == 0 ) - getchar(); - ramchain->prevhash2 = txdata->block.prev_block; - ramchain->hash2 = txdata->block.hash2; - return(ramchain); - } - - int32_t iguana_ramchaintxid(struct iguana_info *coin,bits256 *txidp,struct iguana_ramchain *ramchain,struct iguana_spend *s) - { - memset(txidp,0,sizeof(*txidp)); - //printf("s.%p ramchaintxid vout.%x spendtxidind.%d numexternals.%d isext.%d numspendinds.%d\n",s,s->vout,s->spendtxidind,ramchain->numexternaltxids,s->external,ramchain->numspends); - if ( s->vout == 0xffff ) - return(0); - if ( s->external != 0 && s->spendtxidind < ramchain->numexternaltxids ) - { - *txidp = ramchain->externalT[s->spendtxidind]; - return(0); - } - else if ( s->external == 0 && s->spendtxidind < ramchain->numtxids ) - { - *txidp = ramchain->T[s->spendtxidind].txid; - return(0); - } - return(-1); - }*/ - - /*if ( ptr->type == 'F' ) - { - if ( addr != 0 && addr->fp != 0 ) - { - //printf("flush.%s %p\n",addr->ipaddr,addr->fp); - fflush(addr->fp); - } - } - else*/ - - /* struct iguana_txblock *ptr; struct iguana_ramchain *ptrs[IGUANA_MAXBUNDLESIZE],*ramchains; - struct iguana_block *block; char fname[1024]; uint64_t estimatedsize = 0; - int32_t i,maxrecv,addrind,flag,bundlei,numdirs=0; struct iguana_ramchain *ramchain; - flag = maxrecv = 0; - memset(ptrs,0,sizeof(ptrs)); - ramchains = mycalloc('p',coin->chain->bundlesize,sizeof(*ramchains)); - for (i=0; in && ichain->bundlesize; i++) - { - if ( (block= iguana_blockfind(coin,bp->hashes[i])) != 0 ) - { - iguana_meminit(&memB[i],"ramchainB",0,block->recvlen*2 + 8192,0); - if ( (ptr= iguana_peertxdata(coin,&bundlei,fname,&memB[i],block->ipbits,block->hash2)) != 0 ) - { - if ( bundlei != i || ptr->block.bundlei != i ) - printf("peertxdata.%d bundlei.%d, i.%d block->bundlei.%d\n",bp->hdrsi,bundlei,i,ptr->block.bundlei); - ptrs[i] = &ramchains[i]; - //char str[65]; - //printf("received txdata.%s bundlei.%d T.%d U.%d S.%d P.%d\n",bits256_str(str,ptr->block.hash2),bundlei,ptr->numtxids,ptr->numunspents,ptr->numspends,ptr->numpkinds); - if ( iguana_ramchainset(coin,ptrs[i],ptr) == ptrs[i] ) - { - char str[65]; int32_t err; - //for (j=0; jnumpkinds; j++) - // init_hexbytes_noT(str,ptrs[i]->P[j].rmd160,20), printf("%s ",str); - err = iguana_ramchainverifyPT(coin,ptrs[i]); - printf("conv err.%d ramchain.%s bundlei.%d T.%d U.%d S.%d P.%d\n",err,bits256_str(str,ptrs[i]->data->firsthash2),bundlei,ptrs[i]->data->numtxids,ptrs[i]->data->numunspents,ptrs[i]->data->numspends,ptrs[i]->data->numpkinds); - ptrs[i]->data->firsti = 0; - if ( block->recvlen > maxrecv ) - maxrecv = block->recvlen; - estimatedsize += block->recvlen; - flag++; - } else printf("error setting ramchain.%d\n",i); - } - else - { - printf("error (%s) hdrs.%d ptr[%d]\n",fname,bp->hdrsi,i); - CLEARBIT(bp->recv,i); - bp->issued[i] = 0; - block = 0; - } - } - } - if ( flag == i ) - { - printf("numpkinds >>>>>>>>> start MERGE.(%ld) i.%d flag.%d estimated.%ld maxrecv.%d\n",(long)mem->totalsize,i,flag,(long)estimatedsize,maxrecv); - if ( (ramchain= iguana_ramchainmergeHT(coin,mem,ptrs,i,bp)) != 0 ) - { - iguana_ramchainsave(coin,ramchain); - iguana_ramchainfree(coin,mem,ramchain); - //printf("ramchain saved\n"); - bp->emitfinish = (uint32_t)time(NULL); - for (addrind=0; addrindpeers.active[addrind].ipbits != 0 ) - { - if ( iguana_peerfile_exists(coin,&coin->peers.active[addrind],fname,bp->hashes[0]) >= 0 ) - { - //printf("remove.(%s)\n",fname); - //iguana_removefile(fname,0); - //coin->peers.numfiles--; - } - } - } - } else bp->emitfinish = 0; - } - else - { - printf(">>>>> bundlesaveHT error: numdirs.%d i.%d flag.%d\n",numdirs,i,flag); - bp->emitfinish = 0; - } - for (i=0; in && ichain->bundlesize; i++) - iguana_mempurge(&memB[i]); - myfree(ramchains,coin->chain->bundlesize * sizeof(*ramchains)); - return(flag);*/ - -#ifdef oldway - int32_t iguana_verifyiAddr(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize) - { - struct iguana_iAddr *iA = value; - if ( itemind == 0 || iA->ipbits != 0 ) - return(0); - else return(-1); - } - - int32_t iguana_initiAddr(struct iguana_info *coin,struct iguanakv *kv,void *key,void *value,int32_t itemind,int32_t itemsize,int32_t numitems) - { - struct iguana_iAddr *iA = value; - if ( key == 0 && value == 0 && itemind < 0 && numitems == 0 ) - { - } - else - { - if ( iA != 0 ) - iA->status = 0; - coin->numiAddrs++; - //printf("%x numiAddrs.%d\n",iA->ipbits,coin->numiAddrs); - } - return(0); - } - - int32_t iguana_verifyblock(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize) - { - struct iguana_block *block; - block = value; - if ( bits256_nonz(block->hash2) != 0 ) - return(0); - else return(-1); - } - - int32_t iguana_initblock(struct iguana_info *coin,struct iguanakv *kv,void *key,void *value,int32_t itemind,int32_t itemsize,int32_t numitems) - { - bits256 genesis; //struct iguana_block *block = value; - if ( key == 0 && value == 0 && itemind < 0 && numitems == 0 ) - { - if ( coin->blocks.db == 0 ) - coin->blocks.db = kv; - genesis = iguana_genesis(coin,coin->chain); - if ( bits256_nonz(genesis) == 0 ) - return(-1); - else return(0); - } - return(0); - } - - int32_t iguana_nullinit(struct iguana_info *coin,struct iguanakv *kv,void *key,void *value,int32_t itemind,int32_t itemsize,int32_t numitems) - { - if ( key != 0 && value != 0 && itemind > 0 ) - { - } - return(0); - } - - int32_t iguana_verifyunspent(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize) - { - if ( itemind < coin->latest.dep.numunspents ) - return(0); - else return(-1); - } - - int32_t iguana_verifyspend(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize) - { - if ( itemind < coin->latest.dep.numspends ) - return(0); - else return(-1); - } - - int32_t iguana_verifytxid(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize) - { - if ( itemind < coin->latest.dep.numtxids ) - return(0); - else return(-1); - } - - int32_t iguana_inittxid(struct iguana_info *coin,struct iguanakv *kv,void *key,void *value,int32_t itemind,int32_t itemsize,int32_t numitems) - { - //uint32_t checktxidind,firstvout,firstvin; struct iguana_txid *tx = value; - if ( key != 0 && value != 0 && itemind > 0 ) - { - /*printf("inittxid.(%s) itemind.%d (%d %d)\n",bits256_str(tx->txid),itemind,tx->firstvout,tx->firstvin); - checktxidind = iguana_txidind(coin,&firstvout,&firstvin,tx->txid); - if ( checktxidind != itemind ) - { - printf("init checktxidind != itemind: %s -> %d vs %d\n",bits256_str(tx->txid),checktxidind,itemind); - return(-1); - }*/ - } - return(0); - } - - int32_t iguana_verifypkhash(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize) - { - if ( itemind < coin->latest.dep.numpkinds ) - return(0); - else return(-1); - } - - struct iguanakv *iguana_kvinit(char *name,int32_t keysize,int32_t threadsafe,int32_t mapped_datasize,int32_t RAMvaluesize,int32_t keyoffset,int32_t flags,int32_t valuesize2,int32_t valuesize3) - { - struct iguanakv *kv; - printf("iguana_kvinit.(%s) keysize.%d mapped_datasize.%d keyoffset.%d\n",name,keysize,mapped_datasize,keyoffset); - kv = mycalloc('K',1,sizeof(*kv)); - portable_mutex_init(&kv->MMlock); - //portable_mutex_init(&kv->MEM.mutex); - portable_mutex_init(&kv->HASHPTRS.mutex); - portable_mutex_init(&kv->KVmutex); - strcpy(kv->name,name); - kv->flags = flags; - kv->valuesize2 = valuesize2, kv->valuesize3 = valuesize3; - kv->RAMvaluesize = RAMvaluesize; - kv->HDDvaluesize = mapped_datasize; - kv->keyoffset = keyoffset; - kv->mult = IGUANA_ALLOC_MULT; - kv->threadsafe = threadsafe; - kv->keysize = keysize; - return(kv); - } - - int32_t iguana_loadkvfile(struct iguana_info *coin,struct iguanakv *kv,int32_t valuesize,int32_t (*verifyitem)(struct iguana_info *coin,void *key,void *ptr,int32_t itemind,int32_t itemsize),int32_t (*inititem)(struct iguana_info *coin,struct iguanakv *kv,void *key,void *ptr,int32_t itemind,int32_t itemsize,int32_t numitems),int32_t maxind) - { - FILE *fp; long fpos; uint8_t *ptr; double lastdisp,factor; int32_t numitems=0,itemind,j,n,skip = 0; - factor = 1.; - if ( (fp= fopen(kv->fname,"rb")) != 0 ) - { - fseek(fp,0,SEEK_END); - fpos = ftell(fp); - numitems = (int32_t)(fpos / valuesize); - fclose(fp); - if ( kv->RAMvaluesize > 0 && kv->HDDvaluesize > 0 && kv->RAMvaluesize > kv->HDDvaluesize && numitems > 0 ) - numitems--; - iguana_kvensure(coin,kv,0); - if ( numitems > 2 || maxind > 0 ) - { - if ( maxind == 0 ) - { - for (itemind=numitems-2; itemind>0; itemind--) - { - ptr = (uint8_t *)((unsigned long)kv->M.fileptr + ((unsigned long)itemind * kv->HDDvaluesize)); - if ( (*verifyitem)(coin,(void *)&ptr[kv->keyoffset],(void *)ptr,itemind,kv->RAMvaluesize) < 0 ) - { - numitems = itemind + 1; - printf("numitems.%d\n",numitems); - break; - } - } - } else numitems = maxind; - if ( numitems > 0 ) - { - lastdisp = 0.; - for (itemind=0; itemind 1000000 && ((double)itemind / numitems) > lastdisp+.01*factor ) - { - if ( factor == 1. ) - fprintf(stderr,"%.0f%% ",100. * lastdisp); - else fprintf(stderr,"%.2f%% ",100. * lastdisp); - lastdisp = ((double)itemind / numitems); - } - ptr = (uint8_t *)((uint64_t)kv->M.fileptr + ((uint64_t)itemind * kv->HDDvaluesize)); - if ( 0 && kv->keysize > 0 ) - { - for (j=0; jkeysize; j++) - if ( ptr[j] != 0 ) - break; - if ( j != kv->keysize && iguana_kvread(coin,kv,(void *)&ptr[kv->keyoffset],kv->space,(uint32_t *)&n) != 0 ) - { - printf("%s: skip duplicate %llx itemind.%d already at %d\n",kv->name,*(long long *)&ptr[kv->keyoffset],itemind,n); - continue; - } - //printf("%s uniq item at itemind.%d\n",kv->name,itemind); - } - if ( (*verifyitem)(coin,(void *)&ptr[kv->keyoffset],(void *)ptr,itemind,kv->RAMvaluesize) == 0 ) - { - //if ( strcmp("txids",kv->name) == 0 ) - //printf("inititem.%d %p (%s)\n",itemind,ptr,bits256_str(*(bits256 *)&ptr[kv->keyoffset])); - // iguana_kvwrite(coin,kv,(void *)&ptr[kv->keyoffset],sp->space,(uint32_t *)&n); - if ( (*inititem)(coin,kv,(void *)&ptr[kv->keyoffset],(void *)ptr,itemind,kv->RAMvaluesize,numitems) == 0 ) - { - kv->numvalid++; - n = itemind; - memcpy(kv->space,ptr,kv->RAMvaluesize); - if ( kv->keysize > 0 ) - iguana_kvwrite(coin,kv,(void *)&ptr[kv->keyoffset],kv->space,(uint32_t *)&n); - else iguana_kvwrite(coin,kv,0,kv->space,(uint32_t *)&n); - } else skip++; - } else break; - } - } - } - kv->numitems = numitems; - kv->numkeys = numitems; - kv->maxitemind = (numitems > 0 ) ? numitems - 1 : 0; - printf("%s: numkeys.%d numitems.%d numvalid.%d maxitemind.%d skipped.%d ELAPSED %.2f minutes\n",kv->name,kv->numkeys,kv->numitems,kv->numvalid,kv->maxitemind,skip,(double)(time(NULL)-coin->starttime)/60.); - if ( (kv->flags & IGUANA_ITEMIND_DATA) != 0 ) - iguana_syncmap(&kv->M,0); - /*if ( strcmp(kv->name,"iAddrs") == 0 && kv->numkeys < numitems/2 ) - { - iguana_closemap(&kv->M); - printf("truncate?\n"), getchar(); - truncate(kv->fname,(kv->numkeys+100)*kv->HDDvaluesize); - }*/ - } - return(numitems); - } - - struct iguanakv *iguana_stateinit(struct iguana_info *coin,int32_t flags,char *coinstr,char *subdir,char *name,int32_t keyoffset,int32_t keysize,int32_t HDDvaluesize,int32_t RAMvaluesize,int32_t inititems,int32_t (*verifyitem)(struct iguana_info *coin,void *key,void *ptr,int32_t itemind,int32_t itemsize),int32_t (*inititem)(struct iguana_info *coin,struct iguanakv *kv,void *key,void *ptr,int32_t itemind,int32_t itemsize,int32_t numitems),int32_t valuesize2,int32_t valuesize3,int32_t maxind,int32_t initialnumitems,int32_t threadsafe) - { - struct iguanakv *kv; int32_t valuesize; - if ( maxind <= 1 ) - maxind = 0; - printf("%s MAX.%d\n",name,maxind); - if ( HDDvaluesize == 0 ) - valuesize = HDDvaluesize = RAMvaluesize; - else valuesize = HDDvaluesize; - kv = iguana_kvinit(name,keysize,threadsafe,HDDvaluesize,RAMvaluesize,keyoffset,flags,valuesize2,valuesize3); - if ( kv == 0 ) - { - printf("cant initialize kv.(%s)\n",name); - exit(-1); - } - if ( (kv->incr= inititems) == 0 ) - kv->incr = IGUANA_ALLOC_INCR; - strcpy(kv->name,name); - sprintf(kv->fname,"DB/%s/%s",coin->symbol,kv->name), iguana_compatible_path(kv->fname); - portable_mutex_init(&kv->MMmutex); - kv->space = mycalloc('K',1,RAMvaluesize + kv->keysize); - kv->maxitemind = kv->numvalid = kv->numitems = 0; - if ( strcmp("txids",kv->name) == 0 ) - coin->txids = kv; - else if ( strcmp("pkhashes",kv->name) == 0 ) - coin->pkhashes = kv; - printf("kv.%p chain.%p\n",kv,coin->chain); - (*inititem)(coin,kv,0,0,-1,valuesize,0); - iguana_loadkvfile(coin,kv,valuesize,verifyitem,inititem,maxind); - if ( initialnumitems != 0 ) - iguana_kvensure(coin,kv,initialnumitems); - return(kv); - } - - uint32_t iguana_syncs(struct iguana_info *coin) - { - FILE *fp; char fnameold[512],fnameold2[512],fname[512],fname2[512]; int32_t i,height,flag = 0; - if ( (coin->blocks.parsedblocks > coin->longestchain-1000 && (coin->blocks.parsedblocks % 100) == 1) || - (coin->blocks.parsedblocks > coin->longestchain-10000 && (coin->blocks.parsedblocks % 1000) == 1) || - (coin->blocks.parsedblocks > coin->longestchain-2000000 && (coin->blocks.parsedblocks % 10000) == 1) || - (coin->blocks.parsedblocks > coin->firstblock+100 && (coin->blocks.parsedblocks % 100000) == 1) ) - { - if ( coin->blocks.parsedblocks > coin->loadedLEDGER.snapshot.height+2 ) - flag = 1; - } - if ( flag != 0 ) - { - height = coin->blocks.parsedblocks - (coin->firstblock != 0); - for (i=0; iLEDGER.snapshot.lhashes[i].txid); - char str[65]; - bits256_str(str,coin->LEDGER.snapshot.ledgerhash); - printf("-> syncs %s ledgerhashes.%d\n",str,height); - //iguana_syncmap(&coin->iAddrs->M,0); - iguana_syncmap(&coin->blocks.db->M,0); - iguana_syncmap(&coin->unspents->M,0); - iguana_syncmap(&coin->unspents->M2,0); - iguana_syncmap(&coin->spends->M,0); - iguana_syncmap(&coin->spends->M2,0); - iguana_syncmap(&coin->txids->M,0); - iguana_syncmap(&coin->pkhashes->M,0); - iguana_syncmap(&coin->pkhashes->M2,0); - iguana_syncmap(&coin->pkhashes->M3,0); - printf("%s threads.%d iA.%d ranked.%d hwm.%u parsed.%u T.%d U.%d %.8f S.%d %.8f net %.8f P.%d\n",coin->symbol,iguana_numthreads(coin,-1),coin->numiAddrs,coin->peers.numranked,coin->blocks.hwmheight+1,height,coin->latest.dep.numtxids,coin->latest.dep.numunspents,dstr(coin->latest.credits),coin->latest.dep.numspends,dstr(coin->latest.debits),dstr(coin->latest.credits)-dstr(coin->latest.debits),coin->latest.dep.numpkinds); - sprintf(fname,"tmp/%s/ledger.%d",coin->symbol,height); - sprintf(fname2,"DB/%s/ledger",coin->symbol); - sprintf(fnameold,"tmp/%s/ledger.old",coin->symbol); - sprintf(fnameold2,"tmp/%s/ledger.old2",coin->symbol); - iguana_renamefile(fnameold,fnameold2); - iguana_renamefile(fname2,fnameold); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( fwrite(coin->accounts,sizeof(*coin->accounts),coin->LEDGER.snapshot.dep.numpkinds,fp) != coin->LEDGER.snapshot.dep.numpkinds ) - printf("WARNING: error saving %s accounts[%d]\n",fname,coin->LEDGER.snapshot.dep.numpkinds); - if ( fwrite(&coin->LEDGER,1,sizeof(coin->LEDGER),fp) != sizeof(coin->LEDGER) ) - printf("WARNING: error saving %s\n",fname); - fclose(fp); - iguana_copyfile(fname,fname2,1); - } - printf("backups created\n"); - } - return((uint32_t)time(NULL)); - } - - // 480a886f78a52d94 2c16330bdd8565f2 fbfb8ba91a6cd871 d1feb1e96190d4ff b8fef8854847e7db 8d2692bcfe41c777 ec86c8502288022f 789ebb3966bb640f -> pre parse 35ee0080a9a132e88477e8809a6e2a0696a06b8c7b13fbfde2955998346dd5c8 ledgerhashes.120000 - // 9d1025feba33725a d69751b2f8d3f626 1f19457ce24411f1 76e12fd68b3b5b3c 2ad1a1e4b3b7014e a699f2904d073771 989c145c04a7a0d0 e888ab12de678518 -> syncs b8cf6b625de1d921695d1d2247ad68b86d047adf417c09562dc620ada993c47d ledgerhashes.140000 - // 53faf4c08ae7cd66 60af0f6074a4460a 8fa0f21eb4996161 7d695aa60788e52c 45a5c96ef55a1797 7b3225a83646caec d2d5788986315066 27372b0616caacf0 -> syncs c874aa3554c69038574e7da352eb624ac539fed97bf73b605d00df0c8cec4c1b ledgerhashes.200000 - // 739df50dbbaedada b83cbd69f08d2a0f 7a8ffa182706c5b7 8215ff6c7ffb9985 4d674a6d386bd759 f829283534a1804 aeb3b0644b01e07f 7ffe4899a261ca96 -> syncs fba47203d5c1d08e5cf55fa461f4deb6d0c97dcfa364ee5b51f0896ffcbcbaa7 ledgerhashes.300000 - // 739df50dbbaedada b83cbd69f08d2a0f 7a8ffa182706c5b7 8215ff6c7ffb9985 4d674a6d386bd759 f829283534a1804 b5e66cbe3a2bdbea 7ffe4899a261ca96 -> syncs 6b3620ba67fad34a29dd86cd5ec9fe6afd2a81d8a5296aa33b03da74fdd20a9b ledgerhashes.300001 - - int32_t iguana_loadledger(struct iguana_info *coin,int32_t hwmheight) - { - FILE *fp; char fname[512],mapname[512],newfname[512]; struct iguana_block *block; struct iguana_prevdep L; - struct iguana_prevdep *dep; int32_t height,i,valid = 0; - dep = &coin->latest.dep; - sprintf(fname,"DB/%s/ledger",coin->symbol); - mapname[0] = newfname[0] = 0; - if ( (fp= fopen(fname,"rb")) == 0 ) - { - sprintf(fname,"tmp/%s/ledger.old",coin->symbol); - if ( (fp= fopen(fname,"rb")) == 0 ) - { - sprintf(fname,"tmp/%s/ledger.old2",coin->symbol); - fp = fopen(fname,"rb"); - } - } - if ( fp != 0 ) - { - sprintf(mapname,"DB/%s/pkhashes2",coin->symbol); - sprintf(newfname,"DB/%s/pkhashes2.over",coin->symbol); - fseek(fp,-sizeof(coin->LEDGER),SEEK_END); - if ( fread(&coin->LEDGER,1,sizeof(coin->LEDGER),fp) != sizeof(coin->LEDGER) ) - printf("WARNING: error loading %s\n",fname); - if ( (block= iguana_blockptr(coin,coin->LEDGER.snapshot.height)) != 0 ) - { - if ( memcmp(block->hash2.bytes,coin->LEDGER.snapshot.blockhash.bytes,sizeof(block->hash2)) == 0 ) - { - fclose(fp); - iguana_renamefile(mapname,newfname); - iguana_renamefile(fname,mapname); - *dep = coin->LEDGER.snapshot.dep; - coin->loadedLEDGER = coin->LEDGER; - memcpy(&coin->latest.ledgerhash,&coin->LEDGER.snapshot.ledgerhash,sizeof(coin->LEDGER.snapshot.ledgerhash)); - memcpy(coin->latest.lhashes,coin->LEDGER.snapshot.lhashes,sizeof(coin->LEDGER.snapshot.lhashes)); - memcpy(coin->latest.states,coin->LEDGER.snapshot.states,sizeof(coin->LEDGER.snapshot.states)); - printf("found ledger height.%d loadedht.%d\n",block->height,coin->LEDGER.snapshot.height); //getchar(); - for (i=0; iLEDGER.snapshot.lhashes[i].txid); - char str[65]; - bits256_str(str,coin->LEDGER.snapshot.ledgerhash); - printf("-> %s ledgerhashes.%x\n",str,calc_crc32(0,&coin->latest.states[IGUANA_LHASH_TXIDS],sizeof(coin->latest.states[IGUANA_LHASH_TXIDS]))); - printf("loaded H.%d T%d U%d S%d P%d\n",coin->LEDGER.snapshot.height,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds); //getchar(); - coin->latest.credits = coin->LEDGER.snapshot.credits; - coin->latest.debits = coin->LEDGER.snapshot.debits; - coin->latest.dep.supply = (coin->LEDGER.snapshot.credits - coin->LEDGER.snapshot.debits); - return(block->height); - } - } - fclose(fp); - } - dep->numpkinds = dep->numtxids = dep->numunspents = dep->numspends = 1; - while ( hwmheight > 0 ) - { - if ( (block= iguana_blockptr(coin,hwmheight)) != 0 ) - { - iguana_setdependencies(coin,block,&L); - //printf("block.%d: T.%d (%d %d) U.%d S.%d A.%d\n",hwmheight,dep->numtxids,block->numvouts,block->numvins,dep->numunspents,dep->numspends,dep->numpkhashes); - if ( L.numtxids != 0 && L.numunspents != 0 && L.numspends != 0 && block->numvouts != 0 && block->txn_count != 0 && L.numpkinds != 0 ) - { - if ( valid++ > 25 ) - break; - } - } else printf("missing block.%d\n",hwmheight); - hwmheight--; - } - for (height=0; height<=hwmheight; height++) - { - if ( iguana_setdependencies(coin,iguana_blockptr(coin,height),&L) < 0 ) - break; - dep->numtxids = L.numtxids + 0*block->txn_count; - dep->numunspents = L.numunspents + 0*block->numvouts; - dep->numspends = L.numspends + 0*block->numvins; - dep->numpkinds = L.numpkinds; - } - return(hwmheight); - } - - int32_t iguana_validateramchain(struct iguana_info *coin,int64_t *netp,uint64_t *creditsp,uint64_t *debitsp,int32_t height,struct iguana_block *block,int32_t hwmheight,struct iguana_prevdep *lp) - { - uint32_t i,n,m,u,txidind,unspentind,spendind,pkind,checkind,numvins,numvouts,txind,firstvout,firstvin,nextfirstvout,nextfirstvin; struct iguana_prevdep *nextlp; - struct iguana_txid T,nextT; uint64_t credits,debits,nets; struct iguana_block *nextblock; - credits = debits = nets = *creditsp = *debitsp = *netp = numvouts = numvins = 0; - if ( block->height == height ) - { - txidind = lp->numtxids, unspentind = lp->numunspents, spendind = lp->numspends, pkind = lp->numpkinds; - //printf("validate.%d (t%d u%d s%d p%d)\n",height,txidind,unspentind,spendind,pkind); - for (txind=0; txindtxn_count; txind++,txidind++) - { - T = coin->T[txidind], nextT = coin->T[txidind+1]; - //printf("h%d i%d T.%d (%d %d) -> (%d %d)\n",height,txind,txidind,T.firstvout,T.firstvin,nextT.firstvout,nextT.firstvin); - if ( height == 0 && (T.firstvout == 0 || T.firstvin == 0) ) - return(-1); - //printf(">>>> h%d i%d T.%d (%d %d) -> (%d %d) cmp.(%d %d)\n",height,txind,txidind,T.firstvout,T.firstvin,nextT.firstvout,nextT.firstvin,height == 0,(T.firstvout == 0 || T.firstvin == 0)); - if ( (checkind= iguana_txidind(coin,&firstvout,&firstvin,T.txid)) == txidind ) - { - if ( T.firstvout != firstvout || T.firstvin != firstvin ) - { - printf("mismatched rwtxidind %d != %d, %d != %d\n",T.firstvout,firstvout,T.firstvin,firstvin); - getchar(); - return(-1); - } - if ( txind == 0 && (firstvout != unspentind || firstvin != spendind) ) - { - char str[65]; - bits256_str(str,T.txid); - printf("h.%d txind.%d txidind.%d %s firstvout.%d != U%d firstvin.%d != S%d\n",height,txind,txidind,str,firstvout,unspentind,firstvin,spendind); - iguana_txidind(coin,&firstvout,&firstvin,T.txid); - iguana_txidind(coin,&firstvout,&firstvin,T.txid); - return(-1); - } - nextfirstvout = nextT.firstvout, nextfirstvin = nextT.firstvin; - if ( nextfirstvout < unspentind || nextfirstvin < spendind ) - { - printf("h.%d txind.%d nexttxidind.%d firstvout.%d != U%d firstvin.%d != S%d\n",height,txind,txidind,nextfirstvout,unspentind,nextfirstvin,spendind); - if ( nextfirstvout == 0 && nextfirstvin == 0 ) - { - coin->T[txidind+1].firstvout = unspentind; - coin->T[txidind+1].firstvin = spendind; - printf("autofixed\n"); - } - else - { - getchar(); - return(-1); - } - } - n = (nextfirstvout - T.firstvout); - m = (nextfirstvin - T.firstvin); - //printf("height.%d n.%d m.%d U.(%d - %d) S.(%d - %d)\n",height,n,m,nextfirstvout,T.firstvout,nextfirstvin,T.firstvin); - for (i=0; iU[unspentind].value; - if ( coin->Uextras[unspentind].spendind == 0 ) - nets += coin->U[unspentind].value; - if ( coin->U[unspentind].pkind > pkind ) - pkind = coin->U[unspentind].pkind; - //printf("i.%d: unspentind.%d\n",i,unspentind); - } - for (i=0; iS[spendind].spendtxidind) > 0 && u < coin->latest.dep.numunspents ) - debits += coin->U[u].value; - else - { - printf("cant read spendind.%d or S.unspentind %d\n",spendind+i,u); - getchar(); - } - } - numvouts += n; - numvins += m; - } - else - { - char str[65]; - bits256_str(str,T.txid); - printf("height.%d txind.%d txid.%s txidind.%d != %d\n",height,txind,str,txidind,checkind); - getchar(); - return(-1); - } - } - if ( numvins != block->numvins || numvouts != block->numvouts ) - { - printf("height.%d numvins or numvouts error %d != %d || %d != %d\n",height,numvins,block->numvins,numvouts,block->numvouts); - if ( block->numvins == 0 && block->numvouts == 0 ) - { - block->numvins = numvins; - block->numvouts = numvouts; - iguana_kvwrite(coin,coin->blocks.db,0,block,(uint32_t *)&block->height); - m = 0;//iguana_fixblocks(coin,height,hwmheight); - printf("autocorrected.%d\n",m); - exit(1); - } - else - { - getchar(); - return(-1); - } - } - *creditsp = credits, *debitsp = debits, *netp = nets; - if ( (nextblock= iguana_blockptr(coin,height+1)) != 0 ) - { - nextlp = 0; - if ( 0 && lp->supply+credits-debits != nextlp->supply ) - { - printf("nextblock.%d supply mismatch %.8f (%.8f - %.8f) %.8f != %.8f\n",height+1,dstr(lp->supply),dstr(credits),dstr(debits),dstr(lp->supply+credits-debits),dstr(nextlp->supply)); - getchar(); - return(-1); - } - if ( txidind != nextlp->numtxids || unspentind != nextlp->numunspents || spendind != nextlp->numspends )//|| pkind+1 != nextlp->numpkinds ) - { - printf("Block.(h%d t%d u%d s%d p%d) vs next.(h%d t%d u%d s%d p%d)\n",block->height,txidind,unspentind,spendind,pkind,height+1,nextlp->numtxids,nextlp->numunspents,nextlp->numspends,nextlp->numpkinds); - return(-1); - } - return(0); - } - printf("cant find next block at %d\n",height+1); - //printf("block.%d %.8f (%.8f - %.8f)\n",height,dstr(nets),dstr(credits),dstr(debits)); - } else printf("height mismatch %d != %d\n",height,block->height); - //getchar(); - return(-1); - } - - int32_t iguana_fixsecondary(struct iguana_info *coin,int32_t numtxids,int32_t numunspents,int32_t numspends,int32_t numpkinds,struct iguana_Uextra *Uextras,struct iguana_pkextra *pkextras,struct iguana_account *accounts) - { - uint32_t i; int32_t m,err; - if ( numtxids < 2 || numunspents < 2 || numspends < 2 || numpkinds < 2 ) - return(0); - //struct iguana_Uextra { uint32_t spendind; }; // unspentind - //struct iguana_unspent { uint64_t value; uint32_t pkind,txidind,prevunspentind; }; - for (i=m=err=0; i= numspends ) - m++, Uextras[i].spendind = 0;//, printf("%d ",Uextras[i].spendind); - if ( coin->U[i].prevunspentind != 0 && coin->U[i].prevunspentind >= i ) - err++, printf("preverr.%d/%d ",coin->U[i].prevunspentind,i); - if ( coin->U[i].txidind >= numtxids ) - err++, printf("errtxidind.%d ",coin->U[i].txidind); - if ( coin->U[i].pkind >= numpkinds ) - err++, printf("errpkind.%d ",coin->U[i].pkind); - } - if ( (err+m) != 0 ) - iguana_syncmap(&coin->unspents->M2,0); - printf("cleared %d Uextras before numunspents.%d beyond errs.%d\n",m,numunspents,err); - if ( err != 0 ) - getchar(); - //struct iguana_pkextra { uint32_t firstspendind; }; // pkind - for (i=m=0; i= numspends ) - m++, pkextras[i].firstspendind = 0;//, printf("firstS.%d ",pkextras[i].firstspendind); - } - if ( m != 0 ) - iguana_syncmap(&coin->pkhashes->M3,0); - printf("pkextras beyond numspends.%d m.%d accounts.%p\n",numspends,m,accounts); - //struct iguana_spend { uint32_t unspentind,prevspendind; }; // dont need nextspend - /*for (i=err=m=0; iS[i].unspentind >= numunspents ) - err++, coin->S[i].unspentind = 0;//, printf("S->U%d ",coin->S[i].unspentind); - //printf("%d ",coin->S[i].prevspendind); - if ( coin->Sextras[i].prevspendind != 0 && coin->Sextras[i].prevspendind >= i ) - m++, coin->Sextras[i].prevspendind = 0, printf("preverr.%d:%d ",coin->Sextras[i].prevspendind,i); - } - printf("errs.%d in spends numspends.%d\n",err,numspends); - if ( err != 0 ) - getchar();*/ - return(0); - } - - void clearmem(void *ptr,int32_t len) - { - static const uint8_t zeroes[512]; - if ( len > sizeof(zeroes) || memcmp(ptr,zeroes,len) != 0 ) - memset(ptr,0,len); - } - - int32_t iguana_clearoverage(struct iguana_info *coin,int32_t numtxids,int32_t numunspents,int32_t numspends,int32_t numpkinds,struct iguana_Uextra *Uextras,struct iguana_pkextra *pkextras,struct iguana_account *accounts) - { - uint32_t i,n; - printf("clear txids\n"); - n = (uint32_t)((uint64_t)coin->txids->M.allocsize / coin->txids->HDDvaluesize) - 2; - for (i=numtxids+1; iT[i],sizeof(coin->T[i])); - - printf("clear pkinds\n"); - n = (uint32_t)((uint64_t)coin->pkhashes->M.allocsize / coin->pkhashes->HDDvaluesize) - 2; - for (i=numpkinds; iP[i],sizeof(coin->P[i])); - n = (uint32_t)((uint64_t)coin->pkhashes->M2.allocsize / coin->pkhashes->valuesize2) - 2; - for (i=numpkinds; ipkhashes->M3.allocsize / coin->pkhashes->valuesize3) - 2; - for (i=numpkinds; iunspents->M.allocsize / coin->unspents->HDDvaluesize) - 2; - for (i=numunspents; iU[i],sizeof(coin->U[i])); - n = (uint32_t)((uint64_t)coin->unspents->M2.allocsize / coin->unspents->valuesize2) - 2; - for (i=numunspents; ispends->M.allocsize / coin->spends->HDDvaluesize) - 2; - for (i=numspends; iS[i],sizeof(coin->S[i])); - //n = (uint32_t)((uint64_t)coin->spends->M2.allocsize / coin->spends->valuesize2) - 2; - //for (i=numspends; iSextras[i],sizeof(coin->Sextras[i])); - return(0); - } - - int64_t iguana_verifybalances(struct iguana_info *coin,int32_t fullverify) - { - int64_t err,balance = 0; int32_t i,numerrs = 0; - for (i=0; ilatest.dep.numpkinds; i++) - { - if ( fullverify != 0 ) - { - if ( (err= iguana_verifyaccount(coin,&coin->accounts[i],i)) < 0 ) - { - printf("err.%d from pkind.%d\n",(int32_t)err,i); - numerrs++; - } - } - balance += coin->accounts[i].balance; - } - printf("iguana_verifybalances %.8f numerrs.%d\n",dstr(balance),numerrs); - if ( numerrs > 0 ) - getchar(); - return(balance); - } - - int32_t iguana_initramchain(struct iguana_info *coin,int32_t hwmheight,int32_t mapflags,int32_t fullverify) - { - struct iguana_prevdep *dep; struct iguana_block *block,lastblock; double lastdisp = 0.; - // init sequence is very tricky. must be done in the right order and make sure to only use data - // that has already been initialized. and at the end all the required fields need to be correct - struct iguana_msghdr H; uint8_t buf[1024]; int32_t len,height,valid=0,flag=0; - struct iguana_prevdep L,prevL; - int64_t checkbalance,net,nets; uint64_t prevcredits,prevdebits,credit,debit,credits,debits,origsupply; - dep = &coin->latest.dep; - height = hwmheight; - if ( (height= iguana_loadledger(coin,hwmheight)) < 0 ) - { - printf("iguana_initramchain: unrecoverable loadledger error hwmheight.%d\n",hwmheight); - return(-1); - } - hwmheight = height; - printf("four ramchains start valid.%d height.%d txids.%d vouts.%d vins.%d pkhashes.%d\n",valid,hwmheight,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds); - //four ramchains start valid.0 height.316904 txids.45082870 vouts.27183907 vins.107472009 pkhashes.44807925 3.57 minutes - - coin->unspents = iguana_stateinit(coin,IGUANA_ITEMIND_DATA,coin->symbol,coin->symbol,"unspents",0,0,sizeof(struct iguana_unspent),sizeof(struct iguana_unspent),100000,iguana_verifyunspent,iguana_nullinit,sizeof(*coin->Uextras),0,dep->numunspents,2500000,0); - if ( coin->unspents == 0 ) - printf("cant create unspents\n"), exit(1); - coin->unspents->HDDitemsp = (void **)&coin->U, coin->U = coin->unspents->M.fileptr; - coin->unspents->HDDitems2p = (void **)&coin->Uextras, coin->Uextras = coin->unspents->M2.fileptr; - printf("four ramchains start valid.%d height.%d txids.%d vouts.%d vins.%d pkhashes.%d %.2f minutes\n",valid,hwmheight,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,((double)time(NULL)-coin->starttime)/60.); - - coin->spends = iguana_stateinit(coin,IGUANA_ITEMIND_DATA,coin->symbol,coin->symbol,"spends",0,0,sizeof(struct iguana_spend),sizeof(struct iguana_spend),100000,iguana_verifyspend,iguana_nullinit,0,0,dep->numspends,2500000,0); - if ( coin->spends == 0 ) - printf("cant create spends\n"), exit(1); - printf("four ramchains start valid.%d height.%d txids.%d vouts.%d vins.%d pkhashes.%d %.2f minutes\n",valid,hwmheight,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,((double)time(NULL)-coin->starttime)/60.); - coin->spends->HDDitemsp = (void **)&coin->S, coin->S = coin->spends->M.fileptr; - coin->spends->HDDitems2p = (void **)&coin->Sextras, coin->Sextras = coin->spends->M2.fileptr; - - coin->txids = iguana_stateinit(coin,IGUANA_ITEMIND_DATA|((mapflags&IGUANA_MAPTXIDITEMS)!=0)*IGUANA_MAPPED_ITEM,coin->symbol,coin->symbol,"txids",0,sizeof(bits256),sizeof(struct iguana_txid),sizeof(struct iguana_txid),100000,iguana_verifytxid,iguana_inittxid,0,0,dep->numtxids,1000000,0); - if ( coin->txids == 0 ) - printf("cant create txids\n"), exit(1); - coin->txids->HDDitemsp = (void **)&coin->T, coin->T = coin->txids->M.fileptr; - printf("four ramchains start valid.%d height.%d txids.%d vouts.%d vins.%d pkhashes.%d %.2f minutes\n",valid,hwmheight,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,((double)time(NULL)-coin->starttime)/60.); - - coin->pkhashes = iguana_stateinit(coin,IGUANA_ITEMIND_DATA|((mapflags&IGUANA_MAPPKITEMS)!=0)*IGUANA_MAPPED_ITEM,coin->symbol,coin->symbol,"pkhashes",0,20,sizeof(struct iguana_pkhash),sizeof(struct iguana_pkhash),100000,iguana_verifypkhash,iguana_nullinit,sizeof(*coin->accounts),sizeof(*coin->pkextras),dep->numpkinds,1000000,0); - if ( coin->pkhashes == 0 ) - printf("cant create pkhashes\n"), exit(1); - coin->pkhashes->HDDitemsp = (void **)&coin->P, coin->P = coin->pkhashes->M.fileptr; - coin->pkhashes->HDDitems2p = (void **)&coin->accounts, coin->accounts = coin->pkhashes->M2.fileptr; - coin->pkhashes->HDDitems3p = (void **)&coin->pkextras, coin->pkextras = coin->pkhashes->M3.fileptr; - printf("four ramchains start valid.%d height.%d txids.%d vouts.%d vins.%d pkhashes.%d %.2f minutes\n",valid,hwmheight,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,((double)time(NULL)-coin->starttime)/60.); - - iguana_kvensure(coin,coin->txids,dep->numtxids + coin->txids->incr); - iguana_kvensure(coin,coin->pkhashes,dep->numpkinds + coin->pkhashes->incr); - iguana_kvensure(coin,coin->unspents,dep->numunspents + coin->unspents->incr); - iguana_kvensure(coin,coin->spends,dep->numspends + coin->spends->incr); - coin->txids->numkeys = dep->numtxids; - coin->unspents->numkeys = dep->numunspents; - coin->spends->numkeys = dep->numspends; - coin->pkhashes->numkeys = dep->numpkinds; - iguana_fixsecondary(coin,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,coin->Uextras,coin->pkextras,coin->accounts); - printf("hwmheight.%d KV counts T.%d P.%d U.%d S.%d\n",hwmheight,coin->txids->numkeys,coin->pkhashes->numkeys,coin->unspents->numkeys,coin->spends->numkeys); - memset(&lastblock,0,sizeof(lastblock)); - origsupply = dep->supply, dep->supply = 0; - for (prevcredits=prevdebits=credits=debits=nets=height=0; height<=hwmheight; height++) - { - if ( hwmheight > 10000 && ((double)height / hwmheight) > lastdisp+.01 ) - { - fprintf(stderr,"%.0f%% ",100. * lastdisp); - lastdisp = ((double)height / hwmheight); - } - if ( (block= iguana_blockptr(coin,height)) == 0 ) - { - printf("error getting height.%d\n",height); - break; - } - lastblock = *block; - if ( height == hwmheight ) - break; - printf("need to set valid L\n"); - if ( iguana_validateramchain(coin,&net,&credit,&debit,height,block,hwmheight,&L) < 0 ) - { - printf("UNRECOVERABLE error iguana_validateramchain height.%d\n",height); - getchar(); - exit(1); - break; - } - nets += net, credits += credit, debits += debit; - if ( nets != (credits - debits) ) - { - //printf("height.%d: net %.8f != %.8f (%.8f - %.8f)\n",height,dstr(nets),dstr(credits)-dstr(debits),dstr(credits),dstr(debits)); - //break; - } - prevcredits = credits; - prevdebits = debits; - } - if ( lastblock.height == 0 ) - dep->numpkinds = dep->numspends = dep->numtxids = dep->numunspents = 1, dep->supply = 0, coin->latest.credits = coin->latest.debits = 0; - else - { - printf("set prevL\n"); - dep->numtxids = prevL.numtxids; - dep->numunspents = prevL.numunspents; - dep->numspends = prevL.numspends; - dep->numpkinds = prevL.numpkinds; - dep->supply = prevL.supply; - coin->latest.credits = prevcredits; - coin->latest.debits = prevdebits; - if ( dep->supply != (prevcredits - prevdebits) ) - { - printf("override supply %.8f (%.8f - %.8f)\n",dstr(dep->supply),dstr(prevcredits),dstr(prevdebits)); - dep->supply = (prevcredits - prevdebits); - } - checkbalance = iguana_verifybalances(coin,0); - if ( (checkbalance != dep->supply || fullverify != 0) && iguana_verifybalances(coin,1) != dep->supply ) - { - printf("balances mismatch\n"); - getchar(); - } - } - coin->txids->numkeys = dep->numtxids; - coin->unspents->numkeys = dep->numunspents; - coin->spends->numkeys = dep->numspends; - coin->pkhashes->numkeys = dep->numpkinds; - coin->blocks.parsedblocks = lastblock.height; - printf("\nhwmheight.%d KV counts T.%d P.%d U.%d S.%d %.8f (%.8f - %.8f)\n",hwmheight,coin->txids->numkeys,coin->pkhashes->numkeys,coin->unspents->numkeys,coin->spends->numkeys,dstr(coin->latest.dep.supply),dstr(coin->latest.credits),dstr(coin->latest.debits)); - printf("four ramchains start valid.%d height.%d txids.%d vouts.%d vins.%d pkhashes.%d %.2f minutes\n",valid,hwmheight,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,((double)time(NULL)-coin->starttime)/60.); - printf("height.%d after validateramchain hwmheight.%d flag.%d parsed.%d\n",height,hwmheight,flag,coin->blocks.parsedblocks); //getchar(); - if ( coin->blocks.parsedblocks == 0 ) - { - uint8_t txspace[32768]; struct iguana_memspace MEM; - len = (int32_t)strlen(coin->chain->genesis_hex)/2; - decode_hex(buf,len,(char *)coin->chain->genesis_hex); - iguana_sethdr(&H,coin->chain->netmagic,"block",buf,len); - iguana_meminit(&MEM,"genesis",txspace,sizeof(txspace),0); - iguana_parser(coin,0,&MEM,&MEM,0,&H,buf,len); - printf("coin->blocks.parsedblocks.%d KV counts T.%d P.%d U.%d S.%d\n",coin->blocks.parsedblocks,coin->txids->numkeys,coin->pkhashes->numkeys,coin->unspents->numkeys,coin->spends->numkeys); - printf("auto parse genesis\n"); //getchar(); - } - else iguana_clearoverage(coin,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,coin->Uextras,coin->pkextras,coin->accounts); - return(coin->blocks.parsedblocks); - } -#endif - if ( 0 && queue_size(&coin->blocksQ) == 0 ) - { - HASH_ITER(hh,coin->blocks.hash,block,tmp) - { - if ( bits256_nonz(block->prev_block) > 0 && (prev= iguana_blockfind(coin,block->prev_block)) != 0 ) - { - if ( prev->mainchain != 0 ) - { - char str[65]; printf("idle issue %s %d\n",bits256_str(str,block->hash2),prev->height+1); - iguana_blockQ(coin,0,-1,block->hash2,0); - } - } - } - } - struct iguana_ramchain *iguana_ramchainmergeHT(struct iguana_info *coin,struct iguana_memspace *mem,struct iguana_ramchain *ramchains[],int32_t n,struct iguana_bundle *bp) - { - /* uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,i,j,k; uint64_t allocsize = 0; - struct iguana_txid *tx; struct iguana_account *acct; struct iguana_ramchain *ramchain,*item; - struct iguana_pkhash *p,oldP; struct iguana_unspent *u; struct iguana_kvitem *ptr; - bits256 txid; uint32_t txidind,unspentind,spendind,pkind,numblocks; struct iguana_spend *s; - numtxids = numunspents = numspends = numpkinds = 1; - numexternaltxids = 1; - numblocks = 0; - for (i=0; iramchain.hdrsi,i); - return(0); - } - numtxids += item->numtxids, numunspents += item->numunspents, numspends += item->numspends; - numpkinds += item->numpkinds, numexternaltxids += item->numexternaltxids; - numblocks += item->numblocks; - } - allocsize = sizeof(*ramchain) + - (numtxids * sizeof(*ramchain->T)) + - (numunspents * (sizeof(*ramchain->U) + sizeof(*ramchain->Uextras))) + - (numspends * sizeof(*ramchain->S)) + - (numpkinds * (sizeof(*ramchain->P) + sizeof(*ramchain->pkextras) + sizeof(*ramchain->accounts))) + - (numexternaltxids * sizeof(*ramchain->externalT)); - - iguana_meminit(mem,"ramchain",0,allocsize,0); - mem->alignflag = sizeof(uint32_t); - ramchain= &bp->ramchain; //iguana_memalloc(mem,sizeof(*ramchain),1)) == 0 ) - ramchain->numblocks = numblocks; - ramchain->numtxids = numtxids, ramchain->numunspents = numunspents; - ramchain->numspends = numspends, ramchain->numpkinds = numpkinds; - ramchain->numexternaltxids = numexternaltxids; - ramchain->hdrsi = bp->ramchain.hdrsi, ramchain->bundleheight = bp->ramchain.bundleheight, ramchain->numblocks = n; - ramchain->prevbundlehash2 = bp->prevbundlehash2, ramchain->nextbundlehash2 = bp->nextbundlehash2; - ramchain->hash2 = ramchains[0]->hash2; - ramchain->prevhash2 = ramchains[0]->prevhash2, ramchain->lasthash2 = ramchains[n-1]->hash2; - ramchain->T = iguana_memalloc(mem,sizeof(*ramchain->T) * ramchain->numtxids,0); - ramchain->U = iguana_memalloc(mem,sizeof(*ramchain->U) * ramchain->numunspents,0); - if ( ramchain->numspends > 0 ) - ramchain->S = iguana_memalloc(mem,sizeof(*ramchain->S) * ramchain->numspends,0); - ramchain->Uextras = iguana_memalloc(mem,sizeof(*ramchain->Uextras) * ramchain->numunspents,1); - ramchain->P = iguana_memalloc(mem,sizeof(*ramchain->P) * ramchain->numpkinds,1); - ramchain->pkextras = iguana_memalloc(mem,sizeof(*ramchain->pkextras) * ramchain->numpkinds,1); - ramchain->accounts = iguana_memalloc(mem,sizeof(*ramchain->accounts) * ramchain->numpkinds,1); - if ( ramchain->numexternaltxids > 0 ) - ramchain->externalT = iguana_memalloc(mem,ramchain->numexternaltxids * sizeof(*ramchain->externalT),1); - if ( mem->used != allocsize ) - { - printf("error allocating ramchain %ld != %ld\n",(long)mem->used,(long)allocsize); - iguana_ramchainfree(coin,mem,ramchain); - return(0); - } - ramchain->allocsize = allocsize; - ramchain->firsti = 1; - //printf("Allocated %s for bp %d\n",mbstr(str,allocsize),bp->ramchain.bundleheight); - txidind = unspentind = numtxids = spendind = numunspents = numspends = numpkinds = ramchain->firsti; - numexternaltxids = 0; - for (i=0; ifirsti; jnumtxids; j++,txidind++) - { - tx = &ramchain->T[txidind]; - *tx = item->T[j]; - tx->txidind = txidind; - if ( (ptr= iguana_hashfind(ramchain->txids,tx->txid.bytes,sizeof(tx->txid))) != 0 ) - { - printf("unexpected duplicate txid[%d]\n",txidind); - iguana_ramchainfree(coin,mem,ramchain); - return(0); - } - iguana_hashsetHT(ramchain->txids,0,tx->txid.bytes,sizeof(bits256),txidind); - tx->firstvout = unspentind; - for (k=item->firsti; knumvouts; k++,unspentind++) - { - u = &ramchain->U[unspentind]; - *u = item->U[k]; - u->txidind = txidind; - oldP = item->P[item->U[k].pkind]; - if ( (ptr= iguana_hashfind(ramchain->pkhashes,oldP.rmd160,sizeof(oldP.rmd160))) == 0 ) - { - pkind = numpkinds++; - p = &ramchain->P[pkind]; - *p = oldP; - p->firstunspentind = unspentind; - if ( (ptr= iguana_hashsetHT(ramchain->pkhashes,0,p->rmd160,sizeof(p->rmd160),numpkinds)) == 0 ) - { - iguana_ramchainfree(coin,mem,ramchain); - printf("fatal error adding pkhash\n"); - return(0); - } - //printf("pkind.%d: %p %016lx <- %016lx\n",pkind,p,*(long *)p->rmd160,*(long *)oldP.rmd160); - } else pkind = ptr->hh.itemind; - u->pkind = pkind; - acct = &ramchain->accounts[pkind]; - u->prevunspentind = acct->lastunspentind; - acct->lastunspentind = unspentind; - acct->balance += u->value; - } - tx->firstvin = spendind; - spendind += tx->numvins; - } - numtxids += item->numtxids, numunspents += item->numunspents; - } - } - txidind = spendind = ramchain->firsti; - for (i=0; ifirsti; jnumtxids; j++,txidind++) - { - tx = &ramchain->T[j]; - for (k=item->firsti; knumvins; k++) - { - //printf("item.%p [%d] X.%p i.%d j.%d k.%d txidind.%d/%d spendind.%d/%d s->txidind.%d/v%d\n",item,item->numexternaltxids,item->externalT,i,j,k,txidind,ramchain->numtxids,spendind,ramchain->numspends,item->S[k].spendtxidind,item->S[k].vout); - if ( iguana_ramchaintxid(coin,&txid,item,&item->S[k]) < 0 ) - { - printf("i.%d j.%d k.%d error getting txid firsti.%d X.%d vout.%d spend.%d/%d numX.%d numT.%d\n",i,j,k,item->firsti,item->S[k].external,item->S[k].vout,item->S[k].spendtxidind,item->numspends,item->numexternaltxids,item->numtxids); - //iguana_ramchainfree(coin,mem,ramchain); - //return(0); - } - s = &ramchain->S[spendind]; - *s = item->S[k]; - if ( s->vout == 0xffff ) - { - // mining output - } - else if ( (ptr= iguana_hashfind(ramchain->txids,txid.bytes,sizeof(txid))) != 0 ) - { - if ( (s->spendtxidind= ptr->hh.itemind) >= ramchain->numtxids ) - { - s->external = 1; - s->spendtxidind -= ramchain->numtxids; - } - else if ( s->spendtxidind >= item->firsti && s->spendtxidind < item->numtxids ) - { - s->external = 0; - unspentind = (ramchain->T[s->spendtxidind].firstvout + s->vout); - u = &ramchain->U[unspentind]; - p = &ramchain->P[u->pkind]; - if ( ramchain->pkextras[u->pkind].firstspendind == 0 ) - ramchain->pkextras[u->pkind].firstspendind = spendind; - acct = &ramchain->accounts[u->pkind]; - s->prevspendind = acct->lastspendind; - acct->lastspendind = spendind; - if ( ramchain->Uextras[unspentind].spendind != 0 ) - { - printf("double spend u.%d has spendind.%d when s.%d refers to it\n",unspentind,ramchain->Uextras[unspentind].spendind,spendind); - iguana_ramchainfree(coin,mem,ramchain); - return(0); - } - ramchain->Uextras[unspentind].spendind = spendind; - } - spendind++; - } - else if ( numexternaltxids < ramchain->numexternaltxids ) - { - s->external = 1; - ramchain->externalT[numexternaltxids] = txid; - iguana_hashsetHT(ramchain->txids,0,ramchain->externalT[numexternaltxids].bytes,sizeof(ramchain->externalT[numexternaltxids]),ramchain->numtxids + numexternaltxids); - s->spendtxidind = numexternaltxids++; - spendind++; - } - else printf("numexternaltxids.%d >= ramchain numexternaltxids.%d\n",numexternaltxids,ramchain->numexternaltxids); - } - } - // iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind; } iguana_Uextra { uint32_t spendind; } - // iguana_pkhash { uint8_t rmd160[20]; uint32_t firstunspentind,flags; } iguana_pkextra { uint32_t firstspendind; } - // iguana_account { uint64_t balance; uint32_t lastunspentind,lastspendind; } - // iguana_spend { uint32_t unspentind,prevspendind:31,diffsequence:1; } - numspends += item->numspends; - } - } - //for (i=0; iP[i],*(long *)ramchain->P[i].rmd160); - //printf("numpkinds.%d\n",numpkinds); - if ( 0 ) - { - memcpy(&ramchain->P[numpkinds],ramchain->pkextras,sizeof(*ramchain->pkextras) * numpkinds); - ramchain->pkextras = (void *)&ramchain->P[numpkinds]; - memcpy(&ramchain->pkextras[numpkinds],ramchain->accounts,sizeof(*ramchain->accounts) * numpkinds); - ramchain->accounts = (void *)&ramchain->pkextras[numpkinds]; - memcpy(&ramchain->accounts[numpkinds],ramchain->externalT,sizeof(*ramchain->externalT) * numexternaltxids); - ramchain->externalT = (void *)&ramchain->accounts[numpkinds]; - } - ramchain->allocsize -= ((ramchain->numpkinds - numpkinds) * (sizeof(*ramchain->P) + sizeof(*ramchain->pkextras) + sizeof(*ramchain->accounts))); - ramchain->allocsize -= ((ramchain->numexternaltxids - numexternaltxids) * sizeof(*ramchain->externalT)); - ramchain->numpkinds = numpkinds; - ramchain->numexternaltxids = numexternaltxids;*/ - /*vupdate_sha256(ramchain->lhashes[IGUANA_LHASH_UNSPENT].bytes,&ramchain->states[IGUANA_LHASH_UNSPENT],(void *)ramchain->U,sizeof(*ramchain->U)*ramchain->numunspents); - vupdate_sha256(ramchain->lhashes[IGUANA_LHASH_ACCOUNTS].bytes,&ramchain->states[IGUANA_LHASH_ACCOUNTS],(void *)acct,sizeof(*acct)); - vupdate_sha256(ramchain->lhashes[IGUANA_LHASH_SPENDS].bytes,&ramchain->states[IGUANA_LHASH_SPENDS],(void *)ramchain->S,sizeof(*ramchain->S)*); - vupdate_sha256(ramchain->lhashes[IGUANA_LHASH_TXIDS].bytes,&ramchain->states[IGUANA_LHASH_TXIDS],(void *)tx,sizeof(*tx));*/ - /*mem->used = (long)ramchain->allocsize; - printf("B.%d T.%d U.%d S.%d P.%d combined ramchain size.%ld\n",ramchain->numblocks,ramchain->numtxids,ramchain->numunspents,ramchain->numspends,ramchain->numpkinds,(long)ramchain->allocsize); - return(ramchain);*/ - return(0); - } - - /* - //if ( num > coin->chain->bundlesize+1 ) - // num = coin->chain->bundlesize+1; - for (i=1; i 0 ) - { - if ( (block= iguana_blockhashset(coin,-1,blockhashes[i],1)) != 0 && prev != 0 ) - { - //if ( prev->mainchain == 0 ) - // prev->hh.next = block; - /*if ( prev->hh.next == 0 && block->hh.prev == 0 ) - block->hh.prev = prev; - else if ( prev->hh.next == 0 && block->hh.prev == prev ) - prev->hh.next = block; - else if ( prev->hh.next == block && block->hh.prev == prev ) - { - if ( 0 && i < coin->chain->bundlesize ) - { - if ( iguana_bundlehash2add(coin,0,bp,i,blockhashes[i]) < 0 ) - { - if ( prev->mainchain == 0 ) - block->hh.prev = prev->hh.next = 0; - memset(bp->hashes[i].bytes,0,sizeof(bp->hashes[i])); - } - } - else if ( 0 && bp->bundleheight + coin->chain->bundlesize >= coin->bundlescount*coin->chain->bundlesize ) - { - char str[65]; printf("AUTOCREATE.%d new bundle.%s\n",bp->bundleheight + coin->chain->bundlesize,bits256_str(str,blockhashes[i])); - iguana_bundlecreate(coin,&bundlei,bp->bundleheight + coin->chain->bundlesize,blockhashes[i]); - for (j=2; jmainchain == 0 ) - block->hh.prev = prev->hh.next = 0; - } - //if ( (i % coin->chain->bundlesize) <= 1 ) - // iguana_blockQ(coin,0,-1,blockhashes[i],1); - //else //if ( bp != 0 && i < bp->n && bp->requests[i] == 0 ) - // iguana_blockQ(coin,0,-1,blockhashes[i],0); - } - prev = block; - }*/ - - int32_t iguana_ROmapchain(uint32_t *numtxidsp,uint32_t *numunspentsp,uint32_t *numspendsp,uint32_t *numpkindsp,uint32_t *numexternaltxidsp,struct iguana_ramchain *mapchain,void *ptr,long filesize,long fpos,bits256 firsthash2,bits256 lasthash2,int32_t height,int32_t numblocks,int32_t hdrsi,int32_t bundlei) - { - int32_t firsti = 1; - mapchain->fileptr = ptr; - mapchain->filesize = filesize; - mapchain->H.data = (void *)((long)ptr + fpos); - mapchain->H.ROflag = 1; - if ( iguana_ramchain_size(mapchain) != mapchain->H.data->allocsize || fpos+mapchain->H.data->allocsize > filesize ) - { - printf("iguana_bundlesaveHT size mismatch %ld vs %ld vs filesize.%ld\n",(long)iguana_ramchain_size(mapchain),(long)mapchain->H.data->allocsize,(long)filesize); - return(-1); - } - else if ( memcmp(firsthash2.bytes,mapchain->H.data->firsthash2.bytes,sizeof(bits256)) != 0 ) - { - char str[65],str2[65]; printf("iguana_bundlesaveHT hash2 mismatch %s vs %s\n",bits256_str(str,firsthash2),bits256_str(str2,mapchain->H.data->firsthash2)); - return(-1); - } - iguana_ramchain_link(mapchain,firsthash2,lasthash2,hdrsi,height,bundlei,1,firsti,1); - *numtxidsp += mapchain->H.data->numtxids; - *numunspentsp += mapchain->H.data->numunspents; - *numspendsp += mapchain->H.data->numspends; - if( mapchain->H.data->numpkinds != 0 ) - *numpkindsp += mapchain->H.data->numpkinds; - else *numpkindsp += mapchain->H.data->numunspents; - if( mapchain->H.data->numexternaltxids != 0 ) - *numexternaltxidsp += mapchain->H.data->numspends; - else *numexternaltxidsp += mapchain->H.data->numspends; - //printf("(%d %d %d) ",numtxids,numunspents,numspends); - //printf("%d ",numtxids); - return(0); - } - - bits256 iguana_lhashcalc(struct iguana_info *coin,struct iguana_ramchaindata *rdata,RAMCHAIN_FUNC) - { - bits256 sha256; - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_TXIDS].bytes,(uint8_t *)T,sizeof(struct iguana_txid)*rdata->numtxids); - if ( ramchain->expanded != 0 ) - { - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_UNSPENTS].bytes,(uint8_t *)Ux,sizeof(struct iguana_unspent)*rdata->numunspents); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_SPENDS].bytes,(uint8_t *)Sx,sizeof(struct iguana_spend)*rdata->numspends); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_PKHASHES].bytes,(uint8_t *)P,sizeof(struct iguana_pkhash)*rdata->numpkinds); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_SPENTINDS].bytes,(uint8_t *)U2,sizeof(struct iguana_Uextra)*rdata->numunspents); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_FIRSTSPENDS].bytes,(uint8_t *)P2,sizeof(struct iguana_pkextra)*rdata->numpkinds); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_ACCOUNTS].bytes,(uint8_t *)A,sizeof(struct iguana_account)*rdata->numpkinds); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_EXTERNALS].bytes,(uint8_t *)X,sizeof(bits256)*rdata->numexternaltxids); - } - else - { - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_UNSPENTS].bytes,(uint8_t *)U,sizeof(struct iguana_unspent20)*rdata->numunspents); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_SPENDS].bytes,(uint8_t *)S,sizeof(struct iguana_spend256)*rdata->numspends); - } - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_TXBITS].bytes,TXbits,(int32_t)hconv_bitlen(rdata->numtxsparse*rdata->txsparsebits)); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_PKBITS].bytes,PKbits,(int32_t)hconv_bitlen(rdata->numpksparse*rdata->pksparsebits)); - memset(&rdata->sha256,0,sizeof(rdata->sha256)); - vcalc_sha256(0,sha256.bytes,(void *)rdata,sizeof(*rdata)); - } - - /*struct iguana_prevdep - { - double PoW; // yes I know this is not consensus safe, it is used only for approximations locally - uint64_t supply; - uint32_t numtxids,numunspents,numspends,numpkinds; - } __attribute__((packed)); - - struct iguanakv - { - char name[63],fname[512],threadsafe; FILE *fp; - portable_mutex_t KVmutex,MMlock,MMmutex; - void *HDDitems,*HDDitems2,*HDDitems3,**HDDitemsp,**HDDitems2p,**HDDitems3p; // linear array of HDDitems; - struct iguana_kvitem *hashtables[0x100]; // of HDDitems - struct iguana_mappedptr M,M2,M3; - struct iguana_memspace HASHPTRS;//,MEM; - double mult; - uint64_t updated; - int32_t keysize,keyoffset,RAMvaluesize,HDDvaluesize,valuesize2,valuesize3; - int32_t numkeys,dispflag,flags,incr,numitems,numvalid,maxitemind; - uint32_t iteruarg; int32_t iterarg; - uint8_t *space; - };*/ - rdata->txsparsebits = hcalc_bitsize(numtxids); - rdata->numtxsparse = SPARSECOUNT(numtxids); - rdata->pksparsebits = hcalc_bitsize(numpkinds); - rdata->numpksparse = SPARSECOUNT(numpkinds); - rdata->Toffset = offset, offset += (sizeof(struct iguana_txid) * numtxids); - if ( ramchain->expanded != 0 ) - { - rdata->Uoffset = offset, offset += (sizeof(struct iguana_unspent) * numunspents); - rdata->Soffset = offset, offset += (sizeof(struct iguana_spend) * numspends); - rdata->Poffset = offset, offset += (sizeof(struct iguana_pkhash) * numpkinds); - rdata->U2offset = offset, offset += (sizeof(struct iguana_Uextra) * numunspents); - rdata->P2offset = offset, offset += (sizeof(struct iguana_pkextra) * numpkinds); - rdata->Aoffset = offset, offset += (sizeof(struct iguana_account) * numpkinds); - rdata->Xoffset = offset, offset += (sizeof(bits256) * numexternaltxids); - } - else - { - rdata->Uoffset = offset, offset += (sizeof(struct iguana_unspent20) * numunspents); - rdata->Soffset = offset, offset += (sizeof(struct iguana_spend256) * numspends); - } - - rdata->TXoffset = offset, offset += (((int64_t)rdata->numtxsparse*rdata->txsparsebits)/8 + 1); - rdata->PKoffset = offset, offset += (((int64_t)rdata->numpksparse*rdata->pksparsebits)/8 + 1); - - - tmp = *rdata; - fpos = ftell(fp); - iguana_rdata_action(0,0,&trunc,0,rdata,expanded,numtxids,numunspents,numspends,numpkinds,numexternaltxids,0,0,0,0); - - offset = sizeof(*rdata); - rdata->Toffset = offset, offset += (sizeof(struct iguana_txid) * rdata->numtxids); - if ( ramchain->expanded != 0 ) - { - rdata->Uoffset = offset, offset += (sizeof(struct iguana_unspent) * rdata->numunspents); - rdata->Soffset = offset, offset += (sizeof(struct iguana_spend) * rdata->numspends); - rdata->Poffset = offset, offset += (sizeof(struct iguana_pkhash) * rdata->numpkinds); - rdata->U2offset = offset, offset += (sizeof(struct iguana_Uextra) * rdata->numunspents); - rdata->P2offset = offset, offset += (sizeof(struct iguana_pkextra) * rdata->numpkinds); - rdata->Aoffset = offset, offset += (sizeof(struct iguana_account) * rdata->numpkinds); - rdata->Xoffset = offset, offset += (sizeof(bits256) * rdata->numexternaltxids); - } - else - { - rdata->Uoffset = offset, offset += (sizeof(struct iguana_unspent20) * rdata->numunspents); - rdata->Soffset = offset, offset += (sizeof(struct iguana_spend256) * rdata->numspends); - } - rdata->TXoffset = offset, offset += (((int64_t)rdata->numtxsparse*rdata->txsparsebits)/8 + 1); - rdata->PKoffset = offset, offset += (((int64_t)rdata->numpksparse*rdata->pksparsebits)/8 + 1); - rdata->allocsize = offset; - rdata->sha256 = iguana_lhashcalc(coin,rdata,RAMCHAIN_ARGS); - if ( iguana_ramchain_size(ramchain) != offset ) - printf("iguana_ramchain_size %ld vs %ld\n",(long)iguana_ramchain_size(ramchain),(long)offset), getchar(); - rdata->sha256 = sha256 = iguana_lhashcalc(coin,rdata,RAMCHAIN_ARG); - fwrite(rdata,1,sizeof(*rdata),fp); - *rdata = tmp; - fwrite(T,sizeof(struct iguana_txid),rdata->numtxids,fp); - if ( ramchain->expanded != 0 ) - { - fwrite(Ux,sizeof(struct iguana_unspent),rdata->numunspents,fp); - fwrite(Sx,sizeof(struct iguana_spend),rdata->numspends,fp); - fwrite(P,sizeof(struct iguana_pkhash),rdata->numpkinds,fp); - fwrite(U2,sizeof(struct iguana_Uextra),rdata->numunspents,fp); - fwrite(P2,sizeof(struct iguana_pkextra),rdata->numpkinds,fp); - fwrite(A,sizeof(struct iguana_account),rdata->numpkinds,fp); - fwrite(X,sizeof(bits256),rdata->numexternaltxids,fp); - //printf("iguana_ramchain_save.(%s): (%ld - %ld) diff.%ld vs %ld [%ld]\n",fname,ftell(fp),(long)fpos,(long)(ftell(fp) - fpos),(long)rdata->allocsize,(long)(ftell(fp) - fpos) - (long)rdata->allocsize); - } - else - { - fwrite(U,sizeof(struct iguana_unspent20),rdata->numunspents,fp); - fwrite(S,sizeof(struct iguana_spend256),rdata->numspends,fp); - } - fwrite(TXbits,1,((int64_t)rdata->numtxsparse*rdata->txsparsebits)/8 + 1,fp); - fwrite(PKbits,1,((int64_t)rdata->numpksparse*rdata->pksparsebits)/8 + 1,fp); - if ( (ftell(fp) - fpos) != rdata->allocsize ) - { - printf("(ftell.%ld - fpos.%ld) %ld vs %ld\n",ftell(fp),fpos,ftell(fp)-fpos,(long)rdata->allocsize); - fpos = -1; - } - //int32_t i; char str[65]; - //for (i=0; inumexternaltxids; i++) - // printf("X[%d] %s\n",i,bits256_str(str,X[i])); - uint32_t iguana_updatescript(struct iguana_info *coin,uint32_t blocknum,uint32_t txidind,uint32_t spendind,uint32_t unspentind,uint64_t value,uint8_t *script,int32_t scriptlen,uint32_t sequence) - { - return(0); - } - - function httpGet(theUrl)\ - {\ - var xmlhttp;\ - if ( window.XMLHttpRequest )\ - xmlhttp = new XMLHttpRequest();\ - else\ - xmlhttp = new ActiveXObject(\"Microsoft.XMLHTTP\");\ - xmlhttp.onreadystatechange = function()\ - {\ - if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 )\ - {\ - createDiv(xmlhttp.responseText);\ - }\ - }\ - xmlhttp.open(\"GET\", theUrl, false);\ - xmlhttp.send(null);\ - }\ - var jsonstr = httpGet(\"http://127.0.0.1:7778/json/bitmap\"); \ - struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundlereq *req,struct iguana_block *origblock,int32_t numtx,int32_t datalen,int32_t recvlen,int32_t *newhwmp) - { - struct iguana_bundle *bp=0; int32_t bundlei = -2; struct iguana_block *block; double duration; - bp = iguana_bundleset(coin,&block,&bundlei,origblock); - if ( block != 0 ) - { - block->RO.recvlen = recvlen; - block->ipbits = req->ipbits; - if ( bp == 0 && req->copyflag != 0 && block->rawdata == 0 ) - { - char str[65]; printf("%s copyflag.%d %d data %d %p\n",bits256_str(str,block->RO.hash2),req->copyflag,block->height,req->recvlen,bp); - block->rawdata = mycalloc('n',1,block->RO.recvlen); - memcpy(block->rawdata,req->serialized,block->RO.recvlen); - block->copyflag = 1; - } - //printf("datalen.%d ipbits.%x\n",datalen,req->ipbits); - } else printf("cant create block.%llx block.%p bp.%p bundlei.%d\n",(long long)origblock->RO.hash2.txid,block,bp,bundlei); - if ( bp != 0 && bundlei >= 0 ) - { - //bp->ipbits[bundlei] = block->ipbits; - if ( 0 && bp->requests[bundlei] > 2 ) - printf("recv bundlei.%d hdrs.%d reqs.[%d] fpos.%d datalen.%d recvlen.(%d %d) ipbits.(%x %x %x)\n",bundlei,bp->hdrsi,bp->requests[bundlei],bp->fpos[bundlei],datalen,block->RO.recvlen,req->recvlen,block->ipbits,bp->ipbits[bundlei],req->ipbits); - if ( recvlen > 0 ) - { - SETBIT(bp->recv,bundlei); - if ( bp->issued[bundlei] > 0 ) - { - bp->durationsum += (int32_t)(time(NULL) - bp->issued[bundlei]); - bp->durationcount++; - if ( duration < bp->avetime/10. ) - duration = bp->avetime/10.; - else if ( duration > bp->avetime*10. ) - duration = bp->avetime * 10.; - dxblend(&bp->avetime,duration,.99); - dxblend(&coin->avetime,bp->avetime,.9); - } - } - if ( 0 && strcmp(coin->symbol,"BTC") != 0 && bundlei < coin->chain->bundlesize-1 && bits256_nonz(bp->hashes[bundlei+1]) != 0 && bp->fpos[bundlei+1] < 0 ) - iguana_blockQ(coin,bp,bundlei+1,bp->hashes[bundlei+1],0); - } - if ( 0 && block != 0 && strcmp(coin->symbol,"BTC") != 0 ) - { - if ( (bp = iguana_bundlefind(coin,&bp,&bundlei,block->RO.prev_block)) != 0 ) - { - if ( bp->fpos[bundlei] < 0 ) - iguana_blockQ(coin,bp,bundlei,block->RO.prev_block,0); - } - } - return(req); - } - struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_block **blockp,int32_t *bundleip,struct iguana_block *origblock) - { - struct iguana_block *block; bits256 zero,*hashes; struct iguana_bundle *bp = 0; - int32_t bundlei = -2; - *bundleip = -2; *blockp = 0; - if ( origblock == 0 ) - return(0); - memset(zero.bytes,0,sizeof(zero)); - if ( (block= iguana_blockhashset(coin,-1,origblock->RO.hash2,1)) != 0 ) - { - if ( block != origblock ) - iguana_blockcopy(coin,block,origblock); - *blockp = block; - if ( bits256_nonz(block->RO.prev_block) > 0 ) - iguana_patch(coin,block); - if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,block->RO.hash2)) != 0 ) - { - if ( bundlei < coin->chain->bundlesize ) - { - block->bundlei = bundlei; - block->hdrsi = bp->hdrsi; - //iguana_hash2set(coin,"blockadd",bp,block->bundlei,block->hash2); - iguana_bundlehash2add(coin,0,bp,bundlei,block->RO.hash2); - if ( bundlei == 0 ) - { - if ( bp->hdrsi > 0 && (bp= coin->bundles[bp->hdrsi-1]) != 0 ) - { - //printf("add to prev hdrs.%d\n",bp->hdrsi); - iguana_bundlehash2add(coin,0,bp,coin->chain->bundlesize-1,block->RO.prev_block); - if ( 0 && bp->fpos[coin->chain->bundlesize-1] < 0 && strcmp(coin->symbol,"BTC") != 0 ) - iguana_blockQ(coin,bp,coin->chain->bundlesize-1,block->RO.prev_block,0); - } - } - else - { - //printf("prev issue.%d\n",bp->bundleheight+bundlei-1); - iguana_bundlehash2add(coin,0,bp,bundlei-1,block->RO.prev_block); - if ( 0 && bp->fpos[bundlei-1] < 0 && strcmp(coin->symbol,"BTC") != 0 ) - iguana_blockQ(coin,bp,bundlei-1,block->RO.prev_block,0); - } - } - } - if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,block->RO.prev_block)) != 0 ) - { - //printf("found prev.%d\n",bp->bundleheight+bundlei); - if ( bundlei < coin->chain->bundlesize ) - { - if ( bundlei == coin->chain->bundlesize-1 ) - { - if ( coin->bundlescount < bp->hdrsi+1 ) - { - char str[65]; printf("autoextend CREATE.%d new bundle.%s\n",bp->bundleheight + coin->chain->bundlesize,bits256_str(str,block->RO.hash2)); - iguana_bundlecreate(coin,&bundlei,bp->bundleheight + coin->chain->bundlesize,block->RO.hash2,zero); - } - } - else if ( bundlei < coin->chain->bundlesize-1 ) - { - block->bundlei = bundlei + 1; - block->hdrsi = bp->hdrsi; - iguana_bundlehash2add(coin,0,bp,bundlei+1,block->RO.hash2); - } - } - } - //char str[65]; printf("iguana_recvblock (%s) %d %d[%d] %p\n",bits256_str(str,block->hash2),block->havebundle,block->hdrsi,bundlei,bp); - } - return(iguana_bundlefind(coin,&bp,bundleip,origblock->RO.hash2)); - } - int32_t iguana_bundlemode(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei) - { - if ( bp->ipbits[bundlei] == 0 ) - return(-1); - else if ( bp->emitfinish > coin->starttime ) - { - if ( bp->ramchain.numblocks == bp->n ) - return(1); - else return(2); - } - else return(0); - } - - - /*char *iguana_genericjsonstr(char *jsonstr,char *remoteaddr) - { - cJSON *json; char *retjsonstr,*methodstr,*agentstr; - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - if ( (agentstr= jstr(json,"agent")) == 0 ) - agentstr = "SuperNET"; - if ( (methodstr= jstr(json,"method")) != 0 ) - retjsonstr = iguana_agentjson(agentstr,0,methodstr,json,remoteaddr); - else retjsonstr = clonestr("{\"error\":\"no method in generic JSON\"}"); - free_json(json); - } else retjsonstr = clonestr("{\"error\":\"cant parse generic JSON\"}"); - return(retjsonstr); - }*/ - - char *iguana_remoteparser(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json) - { - int32_t i,n,remains,numsent; char *jsonstr = 0,*retstr = 0; uint8_t hdr[128]; - if ( agent->sock < 0 ) - agent->sock = iguana_socket(0,agent->hostname,agent->port); - if ( agent->sock >= 0 ) - { - i = 0; - jsonstr = jprint(json,0); - n = (int32_t)strlen(jsonstr) + 1; - remains = n; - //printf("RETBUF.(%s)\n",retbuf); - while ( remains > 0 ) - { - if ( (numsent= (int32_t)send(agent->sock,&jsonstr[i],remains,MSG_NOSIGNAL)) < 0 ) - { - if ( errno != EAGAIN && errno != EWOULDBLOCK ) - { - printf("%s: %s numsent.%d vs remains.%d of %d errno.%d (%s) usock.%d\n",jsonstr,agent->name,numsent,remains,n,errno,strerror(errno),agent->sock); - break; - } - } - else if ( remains > 0 ) - { - remains -= numsent; - i += numsent; - if ( remains > 0 ) - printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,n); - } - } - if ( (n= (int32_t)recv(agent->sock,hdr,sizeof(hdr),0)) >= 0 ) - { - remains = (hdr[0] + ((int32_t)hdr[1] << 8) + ((int32_t)hdr[2] << 16)); - retstr = mycalloc('p',1,remains + 1); - i = 0; - while ( remains > 0 ) - { - if ( (n= (int32_t)recv(agent->sock,&retstr[i],remains,0)) < 0 ) - { - if ( errno == EAGAIN ) - { - printf("EAGAIN for len %d, remains.%d\n",n,remains); - usleep(10000); - } - break; - } - else - { - if ( n > 0 ) - { - remains -= n; - i += n; - } else usleep(10000); - } - } - } - free(jsonstr); - } - if ( retstr == 0 ) - retstr = clonestr("{\"error\":\"null return\"}"); - return(retstr); - } - - struct iguana_agent *Agents[16]; - - cJSON *iguana_agentinfojson(struct iguana_agent *agent) - { - cJSON *json= cJSON_CreateObject(); - jaddstr(json,"name",agent->name); - jadd(json,"methods",agent->methods); - if ( agent->port != 0 ) - jaddnum(json,"port",agent->port); - else jaddstr(json,"type","builtin"); - return(json); - } - - char *iguana_addagent(char *name,char *(*parsefunc)(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json),char *hostname,cJSON *methods,uint16_t port,char *pubkeystr,char *privkeystr) - { - int32_t i; struct iguana_agent *agent; char retbuf[8192]; - for (i=0; iname,name) == 0 ) - { - if ( pubkeystr != 0 && privkeystr != 0 && strlen(pubkeystr) == 64 && strlen(privkeystr) == 64 ) - { - decode_hex(agent->pubkey.bytes,sizeof(bits256),pubkeystr); - decode_hex(agent->privkey.bytes,sizeof(bits256),privkeystr); - } - if ( port != 0 && agent->port == 0 ) - { - if ( agent->sock >= 0 ) - close(agent->sock); - agent->port = port; - strcpy(agent->hostname,hostname); - agent->sock = iguana_socket(0,agent->hostname,port); - printf("set (%s) port.%d for %s -> sock.%d\n",hostname,port,agent->name,agent->sock); - } - if ( agent->port > 0 && agent->sock < 0 && agent->hostname[0] != 0 && (agent->sock= iguana_socket(0,agent->hostname,agent->port)) < 0 ) - return(clonestr("{\"result\":\"existing agent couldnt connect to remote agent\"}")); - else return(clonestr("{\"result\":\"agent already there\"}")); - } - } - for (i=0; iname,name,sizeof(agent->name)-1); - strncpy(agent->hostname,hostname,sizeof(agent->hostname)-1); - agent->methods = methods, agent->nummethods = cJSON_GetArraySize(methods); - agent->sock = -1; - agent->port = port; - agent->parsefunc = (void *)parsefunc; - if ( pubkeystr != 0 && privkeystr != 0 && strlen(pubkeystr) == 64 && strlen(privkeystr) == 64 ) - { - decode_hex(agent->pubkey.bytes,sizeof(bits256),pubkeystr); - decode_hex(agent->privkey.bytes,sizeof(bits256),privkeystr); - } - if ( port > 0 ) - { - if ( (agent->sock= iguana_socket(0,hostname,port)) < 0 ) - return(clonestr("{\"result\":\"agent added, but couldnt connect to remote agent\"}")); - } - sprintf(retbuf,"{\"result\":\"agent added\",\"name\":\"%s\",\"methods\":%s,\"hostname\":\"%s\",\"port\":%u,\"sock\":%d}",agent->name,jprint(agent->methods,0),agent->hostname,agent->port,agent->sock); - return(clonestr(retbuf)); - } - } - return(clonestr("{\"error\":\"no more agent slots available\"}")); - } - else if ( strcmp(method,"addagent") == 0 ) - { - char *hostname = "127.0.0.1",*name; uint16_t port; - if ( (name= jstr(json,"name")) != 0 && (methods= jarray(&n,json,"methods")) != 0 ) - { - if ( (port= juint(json,"port")) != 0 ) - { - if ( (hostname= jstr(json,"host")) == 0 ) - { - if ( (hostname= jstr(json,"ipaddr")) == 0 ) - hostname = "127.0.0.1"; - } - if ( hostname == 0 ) - return(clonestr("{\"error\":\"no host specified for remote agent\"}")); - } - else if ( strcmp(name,"pangea") != 0 && strcmp(name,"InstantDEX") != 0 && strcmp(name,"jumblr") != 0 ) - return(clonestr("{\"error\":\"no port specified for remote agent\"}")); - return(iguana_addagent(name,iguana_remoteparser,hostname,methods,port,jstr(json,"pubkey"),jstr(json,"privkey"))); - } else return(clonestr("{\"error\":\"cant addagent without name and methods\"}")); - } - if ( (retstr= iguana_addagent("ramchain",ramchain_parser,"127.0.0.1",cJSON_Parse("[\"block\", \"tx\", \"txs\", \"rawtx\", \"balance\", \"totalreceived\", \"totalsent\", \"utxo\", \"status\"]"),0,0,0)) != 0 ) - printf("%s\n",retstr), free(retstr); - - - /*void iguana_issuejsonstrM(void *arg) - { - cJSON *json; int32_t fd; char *retjsonstr,*jsonstr = arg; - retjsonstr = iguana_JSON(jsonstr); - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - if ( (fd= juint(json,"retdest")) > 0 ) - { - send(fd,jsonstr,(int32_t)strlen(jsonstr)+1,MSG_NOSIGNAL); - } - free_json(json); - return; - } - printf("%s\n",retjsonstr); - free(retjsonstr);//,strlen(retjsonstr)+1); - free(jsonstr);//,strlen(jsonstr)+1); - }*/ - - int32_t iguana_rpctestvector(struct iguana_info *coin,char *checkstr,char *jsonstr,int32_t maxlen,int32_t testi) - { - int32_t len,checklen; - sprintf(jsonstr,"{\"rpc.%s testvector.%d\"}",coin->symbol,testi); - sprintf(checkstr,"{\"rpc.%s testvector.%d checkstr should have all info needed to verify the rpc request\"}",coin->symbol,testi); - len = (int32_t)strlen(jsonstr); - checklen = (int32_t)strlen(checkstr); - if ( len > maxlen || checklen > maxlen ) - printf("iguana_rpctestvector: i was bad and overflowed buffer len.%d checklen.%d\n",len,checklen), exit(-1); - if ( checklen > len ) - len = checklen; - return(len); - } - - int32_t iguana_rpctestcheck(struct iguana_info *coin,char *jsonstr,char *retjsonstr) - { - if ( (rand() % 100) == 0 ) // 1% failure rate - return(-1); - else return(0); - } - - int32_t iguana_rpctest(struct iguana_info *coin) - { - /* static int32_t testi,good,bad; - char *retjsonstr,jsonstr[4096],checkstr[sizeof(jsonstr)]; // should be big enough - //if ( (rand() % 1000) < 999 ) // if no test active, just return 0 - return(0); - if ( iguana_rpctestvector(coin,checkstr,jsonstr,sizeof(jsonstr),testi++) > 0 ) - { - retjsonstr = iguana_rpc(coin,jsonstr); - if ( iguana_rpctestcheck(coin,jsonstr,retjsonstr) < 0 ) - bad++, printf("rpctestcheck.%s error: (%s) -> (%s) | good.%d bad.%d %.2f%%\n",coin->symbol,jsonstr,retjsonstr,good,bad,100.*(double)good/(good+bad)); - else good++; - free(retjsonstr); - return(1); // indicates was active - }*/ - return(0); - } - - char *iguana_agentjson(char *name,struct iguana_info *coin,char *method,cJSON *json,char *remoteaddr) - { - cJSON *retjson = 0,*array,*methods,*obj; int32_t i,n,j; struct iguana_agent *agent; - if ( strcmp(name,"SuperNET") != 0 ) - { - for (i=0; iname,name) == 0 ) - { - if ( agent->parsefunc != 0 ) - { - for (j=0; jnummethods; j++) - { - if ( (obj= jitem(agent->methods,j)) != 0 ) - { - if ( strcmp(method,jstr(obj,0)) == 0 ) - return((*agent->parsefunc)(agent,method,json,remoteaddr)); - } - } - return(clonestr("{\"result\":\"agent doesnt have method\"}")); - } else return(clonestr("{\"result\":\"agent doesnt have parsefunc\"}")); - } - } - } - else if ( remoteaddr == 0 || strcmp(remoteaddr,"127.0.0.1") != 0 ) // public api - { - char *coinstr; int32_t j,k,l,r,rr; struct iguana_peer *addr; - array = 0; - if ( strcmp(method,"getpeers") == 0 ) - { - if ( (coinstr= jstr(json,"coin")) != 0 ) - { - if ( (array= iguana_peersjson(iguana_coinfind(coinstr),1)) == 0 ) - return(clonestr("{\"error\":\"coin not found\"}")); - } - else - { - n = 0; - array = cJSON_CreateArray(); - r = rand(); - for (i=0; ipeers.active[l]; - if ( addr->usock >= 0 && addr->supernet != 0 ) - { - jaddistr(array,addr->ipaddr); - if ( ++n >= 64 ) - break; - } - } - } - } - } - if ( array != 0 ) - { - retjson = cJSON_CreateObject(); - jaddstr(retjson,"agent","SuperNET"); - jaddstr(retjson,"method","mypeers"); - jaddstr(retjson,"result","peers found"); - jadd(retjson,"peers",array); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"no peers found\"}")); - } - else if ( strcmp(method,"mypeers") == 0 ) - { - printf("mypeers from %s\n",remoteaddr!=0?remoteaddr:"local"); - } - } - else // local api - { - if ( strcmp(method,"list") == 0 ) - { - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - for (i=0; isymbol[0] != 0 ) - jaddistr(array,Coins[i]->symbol); - } - jadd(retjson,"coins",array); - array = cJSON_CreateArray(); - for (i=0; iname[0] != 0 ) - jaddi(array,iguana_agentinfojson(Agents[i])); - } - jadd(retjson,"agents",array); - return(jprint(retjson,1)); - } - else if ( strcmp(method,"peers") == 0 ) - { - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - for (i=0; isymbol[0] != 0 ) - jaddi(array,iguana_peersjson(Coins[i],0)); - } - jadd(retjson,"allpeers",array); - return(jprint(retjson,1)); - } - } - return(clonestr("{\"result\":\"stub processed generic json\"}")); - } - - char *iguana_jsonstr(struct iguana_info *coin,char *jsonstr,char *remoteaddr) - { - cJSON *json; char *retjsonstr,*methodstr,*agentstr; - //printf("iguana_jsonstr.(%s)\n",jsonstr); - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - if ( (methodstr= jstr(json,"method")) != 0 ) - { - if ( (agentstr= jstr(json,"agent")) == 0 || strcmp(agentstr,"iguana") == 0 ) - retjsonstr = iguana_coinjson(coin,methodstr,json); - else retjsonstr = iguana_agentjson(agentstr,coin,methodstr,json,remoteaddr); - } else retjsonstr = clonestr("{\"error\":\"no method in JSON\"}"); - free_json(json); - } else retjsonstr = clonestr("{\"error\":\"cant parse JSON\"}"); - printf("iguana_jsonstr.(%s)\n",retjsonstr); - return(retjsonstr); - } - char *iguana_htmlget(char *space,int32_t max,int32_t *jsonflagp,char *path,char *remoteaddr,int32_t localaccess) - { - char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json); - struct iguana_info *coin = 0; cJSON *json; bits256 hash2; int32_t height,i; - char buf[64],jsonstr[1024],coinstr[64],*retstr; - for (i=0; path[i]!=0; i++) - if ( path[i] == ' ' ) - break; - path[i] = 0; - if ( path[strlen(path)-1] == '/' ) - path[strlen(path)-1] = 0; - if ( strncmp(path,"/api",strlen("/api")) == 0 ) - { - *jsonflagp = 1; - path += strlen("/api"); - } else *jsonflagp = 0; - iguana_coinset(coinstr,path); - if ( coinstr[0] != 0 ) - coin = iguana_coinfind(coinstr); - else coin = 0; - if ( strncmp(path,"/bitmap",strlen("/bitmap")) == 0 ) - { - path += strlen("/bitmap"); - *jsonflagp = 2; - iguana_bitmap(space,max,path); - return(space); - } - //printf("GETCHECK.(%s)\n",path); - if ( strncmp(path,"/ramchain/",strlen("/ramchain/")) == 0 ) - { - path += strlen("/ramchain/"); - if ( strncmp(path,"block/",strlen("block/")) == 0 ) - { - path += strlen("block/"); - if ( strncmp(path,"height/",strlen("height/")) == 0 ) - { - height = atoi(path + strlen("height/")); - sprintf(Currentjsonstr,"{\"agent\":\"ramchain\",\"method\":\"block\",\"coin\":\"%s\",\"height\":%d,\"txids\":1}",coinstr,height); - return(iguana_ramchain_glue(coin,"block",Currentjsonstr)); - } - else if ( strncmp(path,"hash/",strlen("hash/")) == 0 ) - { - decode_hex(hash2.bytes,sizeof(hash2),path + strlen("hash/")); - char str[65]; printf("ramchain blockhash.%s\n",bits256_str(str,hash2)); - sprintf(Currentjsonstr,"{\"agent\":\"ramchain\",\"method\":\"block\",\"coin\":\"%s\",\"hash\":\"%s\",\"txids\":1}",coinstr,str); - return(iguana_ramchain_glue(coin,"block",Currentjsonstr)); - } - } - else if ( strncmp(path,"txid/",strlen("txid/")) == 0 ) - { - decode_hex(hash2.bytes,sizeof(hash2),path + strlen("txid/")); - char str[65]; bits256_str(str,hash2); - sprintf(Currentjsonstr,"{\"agent\":\"ramchain\",\"method\":\"tx\",\"coin\":\"%s\",\"txid\":\"%s\"}",coinstr,str); - return(iguana_ramchain_glue(coin,"tx",Currentjsonstr)); - } - else if ( strncmp(path,"explore/",strlen("explore/")) == 0 ) - { - path += strlen("explore/"); - if ( coin != 0 ) - { - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"explore\",\"coin\":\"%s\",\"search\":\"%s\"}",coinstr,path); - } else sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"explore\",\"search\":\"%s\"}",path); - return(iguana_ramchain_glue(coin,"explore",Currentjsonstr)); - } - else if ( strncmp(path,"bundleinfo/",strlen("bundleinfo/")) == 0 ) - { - path += strlen("bundleinfo/"); - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"bundleinfo\",\"coin\":\"%s\",\"height\":%d}",coinstr,atoi(path)); - - } - else - { - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"%s\",\"coin\":\"%s\"}",path,coinstr); - return(iguana_ramchain_glue(coin,path,Currentjsonstr)); - } - } - else if ( strncmp(path,"/hash/",strlen("/hash/")) == 0 ) - { - path += strlen("/hash/"); - return(iguana_hashparse(path)); - } - else if ( strncmp(path,"/iguana/",strlen("/iguana/")) == 0 ) - { - strcpy(Currentjsonstr,path); - path += strlen("/iguana/"); - if ( strncmp(path,"setagent/",strlen("setagent/")) == 0 ) - { - path += strlen("setagent/"); - if ( strncmp(path,"ramchain",strlen("ramchain")) == 0 || strncmp(path,"iguana",strlen("iguana")) == 0 || strncmp(path,"InstantDEX",strlen("InstantDEX")) == 0 || strncmp(path,"pangea",strlen("pangea")) == 0 || strncmp(path,"PAX",strlen("PAX")) == 0 || strncmp(path,"ALL",strlen("ALL")) == 0 || strncmp(path,"jumblr",strlen("jumblr")) == 0 ) - { - if ( strncmp(Default_agent,path,strlen(path)) == 0 ) - { - strcpy(Default_agent,"ALL"); - return(clonestr("{\"result\":\"ALL agents selected\"}")); - } - strcpy(Default_agent,path); - if ( Default_agent[strlen(Default_agent)-1] == '/' ) - Default_agent[strlen(Default_agent)-1] = 0; - sprintf(buf,"{\"result\":\"agent selected\",\"name\":\"%s\"}",path); - return(clonestr(buf)); - } - return(clonestr("{\"error\":\"invalid agent specified\"}")); - } - else - { - if ( strncmp(path,"peers/",strlen("peers/")) == 0 ) - { - path += strlen("peers/"); - if ( coin != 0 ) - { - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"peers\",\"coin\":\"%s\"}",coinstr); - } else sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"peers\"}"); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"peers",json); - free_json(json); - return(retstr); - } - else if ( coin != 0 ) - { - if ( strncmp(path,"addnode/",strlen("addnode/")) == 0 ) - { - path += strlen("addnode/"); - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"addnode\",\"coin\":\"%s\",\"ipaddr\":\"%s\"}",coinstr,path); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"addnode",json); - free_json(json); - return(retstr); - } - else if ( strncmp(path,"nodestatus/",strlen("nodestatus/")) == 0 ) - { - path += strlen("nodestatus/"); - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"nodestatus\",\"coin\":\"%s\",\"ipaddr\":\"%s\"}",coinstr,path); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"nodestatus",json); - free_json(json); - return(retstr); - } - else if ( strncmp(path,"addcoin",strlen("addcoin")) == 0 ) - { - path += strlen("addcoin"); - iguana_coinset(buf,path); - if ( (coin= iguana_coinadd(buf)) != 0 ) - { - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"addcoin\",\"coin\":\"%s\"}",buf); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"addcoin",json); - free_json(json); - } - else retstr = clonestr("{\"error\":\"cant create coin\"}"); - return(retstr); - } - else if ( strncmp(path,"startcoin",strlen("startcoin")) == 0 ) - { - path += strlen("startcoin"); - iguana_coinset(buf,path); - if ( (coin= iguana_coinfind(buf)) != 0 ) - { - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"startcoin\",\"coin\":\"%s\"}",buf); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"startcoin",json); - free_json(json); - } - else retstr = clonestr("{\"error\":\"cant create coin\"}"); - return(retstr); - } - else if ( strncmp(path,"pausecoin",strlen("pausecoin")) == 0 ) - { - path += strlen("pausecoin"); - iguana_coinset(buf,path); - if ( (coin= iguana_coinfind(buf)) != 0 ) - { - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"pausecoin\",\"coin\":\"%s\"}",buf); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"pausecoin",json); - free_json(json); - } - else retstr = clonestr("{\"error\":\"cant create coin\"}"); - return(retstr); - } - else if ( strncmp(path,"maxpeers/",strlen("maxpeers/")) == 0 ) - { - path += strlen("maxpeers/"); - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"maxpeers\",\"coin\":\"%s\",\"max\":%d}",coinstr,atoi(path)); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"maxpeers",json); - free_json(json); - return(retstr); - } - return(clonestr("{\"result\":\"iguana method not found\"}")); - } - return(clonestr("{\"result\":\"iguana method needs coin\"}")); - } - } - else if ( strncmp(path,"/InstantDEX/",strlen("/InstantDEX/")) == 0 ) - { - double price,volume; char base[16],rel[16],exchange[16]; - path += strlen("/InstantDEX/"); - jsonstr[0] = 0; - if ( strncmp(path,"placebid/",strlen("placebid/")) == 0 ) - { - path += strlen("placebid/"); - if ( iguana_InstantDEX(jsonstr,path,"placebid") == 0 ) - return(clonestr("{\"error\":\"error with placebid parameters\"}")); - } - else if ( strncmp(path,"placeask/",strlen("placeask/")) == 0 ) - { - path += strlen("placeask/"); - if ( iguana_InstantDEX(jsonstr,path,"placeask") == 0 ) - return(clonestr("{\"error\":\"error with placeask parameters\"}")); - } - else if ( strncmp(path,"orderbook/",strlen("orderbook/")) == 0 ) - { - path += strlen("orderbook/"); - iguana_parsebidask(base,rel,exchange,&price,&volume,path); - if ( exchange[0] == 0 ) - strcpy(exchange,"active"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"orderbook\",\"base\":\"%s\",\"rel\":\"%s\",\"exchange\":\"%s\",\"allfields\":1}",base,rel,exchange); - } - else if ( strncmp(path,"orderstatus/",strlen("orderstatus/")) == 0 ) - { - path += strlen("orderstatus/"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"orderstatus\",\"orderid\":\"%s\"}",path); - } - else if ( strncmp(path,"cancelorder/",strlen("cancelorder/")) == 0 ) - { - path += strlen("cancelorder/"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"cancelorder\",\"orderid\":\"%s\"}",path); - } - else if ( strncmp(path,"balance/",strlen("balance/")) == 0 ) - { - path += strlen("balance/"); - iguana_parsebidask(base,rel,exchange,&price,&volume,path); - if ( path[0] != ' ' && path[0] != '/' ) - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"balance\",\"exchange\":\"%s\"}",path); - else sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"balance\"}"); - } - else if ( strncmp(path,"openorders",strlen("openorders")) == 0 ) - { - path += strlen("openorders"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"openorders\"}"); - } - else if ( strncmp(path,"tradehistory",strlen("tradehistory")) == 0 ) - { - path += strlen("tradehistory"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"tradehistory\"}"); - } - else if ( strncmp(path,"allorderbooks",strlen("allorderbooks")) == 0 ) - { - path += strlen("allorderbooks"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"allorderbooks\"}"); - } - else if ( strncmp(path,"allexchanges",strlen("allexchanges")) == 0 ) - { - path += strlen("allexchanges"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"allexchanges\"}"); - } - if ( jsonstr[0] != 0 ) - { - strcpy(Currentjsonstr,jsonstr); - return(clonestr(jsonstr)); - //return(InstantDEX(jsonstr,remoteaddr,localaccess)); - } - return(clonestr("{\"error\":\"unrecognized InstantDEX API call\"}")); - } - else if ( strncmp(path,"/pangea/",strlen("/pangea/")) == 0 ) - { - path += strlen("/pangea/"); - } - else if ( strncmp(path,"/jumblr/",strlen("/jumblr/")) == 0 ) - { - path += strlen("/jumblr/"); - } - else printf("no match to (%s)\n",path); - return(0); - } - - char *iguana_rpcparse(char *retbuf,int32_t bufsize,int32_t *postflagp,char *jsonstr) - { - cJSON *json = 0; int32_t i,n,localaccess,datalen,postflag = 0; - char *key,*reststr,*str,*retstr,remoteaddr[65],porturl[65],*data = 0,*value,*agent = "SuperNET"; - //printf("rpcparse.(%s)\n",jsonstr); - localaccess = 1; - if ( (str= strstr("Referer: ",jsonstr)) != 0 ) - { - for (i=0; str[i]!=' '&&str[i]!=0&&str[i]!='\n'&&str[i]!='\r'; i++) - remoteaddr[i] = str[i]; - remoteaddr[i] = 0; - } else strcpy(remoteaddr,"127.0.0.1"); // need to verify this - *postflagp = 0; - if ( strncmp("POST",jsonstr,4) == 0 ) - jsonstr += 6, *postflagp = postflag = 1; - else if ( strncmp("GET",jsonstr,3) == 0 ) - { - jsonstr += 4; - str = 0; - sprintf(porturl,"Referer: http://127.0.0.1:%u",IGUANA_RPCPORT); - if ( (str= iguana_htmlget(retbuf,bufsize,postflagp,jsonstr,remoteaddr,localaccess)) == 0 && (reststr= strstr(jsonstr,porturl)) != 0 ) - { - reststr += strlen(porturl); - str = iguana_htmlget(retbuf,bufsize,postflagp,reststr,remoteaddr,localaccess); - } - if ( str != 0 ) - { - if ( *postflagp == 0 ) - { - json = cJSON_CreateObject(); - jaddstr(json,"result",str); - if ( str != retbuf ) - free(str); - str = cJSON_Print(json); - free_json(json); - } - return(str); - } - jsonstr++; - } - else return(0); - n = (int32_t)strlen(jsonstr); - for (i=0; i 0 ) - { - jsonstr[i] = 0; - agent = jsonstr; - jsonstr += i; - } - jsonstr++; - json = cJSON_CreateObject(); - jaddstr(json,"agent",agent); - while ( 1 ) - { - n = (int32_t)strlen(jsonstr); - key = jsonstr; - value = 0; - for (i=0; i 0. && volume > 0. ) - { - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"%s\",\"base\":\"%s\",\"rel\":\"%s\",\"exchange\":\"%s\",\"price\":\%0.8f,\"volume\":%0.8f}",method,base,rel,exchange,price,volume); - return(jsonstr); - } - else return(0); - } - return(0); - } - - void iguana_coinset(char *buf,char *path) - { - int32_t i; - if ( path[0] == '/' ) - path++; - for (i=0; i<8&&path[i]!=0&&path[i]!=' '&&path[i]!='/'; i++) - buf[i] = path[i]; - buf[i] = 0; - touppercase(buf); - } - - char *iguana_ramchain_glue(struct iguana_info *coin,char *method,char *jsonstr) - { - cJSON *json; char *retstr; - json = cJSON_Parse(jsonstr); - retstr = ramchain_parser(0,method,json); - free_json(json); - return(retstr); - } - - - void iguana_bundlestats(struct iguana_info *coin,char *str) - { - static bits256 zero; - int32_t i,n,issued,dispflag,bundlei,lefti,minrequests,missing,numbundles,numdone,numrecv,totalsaved,numhashes,numcached,numsaved,numemit,numactive,firstbundle,totalrecv = 0; struct iguana_peer *addr1; - bits256 hash2; struct iguana_bundle *bp; struct iguana_block *block; int64_t datasize,estsize = 0; - //iguana_chainextend(coin,iguana_blockfind(coin,coin->blocks.hwmchain)); - //if ( queue_size(&coin->blocksQ) == 0 ) - // iguana_blockQ(coin,0,-1,coin->blocks.hwmchain.hash2,0); - if ( 0 && queue_size(&coin->blocksQ) == 0 && queue_size(&coin->priorityQ) == 0 ) - { - for (i=0; ipeers.active[i].pending = 0; - } - dispflag = (rand() % 1000) == 0; - numbundles = numdone = numrecv = numhashes = numcached = totalsaved = numemit = numactive = 0; - firstbundle = -1; - issued = 0; - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - minrequests = 777; - bp->numhashes = 0; - numbundles++; - numrecv = datasize = numsaved = 0; - missing = -1; - lefti = -1; - if ( bp->numrecv >= bp->n ) - numdone++; - else - { - for (bundlei=0; bundlein; bundlei++) - { - if ( bits256_nonz(bp->hashes[bundlei]) == 0 ) - { - lefti = bundlei; - if ( missing < 0 ) - missing = bundlei; - continue; - } - if ( (block= bp->blocks[bundlei]) != 0 || (block= iguana_blockfind(coin,bp->hashes[bundlei])) != 0 ) - { - bp->blocks[bundlei] = block; - if ( block->numrequests < minrequests ) - minrequests = block->numrequests; - if ( block->fpipbits != 0 ) - numsaved++; - if ( block->RO.recvlen != 0 ) - { - datasize += block->RO.recvlen; - if ( block->queued != 0 ) - numcached++; - numrecv++; - } - if ( block->queued == 0 && block->fpipbits == 0 ) - lefti = bundlei; - } - if ( firstbundle < 0 || firstbundle == bp->hdrsi ) - firstbundle = bp->hdrsi; - bp->numhashes++; - } - } - if ( (bp->minrequests= minrequests) == 100 ) - { - for (i=0; in; i++) - if ( (block= bp->blocks[i]) != 0 ) - block->numrequests = 1; - } - //printf("(%d %d) ",bp->hdrsi,minrequests); - numhashes += bp->numhashes; - bp->numrecv = numrecv; - bp->datasize = datasize; - if ( bp->emitfinish != 0 ) - { - numemit++; - if ( bp->emitfinish > coin->startutc && bp->purgetime == 0 && time(NULL) > bp->emitfinish+30 ) - { - char fname[1024]; int32_t hdrsi,m,j; uint32_t ipbits; - for (j=m=0; jpeers.active)/sizeof(*coin->peers.active); j++) - { - if ( (ipbits= coin->peers.active[j].ipbits) != 0 ) - { - if ( iguana_peerfname(coin,&hdrsi,"tmp",fname,ipbits,bp->hashes[0],zero,1) >= 0 ) - { - if ( OS_removefile(fname,0) > 0 ) - coin->peers.numfiles--, m++; - } - else printf("error removing.(%s)\n",fname); - } - } - //printf("purged hdrsi.%d m.%d\n",bp->hdrsi,m); - bp->purgetime = (uint32_t)time(NULL); - } - } - else if ( numsaved > 0 ) - { - bp->estsize = ((uint64_t)datasize * bp->n) / (numrecv+1); - estsize += bp->estsize; - if ( bp->numhashes == bp->n ) - numactive++; - if ( 0 && dispflag != 0 ) - { - if ( bp->numrecv < bp->n-1 ) - printf("(%d %d) ",i,bp->numrecv); - else printf("(%d -[%d]) ",i,lefti); - } - if ( (rand() % 100) == 0 && bp->numrecv > bp->n-2 && lefti >= 0 && lefti < bp->n ) - { - //printf("remainder issue %d:%d %s\n",bp->hdrsi,lefti,bits256_str(str,bp->hashes[lefti])); - //iguana_blockQ(coin,bp,lefti,bp->hashes[lefti],1); - } - if ( numsaved >= bp->n && bp->emitfinish == 0 ) - { - //printf(">>>>>>>>>>>>>>>>>>>>>>> EMIT\n"); - bp->emitfinish = 1; - iguana_emitQ(coin,bp); - } - /*if ( numrecv > bp->n*.98 ) - { - if ( numrecv > bp->n-3 ) - bp->threshold = bp->avetime; - else bp->threshold = bp->avetime * 2; - } else*/ - bp->threshold = bp->avetime; - bp->metric = (bp->n - numsaved) / (bp->hdrsi + 1);//sqrt(abs((bp->n - bp->numrecv)) * sqrt(bp->estsize - bp->datasize)) / coin->chain->bundlesize; - } else bp->threshold = 10000., bp->metric = 0.; - totalrecv += numrecv; - totalsaved += numsaved; - } - } - coin->blocksrecv = totalrecv; - char str2[65]; uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now(); - for (i=0; ipeers.active[i].usock >= 0 ) - p++; - diff = (int32_t)time(NULL) - coin->startutc; - difft.x = (t.x - coin->starttime.x), difft.millis = (t.millis - coin->starttime.millis); - tmp = (difft.millis * 1000000); - tmp %= 1000000000; - difft.millis = ((double)tmp / 1000000.); - sprintf(str,"N[%d] d.%d p.%d g.%d A.%d h.%d r.%d c.%d:%d s.%d E.%d:%d M.%d L.%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d",coin->bundlescount,numdone,coin->numpendings,numbundles,numactive,numhashes,coin->blocksrecv,coin->numcached,coin->cachefreed,totalsaved,coin->numemitted,coin->numreqsent,coin->blocks.hwmchain.height,coin->longestchain,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS); - //sprintf(str+strlen(str),"%s.%-2d %s time %.2f files.%d Q.%d %d\n",coin->symbol,flag,str,(double)(time(NULL)-coin->starttime)/60.,coin->peers.numfiles,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); - if ( (rand() % 100) == 0 ) - printf("%s\n",str); - strcpy(coin->statusstr,str); - coin->activebundles = numactive; - coin->estsize = estsize; - coin->numrecv = totalrecv; - if ( 0 && queue_size(&coin->priorityQ) == 0 && coin->blocksrecv > coin->longestchain*.9 && coin->blocksrecv < coin->longestchain-1 ) - { - n = 0; - for (i=coin->lastsweep; ilongestchain-1; i++) - { - hash2 = iguana_blockhash(coin,i); - if ( bits256_nonz(hash2) > 0 && (block= iguana_blockfind(coin,hash2)) != 0 ) - { - if ( iguana_bundlefind(coin,&bp,&bundlei,hash2) == 0 || block->fpipbits == 0 ) - { - iguana_blockQ(coin,bp,bundlei,hash2,1); - n++; - printf("%d ",i); - if ( n > 1000 ) - break; - else if ( n < 10 && bp != 0 ) - iguana_bundleiclear(coin,bp,bundlei); - } - coin->lastsweep = i; - } - if ( i >= coin->longestchain-1 ) - coin->lastsweep = 0; - } - if ( n > 0 ) - printf(">>>>>>>>>>> issued.%d 90%% blocks\n",n); - } - else if ( 0 && strcmp(coin->symbol,"BTCD") == 0 && queue_size(&coin->blocksQ) == 0 ) - { - for (i=n=0; ilongestchain-1; i++) - { - hash2 = iguana_blockhash(coin,i); - if ( bits256_nonz(hash2) > 0 && (block= iguana_blockfind(coin,hash2)) != 0 && block->fpipbits == 0 ) - iguana_blockQ(coin,coin->bundles[i/coin->chain->bundlesize],i%coin->chain->bundlesize,hash2,0); - } - } - } - if ( 0 && coin->newramchain != 0 && now > coin->savedblocks+60 ) - { - char fname[512]; FILE *fp; - sprintf(fname,"blocks.%s",coin->symbol), OS_compatible_path(fname); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( fwrite(coin->blocks.RO,sizeof(*coin->blocks.RO),coin->longestchain,fp) != coin->longestchain ) - printf("error saving blocks\n"); - else printf("%s saved\n",fname); - fclose(fp); - coin->savedblocks = (uint32_t)time(NULL); - } - } - - - /*struct iguana_block *iguana_blockrequest(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,uint32_t now,int32_t iamthreadsafe) - { - struct iguana_block *block = 0; - if( bp != 0 && bundlei >= 0 && bundlei < bp->n ) - block = bp->blocks[bundlei]; - if ( block == 0 && iamthreadsafe != 0 ) - block = iguana_blockfind(coin,hash2); - if ( block != 0 ) - { - //block->issued = now; - block->numrequests++; - } - return(block); - }*/ - if ( 0 && addr->msgcounts.verack > 0 && coin->bundlescount > 0 && req == 0 && addr->pendblocks < limit )//&& now > addr->lastpoll ) - { - if ( 1 )//strcmp("BTC",coin->symbol) != 0 ) - { - int32_t bundlei; - incr = coin->peers.numranked == 0 ? coin->MAXPEERS : coin->peers.numranked; - if ( (rand() % 100) < 50 ) - height = addr->rank * _IGUANA_MAXPENDING; - else if ( (rand() % 100) < 50 ) - height = addr->addrind + (addr->rank * (coin->longestchain - coin->blocks.hwmchain.height) / (coin->peers.numranked+1)); - else if ( (rand() % 100) < 50 ) - { - height = (addr->lastheight + 1); - if ( height >= coin->longestchain-coin->chain->bundlesize ) - height = addr->rank*incr*_IGUANA_MAXPENDING; - } - else - { - height = coin->longestchain - (rand() % incr) * 1000; - if ( height < 0 ) - height = coin->blocks.hwmchain.height; - } - for (; heightbundlescount*coin->chain->bundlesize; height+=incr) - { - if ( height > coin->longestchain ) - height = addr->rank*incr*_IGUANA_MAXPENDING; - if ( height > addr->lastheight ) - addr->lastheight = height; - if ( (bp= coin->bundles[height/coin->chain->bundlesize]) != 0 && bp->emitfinish == 0 ) - { - bundlei = (height % coin->chain->bundlesize); - if ( bundlei < bp->n && bits256_nonz(bp->hashes[bundlei]) > 0 && (block= bp->blocks[bundlei]) != 0 && block->numrequests <= bp->minrequests && block->fpipbits == 0 && (bp->issued[bundlei] == 0 || now > bp->issued[bundlei]+13) ) - { - block->numrequests++; - bp->issued[bundlei] = (uint32_t)time(NULL);; - //if ( 0 && (rand() % 100) == 0 ) - printf("%s Send auto blockreq.%d [%d] minreq.%d\n",addr->ipaddr,bp->bundleheight+bundlei,block->numrequests,bp->minrequests); - iguana_sendblockreqPT(coin,addr,bp,bundlei,bp->hashes[bundlei],0); - return(1); - } - } - //if ( (rand() % 100) < 50 ) - // break; - } - } - else - { - //printf("%s lastpoll.%u %u\n",addr->ipaddr,addr->lastpoll,now); - addr->lastpoll = now; - for (i=n=0; ibundlescount; i++) - if ( coin->bundles[i] != 0 && coin->bundles[i]->emitfinish == 0 ) - n++; - if ( n >= coin->bundlescount-(coin->bundlescount>>3) || (addr->ipbits % 10) < 5 ) - refbundlei = (addr->ipbits % coin->bundlescount); - else - { - if ( n*2 < coin->bundlescount ) - { - for (i=refbundlei=0; iusock == coin->peers.active[i].usock ) - break; - if ( coin->peers.active[i].usock >= 0 ) - refbundlei++; - } - //printf("half done\n"); - } else refbundlei = ((addr->addrind*100) % coin->bundlescount); - } - for (i=0; ibundlescount; i++) - { - if ( (diff= (i - refbundlei)) < 0 ) - diff = -diff; - if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 ) - { - metric = (1 + diff * ((addr->addrind&1) == 0 ? 1 : 1) * (1. + bp->metric));// / (i*((addr->addrind&1) != 0 ? 1 : i) + 1); - //printf("%f ",bp->metric); - if ( bestmetric < 0. || metric < bestmetric ) - bestmetric = metric, bestbp = bp; - } - } - if ( bestbp != 0 && bp->emitfinish == 0 ) - { - for (k=0; kbundlescount; k++) - { - i = (bestbp->hdrsi + k) % coin->bundlescount; - if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish != 0 ) - continue; - //printf("%.15f ref.%d addrind.%d bestbp.%d\n",bestmetric,refbundlei,addr->addrind,bp->hdrsi); - m = coin->chain->bundlesize; - if ( bp->n < m ) - m = bp->n; - j = (addr->addrind*3 + 0) % m; - val = (bp->threshold / 1000.); - for (r=0; r= m ) - j = 0; - if ( (block= bp->blocks[j]) != 0 && block->fpipbits == 0 && block->queued == 0 && block->numrequests <= bp->minrequests ) - { - block->numrequests++; - //block->issued = (uint32_t)time(NULL);; - //printf("%s Send auto blockreq.%d\n",addr->ipaddr,bp->bundleheight+j); - iguana_sendblockreqPT(coin,addr,bp,j,hash2,0); - return(1); - } - } - } - } - } - } - - - void iguana_bundlestats(struct iguana_info *coin,char *str) - { - int32_t i,n,dispflag,numrecv,done,numhashes,numcached,numsaved,numemit; int64_t estsize = 0; - struct iguana_bundle *bp; - dispflag = (rand() % 1000) == 0; - numrecv = numhashes = numcached = numsaved = numemit = done = 0; - memset(coin->rankedbps,0,sizeof(coin->rankedbps)); - for (i=n=0; ibundlescount; i++) - { - coin->rankedbps[n][1] = i; - if ( (bp= coin->bundles[i]) != 0 ) - { - estsize += iguana_bundlecalcs(coin,bp); - numhashes += bp->numhashes; - numcached += bp->numcached; - numrecv += bp->numrecv; - numsaved += bp->numsaved; - if ( bp->emitfinish != 0 ) - { - done++; - if ( bp->emitfinish > 1 ) - numemit++; - iguana_bundlepurge(coin,bp); - } - else if ( bp->metric > 0. ) - coin->rankedbps[n++][0] = bp->metric; - } - } - if ( n > 0 ) - { - struct iguana_peer *addr; uint32_t now; struct iguana_block *block; int32_t m,flag,origissue,j,issue,pend = 0; - flag = m = 0; - sortds(&coin->rankedbps[0][0],n,sizeof(coin->rankedbps[0])); - for (i=0; ipeers.numranked; i++) - { - if ( (addr= coin->peers.ranked[i]) != 0 && addr->msgcounts.verack > 0 ) - pend += addr->pendblocks; - } - if ( pend > 0 ) - { - origissue = (_IGUANA_MAXPENDING*coin->peers.numranked - pend); - issue = origissue; - now = (uint32_t)time(NULL); - for (i=0; ibundles[(int32_t)coin->rankedbps[i][1]]) != 0 && bp->emitfinish == 0 && bp->numhashes == bp->n ) - { - for (j=0; jn; j++) - { - if ( bits256_nonz(bp->hashes[j]) > 0 && (block= bp->blocks[j]) != 0 ) - { - //printf("j.%d bp.%d %d %x lag.%d\n",j,bp->minrequests,block->numrequests,block->fpipbits,now - bp->issued[j]); - if ( block->numrequests <= bp->minrequests+10 && block->fpipbits == 0 && (bp->issued[j] == 0 || now > bp->issued[j]+60) ) - { - printf("%d:%d.%d ",bp->hdrsi,j,block->numrequests); - flag++; - bp->issued[j] = now; - iguana_blockQ(coin,bp,j,bp->hashes[j],0); - if ( --issue < 0 ) - break; - } - } - } - } - } - /*for (i=0; irankedbps[i][0],coin->rankedbps[i][1],coin->bundles[(int32_t)coin->rankedbps[i][1]]->numrecv);*/ - if ( flag != 0 ) - printf("rem.%d issue.%d pend.%d | numranked.%d\n",n,origissue,pend,coin->peers.numranked); - } - } - coin->numremain = n; - coin->blocksrecv = numrecv; - char str2[65]; uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now(); - for (i=0; ipeers.active[i].usock >= 0 ) - p++; - diff = (int32_t)time(NULL) - coin->startutc; - difft.x = (t.x - coin->starttime.x), difft.millis = (t.millis - coin->starttime.millis); - tmp = (difft.millis * 1000000); - tmp %= 1000000000; - difft.millis = ((double)tmp / 1000000.); - sprintf(str,"N[%d] Q.%d h.%d r.%d c.%d:%d:%d s.%d d.%d E.%d:%d M.%d L.%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d)",coin->bundlescount,coin->numbundlesQ,numhashes,coin->blocksrecv,coin->numcached,numcached,coin->cachefreed,numsaved,done,numemit,coin->numreqsent,coin->blocks.hwmchain.height,coin->longestchain,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); - //sprintf(str+strlen(str),"%s.%-2d %s time %.2f files.%d Q.%d %d\n",coin->symbol,flag,str,(double)(time(NULL)-coin->starttime)/60.,coin->peers.numfiles,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); - //if ( (rand() % 100) == 0 ) - static uint32_t lastdisp; - if ( time(NULL) > lastdisp+10 ) - { - printf("%s\n",str); - lastdisp = (uint32_t)time(NULL); - } - strcpy(coin->statusstr,str); - coin->estsize = estsize; - } - - char *iguana_bundledisp(struct iguana_info *coin,struct iguana_bundle *prevbp,struct iguana_bundle *bp,struct iguana_bundle *nextbp,int32_t m) - { - static char line[1024]; - line[0] = 0; - if ( bp == 0 ) - return(line); - if ( prevbp != 0 ) - { - if ( memcmp(prevbp->hashes[0].bytes,bp->prevbundlehash2.bytes,sizeof(bits256)) == 0 ) - { - if ( memcmp(prevbp->nextbundlehash2.bytes,bp->hashes[0].bytes,sizeof(bits256)) == 0 ) - sprintf(line+strlen(line),"<->"); - else sprintf(line+strlen(line),"<-"); - } - else if ( memcmp(prevbp->nextbundlehash2.bytes,bp->hashes[0].bytes,sizeof(bits256)) == 0 ) - sprintf(line+strlen(line),"->"); - } - sprintf(line+strlen(line),"(%d:%d).%d ",bp->hdrsi,m,bp->numhashes); - if ( nextbp != 0 ) - { - if ( memcmp(nextbp->hashes[0].bytes,bp->nextbundlehash2.bytes,sizeof(bits256)) == 0 ) - { - if ( memcmp(nextbp->prevbundlehash2.bytes,bp->hashes[0].bytes,sizeof(bits256)) == 0 ) - sprintf(line+strlen(line),"<->"); - else sprintf(line+strlen(line),"->"); - } - else if ( memcmp(nextbp->prevbundlehash2.bytes,bp->hashes[0].bytes,sizeof(bits256)) == 0 ) - sprintf(line+strlen(line),"<-"); - } - return(line); - } - if ( strcmp(method,"status") == 0 || strcmp(method,"getinfo") == 0 ) - return(iguana_getinfo(myinfo,coin)); - /* else if ( strcmp(method,"getbestblockhash") == 0 ) - return(iguana_getbestblockhash(myinfo,coin)); - else if ( strcmp(method,"getblockcount") == 0 ) - return(iguana_getblockcount(myinfo,coin)); - else if ( strcmp(method,"validatepubkey") == 0 ) - return(iguana_validatepubkey(myinfo,coin,jstr(json,"pubkey"))); - else if ( strcmp(method,"listtransactions") == 0 ) - return(iguana_listtransactions(myinfo,coin,jstr(json,"account"),juint(json,"count"),juint(json,"from"))); - else if ( strcmp(method,"getreceivedbyaddress") == 0 ) - return(iguana_getreceivedbyaddress(myinfo,coin,jstr(json,"address"),juint(json,"minconf"))); - else if ( strcmp(method,"listreceivedbyaddress") == 0 ) - return(iguana_listreceivedbyaddress(myinfo,coin,juint(json,"minconf"),juint(json,"includeempty"))); - else if ( strcmp(method,"listsinceblock") == 0 ) - return(iguana_listsinceblock(myinfo,coin,jbits256(json,"blockhash"),juint(json,"target"))); - else if ( strcmp(method,"getreceivedbyaccount") == 0 ) - return(iguana_getreceivedbyaccount(myinfo,coin,jstr(json,"account"),juint(json,"minconf"))); - else if ( strcmp(method,"listreceivedbyaccount") == 0 ) - return(iguana_listreceivedbyaccount(myinfo,coin,jstr(json,"account"),juint(json,"includeempty"))); - else if ( strcmp(method,"getnewaddress") == 0 ) - return(iguana_getnewaddress(myinfo,coin,jstr(json,"account"))); - else if ( strcmp(method,"makekeypair") == 0 ) - return(iguana_makekeypair(myinfo,coin)); - else if ( strcmp(method,"getaccountaddress") == 0 ) - return(iguana_getaccountaddress(myinfo,coin,jstr(json,"account"))); - else if ( strcmp(method,"setaccount") == 0 ) - return(iguana_setaccount(myinfo,coin,jstr(json,"address"),jstr(json,"account"))); - else if ( strcmp(method,"getaccount") == 0 ) - return(iguana_getaccount(myinfo,coin,jstr(json,"account"))); - else if ( strcmp(method,"getaddressesbyaccount") == 0 ) - return(iguana_getaddressesbyaccount(myinfo,coin,jstr(json,"account"))); - else if ( strcmp(method,"listaddressgroupings") == 0 ) - return(iguana_listaddressgroupings(myinfo,coin)); - else if ( strcmp(method,"getbalance") == 0 ) - return(iguana_getbalance(myinfo,coin,jstr(json,"account"),juint(json,"minconf"))); - else if ( strcmp(method,"listaccounts") == 0 ) - return(iguana_listaccounts(myinfo,coin,juint(json,"minconf"))); - else if ( strcmp(method,"dumpprivkey") == 0 ) - return(iguana_dumpprivkey(myinfo,coin,jstr(json,"address"))); - else if ( strcmp(method,"importprivkey") == 0 ) - return(iguana_importprivkey(myinfo,coin,jstr(json,"wip"))); - else if ( strcmp(method,"dumpwallet") == 0 ) - return(iguana_dumpwallet(myinfo,coin)); - else if ( strcmp(method,"importwallet") == 0 ) - return(iguana_importwallet(myinfo,coin,jstr(json,"wallet"))); - else if ( strcmp(method,"walletpassphrase") == 0 ) - return(iguana_walletpassphrase(myinfo,coin,jstr(json,"passphrase"),juint(json,"timeout"))); - else if ( strcmp(method,"walletpassphrasechange") == 0 ) - return(iguana_walletpassphrasechange(myinfo,coin,jstr(json,"oldpassphrase"),jstr(json,"newpassphrase"))); - else if ( strcmp(method,"walletlock") == 0 ) - return(iguana_walletlock(myinfo,coin)); - else if ( strcmp(method,"encryptwallet") == 0 ) - return(iguana_encryptwallet(myinfo,coin,jstr(json,"passphrase"))); - else if ( strcmp(method,"checkwallet") == 0 ) - return(iguana_checkwallet(myinfo,coin)); - else if ( strcmp(method,"repairwallet") == 0 ) - return(iguana_repairwallet(myinfo,coin)); - else if ( strcmp(method,"backupwallet") == 0 ) - return(iguana_backupwallet(myinfo,coin,jstr(json,"filename"))); - else if ( strcmp(method,"signmessage") == 0 ) - return(iguana_signmessage(myinfo,coin,jstr(json,"address"),jstr(json,"message"))); - else if ( strcmp(method,"verifymessage") == 0 ) - return(iguana_verifymessage(myinfo,coin,jstr(json,"address"),jstr(json,"sig"),jstr(json,"message"))); - else if ( strcmp(method,"listunspent") == 0 ) - return(iguana_listunspent(myinfo,coin,juint(json,"minconf"),juint(json,"maxconf"))); - else if ( strcmp(method,"lockunspent") == 0 ) - return(iguana_lockunspent(myinfo,coin,juint(json,"flag"),jobj(json,"array"))); - else if ( strcmp(method,"listlockunspent") == 0 ) - return(iguana_listlockunspent(myinfo,coin)); - else if ( strcmp(method,"gettxout") == 0 ) - return(iguana_gettxout(myinfo,coin,jbits256(json,"txid"),juint(json,"vout"),juint(json,"mempool"))); - else if ( strcmp(method,"gettxoutsetinfo") == 0 ) - return(iguana_gettxoutsetinfo(myinfo,coin)); - else if ( strcmp(method,"sendtoaddress") == 0 ) - return(iguana_sendtoaddress(myinfo,coin,jstr(json,"address"),jdouble(json,"amount"),jstr(json,"comment"),jstr(json,"comment2"))); - else if ( strcmp(method,"move") == 0 ) - return(iguana_move(myinfo,coin,jstr(json,"fromaccount"),jstr(json,"toaccount"),jdouble(json,"amount"),juint(json,"minconf"),jstr(json,"comment"))); - else if ( strcmp(method,"sendfrom") == 0 ) - return(iguana_sendfrom(myinfo,coin,jstr(json,"fromaccount"),jstr(json,"toaddress"),jdouble(json,"amount"),juint(json,"minconf"),jstr(json,"comment"),jstr(json,"comment2"))); - else if ( strcmp(method,"sendmany") == 0 ) - return(iguana_sendmany(myinfo,coin,jstr(json,"fromaccount"),jobj(json,"payments"),juint(json,"minconf"),jstr(json,"comment"))); - else if ( strcmp(method,"settxfee") == 0 ) - return(iguana_settxfee(myinfo,coin,jdouble(json,"amount"))); - else if ( strcmp(method,"getrawtransaction") == 0 ) - return(iguana_getrawtransaction(myinfo,coin,jbits256(json,"txid"),juint(json,"verbose"))); - else if ( strcmp(method,"createrawtransaction") == 0 ) - return(iguana_createrawtransaction(myinfo,coin,jobj(json,"vins"),jobj(json,"vouts"))); - else if ( strcmp(method,"decoderawtransaction") == 0 ) - return(iguana_decoderawtransaction(myinfo,coin,jstr(json,"rawtx"))); - else if ( strcmp(method,"decodescript") == 0 ) - return(iguana_decodescript(myinfo,coin,jstr(json,"script"))); - else if ( strcmp(method,"signrawtransaction") == 0 ) - return(iguana_signrawtransaction(myinfo,coin,jstr(json,"rawtx"),jobj(json,"vins"),jobj(json,"privkeys"))); - else if ( strcmp(method,"sendrawtransaction") == 0 ) - return(iguana_sendrawtransaction(myinfo,coin,jstr(json,"rawtx"))); - else if ( strcmp(method,"getrawchangeaddress") == 0 ) - return(iguana_getrawchangeaddress(myinfo,coin,jstr(json,"account"))); - */ - - char *iguana_jsoncheck(char *retstr,int32_t freeflag) - { - cJSON *retjson; char *errstr; - if ( retstr != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (errstr= jstr(retjson,"error")) == 0 ) - { - free_json(retjson); - return(retstr); - } - free_json(retjson); - } - if ( freeflag != 0 ) - free(retstr); - } - return(0); - } - - char *ramchain_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) - { - char *symbol,*str,*retstr; int32_t height; cJSON *argjson,*obj; struct iguana_info *coin = 0; - /*{"agent":"ramchain","method":"block","coin":"BTCD","hash":""} - {"agent":"ramchain","method":"block","coin":"BTCD","height":345600} - {"agent":"ramchain","method":"tx","coin":"BTCD","txid":""} - {"agent":"ramchain","method":"rawtx","coin":"BTCD","txid":""} - {"agent":"ramchain","method":"balance","coin":"BTCD","address":""} - {"agent":"ramchain","method":"balance","coin":"BTCD","addrs":["",...]} - {"agent":"ramchain","method":"totalreceived","coin":"BTCD","address":""} - {"agent":"ramchain","method":"totalsent","coin":"BTCD","address":""} - {"agent":"ramchain","method":"unconfirmed","coin":"BTCD","address":""} - {"agent":"ramchain","method":"utxo","coin":"BTCD","address":""} - {"agent":"ramchain","method":"utxo","coin":"BTCD","addrs":["", "",...]} - {"agent":"ramchain","method":"txs","coin":"BTCD","block":""} - {"agent":"ramchain","method":"txs","coin":"BTCD","height":12345} - {"agent":"ramchain","method":"txs","coin":"BTCD","address":""} - {"agent":"ramchain","method":"status","coin":"BTCD"}*/ - - if ( (symbol= jstr(json,"coin")) != 0 && symbol[0] != 0 ) - { - if ( coin == 0 ) - coin = iguana_coinfind(symbol); - else if ( strcmp(symbol,coin->symbol) != 0 ) - return(clonestr("{\"error\":\"mismatched coin symbol\"}")); - } - if ( strcmp(method,"explore") == 0 ) - { - obj = jobj(json,"search"); - if ( coin != 0 && obj != 0 ) - { - argjson = cJSON_CreateObject(); - jaddstr(argjson,"agent","ramchain"); - jaddstr(argjson,"method","block"); - jaddnum(argjson,"txids",1); - if ( is_cJSON_Number(obj) != 0 ) - { - height = juint(obj,0); - jaddnum(argjson,"height",height); - } - else if ( (str= jstr(obj,0)) != 0 ) - jaddstr(argjson,"hash",str); - else return(clonestr("{\"error\":\"need number or string to search\"}")); - if ( (retstr= iguana_jsoncheck(ramchain_coinparser(myinfo,coin,"block",argjson),1)) != 0 ) - { - free_json(argjson); - return(retstr); - } - free_json(argjson); - argjson = cJSON_CreateObject(); - jaddstr(argjson,"agent","ramchain"); - jaddstr(argjson,"method","tx"); - jaddstr(argjson,"txid",str); - if ( (retstr= iguana_jsoncheck(ramchain_coinparser(myinfo,coin,"tx",argjson),1)) != 0 ) - { - free_json(argjson); - return(retstr); - } - free_json(argjson); - return(clonestr("{\"result\":\"explore search cant find height, blockhash, txid\"}")); - } - return(clonestr("{\"result\":\"explore no coin or search\"}")); - } - return(ramchain_coinparser(myinfo,coin,method,json)); - } - - /*int32_t pp_bind(char *hostname,uint16_t port) - { - int32_t opt; struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); - struct hostent* hostent = gethostbyname(hostname); - if (hostent == NULL) { - PNACL_message("gethostbyname() returned error: %d", errno); - return -1; - } - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - memcpy(&addr.sin_addr.s_addr, hostent->h_addr_list[0], hostent->h_length); - int sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) { - printf("socket() failed: %s", strerror(errno)); - return -1; - } - opt = 1; - setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(opt)); - #ifdef __APPLE__ - setsockopt(sock,SOL_SOCKET,SO_NOSIGPIPE,&opt,sizeof(opt)); - #endif - //timeout.tv_sec = 0; - //timeout.tv_usec = 1000; - //setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout)); - int result = bind(sock, (struct sockaddr*)&addr, addrlen); - if (result != 0) { - printf("bind() failed: %s", strerror(errno)); - closesocket(sock); - return -1; - } - return(sock); - }*/ - /*if ( strcmp(agent,"ramchain") == 0 ) - return(ramchain_parser(myinfo,method,json,remoteaddr)); - else if ( strcmp(agent,"InstantDEX") == 0 ) - return(InstantDEX_parser(myinfo,method,json,remoteaddr)); - else if ( strcmp(agent,"pangea") == 0 ) - return(pangea_parser(myinfo,method,json,remoteaddr)); - else if ( strcmp(agent,"jumblr") == 0 ) - return(jumblr_parser(myinfo,method,json,remoteaddr)); - else if ( strcmp(agent,"hash") == 0 ) - return(hash_parser(myinfo,method,json,remoteaddr));*/ - - char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json) - { - int32_t i,max,retval,num=0; char buf[1024]; struct iguana_peer *addr; char *ipaddr; cJSON *retjson = 0; - //printf("iguana_coinjson(%s)\n",jprint(json,0)); - if ( strcmp(method,"peers") == 0 ) - return(jprint(iguana_peersjson(coin,0),1)); - else if ( strcmp(method,"getconnectioncount") == 0 ) - { - for (i=0; ipeers.active)/sizeof(*coin->peers.active); i++) - if ( coin->peers.active[i].usock >= 0 ) - num++; - sprintf(buf,"{\"result\":\"%d\"}",num); - return(clonestr(buf)); - } - else if ( strcmp(method,"addnode") == 0 ) - { - if ( (ipaddr= jstr(json,"ipaddr")) != 0 ) - { - iguana_possible_peer(coin,ipaddr); - return(clonestr("{\"result\":\"addnode submitted\"}")); - } else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); - } - else if ( strcmp(method,"removenode") == 0 ) - { - if ( (ipaddr= jstr(json,"ipaddr")) != 0 ) - { - for (i=0; ipeers.active[i].ipaddr,ipaddr) == 0 ) - { - coin->peers.active[i].rank = 0; - coin->peers.active[i].dead = (uint32_t)time(NULL); - return(clonestr("{\"result\":\"node marked as dead\"}")); - } - } - return(clonestr("{\"result\":\"node wasnt active\"}")); - } else return(clonestr("{\"error\":\"removenode needs ipaddr\"}")); - } - else if ( strcmp(method,"oneshot") == 0 ) - { - if ( (ipaddr= jstr(json,"ipaddr")) != 0 ) - { - iguana_possible_peer(coin,ipaddr); - return(clonestr("{\"result\":\"addnode submitted\"}")); - } else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); - } - else if ( strcmp(method,"nodestatus") == 0 ) - { - if ( (ipaddr= jstr(json,"ipaddr")) != 0 ) - { - for (i=0; iMAXPEERS; i++) - { - addr = &coin->peers.active[i]; - if ( strcmp(addr->ipaddr,ipaddr) == 0 ) - return(jprint(iguana_peerjson(coin,addr),1)); - } - return(clonestr("{\"result\":\"nodestatus couldnt find ipaddr\"}")); - } else return(clonestr("{\"error\":\"nodestatus needs ipaddr\"}")); - } - else if ( strcmp(method,"maxpeers") == 0 ) - { - retjson = cJSON_CreateObject(); - if ( (max= juint(json,"max")) <= 0 ) - max = 1; - else if ( max > IGUANA_MAXPEERS ) - max = IGUANA_MAXPEERS; - if ( max > coin->MAXPEERS ) - { - for (i=max; iMAXPEERS; i++) - if ( (addr= coin->peers.ranked[i]) != 0 ) - addr->dead = 1; - } - coin->MAXPEERS = max; - jaddnum(retjson,"maxpeers",coin->MAXPEERS); - jaddstr(retjson,"coin",coin->symbol); - return(jprint(retjson,1)); - } - else if ( strcmp(method,"startcoin") == 0 ) - { - coin->active = 1; - return(clonestr("{\"result\":\"coin started\"}")); - } - else if ( strcmp(method,"pausecoin") == 0 ) - { - coin->active = 0; - return(clonestr("{\"result\":\"coin paused\"}")); - } - else if ( strcmp(method,"addcoin") == 0 ) - { - if ( (retval= iguana_launchcoin(coin->symbol,json)) > 0 ) - return(clonestr("{\"result\":\"coin added\"}")); - else if ( retval == 0 ) - return(clonestr("{\"result\":\"coin already there\"}")); - else return(clonestr("{\"error\":\"error adding coin\"}")); - } - return(clonestr("{\"error\":\"unhandled request\"}")); - } - - char *iguana_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) - { - char *coinstr,SYM[16]; int32_t j,k,l,r,rr; struct iguana_peer *addr; - cJSON *retjson = 0,*array; int32_t i,n; struct iguana_info *coin; char *symbol; - printf("remoteaddr.(%s)\n",remoteaddr!=0?remoteaddr:"local"); - if ( remoteaddr == 0 || remoteaddr[0] == 0 || strcmp(remoteaddr,"127.0.0.1") == 0 ) // local (private) api - { - if ( strcmp(method,"list") == 0 ) - { - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - for (i=0; isymbol[0] != 0 ) - jaddistr(array,Coins[i]->symbol); - } - jadd(retjson,"coins",array); - return(jprint(retjson,1)); - } - else if ( strcmp(method,"allpeers") == 0 ) - { - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - for (i=0; isymbol[0] != 0 ) - jaddi(array,iguana_peersjson(Coins[i],0)); - } - jadd(retjson,"allpeers",array); - return(jprint(retjson,1)); - } - else - { - if ( (symbol= jstr(json,"coin")) != 0 && strlen(symbol) < sizeof(SYM)-1 ) - { - strcpy(SYM,symbol); - touppercase(SYM); - if ( (coin= iguana_coinfind(SYM)) == 0 ) - { - if ( strcmp(method,"addcoin") == 0 ) - coin = iguana_coinadd(SYM); - } - if ( coin != 0 ) - return(iguana_coinjson(coin,method,json)); - else return(clonestr("{\"error\":\"cant get coin info\"}")); - } - } - } - array = 0; - if ( strcmp(method,"getpeers") == 0 ) - { - if ( (coinstr= jstr(json,"coin")) != 0 ) - { - if ( (array= iguana_peersjson(iguana_coinfind(coinstr),1)) == 0 ) - return(clonestr("{\"error\":\"coin not found\"}")); - } - else - { - n = 0; - array = cJSON_CreateArray(); - r = rand(); - for (i=0; ipeers.active[l]; - if ( addr->usock >= 0 && addr->supernet != 0 ) - { - jaddistr(array,addr->ipaddr); - if ( ++n >= 64 ) - break; - } - } - } - } - } - if ( array != 0 ) - { - retjson = cJSON_CreateObject(); - jaddstr(retjson,"agent","SuperNET"); - jaddstr(retjson,"method","mypeers"); - jaddstr(retjson,"result","peers found"); - jadd(retjson,"peers",array); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"no peers found\"}")); - } - else if ( strcmp(method,"mypeers") == 0 ) - { - printf("mypeers from %s\n",remoteaddr!=0?remoteaddr:"local"); - } - return(clonestr("{\"result\":\"stub processed generic json\"}")); - } - - - char *InstantDEX_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) - { - return(clonestr("{\"error\":\"InstantDEX API is not yet\"}")); - } - - char *jumblr_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) - { - return(clonestr("{\"error\":\"jumblr API is not yet\"}")); - } - - char *pangea_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) - { - return(clonestr("{\"error\":\"jumblr API is not yet\"}")); - } - - /* - char *hash_parser(struct supernet_info *myinfo,char *hashname,cJSON *json,char *remoteaddr) - { - int32_t i,len,iter,n; uint8_t databuf[512]; - char hexstr[1025],*password,*name,*msg; - typedef void (*hashfunc)(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); - typedef char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char *message); - struct hashfunc_entry { char *name; hashfunc hashfunc; }; - struct hmacfunc_entry { char *name; hmacfunc hmacfunc; }; - struct hashfunc_entry hashes[] = { {"NXT",calc_NXTaddr}, {"curve25519",calc_curve25519_str }, {"base64_encode",calc_base64_encodestr}, {"base64_decode",calc_base64_decodestr}, {"crc32",calc_crc32str}, {"rmd160_sha256",rmd160ofsha256}, {"sha256_sha256",sha256_sha256}, {"sha256",vcalc_sha256}, {"sha512",calc_sha512}, {"sha384",calc_sha384}, {"sha224",calc_sha224}, {"rmd160",calc_rmd160}, {"rmd256",calc_rmd256}, {"rmd320",calc_rmd320}, {"rmd128",calc_rmd128}, {"sha1",calc_sha1}, {"md5",calc_md5str}, {"md2",calc_md2str}, {"md4",calc_md4str}, {"tiger",calc_tiger}, {"whirlpool",calc_whirlpool} }; - struct hmacfunc_entry hmacs[] = { {"hmac_sha256",hmac_sha256_str}, {"hmac_sha512",hmac_sha512_str}, {"hmac_sha384",hmac_sha384_str}, {"hmac_sha224",hmac_sha224_str}, {"hmac_rmd160",hmac_rmd160_str}, {"hmac_rmd256",hmac_rmd256_str}, {"hmac_rmd320",hmac_rmd320_str}, {"hmac_rmd128",hmac_rmd128_str}, {"hmac_sha1",hmac_sha1_str}, {"hmac_md52",hmac_md2_str},{"hmac_md4",hmac_md4_str},{"hmac_md5",hmac_md5_str}, {"hmac_tiger",hmac_tiger_str}, {"hmac_whirlpool",hmac_whirlpool_str} }; - if ( (msg= jstr(json,"message")) == 0 ) - return(clonestr("{\"error\":\"no message to hash\"}")); - if ( (password= jstr(json,"password")) == 0 || password[0] == 0 ) - password = " "; - n = (int32_t)sizeof(hashes)/sizeof(*hashes); - printf("msg.(%s) password.(%s)\n",msg,password!=0?password:""); - for (iter=0; iter<2; iter++) - { - for (i=0; imyaddr.pubkey)); - jdelete(json,"myip"); - jaddstr(json,"myip",myinfo->ipaddr); - return(json); - }*/ - - - void ramcoder_test(void *data,int64_t datalen) - { - static double totalin,totalout; - int32_t complen,bufsize = 1024 * 1024; uint8_t *buf; - buf = malloc(bufsize); - complen = ramcoder_compress(buf,bufsize,data,(int32_t)datalen); - totalin += datalen; - totalout += (complen >> 3); - printf("datalen.%d -> numbits.%d %d %.3f\n",(int32_t)datalen,complen,complen>>3,(double)totalin/totalout); - free(buf); - } - /*if ( (msgjson= cJSON_Parse(message)) != 0 ) - { - if ( (agent= jstr(msgjson,"agent")) != 0 && strcmp(agent,"SuperNET")) != 0 ) - { - safecopy(agentstr,agent,sizeof(agentstr)-1); - jdelete(msgjson,"agent"); - jaddstr(msgjson,"agent","SuperNET"); - jaddstr(msgjson,"destagent",agentstr); - } - if ( (method= jstr(msgjson,"method")) != 0 && strcmp(agent,"SuperNET")) != 0 ) - { - safecopy(methodstr,method,sizeof(methodstr)-1); - jdelete(msgjson,"method"); - jaddstr(msgjson,"method","DHTsend"); - jaddstr(msgjson,"destmethod",methodstr); - } - msgstr = jprint(msgjson,1); - msglen = (int32_t)strlen(msgstr); - hexstr = calloc(1,msglen*2+1); - flag = 1; - init_hexbytes_noT(hexstr,msgstr,msglen); - } - if ( flag != 0 ) - free(hexstr);*/ - //char str[65],str2[65],str3[65],str4[65]; - //int32_t i; for (i=0; i crc.%08x\n",bits256_str(str,myinfo->privkey),bits256_str(str2,destpub),bits256_str(str3,seed),bits256_str(str4,seed2),crc); - numbits = ramcoder_compress(&compressed[3],maxsize-3,serialized,len,seed2); - compressed[0] = (numbits & 0xff); - compressed[1] = ((numbits>>8) & 0xff); - compressed[2] = ((numbits>>16) & 0xff); - //printf("strlen.%d len.%d -> %s numbits.%d\n",(int32_t)strlen(jprint(json,0)),len,bits256_str(str,seed2),(int32_t)hconv_bitlen(numbits)); - if ( 0 ) - { - uint8_t space[9999]; - int32_t testlen = ramcoder_decompress(space,IGUANA_MAXPACKETSIZE,&compressed[3],numbits,seed2); - printf("len.%d -> testlen.%d cmp.%d\n",len,testlen,memcmp(space,serialized,testlen)); - int32_t i; for (i=0; i<3+hconv_bitlen(numbits); i++) - printf("%02x ",compressed[i]); - printf("complen.%d\n",i+3); - } - *complenp = (int32_t)hconv_bitlen(numbits) + 3; - - cJSON *SuperNET_bits2json(bits256 senderpub,bits256 sharedseed,uint8_t *serialized,uint8_t *space,int32_t datalen,int32_t iscompressed) - { - char destip[64],method[64],checkstr[5],agent[64],myipaddr[64],str[65],*hexmsg; uint64_t tag; - uint16_t apinum,checkc; uint32_t destipbits,myipbits; bits256 seed2; - int32_t numbits,dlen,iter,flag=0,len = 0; uint32_t crc,checkcrc; cJSON *json = cJSON_CreateObject(); - //int32_t i; for (i=0; i sizeof(crc) && dlen < IGUANA_MAXPACKETSIZE ) - { - crc = calc_crc32(0,&serialized[sizeof(crc)],dlen - sizeof(crc)); - iguana_rwnum(0,serialized,sizeof(checkcrc),&checkcrc); - //int32_t i; for (i=0; i %d != datalen.%d\n",numbits,(int32_t)hconv_bitlen(numbits)+3,datalen); - return(0); - } - } - if ( flag == 0 ) - return(0); - len += iguana_rwnum(0,&serialized[len],sizeof(uint32_t),&crc); - len += iguana_rwnum(0,&serialized[len],sizeof(uint32_t),&destipbits); - len += iguana_rwnum(0,&serialized[len],sizeof(uint32_t),&myipbits); - len += iguana_rwbignum(0,&serialized[len],sizeof(bits256),senderpub.bytes); - len += iguana_rwnum(0,&serialized[len],sizeof(tag),&tag); - len += iguana_rwnum(0,&serialized[len],sizeof(checkc),&checkc); - len += iguana_rwnum(0,&serialized[len],sizeof(apinum),&apinum); - //printf("-> dest.%x myip.%x senderpub.%llx tag.%llu\n",destipbits,myipbits,(long long)senderpub.txid,(long long)tag); - if ( SuperNET_num2API(agent,method,apinum) >= 0 ) - { - jaddstr(json,"agent",agent); - jaddstr(json,"method",method); - expand_ipbits(destip,destipbits), jaddstr(json,"yourip",destip); - expand_ipbits(myipaddr,myipbits), jaddstr(json,"myip",myipaddr); - jaddstr(json,"mypub",bits256_str(str,senderpub)); - jadd64bits(json,"tag",tag); - init_hexbytes_noT(checkstr,(void *)&checkc,sizeof(checkc)); - jaddstr(json,"check",checkstr); - if ( len < datalen ) - { - printf("len %d vs %d datalen\n",len,datalen); - hexmsg = malloc(((datalen - len)<<1) + 1); - init_hexbytes_noT(hexmsg,&serialized[len],datalen - len); - printf("hex.(%s)\n",hexmsg); - jaddstr(json,"message",hexmsg); - free(hexmsg); - } - //printf("bits2json.(%s)\n",jprint(json,0)); - return(json); - } else printf("cant decode apinum.%d (%d.%d)\n",apinum,apinum>>5,apinum%0x1f); - return(0); - } - -#ifdef notyet - - int32_t SuperNET_serialize(int32_t reverse,bits256 *senderpubp,uint64_t *senderbitsp,bits256 *sigp,uint32_t *timestampp,uint64_t *destbitsp,uint8_t *origbuf) - { - uint8_t *buf = origbuf; long extra = sizeof(bits256) + sizeof(uint64_t) + sizeof(uint64_t); - buf += SuperNET_copybits(reverse,buf,(void *)destbitsp,sizeof(uint64_t)); - buf += SuperNET_copybits(reverse,buf,senderpubp->bytes,sizeof(bits256)); - buf += SuperNET_copybits(reverse,buf,(void *)senderbitsp,sizeof(uint64_t)); - buf += SuperNET_copybits(reverse,buf,(void *)timestampp,sizeof(uint32_t)), extra += sizeof(uint32_t); - if ( *senderbitsp != 0 ) - buf += SuperNET_copybits(reverse,buf,sigp->bytes,sizeof(bits256)), extra += sizeof(bits256); - else memset(sigp,0,sizeof(*sigp)); - if ( ((long)buf - (long)origbuf) != extra ) - { - printf("SuperNET_serialize: extrasize mismatch %ld vs %ld\n",((long)buf - (long)origbuf),extra); - } - return((int32_t)extra); - } - - int32_t SuperNET_decode(uint64_t *senderbitsp,bits256 *sigp,uint32_t *timestampp,uint64_t *destbitsp,uint8_t *str,uint8_t *cipher,int32_t *lenp,uint8_t *myprivkey) - { - bits256 srcpubkey; uint8_t *nonce; int i,hdrlen,err=0,len = *lenp; - hdrlen = SuperNET_serialize(1,&srcpubkey,senderbitsp,sigp,timestampp,destbitsp,cipher); - cipher += hdrlen, len -= hdrlen; - if ( *destbitsp != 0 && *senderbitsp != 0 ) - { - nonce = cipher; - cipher += crypto_box_NONCEBYTES, len -= crypto_box_NONCEBYTES; - printf("decode ptr.%p[%d]\n",cipher,len); - err = crypto_box_open((uint8_t *)str,cipher,len,nonce,srcpubkey.bytes,myprivkey); - for (i=0; i %d %d\n",len,len+crypto_box_ZEROBYTES,len + crypto_box_ZEROBYTES + crypto_box_NONCEBYTES); - memset(cipher,0,len+crypto_box_ZEROBYTES); - memset(buf,0,crypto_box_ZEROBYTES); - memcpy(buf+crypto_box_ZEROBYTES,str,len); - printf("cryptobox.%p[%d]\n",cipher,len+crypto_box_ZEROBYTES); - crypto_box(cipher,buf,len+crypto_box_ZEROBYTES,nonce,destpubkey.bytes,myprivkey.bytes); - hdrlen += crypto_box_NONCEBYTES + crypto_box_ZEROBYTES; - } - else memcpy(&cipher[hdrlen],str,len); - if ( totalsize != len+hdrlen ) - printf("unexpected totalsize.%d != len.%d + hdrlen.%d %d\n",totalsize,len,hdrlen,len+hdrlen); - *cipherlenp = totalsize; - { - bits256 checksig; uint32_t checkstamp; uint64_t checksender,checkbits; int32_t checklen; - checklen = totalsize; - if ( SuperNET_decode(&checksender,&checksig,&checkstamp,&checkbits,(void *)buf,ptr,&checklen,myprivkey.bytes) == 0 ) - { - printf("decoded %u %llx checklen.%d\n",checkstamp,(long long)checkbits,checklen); - } else printf("encrypt/decrypt error\n"); - printf("decoded %u %llx checklen.%d\n",checkstamp,(long long)checkbits,checklen); - } - free(buf); - return(origcipher); - } - - int32_t SuperNET_decrypt(bits256 *senderpubp,uint64_t *senderbitsp,uint32_t *timestampp,bits256 mypriv,bits256 mypub,uint8_t *dest,int32_t maxlen,uint8_t *src,int32_t len) - { - bits256 seed,sig,msgpriv; uint64_t my64bits,destbits,senderbits,sendertmp,desttmp; - uint8_t *buf; int32_t hdrlen,diff,newlen = -1; HUFF H,*hp = &H; struct acct777_sig checksig; - *senderbitsp = 0; - my64bits = acct777_nxt64bits(mypub); - if ( (buf = calloc(1,maxlen)) == 0 ) - { - printf("SuperNET_decrypt cant allocate maxlen.%d\n",maxlen); - return(-1); - } - hdrlen = SuperNET_serialize(1,senderpubp,&senderbits,&sig,timestampp,&destbits,src); - if ( destbits != 0 && my64bits != destbits && destbits != acct777_nxt64bits(GENESIS_PUBKEY) ) - { - free(buf); - printf("SuperNET_decrypt received destination packet.%llu when my64bits.%llu len.%d\n",(long long)destbits,(long long)my64bits,len); - return(-1); - } - if ( memcmp(mypub.bytes,senderpubp->bytes,sizeof(mypub)) == 0 ) - { - if ( destbits != 0 ) - printf("SuperNET: got my own msg?\n"); - } - printf("decrypt(%d) destbits.%llu my64.%llu mypriv.%llx mypub.%llx senderpub.%llx shared.%llx\n",len,(long long)destbits,(long long)my64bits,(long long)mypriv.txid,(long long)mypub.txid,(long long)senderpubp->txid,(long long)seed.txid); - if ( SuperNET_decode(&sendertmp,&sig,timestampp,&desttmp,(void *)buf,src,&len,mypriv.bytes) == 0 ) - { - if ( (diff= (*timestampp - (uint32_t)time(NULL))) < 0 ) - diff = -diff; - if ( 1 && diff > SUPERNET_MAXTIMEDIFF ) - printf("diff.%d > %d %u vs %u\n",diff,SUPERNET_MAXTIMEDIFF,*timestampp,(uint32_t)time(NULL)); - else - { - if ( 0 ) - { - memset(seed.bytes,0,sizeof(seed)); - //for (i='0'; i<='9'; i++) - // SETBIT(seed.bytes,i); - //for (i='a'; i<='f'; i++) - // SETBIT(seed.bytes,i); - _init_HUFF(hp,len,buf), hp->endpos = (len << 3); - newlen = ramcoder_decoder(0,1,dest,maxlen,hp,&seed); - } - else memcpy(dest,buf,len), newlen = len; - //printf("T%d decrypted newlen.%d\n",threadid,newlen); - if ( senderbits != 0 && senderpubp->txid != 0 ) - { - *senderbitsp = senderbits; - if ( destbits == 0 ) - msgpriv = GENESIS_PRIVKEY; - else msgpriv = mypriv; - acct777_sign(&checksig,msgpriv,*senderpubp,*timestampp,dest,newlen); - if ( memcmp(checksig.sigbits.bytes,&sig,sizeof(checksig.sigbits)) != 0 ) - { - printf("sender.%llu sig %llx compare error vs %llx using sig->pub from %llu, broadcast.%d len.%d -> newlen.%d\n",(long long)senderbits,(long long)sig.txid,(long long)checksig.sigbits.txid,(long long)senderbits,destbits == 0,len,newlen); - //free(buf); - //return(0); - } //else printf("SIG VERIFIED newlen.%d (%llu -> %llu)\n",newlen,(long long)senderbits,(long long)destbits); - } - } - } else printf("%llu: SuperNET_decrypt skip: decode_cipher error len.%d -> newlen.%d\n",(long long)acct777_nxt64bits(mypub),len,newlen); - free(buf); - return(newlen); - } - - int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 destpub,bits256 mypriv,bits256 mypub,uint8_t *msg,int32_t len,uint8_t *data,int32_t delaymillis) - { - int32_t cipherlen,datalen,qlen=-1; bits256 seed; uint8_t *cipher; uint64_t destbits; struct acct777_sig sig; HUFF H,*hp = &H; - if ( destpub.txid != 0 ) - destbits = acct777_nxt64bits(destpub); - else - { - destbits = 0; - destpub = GENESIS_PUBKEY; - } - printf("SuperNET_sendmsg dest.%llu destpub.%llx priv.%llx pub.%llx\n",(long long)destbits,(long long)destpub.txid,(long long)mypriv.txid,(long long)mypub.txid); - memset(&sig,0,sizeof(sig)); - if ( mypub.txid == 0 || mypriv.txid == 0 ) - mypriv = curve25519_keypair(&mypub), sig.timestamp = (uint32_t)time(NULL); - else acct777_sign(&sig,mypriv,destpub,(uint32_t)time(NULL),msg,len); - if ( 0 ) - { - memset(seed.bytes,0,sizeof(seed)); - //seed = addr->sharedseed; - data = calloc(1,len*2); - _init_HUFF(hp,len*2,data); - /*for (i='0'; i<='9'; i++) - SETBIT(seed.bytes,i); - for (i='a'; i<='f'; i++) - SETBIT(seed.bytes,i);*/ - ramcoder_encoder(0,1,msg,len,hp,0,&seed); - datalen = (int32_t)hconv_bitlen(hp->bitoffset); - } - else data = msg, datalen = len; - if ( (cipher= SuperNET_encode(&cipherlen,data,datalen,destpub,mypriv,mypub,sig.signer64bits,sig.sigbits,sig.timestamp)) != 0 ) - { - qlen = iguana_queue_send(coin,addr,delaymillis,cipher,"SuperNETb",cipherlen,0,0); - free(cipher); - } - return(qlen); - } -#endif /*memset(senderpub.bytes,0,sizeof(senderpub)); -if ( iscompressed != 0 ) -{ -if ( (len= SuperNET_decrypt(&senderpub,&senderbits,×tamp,mypriv,mypub,space,IGUANA_MAXPACKETSIZE,serialized,datalen)) > 1 && len < IGUANA_MAXPACKETSIZE ) -{ -if ( memcmp(senderpub.bytes,addr->pubkey.bytes,sizeof(senderpub)) != 0 ) -{ -printf("got new pubkey.(%s) for %s\n",bits256_str(str,senderpub),addr->ipaddr); -addr->pubkey = senderpub; -addr->sharedseed = SuperNET_sharedseed(mypriv,senderpub); -} -serialized = space; -datalen = len; -len = 0; -} else printf("decrypt error len.%d origlen.%d\n",len,datalen); -}*/ - - - bits256 testprivkey(int32_t selector) - { - bits256 privkey; - memset(privkey.bytes,0,sizeof(privkey.bytes)); - privkey.bytes[15] = selector; - return(privkey); - } - - bits256 testpubkey(int32_t selector) - { - return(acct777_pubkey(testprivkey(selector))); - } - - /*char *pangea_univ(uint8_t *mypriv,cJSON *json) - { - char *addrtypes[][3] = { {"BTC","0","80"}, {"LTC","48"}, {"BTCD","60","bc"}, {"DOGE","30"}, {"VRC","70"}, {"OPAL","115"}, {"BITS","25"} }; - char *wipstr,*coin,*coinaddr,pubkeystr[67],rsaddr[64],destaddr[64],wifbuf[128]; uint8_t priv[32],pub[33],addrtype; int32_t i; - uint64_t nxt64bits; cJSON *retjson,*item; - PNACL_message("inside rosetta\n"); - if ( (coin= jstr(json,"coin")) != 0 ) - { - if ( (wipstr= jstr(json,"wif")) != 0 || (wipstr= jstr(json,"wip")) != 0 ) - { - PNACL_message("got wip.(%s)\n",wipstr); - btc_wip2priv(priv,wipstr); - } - else if ( (coinaddr= jstr(json,"addr")) != 0 ) - { - if ( getprivkey(priv,coin,coinaddr) < 0 ) - return(clonestr("{\"error\":\"cant get privkey\"}")); - } - } else memcpy(priv,mypriv,sizeof(priv)); - btc_priv2pub(pub,priv); - init_hexbytes_noT(pubkeystr,pub,33); - PNACL_message("pubkey.%s\n",pubkeystr); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"btcpubkey",pubkeystr); - for (i=0; inumaddrs; i++) - if ( sp->addrs[i] == pm ) - break; - if ( i == sp->numaddrs ) - return(clonestr("{\"error\":\"specified pm destination not at table\"}")); - } else i = -1; - pangea_sendcmd(hex,&sp->tp->hn,"chat",i,(void *)chatstr,(int32_t)strlen(chatstr)+1,pangea_ind(sp,sp->myslot),-1); - return(clonestr("{\"result\":\"chat message sent\"}")); - } - - /*void _pangea_chat(uint64_t senderbits,void *buf,int32_t len,int32_t senderind) - { - PNACL_message(">>>>>>>>>>> CHAT FROM.%d %llu: (%s)\n",senderind,(long long)senderbits,(char *)buf); - } - - else if ( strcmp(methodstr,"newtable") == 0 ) - retstr = pangea_newtable(juint(json,"threadid"),json,plugin->nxt64bits,*(bits256 *)plugin->mypriv,*(bits256 *)plugin->mypub,plugin->transport,plugin->ipaddr,plugin->pangeaport,juint(json,"minbuyin"),juint(json,"maxbuyin"),juint(json,"rakemillis")); - else if ( sender == 0 || sender[0] == 0 ) - { - if ( strcmp(methodstr,"start") == 0 ) - { - strcpy(retbuf,"{\"result\":\"start issued\"}"); - if ( (base= jstr(json,"base")) != 0 ) - { - if ( (maxplayers= juint(json,"maxplayers")) < 2 ) - maxplayers = 2; - else if ( maxplayers > CARDS777_MAXPLAYERS ) - maxplayers = CARDS777_MAXPLAYERS; - if ( jstr(json,"resubmit") == 0 ) - sprintf(retbuf,"{\"resubmit\":[{\"method\":\"start\"}, {\"bigblind\":\"%llu\"}, {\"ante\":\"%llu\"}, {\"rakemillis\":\"%u\"}, {\"maxplayers\":%d}, {\"minbuyin\":%d}, {\"maxbuyin\":%d}],\"pluginrequest\":\"SuperNET\",\"plugin\":\"InstantDEX\",\"method\":\"orderbook\",\"base\":\"%s\",\"exchange\":\"pangea\",\"allfields\":1}",(long long)j64bits(json,"bigblind"),(long long)j64bits(json,"ante"),juint(json,"rakemillis"),maxplayers,juint(json,"minbuyin"),juint(json,"maxbuyin"),jstr(json,"base")!=0?jstr(json,"base"):"BTCD"); - else if ( pangea_start(plugin,retbuf,base,0,j64bits(json,"bigblind"),j64bits(json,"ante"),juint(json,"rakemillis"),maxplayers,juint(json,"minbuyin"),juint(json,"maxbuyin"),json) < 0 ) - ; - } else strcpy(retbuf,"{\"error\":\"no base specified\"}"); - } - else if ( strcmp(methodstr,"status") == 0 ) - retstr = pangea_status(plugin->nxt64bits,j64bits(json,"tableid"),json); - } - - int32_t pangea_unzbuf(uint8_t *buf,char *hexstr,int32_t len) - { - int32_t i,j,len2; - for (len2=i=0; iclient->H.pubdata, sp = dp->table; - priv = hn->client->H.privdata; - if ( hn == 0 || hn->client == 0 || dp == 0 || priv == 0 ) - { - if ( Debuglevel > 2 ) - PNACL_message("pangea_poll: null hn.%p %p dp.%p priv.%p\n",hn,hn!=0?hn->client:0,dp,priv); - return(-1); - } - maxlen = (int32_t)(sizeof(bits256) * dp->N*dp->N*dp->numcards); - if ( (buf= malloc(maxlen)) == 0 ) - { - PNACL_message("pangea_poll: null buf\n"); - return(-1); - } - if ( dp != 0 && priv != 0 && (jsonstr= queue_dequeue(&hn->client->H.Q,1)) != 0 ) - { - //pangea_neworder(dp,dp->table,0,0); - //PNACL_message("player.%d GOT.(%s)\n",hn->client->H.slot,jsonstr); - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - *senderbitsp = j64bits(json,"sender"); - if ( (senderind= juint(json,"myind")) < 0 || senderind >= dp->N ) - { - PNACL_message("pangea_poll: illegal senderind.%d cardi.%d turni.%d (%s)\n",senderind,juint(json,"cardi"),juint(json,"turni"),jsonstr); - goto cleanup; - } - *timestampp = juint(json,"timestamp"); - hn->client->H.state = juint(json,"state"); - len = juint(json,"n"); - cmdstr = jstr(json,"cmd"); - if ( sp->myind < 0 ) - { - // check for reactivation command - goto cleanup; - } - if ( cmdstr != 0 && strcmp(cmdstr,"preflop") == 0 ) - { - if ( (hexstr= jstr(json,"data")) != 0 ) - len = pangea_unzbuf(buf,hexstr,len); - } - else if ( (hexstr= jstr(json,"data")) != 0 && strlen(hexstr) == (len<<1) ) - { - if ( len > maxlen ) - { - PNACL_message("len too big for pangea_poll\n"); - goto cleanup; - } - decode_hex(buf,len,hexstr); - } else if ( hexstr != 0 ) - PNACL_message("len.%d vs hexlen.%ld (%s)\n",len,(long)(strlen(hexstr)>>1),hexstr); - if ( cmdstr != 0 ) - { - if ( strcmp(cmdstr,"newhand") == 0 ) - pangea_newhand(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"ping") == 0 ) - pangea_ping(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"gotdeck") == 0 ) - pangea_gotdeck(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"ready") == 0 ) - pangea_ready(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"encoded") == 0 ) - pangea_encoded(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"final") == 0 ) - pangea_final(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"addfunds") == 0 ) - pangea_addfunds(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"preflop") == 0 ) - pangea_preflop(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"decoded") == 0 ) - pangea_decoded(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"card") == 0 ) - pangea_card(hn,json,dp,priv,buf,len,juint(json,"cardi"),senderind); - else if ( strcmp(cmdstr,"facedown") == 0 ) - pangea_facedown(hn,json,dp,priv,buf,len,juint(json,"cardi"),senderind); - else if ( strcmp(cmdstr,"faceup") == 0 ) - pangea_faceup(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"turn") == 0 ) - pangea_turn(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"confirmturn") == 0 ) - pangea_confirmturn(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"chat") == 0 ) - pangea_chat(*senderbitsp,buf,len,senderind); - else if ( strcmp(cmdstr,"action") == 0 ) - pangea_action(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"showdown") == 0 ) - pangea_showdown(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"summary") == 0 ) - pangea_gotsummary(hn,json,dp,priv,buf,len,senderind); - } - cleanup: - free_json(json); - } - free_queueitem(jsonstr); - } - free(buf); - return(hn->client->H.state); - } - - char *Pangea_bypass(uint64_t my64bits,uint8_t myprivkey[32],cJSON *json) - { - char *methodstr,*retstr = 0; - if ( (methodstr= jstr(json,"method")) != 0 ) - { - if ( strcmp(methodstr,"turn") == 0 ) - retstr = _pangea_input(my64bits,j64bits(json,"tableid"),json); - else if ( strcmp(methodstr,"status") == 0 ) - retstr = _pangea_status(my64bits,j64bits(json,"tableid"),json); - else if ( strcmp(methodstr,"mode") == 0 ) - retstr = _pangea_mode(my64bits,j64bits(json,"tableid"),json); - else if ( strcmp(methodstr,"buyin") == 0 ) - retstr = _pangea_buyin(my64bits,j64bits(json,"tableid"),json); - else if ( strcmp(methodstr,"history") == 0 ) - retstr = _pangea_history(my64bits,j64bits(json,"tableid"),json); - } - return(retstr); - }*/ - - /*sprintf(hex,"{\"cmd\":\"%s\",\"turni\":%d,\"myslot\":%d,\"myind\":%d,\"cardi\":%d,\"dest\":%d,\"sender\":\"%llu\",\"n\":%u,%s\"data\":\"",cmdstr,turni,priv->myslot,pangea_ind(dp->table,priv->myslot),cardi,destplayer,(long long)myinfo->myaddr.nxt64bits,(long)time(NULL),datalen,hoststr); - n = (int32_t)strlen(hex); - if ( strcmp(cmdstr,"preflop") == 0 ) - { - memcpy(&hex[n],data,datalen+1); - hexlen = (int32_t)strlen(hex)+1; - } - else - if ( data != 0 && datalen != 0 ) - init_hexbytes_noT(&hex[n],data,datalen); - strcat(hex,"\"}"); - if ( (json= cJSON_Parse(hex)) == 0 ) - { - PNACL_message("error creating json\n"); - return; - } - free_json(json); - hexlen = (int32_t)strlen(hex)+1;*/ - - - int32_t pangea_hexmsg(struct supernet_info *myinfo,struct pangea_msghdr *pm,int32_t len) - { - cJSON *argjson; char *method; bits256 tablehash; struct table_info *tp; int32_t flag = 0; - int32_t datalen; uint8_t *serialized; uint8_t tmp[sizeof(pm->sig)]; - acct777_rwsig(0,(void *)&pm->sig,(void *)tmp); - memcpy(&pm->sig,tmp,sizeof(pm->sig)); - datalen = len - (int32_t)sizeof(pm->sig); - serialized = (void *)((long)pm + sizeof(pm->sig)); - if ( pangea_validate(pm,acct777_msgprivkey(serialized,datalen),pm->sig.pubkey) == 0 ) - { - flag++; - iguana_rwbignum(0,pm->tablehash.bytes,sizeof(bits256),tablehash.bytes); - pm->tablehash = tablehash; - printf("<<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(pm->sig),(long)serialized-(long)pm,datalen,pm->sig.timestamp,pm->sig.allocsize,(char *)pm->serialized,serialized[datalen-1]); - if ( serialized[datalen-1] == 0 && (argjson= cJSON_Parse((char *)pm->serialized)) != 0 ) - { - tablehash = jbits256(argjson,"subhash"); - if ( (method= jstr(argjson,"cmd")) != 0 ) - { - if ( strcmp(method,"lobby") == 0 ) - { - //categoryhash = jbits256(argjson,"categoryhash"); - } - else if ( strcmp(method,"host") == 0 ) - { - if ( (tp= pangea_table(tablehash)) != 0 ) - { - pangea_gamecreate(&tp->G,pm->sig.timestamp,pm->tablehash,argjson); - tp->G.creatorbits = pm->sig.signer64bits; - } - char str[65],str2[65]; printf("new game detected (%s) vs (%s)\n",bits256_str(str,tablehash),bits256_str(str2,pm->tablehash)); - } - else if ( strcmp(method,"join") == 0 ) - { - printf("JOIN.(%s)\n",jprint(argjson,0)); - } - } - free_json(argjson); - } else printf("ERROR >>>>>>> (%s) cant parse\n",(char *)pm->serialized); - } - else - { - int32_t i; char str[65],str2[65]; - for (i=0; isig),(long)serialized-(long)pm,datalen,bits256_str(str,acct777_msgprivkey(serialized,datalen)),bits256_str(str2,pm->sig.pubkey)); - } - return(flag); - } - - if ( 0 && buf[len-1] == 0 && (argjson= cJSON_Parse((char *)buf)) != 0 ) - { - printf("RESULT.(%s)\n",jprint(argjson,0)); - free_json(argjson); - } - else if ( 0 ) - { - char *method; bits256 tablehash; struct table_info *tp; - int32_t datalen; uint8_t *serialized; uint8_t tmp[sizeof(pm->sig)]; - decode_hex(buf,len,result); - pm = (struct pangea_msghdr *)buf; - acct777_rwsig(0,(void *)&pm->sig,(void *)tmp); - memcpy(&pm->sig,tmp,sizeof(pm->sig)); - datalen = len - (int32_t)sizeof(pm->sig); - serialized = (void *)((long)pm + sizeof(pm->sig)); - char str[65]; printf("OLD pm.%p len.%d serialized.%p datalen.%d crc.%u %s\n",pm,len,serialized,datalen,calc_crc32(0,(void *)pm,len),bits256_str(str,pm->sig.pubkey)); - if ( pangea_validate(pm,acct777_msgprivkey(serialized,datalen),pm->sig.pubkey) == 0 ) - { - iguana_rwbignum(0,pm->tablehash.bytes,sizeof(bits256),tablehash.bytes); - pm->tablehash = tablehash; - printf("<<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(pm->sig),(long)serialized-(long)pm,datalen,pm->sig.timestamp,pm->sig.allocsize,(char *)pm->serialized,serialized[datalen-1]); - if ( serialized[datalen-1] == 0 && (argjson= cJSON_Parse((char *)pm->serialized)) != 0 ) - { - tablehash = jbits256(argjson,"subhash"); - if ( (method= jstr(argjson,"cmd")) != 0 ) - { - if ( strcmp(method,"lobby") == 0 ) - { - //categoryhash = jbits256(argjson,"categoryhash"); - } - else if ( strcmp(method,"host") == 0 ) - { - if ( (tp= pangea_table(tablehash)) != 0 ) - { - pangea_gamecreate(&tp->G,pm->sig.timestamp,pm->tablehash,argjson); - tp->G.creatorbits = pm->sig.signer64bits; - } - char str[65],str2[65]; printf("new game detected (%s) vs (%s)\n",bits256_str(str,tablehash),bits256_str(str2,pm->tablehash)); - } - else if ( strcmp(method,"join") == 0 ) - { - printf("JOIN.(%s)\n",jprint(argjson,0)); - } - } - free_json(argjson); - } else printf("ERROR >>>>>>> (%s) cant parse\n",(char *)pm->serialized); - } - else - { - int32_t i; char str[65],str2[65]; - for (i=0; isig),(long)serialized-(long)pm,datalen,bits256_str(str,acct777_msgprivkey(serialized,datalen)),bits256_str(str2,pm->sig.pubkey)); - } - } - while ( 0 && (retstr= SuperNET_gethexmsg(IGUANA_CALLARGS,"pangea",0)) != 0 ) - { - flag = 0; - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - - if ( (result= jstr(retjson,"result")) != 0 ) - { - len = (int32_t)strlen(result); - if ( is_hexstr(result,len) > 0 ) - { - len >>= 1; - buf = malloc(len); - decode_hex(buf,len,result); - lag = pangea_hexmsg(myinfo,(struct pangea_msghdr *)buf,len,remoteaddr); - } - } - free_json(retjson); - } - free(retstr); - if ( flag == 0 ) - break; - } - uint8_t hex[1024]; char hashstr[65]; bits256 hash,hash2; long l = strlen("c0fbdbb600b7000000010000000000000000000000000000000000000000000000000000000000000000000058283b1b3ea5ad73f9aabc571dedd442d06e4ad8b3867a4f495acacd93a1698a54405408ffff1e0fb2780001010100004000085401540000000000000000000000000000000000000000000000000000000000000000ffffffff0424ffff1d000401541c7568202c2034655320703032343131203a323030303a20304d47ff54ffff01ff0000000000000000000000000000fb00b6c0afdb0000060000009900a46df6901a15d0d99d5dc9efda9b44582b1d3c83a60d119d64e7c7d7000a3300a678b550a606416b7a09510b2f3f89ee88971b7164c6f93fce76bb6d620b5f0c0880ff540fff001ede04010300010000805e54080001000000000000000000000000000000000000000000000000000000000000ff00ffff03ff0151ff02ffff01ff00005d8a45780163761914a96651e5e6e52dfa8d18cb0c673000dcae95f23923ac88000000000000"); - l>>=1; - decode_hex(hex,(int32_t)l,"c0fbdbb600b7000000010000000000000000000000000000000000000000000000000000000000000000000058283b1b3ea5ad73f9aabc571dedd442d06e4ad8b3867a4f495acacd93a1698a54405408ffff1e0fb2780001010100004000085401540000000000000000000000000000000000000000000000000000000000000000ffffffff0424ffff1d000401541c7568202c2034655320703032343131203a323030303a20304d47ff54ffff01ff0000000000000000000000000000fb00b6c0afdb0000060000009900a46df6901a15d0d99d5dc9efda9b44582b1d3c83a60d119d64e7c7d7000a3300a678b550a606416b7a09510b2f3f89ee88971b7164c6f93fce76bb6d620b5f0c0880ff540fff001ede04010300010000805e54080001000000000000000000000000000000000000000000000000000000000000ff00ffff03ff0151ff02ffff01ff00005d8a45780163761914a96651e5e6e52dfa8d18cb0c673000dcae95f23923ac88000000000000"); - vcalc_sha256(0,hash.bytes,hex+24,(int32_t)l-24); - vcalc_sha256(hashstr,hash2.bytes,hash.bytes,sizeof(hash)); - printf("ghash.(%s)\n",hashstr); - - getchar(); - - - bits256 issue_getpubkey(int32_t *haspubkeyp,char *acct) - { - cJSON *json; bits256 pubkey; char cmd[4096],*jsonstr; struct destbuf pubkeystr; - sprintf(cmd,"%s?requestType=getAccountPublicKey&account=%s",NXTAPIURL,acct); - jsonstr = issue_curl(cmd); - pubkeystr.buf[0] = 0; - if ( haspubkeyp != 0 ) - *haspubkeyp = 0; - memset(&pubkey,0,sizeof(pubkey)); - if ( jsonstr != 0 ) - { - printf("PUBKEYRPC.(%s)\n",jsonstr); - if ( (json = cJSON_Parse(jsonstr)) != 0 ) - { - copy_cJSON(&pubkeystr,cJSON_GetObjectItem(json,"publicKey")); - free_json(json); - if ( strlen(pubkeystr.buf) == sizeof(pubkey)*2 ) - { - if ( haspubkeyp != 0 ) - *haspubkeyp = 1; - decode_hex(pubkey.bytes,sizeof(pubkey),pubkeystr.buf); - } - } - free(jsonstr); - } - return(pubkey); - } - - int32_t iguana_rwtxbytes(struct iguana_info *coin,int32_t rwflag,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_msgtx *tx) - { - int32_t i,len = 0; char str[65],str2[65],txidstr[65]; uint32_t numvins,numvouts; bits256 txid; - len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->version),&tx->version); - if ( coin->chain->hastimestamp != 0 ) - len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->timestamp),&tx->timestamp); - numvins = tx->tx_in, numvouts = tx->tx_out; - len += iguana_rwvarint32(rwflag,&serialized[len],&numvins); - for (i=0; ivins[i]); - if ( len > maxlen ) - return(0); - len += iguana_rwvarint32(rwflag,&serialized[len],&numvouts); - for (i=0; ivouts[i]); - if ( len > maxlen ) - return(0); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->lock_time),&tx->lock_time); - txid = bits256_doublesha256(txidstr,serialized,len); - if ( rwflag != 0 ) - tx->txid = txid; - else *txidp = txid; - if ( bits256_nonz(*txidp) > 0 && memcmp(txidp,tx->txid.bytes,sizeof(*txidp)) != 0 ) - { - printf("iguana_rwtxbytes.rw%d: txid.%s vs %s\n",rwflag,bits256_str(str,tx->txid),bits256_str(str2,*txidp)); - return(0); - } - return(len); - } - - void pktest() - { - bits256 p,pub; uint8_t *data,*pubkey,sig[128],*sigptr; struct bp_key key; size_t pubk_len; - int32_t s,v,v2,v4=-99,v3=-99,datalen; uint32_t siglen; EC_KEY *KEY; - //bp_key_init(&key); - // bp_key_generate(&key); - OS_randombytes(p.bytes,sizeof(p)); - - data = (uint8_t *)"hello", datalen = (int32_t)strlen("hello"); - //s = bp_sign(key.k,data,datalen,(void **)&sigptr,&siglen); - //sigptr = sig; - //siglen = iguana_sig(sig,sizeof(sig),data,datalen,p); - //const unsigned char *privkey; - //bp_privkey_set(&key,p.bytes,sizeof(p)); - //bp_pubkey_get(&key,(void **)&pubkey,&pubk_len); - //memcpy(pub.bytes,pubkey+1,sizeof(pub)); - KEY = bitcoin_privkeyset(&pub,p); - siglen = bitcoin_sign(sig,sizeof(sig),data,datalen,p); - s = siglen > 0; - // char str[65]; printf("siglen.%d pk_len.%ld %s\n",siglen,pubk_len,bits256_str(str,*(bits256 *)(pubkey+1))); - - //s = ECDSA_sign(0,data,datalen,sig,&siglen,KEY); - v2 = bp_verify(KEY,data,datalen,sig,siglen); - //bp_pubkey_get(&key,(void **)&pubkey,&pubk_len); - //bp_key_init(&key); - - v3 = bitcoin_verify(sig,siglen,data,datalen,pub); - //v = iguana_ver(sig,siglen,data,datalen,pub); - printf("s.%d siglen.%d v2.%d v3.%d v4.%d\n",s,siglen,v2,v3,v4); - getchar(); - } - http://bitcoin.stackexchange.com/questions/3374/how-to-redeem-a-basic-tx - //msgtx->vins[i].scriptlen = scriptlen; - //printf("VINI.%d (%s)\n",vini,jprint(bitcoin_txjson(coin,msgtx),1)); - //decode_hex(privkey.bytes,sizeof(privkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725"); - //printf("privkey.%s\n",bits256_str(str,privkey)); - //EC_KEY *KEY = bitcoin_privkeyset(&pkey,privkey); - char *refstr = "01000000\ - 01\ - eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2\ - 01000000\ - 8c\ - 4930460221009e0339f72c793a89e664a8a932df073962a3f84eda0bd9e02084a6a9567f75aa022100bd9cbaca2e5ec195751efdfac164b76250b1e21302e51ca86dd7ebd7020cdc0601410450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6\ - ffffffff\ - 01\ - 605af40500000000\ - 19\ - 76a914097072524438d003d23a2f23edb65aae1bb3e46988ac\ - 00000000"; - - char *iguana_txcreate(struct iguana_info *coin,uint8_t *space,int32_t maxlen,char *jsonstr) - { - struct iguana_txid T; struct iguana_msgvin *vins,*vin; struct iguana_msgvout *vouts,*vout; - char *redeemstr; - cJSON *array,*json,*item,*retjson = 0; bits256 scriptPubKey; int32_t i,numvins,numvouts,len = 0; - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - memset(&T,0,sizeof(T)); - if ( (T.version= juint(json,"version")) == 0 ) - T.version = 1; - if ( (T.locktime= juint(json,"locktime")) == 0 ) - T.locktime = 0xffffffff; - vins = (struct iguana_msgvin *)&space[len]; - if ( (array= jarray(&numvins,json,"vins")) != 0 ) - { - len += sizeof(*vins) * numvins; - memset(vins,0,sizeof(*vins) * numvins); - //struct iguana_msgvin { bits256 prev_hash; uint8_t *script; uint32_t prev_vout,scriptlen,sequence; }; - for (i=0; iprev_hash = jbits256(item,"txid"); - vin->prev_vout = juint(item,"vout"); - vin->sequence = juint(item,"sequence"); - scriptPubKey = jbits256(item,"scriptPubKey"); - if ( bits256_nonz(scriptPubKey) > 0 ) - { - if ( (redeemstr= jstr(item,"redeemScript")) == 0 ) - { - vin->scriptlen = (int32_t)strlen(redeemstr); - if ( (vin->scriptlen & 1) != 0 ) - { - free_json(json); - return(clonestr("{\"error\":\"odd redeemScript length\"}")); - } - vin->scriptlen >>= 1; - vin->script = &space[len], len += vin->scriptlen; - } - } - } - } - vouts = (struct iguana_msgvout *)&space[len]; - if ( (array= jarray(&numvouts,json,"vouts")) != 0 ) - { - len += sizeof(*vouts) * numvouts; - memset(vouts,0,sizeof(*vouts) * numvouts); - //struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; }; - for (i=0; i 0 ) - { - - } - free_json(json); - } - if ( retjson == 0 ) - retjson = cJSON_Parse("{\"error\":\"couldnt create transaction\"}"); - return(jprint(retjson,1)); - } - - /* - if ( bp_key_init(&key) != 0 && bp_key_secret_set(&key,privkey,32) != 0 ) - { - if ( (T= calloc(1,sizeof(*T))) == 0 ) - return(0); - *T = *refT; vin = &T->inputs[redeemi]; - for (i=0; inuminputs; i++) - strcpy(T->inputs[i].sigs,"00"); - strcpy(vin->sigs,redeemscript); - vin->sequence = (uint32_t)-1; - T->nlocktime = 0; - //disp_cointx(&T); - emit_cointx(&hash2,data,sizeof(data),T,oldtx_format,SIGHASH_ALL); - //printf("HASH2.(%llx)\n",(long long)hash2.txid); - if ( bp_sign(&key,hash2.bytes,sizeof(hash2),&sig,&siglen) != 0 ) - { - memcpy(sigbuf,sig,siglen); - sigbuf[siglen++] = SIGHASH_ALL; - init_hexbytes_noT(sigs[privkeyind],sigbuf,(int32_t)siglen); - strcpy(vin->sigs,"00"); - for (i=0; isigs + strlen(vin->sigs),"%02x%s",(int32_t)strlen(sigs[i])>>1,sigs[i]); - //printf("(%s).%ld ",sigs[i],strlen(sigs[i])); - } - } - len = (int32_t)(strlen(redeemscript)/2); - if ( len >= 0xfd ) - sprintf(&vin->sigs[strlen(vin->sigs)],"4d%02x%02x",len & 0xff,(len >> 8) & 0xff); - else sprintf(&vin->sigs[strlen(vin->sigs)],"4c%02x",len); - sprintf(&vin->sigs[strlen(vin->sigs)],"%s",redeemscript); - //printf("after A.(%s) othersig.(%s) siglen.%02lx -> (%s)\n",hexstr,othersig != 0 ? othersig : "",siglen,vin->sigs); - //printf("vinsigs.(%s) %ld\n",vin->sigs,strlen(vin->sigs)); - _emit_cointx(hexstr,sizeof(hexstr),T,oldtx_format); - //disp_cointx(&T); - free(T); - return(clonestr(hexstr)); - } - */ - - - /*static char *validateretstr(struct iguana_info *coin,char *coinaddr) - { - char *retstr,buf[512]; cJSON *json; - if ( iguana_addressvalidate(coin,coinaddr) < 0 ) - return(clonestr("{\"error\":\"invalid coin address\"}")); - sprintf(buf,"{\"agent\":\"ramchain\",\"coin\":\"%s\",\"method\":\"validate\",\"address\":\"%s\"}",coin->symbol,coinaddr); - if ( (json= cJSON_Parse(buf)) != 0 ) - retstr = ramchain_coinparser(coin,"validate",json); - else return(clonestr("{\"error\":\"internal error, couldnt parse validate\"}")); - free_json(json); - return(retstr); - } - - static char *validatepubkey(RPCARGS) - { - char *pubkeystr,coinaddr[128]; cJSON *retjson; - retjson = cJSON_CreateObject(); - if ( params[0] != 0 && (pubkeystr= jstr(params[0],0)) != 0 ) - { - if ( btc_coinaddr(coinaddr,coin->chain->pubval,pubkeystr) == 0 ) - return(validateretstr(coin,coinaddr)); - return(clonestr("{\"error\":\"cant convert pubkey\"}")); - } - return(clonestr("{\"error\":\"need pubkey\"}")); - }*/ - - int32_t bitcoin_outputscript(struct iguana_info *coin,char *pubkeys[],int32_t *scriptlenp,uint8_t *scriptspace,bits256 txid,int32_t vout) - { - struct iguana_txid T,*tx; int32_t height,numpubs = 1; char asmstr[8192]; struct iguana_msgvout v; - if ( 0 ) - { - *scriptlenp = 0; - if ( (tx= iguana_txidfind(coin,&height,&T,txid)) != 0 ) - { - *scriptlenp = iguana_voutset(coin,scriptspace,asmstr,height,&v,tx,vout); - return(numpubs); - } - } - //char *str = "2103506a52e95cdfbb9d17d702af6259ba7de8b7a604007999e0266edbf6e4bb6974ac"; - char *str = "76a914010966776006953d5567439e5e39f86a0d273bee88ac"; - *scriptlenp = (int32_t)strlen(str) >> 1; - decode_hex(scriptspace,*scriptlenp,str); - //pubkeys[0] = clonestr("03506a52e95cdfbb9d17d702af6259ba7de8b7a604007999e0266edbf6e4bb6974"); - pubkeys[0] = clonestr("0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6"); - return(numpubs); - } - - cJSON *bitcoin_txjson(struct iguana_info *coin,struct iguana_msgtx *msgtx,struct vin_info *V) - { - char vpnstr[2]; int32_t n; uint8_t *serialized; bits256 txid; cJSON *json = cJSON_CreateObject(); - vpnstr[0] = 0; - serialized = malloc(IGUANA_MAXPACKETSIZE); - if ( (n= iguana_rwmsgtx(coin,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&txid,vpnstr,V)) < 0 ) - { - printf("bitcoin_txtest: n.%d\n",n); - } - free(serialized); - return(json); - } - - /*{ - for (i=0; inuminputs; i++) - strcpy(T->inputs[i].sigs,"00"); - strcpy(vin->sigs,redeemscript); - vin->sequence = (uint32_t)-1; - T->nlocktime = 0; - //disp_cointx(&T); - emit_cointx(&hash2,data,sizeof(data),T,oldtx_format,SIGHASH_ALL); - //printf("HASH2.(%llx)\n",(long long)hash2.txid); - if ( bp_sign(&key,hash2.bytes,sizeof(hash2),&sig,&siglen) != 0 ) - { - memcpy(sigbuf,sig,siglen); - sigbuf[siglen++] = SIGHASH_ALL; - init_hexbytes_noT(sigs[privkeyind],sigbuf,(int32_t)siglen); - strcpy(vin->sigs,"00"); - for (i=0; isigs + strlen(vin->sigs),"%02x%s",(int32_t)strlen(sigs[i])>>1,sigs[i]); - //printf("(%s).%ld ",sigs[i],strlen(sigs[i])); - } - } - len = (int32_t)(strlen(redeemscript)/2); - if ( len >= 0xfd ) - sprintf(&vin->sigs[strlen(vin->sigs)],"4d%02x%02x",len & 0xff,(len >> 8) & 0xff); - else sprintf(&vin->sigs[strlen(vin->sigs)],"4c%02x",len); - sprintf(&vin->sigs[strlen(vin->sigs)],"%s",redeemscript); - //printf("after A.(%s) othersig.(%s) siglen.%02lx -> (%s)\n",hexstr,othersig != 0 ? othersig : "",siglen,vin->sigs); - //printf("vinsigs.(%s) %ld\n",vin->sigs,strlen(vin->sigs)); - _emit_cointx(hexstr,sizeof(hexstr),T,oldtx_format); - //disp_cointx(&T); - free(T); - return(clonestr(hexstr)); - } - else printf("error signing\n"); - free(T); - }*/ - - /*cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height,struct vin_info *V) - { - struct iguana_msgvin vin; struct iguana_msgvout vout; int32_t i; char asmstr[512],str[65]; uint8_t space[8192]; - cJSON *vouts,*vins,*json; - json = cJSON_CreateObject(); - jaddstr(json,"txid",bits256_str(str,tx->txid)); - if ( height >= 0 ) - jaddnum(json,"height",height); - jaddnum(json,"version",tx->version); - jaddnum(json,"timestamp",tx->timestamp); - jaddnum(json,"locktime",tx->locktime); - vins = cJSON_CreateArray(); - vouts = cJSON_CreateArray(); - for (i=0; inumvouts; i++) - { - iguana_voutset(coin,space,asmstr,height,&vout,tx,i); - jaddi(vouts,iguana_voutjson(coin,&vout,i,tx->txid)); - } - jadd(json,"vout",vouts); - for (i=0; inumvins; i++) - { - iguana_vinset(coin,height,&vin,tx,i); - jaddi(vins,iguana_vinjson(coin,&vin,V != 0 ? &V[i] : 0)); - } - jadd(json,"vin",vins); - return(json); - }*/ - - /* - if ( strcmp(cmdstr+3,"offer") == 0 ) - { - - } - if ( (price= instantdex_acceptable(myinfo,0,refstr,base,rel,volume)) > 0. ) - { - // sends NXT assetid, volume and desired - if ( strcmp(base,"NXT") == 0 || strcmp(base,"nxt") == 0 ) - assetbits = NXT_ASSETID; - else if ( is_decimalstr(base) > 0 ) - assetbits = calc_nxt64bits(base); - if ( assetbits != 0 ) - { - nextcmd = INSTANTDEX_REQUEST; - nextcmdstr = "request"; - } - } - } - else if ( strncmp(cmdstr,"ALT",3) == 0 ) - { - if ( (price= instantdex_acceptable(myinfo,0,refstr,base,rel,volume)) > 0. ) - { - // sends NXT assetid, volume and desired - if ( strcmp(base,"NXT") == 0 || strcmp(base,"nxt") == 0 ) - assetbits = NXT_ASSETID; - else if ( is_decimalstr(base) > 0 ) - assetbits = calc_nxt64bits(base); - if ( assetbits != 0 ) - { - nextcmd = INSTANTDEX_REQUEST; - nextcmdstr = "request"; - } - } - } - else if ( strncmp(cmdstr,"NXT",3) == 0 ) - { - if ( (price= instantdex_acceptable(myinfo,0,refstr,base,rel,volume)) > 0. ) - { - // sends NXT assetid, volume and desired - if ( strcmp(base,"NXT") == 0 || strcmp(base,"nxt") == 0 ) - assetbits = NXT_ASSETID; - else if ( is_decimalstr(base) > 0 ) - assetbits = calc_nxt64bits(base); - if ( assetbits != 0 ) - { - nextcmd = INSTANTDEX_REQUEST; - nextcmdstr = "request"; - } - } - } - { - - } - - if ( strcmp(cmdstr,"request") == 0 ) - { - // request: - // other node sends (othercoin, othercoinaddr, otherNXT and reftx that expires before phasedtx) - if ( (strcmp(rel,"BTC") == 0 || strcmp(base,"BTC") == 0) && (price= instantdex_acceptable(myinfo,0,refstr,base,rel,volume)) > 0. ) - { - //aveprice = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&totalvol,base,rel,volume,argjson); - set_NXTtx(myinfo,&feeT,assetbits,SATOSHIDEN*3,calc_nxt64bits(INSTANTDEX_ACCT),-1); - if ( (feejson= gen_NXT_tx_json(myinfo,fullhash,&feeT,0,1.)) != 0 ) - free_json(feejson); - nextcmd = INSTANTDEX_PROPOSE; - nextcmdstr = "proposal"; - othercoinaddr = myinfo->myaddr.BTC; - otherNXTaddr = myinfo->myaddr.NXTADDR; - } - } - else - { - if ( strcmp(cmdstr,"proposal") == 0 ) - { - // proposal: - // NXT node submits phasedtx that refers to it, but it wont confirm - nextcmd = INSTANTDEX_ACCEPT; - nextcmdstr = "accept"; - message = ""; - //instantdex_phasetxsubmit(refstr); - } - else if ( strcmp(cmdstr,"accept") == 0 ) - { - // accept: - // other node verifies unconfirmed has phasedtx and broadcasts cltv, also to NXT node, releases trigger - nextcmd = INSTANTDEX_CONFIRM; - nextcmdstr = "confirm"; - message = ""; - //instantdex_phasedtxverify(); - //instantdex_cltvbroadcast(); - //instantdex_releasetrigger(); - } - else if ( strcmp(cmdstr,"confirm") == 0 ) - { - // confirm: - // NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey - // BTC* node approves phased tx with onetimepubkey - //instantdex_cltvverify(); - //instantdex_phasetxapprove(); - return(clonestr("{\"error\":\"trade confirmed\"}")); - } - } - if ( nextcmd != 0 && (newjson= InstantDEX_argjson(refstr,message,othercoinaddr,otherNXTaddr,nextcmd,duration,flags)) != 0 ) - { - jaddnum(newjson,"price",price); - jaddnum(newjson,"volume",volume); - return(instantdex_sendcmd(myinfo,newjson,nextcmdstr,myinfo->ipaddr,INSTANTDEX_HOPS)); - } - } - return(clonestr("{\"error\":\"request needs argjson\"}")); - } - num = 0; - depth = 30; - request = jstr(argjson,"request"); - base = jstr(argjson,"base"); - rel = jstr(argjson,"rel"); - refstr = jstr(argjson,"refstr"); - volume = jdouble(argjson,"volume"); - duration = juint(argjson,"duration"); - flags = juint(argjson,"flags"); - nextcmd = 0; - nextcmdstr = message = ""; - - */ - if ( A->orderid != orderid ) - { - printf("orderid mismatch %llu vs %llu\n",(long long)orderid,(long long)A->orderid); - return(clonestr("{\"error\":\"instantdex_BTCswap orderid mismatch\"}")); - } - if ( senderaddr == 0 || strcmp(A->A.base,base) != 0 || strcmp(A->A.rel,"BTC") != 0 ) - { - printf("senderaddr.%p base.(%s vs %s) rel.(%s vs %s)\n",senderaddr,A->A.base,base,A->A.rel,"BTC"); - return(clonestr("{\"error\":\"instantdex_BTCswap base or rel mismatch\"}")); - } - { - printf("satoshis mismatch %llu vs %llu\n",(long long)satoshis,(long long)instantdex_relsatoshis(A->A.price64,A->A.basevolume64)); - return(clonestr("{\"error\":\"instantdex_BTCswap satoshis mismatch\"}")); - } - if ( othersatoshis != A->A.basevolume64 ) - { - printf("othersatoshis mismatch %llu vs %llu\n",(long long)satoshis,(long long)A->A.basevolume64); - return(clonestr("{\"error\":\"instantdex_BTCswap satoshis mismatch\"}")); - } - - /*TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,BTCoffer,othercoin,otherassetid,maxprice,othervolume) - { - if ( remoteaddr == 0 ) - return(instantdex_btcoffer(myinfo,exchanges777_find("bitcoin"),othercoin[0] != 0 ? othercoin : otherassetid,othervolume,maxprice)); - else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); - } - - STRING_AND_TWO_DOUBLES(InstantDEX,ALToffer,basecoin,minprice,basevolume) - { - int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *str; struct instantdex_accept A; - if ( remoteaddr == 0 ) - { - if ( iguana_coinfind(basecoin) == 0 ) - return(clonestr("{\"error\":\"InstantDEX basecoin is not active, need to addcoin\"}")); - instantdex_acceptset(&A,basecoin,"BTC",INSTANTDEX_OFFERDURATION,0,1,minprice,basevolume,myinfo->myaddr.nxt64bits); - argjson = instantdex_acceptsendjson(&A); - if ( minprice > 0. ) - { - if ( (str= InstantDEX_minaccept(IGUANA_CALLARGS,basecoin,"BTC",minprice,basevolume)) != 0 ) - free(str); - } - return(instantdex_sendcmd(myinfo,argjson,"ALToffer",myinfo->ipaddr,hops)); - } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); - } - - STRING_AND_TWO_DOUBLES(InstantDEX,NXToffer,assetid,minprice,basevolume) - { - int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *base,*str; struct instantdex_accept A; - if ( remoteaddr == 0 ) - { - if ( assetid == 0 || assetid[0] == 0 || strcmp(assetid,"0") == 0 || strcmp(assetid,"NXT") == 0 || strcmp(assetid,"nxt") == 0 ) - base = "NXT"; - else if ( is_decimalstr(assetid) <= 0 ) - return(clonestr("{\"error\":\"InstantDEX NXToffer illegal assetid\"}")); - else base = assetid; - instantdex_acceptset(&A,base,"BTC",INSTANTDEX_OFFERDURATION,0,1,minprice,basevolume,myinfo->myaddr.nxt64bits); - argjson = instantdex_acceptsendjson(&A); - if ( minprice > 0. ) - { - if ( (str= InstantDEX_minaccept(IGUANA_CALLARGS,base,"BTC",minprice,basevolume)) != 0 ) - free(str); - } - return(instantdex_sendcmd(myinfo,argjson,"NXToffer",myinfo->ipaddr,hops)); - } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); - } - */ - if ( sendprivs != 0 ) - { - printf("sendprivs.%d\n",sendprivs); - if ( swap->otherschoosei < 0 ) - printf("instantdex_newjson otherschoosei < 0 when sendprivs != 0\n"); - else - { - if ( privs == 0 && (privs= calloc(1,sizeof(*swap->privkeys))) == 0 ) - printf("instantdex_newjson couldnt allocate hex\n"); - else if ( hexstr == 0 && (hexstr= malloc(sizeof(*swap->privkeys) * 2 + 1)) == 0 ) - printf("instantdex_newjson couldnt allocate hexstr\n"); - else - { - memcpy(privs,swap->privkeys,sizeof(*swap->privkeys)); - memset(privs[swap->otherschoosei].bytes,0,sizeof(*privs)); - for (i=0; iprivkeys)/sizeof(*swap->privkeys); i++) - { - iguana_rwbignum(1,serialized,sizeof(privs[i]),privs[i].bytes); - memcpy(privs[i].bytes,serialized,sizeof(privs[i])); - } - } - } - } - - /*cJSON *instantdex_acceptsendjson(struct instantdex_accept *ap) - { - cJSON *json = cJSON_CreateObject(); - jaddstr(json,"b",ap->offer.base); - jaddstr(json,"r",ap->offer.rel); - jaddnum(json,"n",ap->offer.nonce); - jaddnum(json,"e",ap->offer.expiration); - jaddnum(json,"s",ap->offer.myside); - jaddnum(json,"d",ap->offer.acceptdir); - jadd64bits(json,"p",ap->offer.price64); - jadd64bits(json,"v",ap->offer.basevolume64); - jadd64bits(json,"o",ap->offer.offer64); - jadd64bits(json,"id",ap->orderid); - return(json); - }*/ - if ( A->offer.price64 != 0 ) - { - if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,A->orderid,"*","*",1)) != 0 ) - { - swap->state++; - A->info = swap; - printf(">>>>>>>>>> PENDING ORDER %llu\n",(long long)A->orderid); - } - } - if ( ap == 0 ) - { - printf("couldnt find accept?? dir.%d orderid.%llu\n",ap->offer.acceptdir,(long long)A->orderid); - free(swap); - return(clonestr("{\"error\":\"couldnt find order just created\"}")); - } - if ( strncmp(cmdstr,"BTC",3) == 0 ) - else if ( strncmp(cmdstr,"NXT",3) == 0 ) - retstr = instantdex_NXTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,serdata,datalen); - else if ( strncmp(cmdstr,"ALT",3) == 0 ) - retstr = instantdex_ALTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,serdata,datalen); - else if ( strncmp(cmdstr,"PAX",3) == 0 ) - retstr = instantdex_PAXswap(myinfo,exchanges777_find("PAX"),&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,serdata,datalen); - else return(clonestr("{\"error\":\"unrecognized atomic swap family\"}")); - if ( ap != 0 ) - { - ap->info = A.info; - ap->pendingvolume64 = A.pendingvolume64; - } - //printf("after swap ap.%p (%s)\n",ap,retstr); - return(retstr); - - char *instantdex_BTCswap(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *serdata,int32_t serdatalen) // receiving side - { - uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis; - struct instantdex_accept *ap; struct bitcoin_swapinfo *swap = 0; bits256 orderhash,traderpub; - struct iguana_info *coinbtc,*altcoin; cJSON *newjson=0; char *retstr=0; - relsatoshis = instantdex_relsatoshis(A->offer.price64,A->offer.basevolume64); - traderpub = jbits256(argjson,"traderpub"); - if ( (minperc= jdouble(argjson,"p")) < INSTANTDEX_MINPERC ) - minperc = INSTANTDEX_MINPERC; - coinbtc = iguana_coinfind("BTC"); - insurance = (satoshis[1] * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee prevents papercut attack - offerdir = instantdex_bidaskdir(A); - vcalc_sha256(0,orderhash.bytes,(void *)&A->offer,sizeof(ap->offer)); - swap = A->info; - if ( bits256_cmp(traderpub,myinfo->myaddr.persistent) == 0 ) - { - printf("got my own packet\n"); - return(clonestr("{\"result\":\"got my own packet\"}")); - } - printf("T.%d [%s] got %s.(%s/%s) %.8f vol %.8f %llu offerside.%d offerdir.%d swap.%p decksize.%ld/datalen.%d\n",bits256_cmp(traderpub,myinfo->myaddr.persistent),swap!=0?swap->nextstate:"",cmdstr,A->offer.base,A->offer.rel,dstr(A->offer.price64),dstr(A->offer.basevolume64),(long long)A->orderid,A->offer.myside,A->offer.acceptdir,A->info,sizeof(swap->deck),serdatalen); - if ( exchange == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap null exchange ptr\"}")); - if ( (altcoin= iguana_coinfind(A->offer.base)) == 0 || coinbtc == 0 ) - { - printf("other.%p coinbtc.%p (%s/%s)\n",altcoin,coinbtc,A->offer.base,A->offer.rel); - return(clonestr("{\"error\":\"instantdex_BTCswap cant find btc or other coin info\"}")); - } - if ( strcmp(A->offer.rel,"BTC") != 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap offer non BTC rel\"}")); - if ( orderhash.txid != A->orderid ) - return(clonestr("{\"error\":\"txid mismatches orderid\"}")); - if ( strcmp(cmdstr,"offer") == 0 ) // receiver is networkwide - { - if ( A->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) ) - return(clonestr("{\"error\":\"instantdex_BTCswap offer too close to expiration\"}")); - if ( (ap= instantdex_acceptable(myinfo,exchange,A,acct777_nxt64bits(traderpub),minperc)) != 0 ) - { - if ( A->info == 0 ) - { - swap = calloc(1,sizeof(struct bitcoin_swapinfo)); - swap->choosei = swap->otherschoosei = -1; - swap->othertrader = traderpub; - if ( offerdir > 0 ) - swap->bidid = A->orderid; - else swap->askid = A->orderid; - swap->isbob = (A->offer.myside ^ 1); - printf("%p SET ISBOB.%d orderid.%llu\n",ap,swap->isbob,(long long)A->orderid); - } - char str[65]; printf("GOT OFFER! %p (%s/%s) other.%s myside.%d next.%s\n",A->info,A->offer.base,A->offer.rel,bits256_str(str,traderpub),swap->isbob,swap->nextstate); - if ( (A->info= swap) != 0 ) - { - ap->info = swap; - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,orderhash,A,1)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}")); - else - { - // verify feetx - instantdex_pendingnotice(myinfo,exchange,ap,A->offer.basevolume64); - if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) - { - return(retstr); - } - else - { - // generate feetx to send - if ( swap->isbob != 0 ) - strcpy(swap->nextstate,"step2"); - else strcpy(swap->nextstate,"step3"); - return(instantdex_sendcmd(myinfo,&A->offer,newjson,"BTCstep1",traderpub,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); - } - } - } else return(clonestr("{\"error\":\"couldnt allocate swap info\"}")); - } - else - { - printf("no matching trade for %llu -> InstantDEX_minaccept isbob.%d\n",(long long)A->orderid,A->offer.myside); - if ( instantdex_offerfind(myinfo,exchange,0,0,A->orderid,"*","*",1) == 0 ) - { - ap = calloc(1,sizeof(*ap)); - *ap = *A; - queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); - return(clonestr("{\"result\":\"added new order to orderbook\"}")); - } else return(clonestr("{\"result\":\"order was already in orderbook\"}")); - } - } - else if ( swap == 0 ) - return(clonestr("{\"error\":\"no swap info\"}")); - if ( offerdir > 0 ) - swap->bidid = A->orderid; - else swap->askid = A->orderid; - if ( bits256_nonz(swap->othertrader) == 0 ) - swap->othertrader = traderpub; - else if ( bits256_cmp(traderpub,swap->othertrader) != 0 ) - { - printf("competing offer received for (%s/%s) %.8f %.8f\n",A->offer.base,A->offer.rel,dstr(A->offer.price64),dstr(A->offer.basevolume64)); - return(clonestr("{\"error\":\"no competing offers for now\"}")); - } - if ( bits256_nonz(swap->orderhash) == 0 ) - swap->orderhash = orderhash; - else if ( bits256_cmp(orderhash,swap->orderhash) != 0 ) - { - printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid); - return(clonestr("{\"error\":\"orderhash mismatch???\"}")); - } - swap->satoshis[0] = A->offer.basevolume64; - swap->satoshis[1] = relsatoshis; - swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee - if ( swap->minperc < minperc ) - swap->minperc = minperc; - return(instantdex_statemachine(myinfo,exchange,A,cmdstr,swap,argjson,serdata,serdatalen,altcoin,coinbtc)); - } - -#ifdef xxx - if ( strcmp(cmdstr,"step1") == 0 && strcmp(swap->nextstate,cmdstr) == 0 ) // either - { - printf("%s got step1, should have other's choosei\n",swap->isbob!=0?"BOB":"alice"); - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap step1 null newjson\"}")); - else if ( swap->otherschoosei < 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap step1, no didnt choosei\"}")); - else - { - printf("%s chose.%d\n",swap->isbob==0?"BOB":"alice",swap->otherschoosei); - if ( swap->isbob == 0 ) - swap->privAm = swap->privkeys[swap->otherschoosei]; - else swap->privBn = swap->privkeys[swap->otherschoosei]; - memset(&swap->privkeys[swap->otherschoosei],0,sizeof(swap->privkeys[swap->otherschoosei])); - if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) - return(retstr); - /*if ( swap->isbob == 0 ) - { - if ( (swap->feetx= instantdex_bobtx(myinfo,coinbtc,&swap->ftxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->otherschoosei],reftime,swap->insurance,1)) != 0 ) - { - jaddstr(newjson,"feetx",swap->feetx); - jaddbits256(newjson,"ftxid",swap->ftxid); - // broadcast to network - } - }*/ - if ( swap->isbob != 0 ) - { - strcpy(swap->nextstate,"step4"); - printf("BOB sends (%s), next.(%s)\n","BTCstep3",swap->nextstate); - } - else - { - strcpy(swap->nextstate,"step3"); - printf("Alice sends (%s), next.(%s)\n","BTCstep2",swap->nextstate); - } - return(instantdex_sendcmd(myinfo,&A->offer,newjson,swap->isbob != 0 ? "BTCstep3" : "BTCstep2",swap->othertrader,INSTANTDEX_HOPS,swap->privkeys,sizeof(swap->privkeys))); - } - } - else if ( strcmp(cmdstr,"step2") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // bob - { - printf("%s got step2, should have other's privkeys\n",swap->isbob!=0?"BOB":"alice"); - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap step2 null newjson\"}")); - else - { - instantdex_privkeysextract(myinfo,swap,serdata,serdatalen); - if ( swap->cutverified == 0 || swap->otherverifiedcut == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap step2, both sides didnt validate\"}")); - else - { - if ( (swap->deposit= instantdex_bobtx(myinfo,coinbtc,&swap->dtxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->otherschoosei],reftime,swap->satoshis[swap->isbob],1)) != 0 ) - { - jaddstr(newjson,"deposit",swap->deposit); - jaddbits256(newjson,"dtxid",swap->dtxid); - //jaddbits256(newjson,"pubBn",bitcoin_pubkey33(pubkey,swap->pubBn)); - // broadcast to network - strcpy(swap->nextstate,"step4"); - printf("BOB sends (%s), next.(%s)\n","BTCstep3",swap->nextstate); - return(instantdex_sendcmd(myinfo,&A->offer,newjson,"BTCstep3",swap->othertrader,INSTANTDEX_HOPS,0,0)); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step2, cant create deposit\"}")); - } - } //else return(clonestr("{\"error\":\"instantdex_BTCswap step2 invalid fee\"}")); - } - else if ( strcmp(cmdstr,"step3") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // alice - { - printf("Alice got step3 should have Bob's choosei\n"); - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap Alice step3 null newjson\"}")); - else - { - instantdex_privkeysextract(myinfo,swap,serdata,serdatalen); - if ( swap->cutverified == 0 || swap->otherverifiedcut == 0 || bits256_nonz(swap->pubBn) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap step3, both sides didnt validate\"}")); - else if ( instantdex_paymentverify(myinfo,coinbtc,swap,A,argjson,1) == 0 ) - { - //swap->pubAm = bitcoin_pubkey33(pubkey,swap->privkeys[swap->otherschoosei]); - if ( (swap->altpayment= instantdex_alicetx(myinfo,altcoin,swap->altmsigaddr,&swap->aptxid,swap->pubAm,swap->pubBn,swap->satoshis[swap->isbob])) != 0 ) - { - jaddstr(newjson,"altpayment",swap->altpayment); - jaddstr(newjson,"altmsigaddr",swap->altmsigaddr); - jaddbits256(newjson,"aptxid",swap->aptxid); - jaddbits256(newjson,"pubAm",swap->pubAm); - // broadcast to network - strcpy(swap->nextstate,"step5"); - printf("Alice sends (%s), next.(%s)\n","BTCstep4",swap->nextstate); - return(instantdex_sendcmd(myinfo,&A->offer,newjson,"BTCstep4",swap->othertrader,INSTANTDEX_HOPS,0,0)); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Alice step3, error making altpay\"}")); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Alice step3, invalid deposit\"}")); - } - } - else if ( strcmp(cmdstr,"step4") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // bob - { - printf("Bob got step4 should have Alice's altpayment\n"); - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap Bob step4 null newjson\"}")); - else if ( bits256_nonz(swap->pubAm) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap step4, no pubAm\"}")); - else if ( instantdex_altpaymentverify(myinfo,altcoin,swap,A,argjson) == 0 ) - { - if ( (swap->deposit= instantdex_bobtx(myinfo,coinbtc,&swap->ptxid,swap->mypubs[1],swap->otherpubs[0],swap->privkeys[swap->otherschoosei],reftime,swap->satoshis[swap->isbob],0)) != 0 ) - { - jaddstr(newjson,"payment",swap->payment); - jaddbits256(newjson,"ptxid",swap->ptxid); - // broadcast to network - strcpy(swap->nextstate,"step6"); - return(instantdex_sendcmd(myinfo,&A->offer,newjson,"BTCstep5",swap->othertrader,INSTANTDEX_HOPS,0,0)); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step4, cant create payment\"}")); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Alice step3, invalid deposit\"}")); - } - else if ( strcmp(cmdstr,"step5") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // alice - { - printf("Alice got step5 should have Bob's payment\n"); - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap Alice step5 null newjson\"}")); - else if ( instantdex_paymentverify(myinfo,coinbtc,swap,A,argjson,0) == 0 ) - { - strcpy(swap->nextstate,"step7"); - /*if ( (swap->spendtx= instantdex_spendpayment(myinfo,coinbtc,&swap->stxid,swap,argjson,newjson)) != 0 ) - { - // broadcast to network - return(instantdex_sendcmd(myinfo,&A->A,newjson,"BTCstep6",swap->othertrader,INSTANTDEX_HOPS)); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Alice step5, cant spend payment\"}"));*/ - } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step6, invalid payment\"}")); - } - else if ( strcmp(cmdstr,"step6") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // bob - { - printf("Bob got step6 should have Alice's privkey\n"); - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap Bob step6 null newjson\"}")); - strcpy(swap->nextstate,"step7"); - /*else if ( instantdex_spendverify(myinfo,coinbtc,swap,A,argjson,0) == 0 ) - { - if ( (swap->altspend= instantdex_spendaltpayment(myinfo,altcoin,&swap->astxid,swap,argjson,newjson)) != 0 ) - { - jaddstr(newjson,"altspend",swap->altspend); - jaddbits256(newjson,"astxid",swap->astxid); - // broadcast to network - return(clonestr("{\"result\":\"Bob finished atomic swap\"}")); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step6, cant spend altpayment\"}")); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step6, invalid spend\"}"));*/ - } - else if ( strcmp(cmdstr,"step7") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // both - { - // update status, goto refund if thresholds exceeded - retstr = clonestr("{\"result\":\"BTC swap updated state\"}"); - } - else retstr = clonestr("{\"error\":\"BTC swap got unrecognized command\"}"); - if ( retstr == 0 ) - retstr = clonestr("{\"error\":\"BTC swap null retstr\"}"); - if ( swap != 0 ) - printf("BTCSWAP next.(%s) (%s) isbob.%d nextstate.%s verified.(%d %d)\n",swap->nextstate,cmdstr,swap->isbob,swap->nextstate,swap->cutverified,swap->otherverifiedcut); - else printf("BTCSWAP.(%s)\n",retstr); - return(retstr); -#endif - else if ( strcmp(cmdstr,"BTCdeckC") == 0 ) - { - if ( ap->info == 0 ) - { - printf("A (%s) null swap for orderid.%llu p.%p\n",cmdstr,(long long)ap->orderid,ap); - return(clonestr("{\"error\":\"no swap for orderid\"}")); - } - else - { - if ( ap->otherorderid == 0 ) - { - ap->otherorderid = ap->orderid; - ap->otheroffer = ap->offer; - ap->offer = A.offer; - ap->orderid = A.orderid; - ((struct bitcoin_swapinfo *)ap->info)->feetag64 = ap->orderid; - } - printf("add to statemachine\n"); - queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0); - newjson = instantdex_parseargjson(myinfo,exchange,ap,argjson,0); - if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,ap->info,"BOB_sentoffer","ALICE_sentoffer")) == 0 ) - { - return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,ap,cmdstr,argjson,newjson,serdata,serdatalen)); - } else return(clonestr("{\"error\":\"couldnt add fee\"}")); - } - /* - for (iter=0; iter<2; iter++) - { - while ( (m= category_gethexmsg(myinfo,instantdexhash,iter == 0 ? GENESIS_PUBKEY : myinfo->myaddr.persistent)) != 0 ) - { - //printf("gothexmsg len.%d\n",m->len); - pm = (struct instantdex_msghdr *)m->msg; - if ( m->remoteipbits != 0 ) - expand_ipbits(remote,m->remoteipbits); - else remote[0] = 0; - if ( (str= InstantDEX_hexmsg(myinfo,pm,m->len,remote)) != 0 ) - free(str); - free(m); - } - }*/ - - /* uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis; - bits256 orderhash,traderpub; struct iguana_info *coinbtc; - if ( (swap= ap->info) == 0 ) - return(clonestr("{\"error\":\"no swapinfo set\"}")); - relsatoshis = instantdex_BTCsatoshis(ap->offer.price64,ap->offer.basevolume64); - if ( (minperc= jdouble(argjson,"m")) < INSTANTDEX_MINPERC ) - minperc = INSTANTDEX_MINPERC; - offerdir = instantdex_bidaskdir(&ap->offer); - if ( 0 ) - { - int32_t i; - for (i=0; ioffer); i++) - printf("%02x ",((uint8_t *)&ap->offer)[i]); - printf("swapset.%llu\n",(long long)ap->orderid); - } - if ( offerdir > 0 ) - { - swap->bidid = ap->orderid; - swap->askid = ap->otherorderid; - } - else - { - swap->askid = ap->orderid; - swap->bidid = ap->otherorderid; - } - if ( bits256_nonz(swap->othertrader) == 0 ) - swap->othertrader = traderpub; - else if ( bits256_cmp(traderpub,swap->othertrader) != 0 ) - { - printf("competing offer received for (%s/%s) %.8f %.8f\n",ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64)); - return(clonestr("{\"error\":\"no competing offers for now\"}")); - } - if ( bits256_nonz(swap->orderhash) == 0 ) - swap->orderhash = orderhash; - else if ( bits256_cmp(orderhash,swap->orderhash) != 0 ) - { - printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid); - return(clonestr("{\"error\":\"orderhash mismatch???\"}")); - } - swap->satoshis[0] = ap->offer.basevolume64; - swap->satoshis[1] = relsatoshis; - swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee - /* if ( ap->info == 0 ) - //printf("gotoffer SETSWAP for orderid.%llu (%s)\n",(long long)ap->orderid,jprint(argjson,0)); - swap->choosei = swap->otherschoosei = -1; - if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 ) - return(retstr); - swap->feetag64 = ap->orderid;*/ - - /*char *instantdex_swapset(struct supernet_info *myinfo,struct instantdex_accept *ap,cJSON *argjson) - { - uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis; - struct bitcoin_swapinfo *swap; bits256 orderhash,traderpub; struct iguana_info *coinbtc; - if ( (swap= ap->info) == 0 ) - return(clonestr("{\"error\":\"no swapinfo set\"}")); - relsatoshis = instantdex_BTCsatoshis(ap->offer.price64,ap->offer.basevolume64); - traderpub = jbits256(argjson,"traderpub"); - if ( (minperc= jdouble(argjson,"m")) < INSTANTDEX_MINPERC ) - minperc = INSTANTDEX_MINPERC; - if ( (coinbtc= iguana_coinfind("BTC")) == 0 ) - return(clonestr("{\"error\":\"no BTC found\"}")); - insurance = (satoshis[1] * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); - offerdir = instantdex_bidaskdir(&ap->offer); - vcalc_sha256(0,orderhash.bytes,(void *)&ap->offer,sizeof(ap->offer)); - if ( 0 ) - { - int32_t i; - for (i=0; ioffer); i++) - printf("%02x ",((uint8_t *)&ap->offer)[i]); - printf("swapset.%llu\n",(long long)ap->orderid); - } - if ( offerdir > 0 ) - { - swap->bidid = ap->orderid; - swap->askid = ap->otherorderid; - } - else - { - swap->askid = ap->orderid; - swap->bidid = ap->otherorderid; - } - if ( bits256_nonz(swap->othertrader) == 0 ) - swap->othertrader = traderpub; - else if ( bits256_cmp(traderpub,swap->othertrader) != 0 ) - { - printf("competing offer received for (%s/%s) %.8f %.8f\n",ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64)); - return(clonestr("{\"error\":\"no competing offers for now\"}")); - } - if ( bits256_nonz(swap->orderhash) == 0 ) - swap->orderhash = orderhash; - else if ( bits256_cmp(orderhash,swap->orderhash) != 0 ) - { - printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid); - return(clonestr("{\"error\":\"orderhash mismatch???\"}")); - } - swap->satoshis[0] = ap->offer.basevolume64; - swap->satoshis[1] = relsatoshis; - swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee - return(0); - } - - char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson) // Bob sending to network (Alice) - { - struct iguana_info *other; struct bitcoin_swapinfo *swap; int32_t isbob; cJSON *newjson; char *retstr; - if ( strcmp(ap->offer.rel,"BTC") != 0 ) - return(clonestr("{\"error\":\"invalid othercoin\"}")); - else if ( (other= iguana_coinfind(ap->offer.base)) == 0 ) - return(clonestr("{\"error\":\"invalid othercoin\"}")); - else if ( ap->offer.price64 <= 0 || ap->offer.basevolume64 <= 0 ) - return(clonestr("{\"error\":\"illegal price or volume\"}")); - isbob = (ap->offer.myside == 1); - swap = calloc(1,sizeof(struct bitcoin_swapinfo)); - swap->isbob = isbob; - swap->expiration = ap->offer.expiration;//(uint32_t)(time(NULL) + INSTANTDEX_LOCKTIME*isbob); - swap->choosei = swap->otherschoosei = -1; - swap->depositconfirms = swap->paymentconfirms = swap->altpaymentconfirms = swap->myfeeconfirms = swap->otherfeeconfirms = -1; - ap->info = swap; - printf("sendoffer SETSWAP for orderid.%llu ap.%p (%p)\n",(long long)ap->orderid,ap,swap); - if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 ) - return(retstr); - ap->orderid = swap->orderhash.txid; - if ( (newjson= instantdex_parseargjson(myinfo,exchange,ap,argjson,1)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}")); - else - { - //instantdex_bobtx(myinfo,iguana_coinfind("BTCD"),&swap->deposittxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->choosei],ap->offer.expiration-INSTANTDEX_LOCKTIME*2,swap->satoshis[1],1); - //instantdex_alicetx(myinfo,iguana_coinfind("BTCD"),swap->altmsigaddr,&swap->altpaymenttxid,swap->pubAm,swap->pubBn,swap->satoshis[0]); - if ( 0 ) - { - int32_t i; - for (i=0; ioffer); i++) - printf("%02x ",((uint8_t *)&ap->offer)[i]); - printf("BTCoffer.%llu\n",(long long)ap->orderid); - } - return(instantdex_sendcmd(myinfo,&ap->offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); - } - }*/ - /*ptr = (void *)bp->scriptsmap; - ind = unspentind << 1; - for (i=0; inumscriptsmaps; i++,ptr+=2) - { - if ( ind == ptr[0] ) - { - printf("bp.[%d] ind.%d offset.%d vs %ld\n",bp->hdrsi,ind,ptr[1],coin->scriptsfilesize); - if ( ptr[1] + sizeof(struct scriptdata) <= coin->scriptsfilesize ) - { - if ( memcmp((void *)((long)coin->scriptsptr + ptr[1] + sizeof(struct scriptdata)),spendscript,spendlen) == 0 ) - { - printf("matched against existing scriptsptr[%d] %d\n",ptr[1],spendlen); - return(ptr[1]); - } - printf("mismatch against existing scriptsptr[%d] %d\n",ptr[1],spendlen); - } - else - { - if ( (fp= fopen(coin->scriptsfname,"rb")) != 0 ) - { - fseek(fp,ptr[1] + sizeof(struct scriptdata),SEEK_SET); - for (i=0; ihdrsi,unspentind,i,ftell(fp),ptr[1],ptr[1]+sizeof(struct scriptdata)+spendlen,c,spendscript[i]); - for (; inumscriptsmaps >= bp->maxscriptsmaps ) - { - bp->scriptsmap = realloc(bp->scriptsmap,(1000+bp->maxscriptsmaps) * (sizeof(offset) + sizeof(ind))); - bp->maxscriptsmaps += 1000; - } - ptr = (void *)((long)bp->scriptsmap + bp->numscriptsmaps*size); - ptr[0] = ind; - ptr[1] = offset; - bp->numscriptsmaps++; - }*/ - - uint32_t iguana_scriptstableadd(struct iguana_info *coin,int32_t spendflag,uint32_t fpos,uint8_t *script,uint16_t scriptlen) - { - struct scriptinfo *ptr; - HASH_FIND(hh,coin->scriptstable[spendflag],script,scriptlen,ptr); - if ( ptr == 0 ) - { - ptr = mycalloc('w',1,sizeof(*ptr) + scriptlen); - ptr->fpos = fpos; - ptr->scriptlen = scriptlen; - memcpy(ptr->script,script,scriptlen); - HASH_ADD(hh,coin->scriptstable[spendflag],script,scriptlen,ptr); - } - return(fpos); - } - - uint32_t iguana_scriptstablefind(struct iguana_info *coin,int32_t spendflag,uint8_t *script,int32_t scriptlen) - { - struct scriptinfo *ptr; - HASH_FIND(hh,coin->scriptstable[spendflag],script,scriptlen,ptr); - if ( ptr != 0 ) - return(ptr->fpos); - else return(0); - } - - long iguana_rwscript(struct iguana_info *coin,int32_t rwflag,void *fileptr,long offset,long filesize,FILE *fp,struct iguana_bundle *bp,uint8_t **scriptptrp,int32_t *lenp,int32_t hdrsi,uint32_t ind,int32_t spendflag) - { - long scriptpos; struct scriptdata data; uint8_t *script = *scriptptrp; - if ( spendflag == 0 && (scriptpos= iguana_scriptstablefind(coin,spendflag,script,*lenp)) != 0 ) - return(scriptpos); - memset(&data,0,sizeof(data)); - if ( rwflag != 0 && fp != 0 && fileptr == 0 ) - { - scriptpos = ftell(fp); - data.ind = ind, data.spendflag = spendflag; - data.hdrsi = hdrsi; - data.scriptlen = *lenp; - if ( fwrite(&data,1,sizeof(data),fp) != sizeof(data) ) - return(-1); - if ( fwrite(script,1,data.scriptlen,fp) != data.scriptlen ) - return(-1); - offset = (uint32_t)ftell(fp); - //printf("spend.%d filesize.%ld wrote.h%d u%d len.%d [%ld,%ld) crc.%08x\n",spendflag,coin->scriptsfilesize[spendflag],hdrsi,ind,data.scriptlen,scriptpos,ftell(fp),calc_crc32(0,script,data.scriptlen)); - } - else if ( rwflag == 0 && fp == 0 && fileptr != 0 ) - { - scriptpos = offset; - if ( offset+sizeof(data) <= filesize ) - { - memcpy(&data,(void *)((long)fileptr + offset),sizeof(data)); - if ( data.scriptlen > 0 && data.scriptlen < *lenp && offset+sizeof(data)+data.scriptlen <= filesize ) - { - if ( data.scriptlen > 0 ) - { - *scriptptrp = script = (void *)((long)fileptr + offset); - offset += data.scriptlen + sizeof(data); - if ( data.hdrsi < coin->bundlescount ) - bp = coin->bundles[data.hdrsi]; - else printf("illegal hdrsi.%d/%d\n",data.hdrsi,coin->bundlescount); - } else printf("illegal scriptlen %d\n",data.scriptlen); - //printf("hdrsi.%d loaded script.%d %u s%d\n",data.hdrsi,data.scriptlen,data.ind,data.spendflag); - } - else if ( data.scriptlen > 0 ) - { - printf("spendlen overflow.%d vs %d\n",data.scriptlen,*lenp); - return(-1); - } - } - else - { - printf("error reading from %ld\n",scriptpos); - return(-1); - } - //printf("hdrsi.%d scriptlen.%d\n",data.hdrsi,data.scriptlen); - *lenp = data.scriptlen; - } - if ( bp != 0 ) - { - //if ( spendflag == 0 ) - iguana_scriptstableadd(coin,spendflag,(uint32_t)scriptpos,script,*lenp); - } - else if ( rwflag == 0 ) - { - printf("null bp for iguana_rwscript hdrsi.%d/%d\n",data.hdrsi,coin->bundlescount); - return(-1); - } - return(offset); - } - - long iguana_initscripts(struct iguana_info *coin) - { - long fpos=0,offset = 0; uint8_t scriptdata[IGUANA_MAXSCRIPTSIZE],*scriptptr; int32_t spendflag,size,n=0; struct scriptdata script; - for (spendflag=0; spendflag<2; spendflag++) - { - portable_mutex_lock(&coin->scripts_mutex[spendflag]); - sprintf(coin->scriptsfname[spendflag],"tmp/%s/%sscripts",coin->symbol,spendflag==0?"":"sig"), OS_portable_path(coin->scriptsfname[spendflag]); - printf("scripts fname.(%s)\n",coin->scriptsfname[spendflag]); - if ( (coin->scriptsptr[spendflag]= OS_mapfile(coin->scriptsfname[spendflag],&coin->scriptsfilesize[spendflag],0)) == 0 ) - { - coin->scriptsfp[spendflag] = fopen(coin->scriptsfname[spendflag],"wb"); - memset(&script,0,sizeof(script)); - fwrite(&script,1,sizeof(script),coin->scriptsfp[spendflag]); - } - else - { - while ( 1 ) - { - size = sizeof(scriptdata); - scriptptr = scriptdata; - if ( (offset= iguana_rwscript(coin,0,coin->scriptsptr[spendflag],offset,coin->scriptsfilesize[spendflag],0,0,&scriptptr,&size,0,0,spendflag)) < 0 ) - break; - else fpos = offset; - n++; - } - coin->scriptsfp[spendflag] = fopen(coin->scriptsfname[spendflag],"ab"); - portable_mutex_unlock(&coin->scripts_mutex[spendflag]); - printf("initialized %d scripts, fpos %ld\n",n,fpos); - return(offset); - } - portable_mutex_unlock(&coin->scripts_mutex[spendflag]); - } - return(-1); - } - - uint32_t iguana_scriptsave(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t ind,int32_t spendflag,uint8_t *script,int32_t scriptlen) - { - FILE *fp; long fpos = 0; - if ( scriptlen > 0 && (fp= coin->scriptsfp[spendflag]) != 0 ) - { - portable_mutex_lock(&coin->scripts_mutex[spendflag]); - fpos = ftell(fp); - if ( iguana_rwscript(coin,1,0,0,0,fp,bp,&script,&scriptlen,bp->hdrsi,ind,spendflag) < 0 ) - { - fseek(fp,fpos,SEEK_SET); - fpos = -1; - printf("error saving script at %ld\n",fpos); - } else fflush(fp); - portable_mutex_unlock(&coin->scripts_mutex[spendflag]); - } else printf("cant scriptsave.%d to (%s).%p scriptlen.%d\n",spendflag,coin->scriptsfname[spendflag],coin->scriptsfp[spendflag],scriptlen); - return((uint32_t)fpos); - } - - long iguana_scriptadd(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t unspentind,int32_t type,uint8_t *spendscript,int32_t spendlen,uint8_t rmd160[20],int32_t vout) - { - static long total,saved; - int32_t scriptlen; char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; uint8_t script[IGUANA_MAXSCRIPTSIZE]; long fpos=0; struct vin_info V,*vp = &V; - if ( spendlen == 0 ) - { - printf("null script?\n"); - getchar(); - return(0); - } - memset(vp,0,sizeof(*vp)); - asmstr[0] = 0; - total++; - scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,rmd160,type,(const struct vin_info *)vp,vout); - if ( scriptlen == spendlen && memcmp(script,spendscript,scriptlen) == 0 ) - return(0); - else - { - saved++; - //if ( (saved % 1000) == 0 ) - printf("add type.%d scriptlen.%d fpos.%ld saved.%ld/%ld\n",type,spendlen,coin->scriptsfp!=0?ftell(coin->scriptsfp[0]):-1,saved,total); - fpos = iguana_scriptsave(coin,bp,unspentind,0,spendscript,spendlen); - } - return(fpos); - } - if ( s->sighash != iguana_vinscriptparse(coin,&V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,vinscript,vinscriptlen) ) - { - static uint64_t counter; - if ( counter++ < 100 ) - { - for (i=0; isighash); - } - return(spendind); - } - //ramchain->H.stacksize += sigsize;// + 1 + (sigsize >= 0xfd)*2; - if ( s->numpubkeys > 0 ) - { - for (i=0; inumpubkeys; i++) - { - if ( (ptr= iguana_hashfind(ramchain,'P',V.signers[i].rmd160)) == 0 ) - { - //printf("from addspend\n"); - //pkind = iguana_ramchain_addpkhash(coin,RAMCHAIN_ARG,V.signers[i].rmd160,0,0,0); - //printf("create pkind.%d from vin\n",pkind); - } else pkind = ptr->hh.itemind; - } - } - if ( 0 && s->numsigs > 0 ) - printf("autoverify numsigs.%d\n",s->numsigs); - - - uint8_t *iguana_scriptptr(struct iguana_info *coin,int32_t *scriptlenp,uint8_t _script[IGUANA_MAXSCRIPTSIZE],uint32_t scriptfpos,uint8_t *scriptdata,int32_t scriptlen,int32_t maxsize,int32_t spendflag) - { - *scriptlenp = scriptlen; - if ( 0 && scriptlen > 0 ) - { - if ( scriptfpos != 0 ) - scriptdata = iguana_scriptfpget(coin,scriptlenp,_script,scriptfpos,spendflag); - } - return(scriptdata); - } - - uint8_t *iguana_scriptfpget(struct iguana_info *coin,int32_t *scriptlenp,uint8_t _script[IGUANA_MAXSCRIPTSIZE],uint32_t scriptoffset,int32_t spendflag) - { - FILE *fp; uint8_t *scriptdata=0; int32_t scriptlen=0; struct scriptdata sdata; - *scriptlenp = 0; - if ( (fp= fopen(coin->scriptsfname[spendflag],"rb")) != 0 ) - { - fseek(fp,scriptoffset,SEEK_SET); - if ( fread(&sdata,1,sizeof(sdata),fp) != sizeof(sdata) ) - printf("iguana_scriptfpget: error reading sdata\n"); - else if ( sdata.scriptlen > 0 && sdata.scriptlen <= IGUANA_MAXSCRIPTSIZE ) - { - if ( fread(_script,1,sdata.scriptlen,fp) == sdata.scriptlen ) - { - scriptdata = _script; - *scriptlenp = scriptlen = sdata.scriptlen; - //printf("raw [%d] offset.%d scriptlen.%d\n",bp->hdrsi,scriptoffset,scriptlen); - //for (i=0; i<16; i++) - // printf("%02x",_script[i]); - //printf(" set script.%d\n",scriptlen); - } - } - fclose(fp); - } - return(scriptdata); - } - //struct scriptdata { uint32_t ind:31,spendflag:1; uint16_t hdrsi,scriptlen; }__attribute__((packed)); - - if ( ramchain->expanded != 0 ) - { - if ( (long)destoffset < (long)srcoffset ) - { - /*sprintf(fname,"sigs/%s/%s",coin->symbol,bits256_str(str,bp->hashes[0])); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( ramchain->H.stacksize > 0 ) - { - if ( fwrite(srcoffset,1,ramchain->H.stacksize,fp) != ramchain->H.stacksize ) - printf("error writing %d sigs to %s\n",ramchain->H.stacksize,fname); - } - else - { - if ( fwrite(&izero,1,sizeof(izero),fp) != sizeof(izero) ) - printf("error writing izero to %s\n",fname); - } - fclose(fp); - } - if ( (ramchain->sigsfileptr= OS_mapfile(fname,&ramchain->sigsfilesize,0)) == 0 ) - return(-1); - printf("%s bp.[%d] ht.%d stacksize.%u filesize.%u\n",fname,bp->hdrsi,bp->bundleheight,ramchain->H.stacksize,(uint32_t)ramchain->sigsfilesize);*/ - //for (i=0; iH.stacksize; i++) - // c = *srcoffset, *destoffset++ = c, *srcoffset++ = 0; - } else printf("smashed stack? dest.%ld vs src %ld offset.%u stacksize.%u space.%u\n",(long)destoffset,(long)srcoffset,(uint32_t)ramchain->H.scriptoffset,(uint32_t)ramchain->H.stacksize,(uint32_t)ramchain->H.scriptoffset); - } - // if file exists and is valid, load and then process only the incremental - long iguana_spentsfile(struct iguana_info *coin,int32_t n) - { - int32_t i,iter,allocated = 0; long filesize,total,count; struct iguana_bundleind *spents = 0; struct iguana_ramchain *ramchain; char fname[1024]; struct iguana_bundle *bp; FILE *fp; - fname[0] = 0; - for (total=iter=0; iter<2; iter++) - { - for (count=i=0; ibundles[i]) != 0 ) - { - ramchain = &bp->ramchain; - if ( ramchain->H.data != 0 ) - { - if ( iter == 1 ) - { - ramchain->spents = &spents[count]; - //printf("bp.[%d] count.%ld %p\n",i,count,ramchain->spents); - if ( allocated != 0 && iguana_spentsinit(coin,spents,bp,ramchain) < 0 ) - { - printf("error initializing spents bp.%d\n",i); - exit(-1); - } - } - count += ramchain->H.data->numunspents; - } else break; - } else return(-1); - } - if ( i < n ) - n = (i + 1); - sprintf(fname,"DB/%s/spents_%d.%ld",coin->symbol,n,count); - printf("%s total unspents.%ld\n",fname,count); - if ( iter == 0 ) - { - total = count; - if ( (spents= OS_filestr(&filesize,fname)) == 0 ) - spents = calloc(total,sizeof(*spents)), allocated = 1; - } - else if ( total != count ) - printf("%s total.%ld != count.%ld\n",fname,total,count); - } - if ( allocated != 0 && fname[0] != 0 && (fp= fopen(fname,"wb")) != 0 ) - { - fwrite(spents,total,sizeof(*spents),fp); - fclose(fp); - } - return(total); - } - - int32_t iguana_spentsinit(struct iguana_info *coin,struct iguana_bundleind *spents,struct iguana_bundle *bp,struct iguana_ramchain *ramchain) - { - int32_t spendind,n,max,hdrsi,errs,flag; uint32_t unspentind; struct iguana_bundle *spentbp; - struct iguana_spend *S; bits256 prevhash; - S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); - max = ramchain->H.data->numunspents; - n = ramchain->H.data->numspends; - for (spendind=1,errs=0; spendindhdrsi; - if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,&S[spendind])) != 0 ) - { - spentbp->ramchain.spents[unspentind].ind = spendind; - spentbp->ramchain.spents[unspentind].hdrsi = bp->hdrsi; - flag = 1; - if ( S[spendind].external == 0 && spentbp != bp ) - printf("spentsinit unexpected spendbp: %p bp.[%d] U%d <- S%d.[%d] [%p %p %p]\n",&spentbp->ramchain.spents[unspentind],hdrsi,unspentind,spendind,bp->hdrsi,coin->bundles[0],coin->bundles[1],coin->bundles[2]); - } - else if ( S[spendind].prevout < 0 ) - flag = 1; - else printf("unresolved spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); - if ( flag == 0 ) - errs++; - } - printf("processed %d spendinds for bp.[%d] -> errs.%d\n",spendind,bp->hdrsi,errs); - return(-errs); - } - if ( bp != currentbp ) - { - //printf("initial requests for hdrs.%d\n",bp->hdrsi); - pend = queue_size(&coin->priorityQ) + queue_size(&coin->blocksQ); - for (i=0; ipeers.active[i].pendblocks; - if ( 0 && pend >= IGUANA_BUNDLELOOP ) - { - //for (i=better=0; ibundlescount; i++) - // if ( coin->bundles[i] != 0 && coin->bundles[i]->numsaved > bp->numsaved ) - // better++; - //if ( better > coin->peers.numranked ) - { - //usleep(10000); - //printf("SKIP pend.%d vs %d: better.%d ITERATE bundle.%d n.%d r.%d s.%d finished.%d timelimit.%d\n",pend,coin->MAXPENDING*coin->peers.numranked,better,bp->bundleheight,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit); - iguana_bundleQ(coin,bp,1000); - return(0); - } - } - counter = iguana_bundlekick(coin,bp,starti,max); - } - if ( req == 0 && 0 ) - { - if ( 1 )//(rand() % 10) == 0 ) - flag = iguana_neargap(coin,addr); - else if ( 0 && (bp= addr->bp) != 0 && bp->rank != 0 && addr->pendblocks < limit ) - { - r = rand(); - for (j=0; jn; j++) - { - i = (r + j) % bp->n; - if ( (block= bp->blocks[i]) != 0 && block->numrequests == bp->minrequests && block->fpipbits == 0 && block->queued == 0 ) - { - printf("peer.%s BPranked.%d [%d:%d] pending.%d numreqs.%d\n",addr->ipaddr,bp->rank,bp->hdrsi,i,addr->pendblocks,block->numrequests); - block->numrequests++; - flag++; - iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - break; - } - } - } - } - - int32_t iguana_neargap(struct iguana_info *coin,struct iguana_peer *addr) - { - struct iguana_block *block,*bestblock = 0; struct iguana_bundle *bp,*bestbp = 0; - int32_t height,hdrsi,i,j,n,bundlei,gap,besti = -1; uint32_t r; - if ( addr->rank > 0 ) - { - n = coin->peers.numranked * 2; - gap = addr->rank * (1 + n + coin->peers.numranked) + coin->peers.numranked; - for (i=0; ibundlescount; i++) - if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish == 0 ) - break; - height = (i * coin->chain->bundlesize); - r = rand(); - for (i=0; ichain->bundlesize; - if ( (bp= coin->bundles[hdrsi]) != 0 ) - { - bundlei = (height + j) % coin->chain->bundlesize; - if ( (block= bp->blocks[bundlei]) != 0 && block->fpipbits == 0 && block->queued == 0 ) - { - if ( block->numrequests == bp->minrequests ) - { - bestblock = block; - bestbp = bp; - besti = bundlei; - break; - } - else if ( bestblock == 0 || block->numrequests < bestblock->numrequests ) - { - bestblock = block; - bestbp = bp; - besti = bundlei; - } - } - } - } - if ( bestblock != 0 ) - { - printf("near hwm.%d gap.%d peer.%s bpranked.%d [%d:%d] pending.%d numreqs.%d\n",height,j,addr->ipaddr,bestbp->rank,bestbp->hdrsi,besti,addr->pendblocks,bestblock->numrequests); - bestblock->numrequests++; - iguana_sendblockreqPT(coin,addr,bestbp,besti,bestblock->RO.hash2,0); - return(1); - } - } - return(0); - } - /*if ( doneval != maxval ) - { - r = rand() % numpeers; - oldest = 0; - for (i=0; i 0 ) - { - for (i=j; in; i+=numpeers) - if ( (block= bp->blocks[i]) != 0 && block->fpipbits == 0 ) - { - if ( oldest == 0 || block->issued < oldest->issued ) - oldest = block; - if ( now > block->issued+10+60*(bp!=coin->current) ) - { - for (k=0; k 0 && (addr= coin->peers.ranked[z]) != 0 ) - { - if ( bp == coin->current ) - printf("send [%d:%d] to addr[%d]\n",bp->hdrsi,block->bundlei,z); - block->issued = (uint32_t)time(NULL); - counter++; - iguana_sendblockreqPT(coin,addr,bp,block->bundlei,block->RO.hash2,0); - break; - } - } - } - } - } - } - }*/ - //return(counter); - /*if ( 0 && time(NULL) > bp->lastspeculative+60 ) - { - for (i=1,counter=0; in; i++) - { - if ( (block= bp->blocks[i]) == 0 || block->fpos < 0 || block->fpipbits == 0 ) - { - if ( bp->speculative != 0 && bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) > 0 && i < bp->numspec ) - iguana_blockQ("speculate0",coin,0,-2,bp->speculative[i],0), counter++; - else if ( bits256_nonz(bp->hashes[i]) != 0 ) - iguana_blockQ("speculate1",coin,0,-3,bp->hashes[i],0), counter++; - } - } - if ( counter != 0 ) - printf("SPECULATIVE issue.%d bp.[%d]\n",counter,bp->hdrsi); - bp->lastspeculative = (uint32_t)time(NULL); - }*/ - //ramchain->A = OS_filestr(&filesize,fname); - //if ( filesize != sizeof(*ramchain->A)*ramchain->H.data->numpkinds ) - // printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->A)*ramchain->H.data->numpkinds); - sprintf(fname,"DB/%s/accounts/lastspends.%d",coin->symbol,ramchain->H.data->height); - //ramchain->Uextras = OS_filestr(&filesize,fname); - //if ( filesize != sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds ) - // printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds); - //if ( ramchain->A == 0 ) - ramchain->A = myaligned_alloc(sizeof(*ramchain->A) * ramchain->H.data->numpkinds); - //if ( ramchain->Uextras == 0 ) - ramchain->Uextras = myaligned_alloc(sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents); - //printf("hashmem.%p A allocated.%p numpkinds.%d %ld\n",hashmem,ramchain->A,ramchain->H.data->numpkinds,sizeof(struct iguana_account)*ramchain->H.data->numpkinds); - //ramchain->P2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_pkextra) * ramchain->H.data->numpkinds,1) : mycalloc('2',ramchain->H.data->numpkinds,sizeof(struct iguana_pkextra)); - ///ramchain->U2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_Uextra) * ramchain->H.data->numunspents,1) : mycalloc('3',ramchain->H.data->numunspents,sizeof(struct iguana_Uextra)); - //printf("iguana_ramchain_extras A.%p:%p U2.%p:%p P2.%p:%p\n",ramchain->A,ramchain->roA,ramchain->U2,ramchain->roU2,ramchain->P2,ramchain->roP2); - //memcpy(ramchain->U2,ramchain->roU2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents); - //memcpy(ramchain->P2,ramchain->roP2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds); - - int32_t iguana_spendfind(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t spendind,int32_t emit) - { - struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; - struct iguana_bundle *spentbp; struct iguana_txid *T; - ramchain = &bp->ramchain; - if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 || ramchain->Xspendinds == 0 ) - return(-1); - S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); - s = &S[spendind]; - u = 0; - unspentind = 0; - hdrsi = -1; - spentbp = 0; - if ( s->external != 0 && s->prevout >= 0 ) - { - if ( emit >= ramchain->numXspends ) - errs++; - else - { - h = ramchain->Xspendinds[emit].height; - unspentind = ramchain->Xspendinds[emit].ind; - if ( (hdrsi= ramchain->Xspendinds[emit].hdrsi) >= 0 && hdrsi <= bp->hdrsi ) - spentbp = coin->bundles[hdrsi]; - else - { - printf("iguana_balancegen[%d] s.%d illegal hdrsi.%d emit.%d\n",bp->hdrsi,spendind,hdrsi,emit); - return(-1); - } - //printf("%d of %d: [%d] X spendind.%d -> (%d u%d)\n",emit,ramchain->numXspends,bp->hdrsi,spendind,hdrsi,unspentind); - emit++; - } - } - else if ( s->prevout >= 0 ) - { - spentbp = bp; - hdrsi = bp->hdrsi; - h = refheight; - if ( (txidind= s->spendtxidind) != 0 && txidind < spentbp->ramchain.H.data->numtxids ) - { - T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); - unspentind = T[txidind].firstvout + s->prevout; - if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) - { - printf("iguana_balancegen unspentind overflow %u vs %u\n",unspentind,spentbp->ramchain.H.data->numunspents); - return(-1); - } - //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); - } - else - { - printf("iguana_balancegen txidind overflow %u vs %u\n",txidind,spentbp->ramchain.H.data->numtxids); - return(-1); - } - //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); - } - else return(0); - if ( (spendind & 0xff) == 1 ) - now = (uint32_t)time(NULL); - if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) - { - if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) - { - //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); - iguana_ramchain_prefetch(coin,&spentbp->ramchain); - spentbp->lastprefetch = now; - } - } - - } - if ( 0 && coin->blocks.hwmchain.height > coin->chain->bundlesize && bp->hdrsi == coin->blocks.hwmchain.height/coin->chain->bundlesize ) - { - for (bundlei=0; bundlein; bundlei++) - { - checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); - if ( checki == bundlei ) - { - if ( (fp= fopen(fname,"rb")) != 0 ) - fclose(fp); - else break; - } - } - if ( bp == coin->current && (bp->ramchain.H.data == 0 || bp->ramchain.H.data->numblocks != bundlei) ) - { - printf("RT bundls\n"); - if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) - { - - } - } - } - /*for (j=0; jRO.prev_block)) != 0 ) - { - printf("iguana_recvblock got prev block [%d:%d]\n",bp->hdrsi,bundlei); - if ( bundlei < bp->n-1 ) - bundlei++; - else bp = 0, bundlei = -2; - /*if ( bits256_cmp(prev->RO.hash2,block->RO.prev_block) == 0 && bundlei < bp->n-1 ) - { - bundlei++; - iguana_bundlehash2add(coin,&tmpblock,bp,bundlei,block->RO.hash2); - if ( tmpblock == block ) - { - printf("[%d:%d] speculative block.%p\n",bp->hdrsi,bundlei,block); - bp->blocks[bundlei] = block; - bp->hashes[bundlei] = block->RO.hash2; - block->bundlei = bundlei; - block->hdrsi = bp->hdrsi; - block->mainchain = prev->mainchain; - } else printf("error adding speculative prev [%d:%d]\n",bp->hdrsi,bundlei); - }*/ - } - /*for (i=coin->bundlescount-1; i>=0; i--) - { - //if ( coin->bundles[i] != 0 ) - // printf("compare vs %s\n",bits256_str(str,coin->bundles[i]->hashes[0])); - if ( coin->bundles[i] != 0 && bits256_cmp(origblock->RO.prev_block,coin->bundles[i]->hashes[0]) == 0 ) - { - bp = coin->bundles[i]; - bundlei = 1; - iguana_bundlehash2add(coin,&block,bp,bundlei,origblock->RO.hash2); - printf("iguana_recvblock [%d] bundlehashadd set.%d block.%p\n",i,bundlei,block); - if ( block != 0 ) - { - bp->blocks[bundlei] = block; - block->bundlei = bundlei; - block->hdrsi = bp->hdrsi; - } - break; - } - }*/ - //printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); - /*if ( checki != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) - { - printf("iguana_bundlecalcs.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); - continue; - }*/ - if ( 0 && coin->current == bp )//&& (bp->isRT != 0 || bp->hdrsi > coin->bundlescount-3) ) - { - //checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); - if ( (fp= fopen(fname,"rb")) != 0 ) - { - fseek(fp,0,SEEK_END); - block->RO.recvlen = (uint32_t)ftell(fp); - block->fpipbits = 1; - block->fpos = 0; - //printf("fp.[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); - fclose(fp); - } - else - { - //char str[65]; printf("missing.(%s) issue.%s\n",fname,bits256_str(str,bp->hashes[bundlei])); - block->RO.recvlen = 0; - block->fpipbits = 0; - block->fpos = -1; - //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); - } - } - int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t max,int32_t timelimit) - { - int32_t i,j,k,peerid,doneflag,len,forceflag,saved,starti,lag,doneval,nonz,total=0,maxval,numpeers,laggard=0,flag=0,finished=0,peercounts[IGUANA_MAXPEERS],donecounts[IGUANA_MAXPEERS],priority,counter = 0; - struct iguana_peer *addr; uint32_t now; struct iguana_block *block; - bits256 hashes[50],hash2; uint8_t serialized[sizeof(hashes) + 256]; - if ( bp == 0 ) - return(0); - now = (uint32_t)time(NULL); - memset(peercounts,0,sizeof(peercounts)); - memset(donecounts,0,sizeof(donecounts)); - if ( coin->current != 0 ) - starti = coin->current->hdrsi; - else starti = 0; - priority = (bp->hdrsi < starti + coin->peers.numranked); - if ( strcmp("BTC",coin->symbol) == 0 ) - lag = 10 + (bp->hdrsi - starti); - else lag = 3 + (bp->hdrsi - starti)/10; - if ( coin->current != bp ) - lag *= 3; - if ( (numpeers= coin->peers.numranked) > 3 && 0 )//(bp->numhashes == bp->n || bp->speculative != 0) )//&& bp->currentflag < bp->n ) - { - if ( numpeers > 0xff ) - numpeers = 0xff; // fit into 8 bitfield - if ( bp->currentflag == 0 ) - bp->currenttime = now; - if ( bp->numhashes >= 1 ) - { - for (j=0; jpeers.ranked[j]) != 0 && addr->dead == 0 && addr->usock >= 0 && addr->msgcounts.verack != 0 ) - { - now = (uint32_t)time(NULL); - for (i=j,k=doneval=maxval=0; in&&khashes[i]) != 0 ) - { - hash2 = bp->hashes[i]; - if ( (block= bp->blocks[i]) != 0 ) - { - if ( (peerid= block->peerid) == 0 ) - { - //printf("<%d>.%d ",i,j); - if ( block->fpipbits != 0 || bp->speculativecache[i] != 0 ) - doneflag = 1; - } - } - } - else if ( bp->speculative != 0 && i < bp->numspec && bits256_nonz(bp->speculative[i]) != 0 ) - { - hash2 = bp->speculative[i]; - if ( bp->speculativecache[i] != 0 ) - doneflag = peerid = 1; - } - if ( doneflag == 0 ) - { - hashes[k++] = hash2; - bp->issued[i] = now; - if ( block != 0 ) - { - block->issued = now; - block->peerid = j + 1; - block->numrequests++; - } - } - else - { - doneflag = 1; - if ( block != 0 ) - { - block->peerid = 1; - block->numrequests++; - } - } - if ( bits256_nonz(hash2) != 0 ) - { - if ( peerid > 1 ) - { - total++; - if ( doneflag != 0 ) - { - donecounts[peerid - 1]++; - if ( donecounts[peerid - 1] > doneval ) - doneval = donecounts[peerid - 1]; - } - else - { - peercounts[peerid - 1]++; - if ( peercounts[peerid - 1] > maxval ) - maxval = peercounts[peerid - 1]; - } - } - } - } - if ( k > 0 ) - { - if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,hashes,k)) > 0 ) - { - iguana_send(coin,addr,serialized,len); - counter += k; - coin->numreqsent += k; - addr->pendblocks += k; - addr->pendtime = (uint32_t)time(NULL); - bp->currentflag += k; - } - //printf("a%d/%d ",j,k); - } - } - } - //printf("doneval.%d maxval.%d\n",doneval,maxval); - if ( 0 && priority != 0 ) - { - double threshold; - for (i=nonz=0; i threshold ) - laggard++; - if ( peercounts[i] == 0 && donecounts[i] > threshold ) - finished++; - } - if ( finished > laggard*10 && numpeers > 2*laggard && laggard > 0 ) - { - for (i=0; i threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag && addr->dead == 0 ) - { - if ( (numpeers > 64 || addr->laggard++ > 13) && coin->current == bp ) - { - addr->dead = (uint32_t)time(NULL); - addr->rank = 0; - } - for (j=0; jn; j++) - { - if ( ((block= bp->blocks[j]) != 0 && block->peerid == i && block->fpipbits == 0) || bp->speculativecache[i] == 0 ) - { - if ( bp == coin->current ) - printf("%d ",j); - flag++; - counter++; - if ( block != 0 ) - { - block->issued = now; - block->peerid = 0; - iguana_blockQ("kick",coin,bp,j,block->RO.hash2,0);//bp == coin->current); - } else iguana_blockQ("kick",coin,bp,j,block->RO.hash2,0);//bp == coin->current); - if ( bp == coin->current ) - bp->issued[i] = now; - } - } - if ( flag != 0 && bp == coin->current ) - printf("slow peer.%d dead.%u (%s) reissued.%d [%d]\n",i,addr->dead,addr->ipaddr,flag,bp->hdrsi); - } - } - } - if ( 0 && laggard != 0 ) - { - for (i=0; ihdrsi,finished,laggard,threshold); - } - } - } - for (i=0; in; i++) - { - if ( 0 && (block= bp->blocks[i]) != 0 && iguana_blockstatus(coin,block) == 0 && bp->speculativecache[i] == 0 ) - { - if ( now > block->issued+lag ) - { - counter++; - saved = block->issued; - if ( bp == coin->current ) - forceflag = (now > block->issued + lag); - else forceflag = (now > block->issued + 10*lag); - if ( priority != 0 ) - { - printf("kick.[%d:%d] ",bp->hdrsi,i); - iguana_blockQ("kicka",coin,bp,i,block->RO.hash2,0*forceflag); - if ( forceflag != 0 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) - iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - } else iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,0*forceflag); - if ( forceflag != 0 ) - bp->issued[i] = block->issued = now; - else bp->issued[i] = block->issued = saved; - flag++; - } //else printf("%d ",now - block->issued); - } - } - if ( flag != 0 && priority != 0 && laggard != 0 && coin->current == bp ) - printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); - } - if ( bp == coin->current ) - return(counter); - } - for (i=0; in; i++) - { - if ( (block= bp->blocks[i]) != 0 && bp->speculativecache[i] == 0 ) - { - if ( block->fpipbits == 0 || block->fpos < 0 )// || block->RO.recvlen == 0 ) - { - if ( now > block->issued+lag ) - { - block->numrequests++; - if ( bp == coin->current ) - printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kickc",coin,bp,i,block->RO.hash2,0);//bp == coin->current && now > block->issued+lag); - bp->issued[i] = block->issued = now; - counter++; - if ( --max <= 0 ) - break; - } - } - } - else if ( block != 0 && block->fpipbits == 0 && bits256_nonz(bp->hashes[i]) != 0 && now > bp->issued[i]+lag ) - { - if ( bp == coin->current ) - printf("b[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kickd",coin,bp,i,bp->hashes[i],0);//bp == coin->current && now > bp->issued[i]+lag*3); - bp->issued[i] = now; - counter++; - } - else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+lag ) - { - if ( bp == coin->current ) - printf("i[%d:%d] ",bp->hdrsi,i); - iguana_blockQ("kicke",coin,bp,i,bp->speculative[i],0); - bp->issued[i] = now; - counter++; - } - } - return(counter); - } - /*else if ( 0 && bp == coin->current && bp->speculativecache[bundlei] == 0 ) - { - char str[65]; printf("missing prev_block [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei])); - if ( block != 0 ) - { - block->RO.recvlen = 0; - block->fpipbits = 0; - block->fpos = -1; - } - else if ( now > bp->issued[bundlei]+13 ) - iguana_blockQ("missing",coin,bp,bundlei,bp->hashes[bundlei],1); - }*/ - } - /*else - { - char str[65],str2[65]; printf(" mismatched [%d:%d] %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2)); - //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); - bp->issued[bundlei] = 0; - bp->blocks[bundlei] = 0; - memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); - OS_removefile(fname,0); - }*/ - /*if ( 0 && bp->numhashes < bp->n && bp->speculative != 0 ) - { - for (j=1; jnumspec&&jn; j++) - { - if ( (block= bp->blocks[j]) == 0 ) - { - if ( bits256_nonz(bp->hashes[j]) != 0 ) - block = iguana_blockfind(coin,bp->hashes[j]); - else if ( bits256_nonz(bp->speculative[j]) != 0 ) - { - if ( (block= iguana_blockfind(coin,bp->speculative[j])) == 0 ) - block = iguana_blockhashset(coin,-1,bp->speculative[j],1); - } - } - else if ( bits256_nonz(block->RO.prev_block) != 0 && iguana_blockstatus(coin,block) != 0 ) - continue; - prev = bp->blocks[j-1]; - //printf("[%d:%d] prev.%p nonz.%d speculative.%d block.%p\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bp->blocks[j]); - if ( block != 0 && bp->blocks[j] == 0 ) //prev != 0 && - { - //char str2[65]; printf("[%d:%d] prev.%p nonz.%d speculative.%d prev.%s vs %s ipbits.%x q.%d\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bits256_str(str,prev->RO.hash2),bits256_str(str2,block->RO.prev_block),block->fpipbits,block->queued); - if ( iguana_blockstatus(coin,block) == 0 && bp->speculativecache[j] == 0 ) - { - if ( block->req != 0 ) - { - block->queued = 1; - queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); - block->req = 0; - //printf("submit cached [%d:%d]\n",bp->hdrsi,j); - } - else if ( now > block->issued+10 ) - { - block->issued = now; - //printf("submit speculative [%d:%d]\n",bp->hdrsi,j); - iguana_blockQ("spec",coin,0,-1,block->RO.hash2,0); - } - } - } // else break; - } - }*/ - int32_t checki,hdrsi,havefile,missing,recvlen; char fname[1024]; FILE *fp; - static bits256 zero; - //if ( bp->speculative != 0 ) - { - now = (int32_t)time(NULL); - for (j=havefile=missing=0; jn; j++) - { - if ( bits256_nonz(bp->hashes[j]) != 0 ) - hash2 = bp->hashes[j]; - else if ( bp->speculative != 0 ) - hash2 = bp->speculative[j]; - if ( bits256_nonz(hash2) == 0 ) - { - missing++; - continue; - } - checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,hash2,zero,1,0); - if ( 1 && (fp= fopen(fname,"rb")) != 0 ) - { - havefile++; - fclose(fp); - continue; - } - //if ( (block= bp->blocks[j]) != 0 && block->fpipbits != 0 && block->fpos >= 0 && block->RO.recvlen > 0 && bits256_nonz(block->RO.prev_block) != 0 ) - // continue; - missing++; - if ( bp->speculativecache[j] != 0 ) - { - block = iguana_blockfind(coin,bp->speculative[j]); - if ( block != 0 ) - block->queued = 1; - if ( bp->speculativecache[j] != 0 && block != 0 ) - xx else if ( bits256_nonz(bp->hashes[j]) != 0 ) - { - iguana_blockQ("currentstop",coin,bp,j,hash2,0); - - } - continue; - } - if ( bp == coin->current && (now > bp->issued[j]+3 || (rand() % 10) == 0) ) - { - fprintf(stderr,"-[%d:%d].%d ",bp->hdrsi,j,now-bp->issued[j]); - struct iguana_peer *addr; int32_t r; - if ( (rand() % 10) == 0 && (r= coin->peers.numranked) != 0 && (addr= coin->peers.ranked[rand() % r]) != 0 && addr->dead == 0 && addr->usock >= 0 ) - iguana_sendblockreqPT(coin,addr,bp,j,hash2,0); - else iguana_blockQ("currentstop",coin,bp,j,hash2,1); - //fprintf(stderr,"currentstop [%d:%d]\n",bp->hdrsi,j); - bp->issued[j] = now; - } - } - if ( bp == coin->current ) - fprintf(stderr,"[%d] check numcached.%d numhashes.%d numsaved.%d havefile.%d missing.%d\n",bp->hdrsi,bp->numcached,bp->numhashes,bp->numsaved,havefile,missing); - } - if ( bp->speculative != 0 && missing == 0 ) - { - hash2 = bp->hashes[0]; - for (i=1; in; i++) - { - /*if ( bits256_nonz(bp->speculative[i]) != 0 ) - block = iguana_blockfind(coin,bp->speculative[i]); - else if ( bits256_nonz(bp->hashes[i]) != 0 ) - block = iguana_blockfind(coin,bp->hashes[i]);*/ - if ( (block= bp->blocks[i]) == 0 || bits256_cmp(block->RO.prev_block,hash2) != 0 ) - { - char str[65],str2[65]; - printf("error with speculative prev at i.%d block.%p %s vs %s\n",i,block,bits256_str(str,bp->hashes[i]),bits256_str(str2,hash2)); - if ( block != 0 ) - { - checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[i],zero,1,0); - if ( fname[0] != 0 ) - OS_removefile(fname,0); - printf(">>>>>>> block contents error at ht.%d (%s)\n",bp->bundleheight+i,fname); - //char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); - block->fpipbits = 0; - block->fpos = -1; - block->queued = 0; - block->RO.recvlen = 0; - } - break; - } - hash2 = block->RO.hash2; - } - if ( i == bp->n && iguana_bundlefinalize(coin,bp,&coin->MEM,coin->MEMB) == 0 ) - { - //free(bp->speculative); - //bp->speculative = 0; - } - } - /*if ( bp->speculative != 0 && missing == 0 ) - { - if ( i == bp->n ) - { - printf("have complete speculative bundle!\n"); - for (i=1; in; i++) - { - if ( bits256_nonz(bp->speculative[i]) != 0 && bits256_nonz(bp->hashes[i]) != 0 ) - { - if ( (block= iguana_blockfind(coin,bp->speculative[i])) != 0 ) - { - block->bundlei = i; - block->hdrsi = bp->hdrsi; - bp->blocks[i] = block; - printf("bundlehashadd set.%d\n",i); - iguana_bundlehash2add(coin,0,bp,i,bp->speculative[i]); - } - } - } - } - }*/ - //bp->rank = 0; - /*if ( bp->speculative != 0 )//&& bp == coin->current ) - { - now = (uint32_t)time(NULL); - for (i=1; inumspec&&in; i++) - { - if ( bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) != 0 ) - { - if ( (block= bp->blocks[i]) == 0 && bp->speculativecache[i] == 0 && now > bp->issued[i]+60 ) - { - //printf("speculative.[%d:%d]\n",bp->hdrsi,i); - iguana_blockQ("speculative",coin,bp,-i,bp->speculative[i],0);//now > bp->issued[i]+60); - bp->issued[i] = now; - continue; - } - } - else if ( 0 && (block= bp->blocks[i]) != 0 && bp->speculativecache[i] == 0 && block->fpipbits == 0 && now > bp->issued[i]+60 ) - { - printf("speculativeB.[%d:%d]\n",bp->hdrsi,i); - iguana_blockQ("speculativeB",coin,bp,i,block->RO.hash2,1); - continue; - } - if ( bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+13 ) - { - //printf("speculativeC [%d:%d]\n",bp->hdrsi,i); - iguana_blockQ("speculativeC",coin,bp,-i,bp->speculative[i],0); - bp->issued[i] = now; - } - } - }*/ - if ( 0 && block->newtx != 0 ) - { - if ( (prev= iguana_blockfind(coin,block->RO.prev_block)) == 0 ) - prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); - width = coin->chain->bundlesize; - while ( coin->active != 0 && prev != 0 && width-- > 0 ) - { - if ( prev->fpipbits == 0 || prev->RO.recvlen == 0 || prev->fpos < 0 || bits256_nonz(prev->RO.prev_block) == 0 ) - { - //printf("width.%d auto prev newtx %s ht.%d\n",width,bits256_str(str,prev->RO.hash2),prev->height); - prev->newtx = 1; - iguana_blockQ("autoprev",coin,0,-1,prev->RO.hash2,0); - } - tmpblock = prev; - if ( bits256_nonz(prev->RO.prev_block) != 0 ) - { - if ( (prev = iguana_blockhashset(coin,-1,prev->RO.prev_block,1)) != 0 ) - prev->newtx = 1; - prev->hh.next = tmpblock; - if ( prev->mainchain != 0 ) - { - while ( tmpblock != 0 && _iguana_chainlink(coin,tmpblock) != 0 ) - { - printf("NEWHWM.%d\n",tmpblock->height); - tmpblock = tmpblock->hh.next; - } - break; - } - } else prev = 0; - } - } - /*else if ( bp != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+60 ) - { - if ( bundlei > 0 && bits256_nonz(bp->hashes[bundlei+1]) != 0 ) - { - if ( (block= iguana_blockfind(coin,bp->hashes[bundlei+1])) != 0 && bits256_nonz(block->RO.prev_block) != 0 ) - { - bp->hashes[bundlei] = block->RO.prev_block; - printf("reqblock [%d:%d]\n",bp->hdrsi,bundlei); - iguana_blockQ("reqblocks1",coin,bp,bundlei,bp->hashes[bundlei],0); - } - } - }*/ - else if ( 0 && bp != 0 && time(NULL) > bp->hdrtime+10 && bp->speculative == 0 ) - { - char str[65]; - //printf("MAINCHAIN gethdr %d %s\n",bp->bundleheight,bits256_str(str,bp->hashes[0])); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); - bp->hdrtime = (uint32_t)time(NULL); - } - /*if ( block != 0 && bundlei > 0 && (prev= iguana_blockfind(coin,block->RO.prev_block)) != 0 ) - { - if ( bp->bundleheight+bundlei-1 >= coin->blocks.hwmchain.height ) - { - printf("prev issue.%s\n",bits256_str(str,prev->RO.hash2)); - iguana_blockQ("previssue",coin,bp,bundlei-1,prev->RO.hash2,0); - } - }*/ - /*if ( 0 && (bp= coin->current) != 0 && bp->numsaved < bp->n ) - { - for (hdrsi=numissued=0; hdrsiMAXBUNDLES && coin->current->hdrsi+hdrsibundlescount && numissued<100; hdrsi++) - { - if ( (bp= coin->bundles[hdrsi + coin->current->hdrsi]) == 0 ) - continue; - if ( (addr= coin->peers.ranked[hdrsi]) == 0 || addr->msgcounts.verack == 0 ) - continue; - for (bundlei=n=flag=0; bundlein; bundlei++) - if ( (block= bp->blocks[bundlei]) != 0 ) - { - if ( bits256_nonz(block->RO.hash2) > 0 && block->fpos >= 0 ) - n++; - else if ( block->fpipbits == 0 || time(NULL) > block->issued+60 ) - { - block->issued = (uint32_t)time(NULL); - //iguana_sendblockreqPT(coin,addr,bp,bundlei,block->RO.hash2,0); - iguana_blockQ("reqblocks",coin,bp,bundlei,block->RO.hash2,0); - flag++; - if ( ++numissued > 100 ) - break; - } - } - if ( 0 && flag != 0 ) - printf("issued %d priority blocks for %d current.[%d] have %d blocks emit.%u\n",flag,hdrsi,bp->hdrsi,n,bp->emitfinish); - } - }*/ - /*else if ( iguana_blockfind(coin,bp->hashes[bundlei]) == 0 ) - { - //if ( bits256_nonz(bp->hashes[bundlei]) > 0 ) - // { - // printf("next %d\n",coin->blocks.hwmchain.height+1); - // iguana_blockQ(coin,bp,bundlei,bp->hashes[bundlei],0); - // } - // else if ( bp->speculative != 0 && (bits256_cmp(bp->hashes[bundlei],bp->speculative[bundlei]) != 0 || (rand() % 100) == 0) ) - { - if ( time(NULL) > bp->issued[bundlei]+30 && iguana_blockfind(coin,bp->speculative[bundlei]) == 0 ) - { - bp->hashes[bundlei] = bp->speculative[bundlei]; - struct iguana_bloominds bit = iguana_calcbloom(bp->speculative[bundlei]); - if ( iguana_bloomfind(coin,&bp->bloom,0,bit) < 0 ) - iguana_bloomset(coin,&bp->bloom,0,bit); - printf("speculative next %d\n",coin->blocks.hwmchain.height+1); - iguana_blockQ("speculativenext",coin,0,-1,bp->speculative[bundlei],0); - bp->issued[bundlei] = (uint32_t)time(NULL); - } - } - }*/ - /*else if ( 0 && (bp= coin->bundles[--hdrsi]) != 0 ) - { - char str[65]; - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); - }*/ - /*double threshold,lag = OS_milliseconds() - coin->backstopmillis; - threshold = (10 + coin->longestchain - coin->blocksrecv); - if ( threshold < 1 ) - threshold = 1.; - if ( (bp= coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]) != 0 ) - threshold = (bp->avetime + coin->avetime) * .5; - else threshold = coin->avetime; - threshold *= 100. * sqrt(threshold) * .000777;*/ - /*for (i=n=0; in; i++) - { - if ( lag < coin->MAXSTUCKTIME ) - { - if ( bits256_nonz(bp->hashes[i]) != 0 ) - iguana_blockQ("stuck",coin,bp,i,bp->hashes[i],0); - } - if ( (block= bp->blocks[i]) != 0 && block->fpipbits == 0 && bp->speculativecache[i] == 0 ) - { - printf("s.[%d:%d] ",bp->hdrsi,i); - iguana_blockQ("stuck",coin,bp,i,block->RO.hash2,0); - iguana_blockQ("stuck",coin,bp,i,block->RO.hash2,1); - if ( coin->peers.numranked > 8 && (addr= coin->peers.ranked[n % 8]) != 0 && addr->usock >= 0 && addr->dead == 0 && addr->msgcounts.verack != 0 ) - { - if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&block->RO.hash2,1)) > 0 ) - { - printf("%s, ",addr->ipaddr); - iguana_send(coin,addr,serialized,len); - } - } - block->issued = (uint32_t)time(NULL); - n++; - } - } - if ( n > 0 ) - printf("issued %d priority requests [%d] to unstick stuckiters.%d lag.%d\n",n,bp->hdrsi,coin->stuckiters,lag);*/ - /*if ( 0 && n >= coin->chain->bundlesize ) - { - blockhashes = malloc(sizeof(*blockhashes) * coin->chain->bundlesize); - for (i=0; ichain->bundlesize; i++) - blockhashes[i] = blocks[i].RO.hash2; - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 ) - { - blockhashes[0] = bp->hashes[0]; - vcalc_sha256(0,allhash.bytes,blockhashes[0].bytes,coin->chain->bundlesize * sizeof(*blockhashes)); - if ( bits256_cmp(allhash,bp->allhash) == 0 ) - { - if ( bp->queued != 0 ) - bp->queued = 0; - if ( iguana_allhashcmp(coin,bp,blockhashes,coin->chain->bundlesize) > 0 ) - { - free(blockhashes); - return(req); - } - } - } - } - free(blockhashes); - }*/ - - - /*void iguana_patch(struct iguana_info *coin,struct iguana_block *block) - { - int32_t i,j,origheight,height; struct iguana_block *prev,*next; struct iguana_bundle *bp; - prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); - block->hh.prev = prev; - if ( prev != 0 ) - { - if ( prev->mainchain != 0 ) - { - prev->hh.next = block; - if ( memcmp(block->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) - _iguana_chainlink(coin,block); - if ( (next= block->hh.next) != 0 && bits256_nonz(next->RO.hash2) > 0 ) - next->height = block->height + 1; - } - else if ( 0 && block->height < 0 ) - { - for (i=0; i<1; i++) - { - if ( (prev= prev->hh.prev) == 0 ) - break; - if ( prev->mainchain != 0 && prev->height >= 0 ) - { - j = i; - origheight = (prev->height + i + 2); - prev = block->hh.prev; - height = (origheight - 1); - while ( i > 0 && prev != 0 ) - { - if ( prev->mainchain != 0 && prev->height != height ) - { - printf("mainchain height mismatch j.%d at i.%d %d != %d\n",j,i,prev->height,height); - break; - } - prev = prev->hh.prev; - height--; - } - if ( i == 0 ) - { - //printf("SET HEIGHT.%d j.%d\n",origheight,j); - if ( (bp= coin->bundles[origheight / coin->chain->bundlesize]) != 0 ) - { - iguana_bundlehash2add(coin,0,bp,origheight % coin->chain->bundlesize,block->RO.hash2); - block->height = origheight; - block->mainchain = 1; - prev = block->hh.prev; - prev->hh.next = block; - } - } //else printf("break at i.%d for j.%d origheight.%d\n",i,j,origheight); - break; - } - } - } - } - }*/ - -#ifdef newstuff - int32_t iguana_realtime_update(struct iguana_info *coin) - { - double startmillis0; static double totalmillis0; static int32_t num0; - struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t bundlei,i,n,flag=0; bits256 hash2; struct iguana_peer *addr; - struct iguana_block *block=0; struct iguana_blockRO *B; struct iguana_ramchain *dest=0,blockR; - if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize && bp->hdrsi == coin->balanceswritten && coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n && (coin->RTheight < coin->blocks.hwmchain.height-3 || time(NULL) > bp->lastRT) )//&& coin->blocks.hwmchain.height >= coin->longestchain-1 && coin->RTramchain.H.data->numblocks < bp->n ) - { - if ( bits256_cmp(coin->RThash1,bp->hashes[1]) != 0 ) - coin->RThash1 = bp->hashes[1]; - bp->lastRT = (uint32_t)time(NULL); - if ( coin->peers.numranked > 0 && time(NULL) > coin->RThdrstime+10 ) - { - iguana_RThdrs(coin,bp,coin->peers.numranked); - coin->RThdrstime = bp->lastRT; - for (i=0; ipeers.numranked; i++) - { - if ( (addr= coin->peers.ranked[i]) != 0 ) - printf("%d ",addr->numRThashes); - } - printf("RTheaders\n"); - } - iguana_RTramchainalloc(coin,bp); - bp->isRT = 1; - while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height ) - { - //printf("RT.%d vs hwm.%d starti.%d bp->n %d\n",coin->RTheight,coin->blocks.hwmchain.height,starti,bp->n); - dest = &coin->RTramchain; - B = (void *)(long)((long)rdata + rdata->Boffset); - bundlei = (coin->RTheight % coin->chain->bundlesize); - if ( (block= bp->blocks[bundlei]) != 0 && bits256_nonz(block->RO.prev_block) != 0 ) - { - iguana_blocksetcounters(coin,block,dest); - startmillis0 = OS_milliseconds(); - if ( iguana_ramchainfile(coin,dest,&blockR,bp,bundlei,block) == 0 ) - { - for (i=bundlei; in; i++) - { - block = iguana_bundleblock(coin,&hash2,bp,bundlei+i); - if ( i == 0 || (bits256_nonz(hash2) != 0 && (block == 0 || block->txvalid == 0)) ) - { - uint8_t serialized[512]; int32_t len; - //char str[65]; printf("RT error [%d:%d] %s %p\n",bp->hdrsi,i,bits256_str(str,hash2),block); - addr = coin->peers.ranked[rand() % 8]; - if ( addr != 0 && (len= iguana_getdata(coin,serialized,MSG_BLOCK,&hash2,1)) > 0 ) - iguana_send(coin,addr,serialized,len); - coin->RTgenesis = 0; - } - break; - } - return(-1); - } else iguana_ramchain_free(coin,&blockR,1); - B[bundlei] = block->RO; - totalmillis0 += (OS_milliseconds() - startmillis0); - num0++; - flag++; - coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; - coin->RTheight++; - printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); - coin->RTramchain.H.data->numblocks = bundlei + 1; - } else break; - } - } - n = 0; - if ( dest != 0 && flag != 0 && coin->RTheight >= coin->longestchain ) - { - while ( block != 0 ) - { - if ( bits256_cmp(iguana_blockhash(coin,coin->RTheight-n-1),block->RO.hash2) != 0 ) - { - printf("blockhash error at %d\n",coin->RTheight-n-1); - break; - } - block = iguana_blockfind("RTupdate",coin,block->RO.prev_block); - n++; - if ( coin->RTgenesis != 0 && n >= bp->n ) - break; - } - if ( coin->RTgenesis == 0) - { - if ( n == coin->RTheight ) - { - printf("RTgenesis verified\n"); - coin->RTgenesis = (uint32_t)time(NULL); - } else printf("RTgenesis failed to verify\n"); - } - if ( coin->RTgenesis != 0 ) - { - struct iguana_ramchain R; struct iguana_ramchaindata RDATA; - iguana_rdataset(&R,&RDATA,dest); - bp->ramchain = coin->RTramchain; - printf("ramchainiterate.[%d] ave %.2f micros, total %.2f seconds starti.%d num.%d\n",num0,(totalmillis0*1000.)/num0,totalmillis0/1000.,coin->RTstarti,coin->RTheight%bp->n); - if ( iguana_spendvectors(coin,bp,dest,coin->RTstarti,coin->RTheight%bp->n,0) < 0 ) - { - printf("RTutxo error -> RTramchainfree\n"); - iguana_RTramchainfree(coin); - return(-1); - } - else - { - coin->RTstarti = (coin->RTheight % bp->n); - printf("spendvectors calculated to %d\n",coin->RTheight); - iguana_convert(coin,bp);//,dest); - printf("spendvectors converted to %d\n",coin->RTheight); - } - iguana_rdatarestore(&R,&RDATA,dest); - } - } - if ( dest != 0 && flag != 0 ) - printf("<<<< flag.%d RT.%d:%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",flag,coin->RTheight,n,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); - return(flag); - } - - int32_t iguana_blocksmissing(struct iguana_info *coin,int32_t *nonzp,uint8_t missings[IGUANA_MAXBUNDLESIZE/8+1],bits256 hashes[],double mult,struct iguana_bundle *bp,int32_t capacity) - { - int32_t i,lag,nonz=0,m = 0; double aveduration; bits256 hash2; struct iguana_block *block; uint32_t now = (uint32_t)time(NULL); - if ( bp->durationscount != 0 ) - aveduration = (double)bp->totaldurations / bp->durationscount; - else aveduration = IGUANA_DEFAULTLAG/3 + 1; - aveduration *= mult; - lag = aveduration; - if ( lag > IGUANA_DEFAULTLAG ) - lag = IGUANA_DEFAULTLAG * 8; - memset(missings,0,IGUANA_MAXBUNDLESIZE/8+1); - if ( bp->emitfinish == 0 || bp->ramchain.H.data == 0 ) - { - for (i=0; in; i++) - { - if ( bp->speculativecache[i] != 0 ) - { - //printf("[%d:%d].havec ",bp->hdrsi,i); - continue; - } - if ( (block= iguana_bundleblock(coin,&hash2,bp,i)) != 0 ) - { - if ( block->fpipbits != 0 && block->txvalid != 0 && block->fpos >= 0 && block->RO.recvlen != 0 && (bp->bundleheight+i == 0 || bits256_nonz(block->RO.prev_block) != 0) ) - { - //printf("[%d:%d].have ",bp->hdrsi,i); - continue; - } - } - if ( bits256_nonz(hash2) != 0 ) - { - if ( now > bp->issued[i]+lag ) - { - if ( nonz < capacity ) - { - if ( hashes != 0 ) - hashes[nonz] = hash2; - nonz++; - } - } - } - SETBIT(missings,i); - m++; - } - } //else printf("[%d] emitfinish.%u\n",bp->hdrsi,bp->emitfinish); - *nonzp = nonz; - //printf("missings.[%d] m.%d nonz.%d spec.%p[%d]\n",bp->hdrsi,m,nonz,bp->speculative,bp->numspec); - return(m); - } - - /*int32_t iguana_nextnonz(uint8_t *missings,int32_t i,int32_t max) - { - for (; i 0 ) - { - *capacityp = capacity; - if ( (n= iguana_blocksmissing(coin,&avail,missings,hashes,mult,bp,capacity < max ? capacity : max)) > 0 && avail > 0 ) - { - *missingp = n; - printf("n.%d avail.%d numpeers.%d\n",n,avail,numpeers); - for (i=0; i0; i++) - { - if ( (addr= peers[i]) != 0 && addr->usock >= 0 && addr->dead == 0 && (c= (coin->MAXPENDINGREQUESTS - addr->pendblocks)) > 0 ) - { - if ( c+m > max ) - c = max - m; - if ( avail < c ) - c = avail; - printf("i.%d c.%d avail.%d m.%d max.%d\n",i,c,avail,m,max); - if ( c > 0 && (numsent= iguana_sendhashes(coin,addr,MSG_BLOCK,&hashes[m],c,priority)) > 0 ) - { - for (j=0; jn)) < bp->n ) - { - if ( (block= iguana_bundleblock(coin,&hash2,bp,nonz)) != 0 ) - { - hash2 = block->RO.hash2; - if ( addr->addrind < 0x100 ) - block->peerid = addr->addrind; - else block->peerid = 0; - block->issued = now; - } - bp->issued[nonz] = now; - //char str[65]; printf("issue.[%d:%d] %s %u\n",bp->hdrsi,nonz,bits256_str(str,hash2),now); - nonz++; - } else printf("bundlerequests unexpected nonz.%d c.%d m.%d n.%d numsent.%d i.%d\n",nonz,c,m,n,numsent,i); - } - m += numsent; - avail -= numsent; - } - } - } - } //else printf("err avail.%d n.%d\n",avail,n); - } //else printf("numpeers.%d\n",numpeers); - return(m); - }*/ - /*missing = iguana_blocksmissing(coin,&avail,missings,0,mult,bp,0); - /*if ( coin->current != 0 ) - { - if ( (dist= bp->hdrsi - coin->current->hdrsi) < coin->MAXBUNDLES && (bp == coin->current || netBLOCKS < 50*bp->n) ) - { - iguana_unstickhdr(coin,bp,60); - if ( bp->numcached > bp->n - (coin->MAXBUNDLES - dist) ) - priority += 1 + (bp == coin->current); - if ( bp == coin->current || queue_size(&coin->priorityQ) < (2 * bp->n)/(dist+1) ) - { - //printf("[%d] dist.%d numcached.%d priority.%d\n",bp->hdrsi,dist,bp->numcached,priority); - //iguana_bundleissuemissing(coin,bp,missings,((rand() % 100) == 0 && bp == coin->current)*3); - priority = ((rand() % 20) == 0 && bp == coin->current) * 3; - if ( (n= iguana_bundlerequests(coin,missings,&bp->origmissings,&tmp,mult,bp,priority)) > 0 ) - { - bp->numissued += n; - bp->missingstime = (uint32_t)time(NULL); - } - return(aveduration); - } - } - }*/ - //printf("helper.%d\n",helperid); - /*if ( ((ptr= queue_dequeue(&emitQ,0)) != 0 || (ptr= queue_dequeue(&helperQ,0)) != 0) ) - { - printf("unexpected emitQ or helperQ\n"); - exit(-1); - if ( ptr->bp != 0 && (coin= ptr->coin) != 0 && coin->active != 0 ) - { - idle = 0; - coin->helperdepth++; - iguana_helpertask(fp,&MEM,MEMB,ptr); - coin->helperdepth--; - flag++; - } - myfree(ptr,ptr->allocsize); - }*/ - if ( 0 && (ptr= queue_dequeue(&spendvectorsQ,0)) != 0 ) - { - //printf("spendvectorsQ size.%d\n",queue_size(&spendvectorsQ)); - coin = ptr->coin; - if ( (bp= ptr->bp) != 0 && coin != 0 ) - { - if ( coin->polltimeout < polltimeout ) - polltimeout = coin->polltimeout; - //printf("call spendvectors.%d\n",bp->hdrsi); - if ( coin->PREFETCHLAG > 0 ) - { - iguana_ramchain_prefetch(coin,&bp->ramchain,0); - if ( 0 && bp->hdrsi > 0 ) - iguana_prefetch(coin,bp,bp->hdrsi-1,1); - } - if ( (retval= iguana_spendvectors(coin,bp,&bp->ramchain,0,bp->n,0)) >= 0 ) - { - flag++; - if ( retval > 0 ) - { - printf("GENERATED UTXO.%d for ht.%d duration %d seconds\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL)-bp->startutxo); - } // else printf("null retval from iguana_spendvectors.[%d]\n",bp->hdrsi); - bp->utxofinish = (uint32_t)time(NULL); - iguana_balancesQ(coin,bp); - } else printf("UTXO gen.[%d] utxo error\n",bp->hdrsi); - } - else if ( coin->active != 0 ) - printf("helper missing param? %p %p\n",coin,bp); - myfree(ptr,ptr->allocsize); - } - void iguana_spendvectorsQ(struct iguana_info *coin,struct iguana_bundle *bp) - { - struct iguana_helper *ptr; - bp->queued = (uint32_t)time(NULL); - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->bp = bp, ptr->hdrsi = bp->hdrsi; - ptr->type = 's'; - ptr->starttime = (uint32_t)time(NULL); - queue_enqueue("spendvectorsQ",&spendvectorsQ,&ptr->DL,0); - } - - void iguana_convertQ(struct iguana_info *coin,struct iguana_bundle *bp) - { - struct iguana_helper *ptr; - bp->queued = (uint32_t)time(NULL); - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->bp = bp, ptr->hdrsi = bp->hdrsi; - ptr->type = 's'; - ptr->starttime = (uint32_t)time(NULL); - queue_enqueue("convertQ",&convertQ,&ptr->DL,0); - } - - void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp) - { - struct iguana_helper *ptr; - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->bp = bp, ptr->hdrsi = bp->hdrsi; - ptr->type = 'B'; - ptr->starttime = (uint32_t)time(NULL); - ptr->timelimit = 0; - if ( bp->balancefinish == 0 ) - bp->balancefinish = 1; - coin->pendbalances++; - //printf("BALANCES Q[%d] %s bundle.%d[%d] balances.%u balancefinish.%u\n",coin->pendbalances,coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); - queue_enqueue("balancesQ",&balancesQ,&ptr->DL,0); - } - - /*int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_helper *ptr) - { - struct iguana_info *coin; struct iguana_peer *addr; struct iguana_bundle *bp,*nextbp; - addr = ptr->addr; - if ( (coin= ptr->coin) != 0 ) - { - if ( (bp= ptr->bp) != 0 ) - { - if ( 0 && ptr->type == 'M' ) - { - if ( (nextbp= ptr->nextbp) != 0 ) - { - bp->mergefinish = nextbp->mergefinish = (uint32_t)time(NULL); - if ( iguana_bundlemergeHT(coin,mem,memB,bp,nextbp,ptr->starttime) < 0 ) - bp->mergefinish = nextbp->mergefinish = 0; - } - } - else if ( ptr->type == 'B' ) - { - printf("helper bundleiters\n"); - iguana_bundleiters(coin,mem,memB,bp,ptr->timelimit); - } - else if ( ptr->type == 'E' ) - { - coin->emitbusy++; - if ( iguana_bundlesaveHT(coin,mem,memB,bp,ptr->starttime) == 0 ) - { - //fprintf(stderr,"emitQ coin.%p bp.[%d]\n",ptr->coin,bp->bundleheight); - bp->emitfinish = (uint32_t)time(NULL) + 1; - coin->numemitted++; - } else bp->emitfinish = 0; - coin->emitbusy--; - } - } else printf("no bundle in helperrequest\n"); - } else printf("no coin in helperrequest\n"); - return(0); - }*/ - - void iguana_mergeQ(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_bundle *nextbp) - { - struct iguana_helper *ptr; - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->bp = bp, ptr->hdrsi = bp->hdrsi; - ptr->nextbp = nextbp; - ptr->type = 'M'; - ptr->starttime = (uint32_t)time(NULL); - //printf("%s EMIT.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); - queue_enqueue("helperQ",&helperQ,&ptr->DL,0); - } - if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize ) - { - n = bp->hdrsi; - for (j=0; jbundles[j]) == 0 || bp->emitfinish <= 1 ) - break; - } - if ( j == n ) - { - for (j=0; jbundles[j]) == 0 || (bp->startutxo == 0 && bp->utxofinish == 0) ) - break; - } - if ( j != n ) - { - for (j=0; jbundles[j]) != 0 ) - { - //printf("bundleQ.[%d]\n",j); - bp->balancefinish = bp->startutxo = 0; - bp->utxofinish = 1; - iguana_bundleQ(coin,bp,1000); - } - } - } //else printf("skip A j.%d vs n.%d\n",j,n); - } //else printf("skip j.%d vs n.%d\n",j,n); - } //else printf("skip hdrsi.%d vs %d\n",coin->current->hdrsi,coin->longestchain/coin->chain->bundlesize); - n = queue_size(&balancesQ); - for (iter=0; iterbp; - if ( ptr->coin != coin || bp == 0 || time(NULL) < bp->nexttime ) - { - if ( 0 && bp != 0 ) - printf("skip.%d lag.%ld\n",bp->hdrsi,bp->nexttime-time(NULL)); - //bp->nexttime = (uint32_t)time(NULL); - queue_enqueue("balanceQ",&balancesQ,&ptr->DL,0); - continue; - } - flag++; - if ( coin != 0 ) - { - iguana_balancecalc(coin,bp,bp->bundleheight,bp->bundleheight+bp->n-1); - if ( coin->active == 0 ) - { - printf("detected autopurge after account filecreation. restarting.%s\n",coin->symbol); - coin->active = 1; - } - } - myfree(ptr,ptr->allocsize); - } - } - - int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *RTramchain,int32_t bundlei) - { - struct iguana_txid *T; int32_t height,spendind,txidind,j,k; bits256 prevhash; - struct iguana_bundle *spentbp; struct iguana_unspent *spentU,*u; - struct iguana_ramchaindata *RTdata,*rdata; - uint32_t spent_unspentind,now; struct iguana_blockRO *B; struct iguana_spend *S,*s; - if ( (RTdata= RTramchain->H.data) == 0 || RTdata->numspends < 1 ) - { - printf("iguana_RTutxo null data or no spends %p\n",RTramchain->H.data); - return(-1); - } - B = (void *)(long)((long)RTdata + RTdata->Boffset); - S = (void *)(long)((long)RTdata + RTdata->Soffset); - T = (void *)(long)((long)RTdata + RTdata->Toffset); - txidind = B[bundlei].firsttxidind; - spendind = B[bundlei].firstvin; - height = bp->bundleheight + bundlei; - now = (uint32_t)time(NULL); - //printf("RTutxo.[%d:%d] txn_count.%d\n",bp->hdrsi,bundlei,B[bundlei].txn_count); - for (j=0; jexternal != 0 && s->prevout >= 0 ) - { - continue; - double startmillis = OS_milliseconds(); static double totalmillis; static int32_t num; - if ( (spentbp= iguana_externalspent(coin,&prevhash,&spent_unspentind,RTramchain,bp->hdrsi,s,2)) == 0 || spent_unspentind == 0 || spent_unspentind >= spentbp->ramchain.H.data->numunspents || spentbp->hdrsi < 0 || spentbp->hdrsi >= bp->hdrsi || spentbp == bp ) - { - char str[65]; - printf("RTutxo: unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",height,spentbp!=0?spentbp->hdrsi:-1,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); - return(-1); - } - totalmillis += (OS_milliseconds() - startmillis); - if ( (++num % 10000) == 0 ) - printf("externalspents.[%d] ave %.2f micros, total %.2f seconds\n",num,(totalmillis*1000.)/num,totalmillis/1000.); - rdata = spentbp->ramchain.H.data; - if ( 0 && coin->PREFETCHLAG > 0 && now >= spentbp->lastprefetch+coin->PREFETCHLAG ) - { - printf("RT prefetch[%d] from.[%d] lag.%d bundlei.%d numspends.%d of %d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch,bundlei,spendind,RTramchain->H.spendind); - iguana_ramchain_prefetch(coin,&spentbp->ramchain,2); - spentbp->lastprefetch = now; - } - } - else if ( s->prevout >= 0 ) - { - spentbp = bp; - rdata = RTramchain->H.data; - if ( s->spendtxidind != 0 && s->spendtxidind < RTdata->numtxids ) - { - spent_unspentind = T[s->spendtxidind].firstvout + s->prevout; - //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); - } - else - { - printf("RTutxo txidind overflow %u vs %d\n",s->spendtxidind,RTdata->numtxids); - return(-1); - } - } - else continue; // coinbase always already spent - if ( spentbp != 0 && rdata != 0 && spent_unspentind != 0 && spent_unspentind < rdata->numunspents ) - { - double startmillis = OS_milliseconds(); static double totalmillis; static int32_t num; - spentU = (void *)(long)((long)rdata + rdata->Uoffset); - u = &spentU[spent_unspentind]; - if ( iguana_volatileupdate(coin,1,spentbp == bp ? RTramchain : &spentbp->ramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height) < 0 ) - return(-1); - totalmillis += (OS_milliseconds() - startmillis); - if ( (++num % 10000) == 0 ) - printf("volatile.[%d] ave %.2f micros, total %.2f seconds\n",num,(totalmillis*1000.)/num,totalmillis/1000.); - } - else - { - printf("RTutxo error spentbp.%p u.%u vs %d\n",spentbp,spent_unspentind,rdata->numunspents); - return(-1); - } - } - } - return(0); - } - - /*int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) - { - int32_t retval=-1,i,n,flag = 0; - if ( bp->balancefinish > 1 ) - { - printf("make sure DB files have this bp.%d\n",bp->hdrsi); - iguana_validateQ(coin,bp); - return(flag); - } - bp->nexttime = (uint32_t)time(NULL) + 1; - if ( bp != 0 && coin != 0 ) - { - if ( coin->origbalanceswritten <= 1 && coin->spendvectorsaved == 0 ) - { - for (i=0; ibundlescount-1; i++) - { - if ( coin->bundles[i] == 0 || coin->bundles[i]->tmpspends == 0 ) - break; - } - if ( i == coin->bundlescount-1 && bp->tmpspends != 0 && bp->ramchain.H.data != 0 && (n= bp->ramchain.H.data->numspends) != 0 && bp->converted == 0 ) - { - iguana_convertQ(coin,bp); - retval = 0; - } - else if ( bp->converted == 0 ) - { - for (i=0; ibundlescount-1; i++) - { - if ( coin->bundles[i] == 0 || coin->bundles[i]->utxofinish <= 1 ) - break; - } - if ( i == coin->bundlescount-1 ) - { - printf("must be restart after all the spendvectors are saved\n"); - coin->spendvectorsaved = (uint32_t)time(NULL); - } - } - } else retval = iguana_balancenormal(coin,bp,startheight,endheight); - if ( retval < 0 ) - { - //printf("third case.%d utxo.%u balance.%u prev.%u\n",bp->hdrsi,bp->utxofinish,bp->balancefinish,prevbp!=0?prevbp->utxofinish:-1); - coin->pendbalances--; - iguana_balancesQ(coin,bp); - } - else - { - iguana_validateQ(coin,bp); - flag++; - } - } - return(flag); - }*/ - - /*int32_t iguana_balancenormal(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) - { - uint32_t starttime; int32_t j=0,n; struct iguana_bundle *prevbp; - n = coin->bundlescount - 1; - for (j=0; jbundles[j]) == 0 ) - break; - if ( prevbp->utxofinish <= 1 || (j < bp->hdrsi && prevbp->balancefinish <= 1) ) - break; - } - //printf("B [%d] j.%d u.%u b.%u\n",bp->hdrsi,j,bp->utxofinish,bp->balancefinish); - if ( (j == n || bp->hdrsi == 0) && bp->bundleheight+bp->n <= coin->blocks.hwmchain.height && bp->utxofinish > 1 && bp->balancefinish <= 1 ) - { - bp->balancefinish = 1; - if ( bp->hdrsi >= coin->balanceswritten ) - { - //printf("balancecalc for %d when %d\n",bp->hdrsi,coin->balanceswritten); - starttime = (uint32_t)time(NULL); - for (j=0; j<=bp->hdrsi; j++) - iguana_allocvolatile(coin,&coin->bundles[j]->ramchain); - if ( iguana_balancegen(coin,bp,startheight,endheight) < 0 ) - { - printf("GENERATE BALANCES.%d ERROR ht.%d\n",bp->hdrsi,bp->bundleheight); - exit(-1); - } - printf("GENERATED BALANCES.%d for ht.%d duration %d seconds, (%d %d).%d\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL) - (uint32_t)starttime,bp->hdrsi,coin->blocks.hwmchain.height/coin->chain->bundlesize-1,bp->hdrsi >= coin->blocks.hwmchain.height/coin->chain->bundlesize-1); - coin->balanceswritten++; - } - bp->balancefinish = (uint32_t)time(NULL); - bp->queued = 0; - if ( bp->hdrsi >= coin->blocks.hwmchain.height/coin->chain->bundlesize-1 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize-1 ) - { - printf("TRIGGER FLUSH %d vs %d\n",bp->hdrsi,coin->blocks.hwmchain.height/coin->chain->bundlesize); - sleep(1); - if ( time(NULL) > coin->startutc+10 && bp->hdrsi >= coin->blocks.hwmchain.height/coin->chain->bundlesize-1 ) - { - if ( iguana_balanceflush(coin,bp->hdrsi,3) > 0 ) - printf("balanceswritten.%d flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",coin->balanceswritten,bp->hdrsi,coin->longestchain/coin->chain->bundlesize); - } else printf("TRIGGER cancelled %d vs %d\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize-1); - } - return(0); - } - return(-1); - }*/ - /*if ( iguana_spendvectors(coin,bp,dest,starti,coin->RTheight%bp->n,0) < 0 ) - { - printf("RTutxo error -> RTramchainfree\n"); - iguana_RTramchainfree(coin); - return(-1); - } else printf("spendvectors calculated to %d\n",coin->RTheight);*/ - /*while ( block != 0 ) - { - if ( bits256_cmp(iguana_blockhash(coin,coin->RTheight-n-1),block->RO.hash2) != 0 ) - { - printf("blockhash error at %d\n",coin->RTheight-n-1); - break; - } - block = iguana_blockfind("RTupdate",coin,block->RO.prev_block); - n++; - if ( coin->RTgenesis != 0 && n >= bp->n ) - break; - }*/ - //if ( coin->RTHASHMEM.ptr == 0 ) - // iguana_meminit(&coin->RTHASHMEM,"RTHASH",0,1024L*1024L*1024L,0); - if ( coin->PREFETCHLAG > 0 ) - { - //iguana_ramchain_prefetch(coin,&coin->RTramchain,0); - //iguana_prefetch(coin,bp,coin->bundlescount,1); - } - - void iguana_prefetch(struct iguana_info *coin,struct iguana_bundle *bp,int32_t width,int32_t flags) - { - int32_t i; struct iguana_bundle *spentbp; uint32_t starttime = (uint32_t)time(NULL); - if ( bp->hdrsi > width ) - { - //printf("start prefetch.%d for [%d]\n",width,bp->hdrsi); - for (i=1; ibundles[bp->hdrsi - i]) != 0 ) - { - iguana_ramchain_prefetch(coin,&spentbp->ramchain,flags); - spentbp->lastprefetch = starttime; - } - } - //printf("end prefetch.%d for [%d] elapsed %d\n",width,bp->hdrsi,(uint32_t)time(NULL)-starttime); - } - } - /*if ( (fp= fopen(fname,"r")) == 0 ) - { - sprintf(fname,"confs/%s_%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); - OS_compatible_path(fname); - fp = fopen(fname,"r"); - } - else if ( 0 && iter == 1 ) - { - sprintf(fname,"confs/%s_%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); - OS_compatible_path(fname); - if ( (fp2= fopen(fname,"r")) != 0 ) - { - fseek(fp,0,SEEK_END), fseek(fp2,0,SEEK_END); - if ( ftell(fp2) > ftell(fp) ) - { - fclose(fp); - fp = fp2; - } - else - { - fclose(fp2); - printf("%s is not used as tmp version is bigger\n",fname); - } - } - }*/ - /*else if ( bp->emitfinish != 0 ) - { - if ( bp->utxofinish > 1 ) - { - if ( bp->balancefinish == 0 ) - { - //bp->queued = 0; - iguana_balancesQ(coin,bp); - } - return(1); - } - if ( bp->emitfinish > 1 ) - { - if ( (retval= iguana_bundlefinish(coin,bp)) > 0 ) - { - //printf("moved to balancesQ.%d bundleiters.%d\n",bp->hdrsi,bp->bundleheight); - //bp->queued = 0; - return(0); - } //else printf("finish incomplete.%d\n",bp->hdrsi); - } - }*/ - //fprintf(stderr,"RO %p U[%d] txidind.%d pkind.%d\n",u,unspentind,ramchain->H.txidind,ramchain->pkind); - /*if ( 0 && u->scriptpos != 0 && u->scriptlen > 0 )//&& u->scriptlen <= sizeof(u->script) ) - { - scriptptr = &Kspace[u->scriptpos]; - if ( memcmp(script,scriptptr,u->scriptlen) != 0 ) - { - int32_t i; - for (i=0; iscriptlen; i++) - printf("%02x",scriptptr[i]); - printf(" u->script\n"); - for (i=0; iscriptlen; i++) - printf("%02x",script[i]); - printf(" script\n"); - printf("[%d] u%d script compare error.%d vs %d\n",bp->hdrsi,unspentind,scriptlen,u->scriptlen); - return(0); - } //else printf("SCRIPT.%d MATCHED!\n",u->scriptlen); - } // else would need to get from HDD to verify*/ - - /* - //char *hashstr,*txidstr,*coinaddr,*txbytes,rmd160str[41],str[65]; int32_t len,height,i,n,valid = 0; - //cJSON *addrs,*retjson,*retitem; uint8_t rmd160[20],addrtype; bits256 hash2,checktxid; - //memset(&hash2,0,sizeof(hash2)); struct iguana_txid *tx,T; struct iguana_block *block = 0; - - if ( (coinaddr= jstr(json,"address")) != 0 ) - { - if ( btc_addr2univ(&addrtype,rmd160,coinaddr) == 0 ) - { - if ( addrtype == coin->chain->pubval || addrtype == coin->chain->p2shval ) - valid = 1; - else return(clonestr("{\"error\":\"invalid addrtype\"}")); - } else return(clonestr("{\"error\":\"cant convert address to rmd160\"}")); - } - if ( strcmp(method,"block") == 0 ) - { - height = -1; - if ( ((hashstr= jstr(json,"blockhash")) != 0 || (hashstr= jstr(json,"hash")) != 0) && strlen(hashstr) == sizeof(bits256)*2 ) - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - else - { - height = juint(json,"height"); - hash2 = iguana_blockhash(coin,height); - } - retitem = cJSON_CreateObject(); - if ( (block= iguana_blockfind(coin,hash2)) != 0 ) - { - if ( (height >= 0 && block->height == height) || memcmp(hash2.bytes,block->RO.hash2.bytes,sizeof(hash2)) == 0 ) - { - char str[65],str2[65]; printf("hash2.(%s) -> %s\n",bits256_str(str,hash2),bits256_str(str2,block->RO.hash2)); - return(jprint(iguana_blockjson(coin,block,juint(json,"txids")),1)); - } - } - else return(clonestr("{\"error\":\"cant find block\"}")); - } - else if ( strcmp(method,"tx") == 0 ) - { - if ( ((txidstr= jstr(json,"txid")) != 0 || (txidstr= jstr(json,"hash")) != 0) && strlen(txidstr) == sizeof(bits256)*2 ) - { - retitem = cJSON_CreateObject(); - decode_hex(hash2.bytes,sizeof(hash2),txidstr); - if ( (tx= iguana_txidfind(coin,&height,&T,hash2)) != 0 ) - { - jadd(retitem,"tx",iguana_txjson(coin,tx,height)); - return(jprint(retitem,1)); - } - return(clonestr("{\"error\":\"cant find txid\"}")); - } - else return(clonestr("{\"error\":\"invalid txid\"}")); - } - else if ( strcmp(method,"rawtx") == 0 ) - { - if ( ((txidstr= jstr(json,"txid")) != 0 || (txidstr= jstr(json,"hash")) != 0) && strlen(txidstr) == sizeof(bits256)*2 ) - { - decode_hex(hash2.bytes,sizeof(hash2),txidstr); - if ( (tx= iguana_txidfind(coin,&height,&T,hash2)) != 0 ) - { - if ( (len= iguana_txbytes(coin,coin->blockspace,coin->blockspacesize,&checktxid,tx,height,0,0)) > 0 ) - { - txbytes = mycalloc('x',1,len*2+1); - init_hexbytes_noT(txbytes,coin->blockspace,len*2+1); - retitem = cJSON_CreateObject(); - jaddstr(retitem,"txid",bits256_str(str,hash2)); - jaddnum(retitem,"height",height); - jaddstr(retitem,"rawtx",txbytes); - myfree(txbytes,len*2+1); - return(jprint(retitem,1)); - } else return(clonestr("{\"error\":\"couldnt generate txbytes\"}")); - } - return(clonestr("{\"error\":\"cant find txid\"}")); - } - else return(clonestr("{\"error\":\"invalid txid\"}")); - } - else if ( strcmp(method,"txs") == 0 ) - { - if ( ((hashstr= jstr(json,"block")) != 0 || (hashstr= jstr(json,"blockhash")) != 0) && strlen(hashstr) == sizeof(bits256)*2 ) - { - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - if ( (block= iguana_blockfind(coin,hash2)) == 0 ) - return(clonestr("{\"error\":\"cant find blockhash\"}")); - } - else if ( jobj(json,"height") != 0 ) - { - height = juint(json,"height"); - hash2 = iguana_blockhash(coin,height); - if ( (block= iguana_blockfind(coin,hash2)) == 0 ) - return(clonestr("{\"error\":\"cant find block at height\"}")); - } - else if ( valid == 0 ) - return(clonestr("{\"error\":\"txs needs blockhash or height or address\"}")); - retitem = cJSON_CreateArray(); - if ( block != 0 ) - { - for (i=0; iRO.txn_count; i++) - { - if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) - jaddi(retitem,iguana_txjson(coin,tx,-1)); - } - } - else - { - init_hexbytes_noT(rmd160str,rmd160,20); - jaddnum(retitem,"addrtype",addrtype); - jaddstr(retitem,"rmd160",rmd160str); - jaddstr(retitem,"txlist","get list of all tx for this address"); - } - return(jprint(retitem,1)); - } - - else - { - n = 0; - if ( valid == 0 ) - { - if ( (addrs= jarray(&n,json,"addrs")) == 0 ) - return(clonestr("{\"error\":\"need address or addrs\"}")); - } - for (i=0; i<=n; i++) - { - retitem = cJSON_CreateObject(); - if ( i > 0 ) - retjson = cJSON_CreateArray(); - if ( i > 0 ) - { - if ( (coinaddr= jstr(jitem(addrs,i-1),0)) == 0 ) - return(clonestr("{\"error\":\"missing address in addrs\"}")); - if ( btc_addr2univ(&addrtype,rmd160,coinaddr) < 0 ) - { - free_json(retjson); - return(clonestr("{\"error\":\"illegal address in addrs\"}")); - } - if ( addrtype != coin->chain->pubval && addrtype != coin->chain->p2shval ) - return(clonestr("{\"error\":\"invalid addrtype in addrs\"}")); - } - if ( strcmp(method,"utxo") == 0 ) - { - jaddstr(retitem,"utxo","utxo entry"); - } - else if ( strcmp(method,"unconfirmed") == 0 ) - { - jaddstr(retitem,"unconfirmed","unconfirmed entry"); - } - else if ( strcmp(method,"balance") == 0 ) - { - jaddstr(retitem,"balance","balance entry"); - } - else if ( strcmp(method,"totalreceived") == 0 ) - { - jaddstr(retitem,"totalreceived","totalreceived entry"); - } - else if ( strcmp(method,"totalsent") == 0 ) - { - jaddstr(retitem,"totalsent","totalsent entry"); - } - else if ( strcmp(method,"validateaddress") == 0 ) - { - jaddstr(retitem,"validate",coinaddr); - } - if ( n == 0 ) - return(jprint(retitem,1)); - else jaddi(retjson,retitem); - } - return(jprint(retjson,1)); - } - */ - - /* - char *iguana_listsinceblock(struct supernet_info *myinfo,struct iguana_info *coin,bits256 blockhash,int32_t target) - { - cJSON *retitem = cJSON_CreateObject(); - return(jprint(retitem,1)); - } - - char *iguana_getinfo(struct supernet_info *myinfo,struct iguana_info *coin) - { - cJSON *retitem = cJSON_CreateObject(); - jaddstr(retitem,"result",coin->statusstr); - return(jprint(retitem,1)); - } - - char *iguana_getbestblockhash(struct supernet_info *myinfo,struct iguana_info *coin) - { - cJSON *retitem = cJSON_CreateObject(); - char str[65]; jaddstr(retitem,"result",bits256_str(str,coin->blocks.hwmchain.RO.hash2)); - return(jprint(retitem,1)); - } - - char *iguana_getblockcount(struct supernet_info *myinfo,struct iguana_info *coin) - { - cJSON *retitem = cJSON_CreateObject(); - jaddnum(retitem,"result",coin->blocks.hwmchain.height); - return(jprint(retitem,1)); - }*/ - if ( 0 ) - { - int32_t i,n; int64_t total; char *coinaddr; struct iguana_pkhash *P; struct iguana_info *coin; uint8_t rmd160[20],addrtype,pubkey33[33]; double startmillis; - coin = iguana_coinfind("BTCD"); - if ( 1 && coin != 0 ) - { - getchar(); - for (i=0; ibundlescount; i++) - if ( coin->bundles[i] == 0 ) - break; - coinaddr = "RUZ9AKxy6J2okcBd1PZm4YH6atmPwqV4bo"; - bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); - P = calloc(coin->bundlescount,sizeof(*P)); - memset(pubkey33,0,sizeof(pubkey33)); - n = iguana_pkhasharray(coin,0,0,0,&total,P,coin->bundlescount,rmd160,coinaddr,pubkey33); - printf("%s has total outputs %.8f from %d bundles\n",coinaddr,dstr(total),n); - startmillis = OS_milliseconds(); - for (i=0; i<1000; i++) - n = iguana_pkhasharray(coin,0,0,0,&total,P,coin->bundlescount,rmd160,coinaddr,pubkey33); - printf("%s has total outputs %.8f from %d bundles %.3f millis\n",coinaddr,dstr(total),n,OS_milliseconds()-startmillis); - getchar(); - } - } - int32_t i,numretries = 5; - for (i=0; i 2 ) - //printf("write.%d of %d worked!\n",i+1,numretries+1); - break; - } - fseek(fp,startfpos,SEEK_SET); - } - } -#else - //printf("call _iguana_chainlink\n"); - /*for (i=coin->blocks.hwmchain.height%coin->chain->bundlesize; ichain->bundlesize; i++) - { - if ( (bp= coin->current) != 0 && (block= bp->blocks[i]) != 0 ) - { - //printf("i.%d %s main.%d txvalid.%d\n",i,bits256_str(str,block->RO.hash2),block->mainchain,block->txvalid); - if ( _iguana_chainlink(coin,block) == 0 ) - iguana_blockQ("mainchain",coin,bp,-i,block->RO.hash2,1); - //iguana_realtime_update(coin); - } - }*/ - /*int32_t numrmds,minconf=0,maxconf=0,m = 0; uint8_t *rmdarray; cJSON *retjson; - retjson = cJSON_CreateArray(); - if ( (minconf= juint(params[0],0)) > 0 ) - { - m++; - if ( (maxconf= juint(params[1],0)) > 0 ) - m++; - } - if ( minconf == 0 ) - minconf = 1; - if ( maxconf == 0 ) - maxconf = 9999999; - rmdarray = iguana_rmdarray(coin,&numrmds,array,m); - iguana_unspents(myinfo,coin,retjson,minconf,maxconf,rmdarray,numrmds); - if ( rmdarray != 0 ) - free(rmdarray); - return(jprint(retjson,1));*/ - char *iguana_payloadsave(char *filename,cJSON *wallet) - { - FILE *fp; - if ( (fp= fopen(filename,"wb")) != 0 ) - { - if ( fwrite(payloadstr,1,strlen(payloadstr),fp) != strlen(payloadstr) ) - { - fclose(fp); - return(clonestr("{\"error\":\"couldnt save wallet backup\"}")); - } - fclose(fp); - return(0); - } else return(clonestr("{\"error\":\"couldnt save wallet backup\"}")); - } - - /*struct iguana_waddress *iguana_waccountadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount **wacctp,char *walletaccount,char *coinaddr,char *redeemScript) - { - struct iguana_waccount *wacct; struct iguana_waddress *waddr = 0; - if ( (wacct= iguana_waccountfind(myinfo,coin,walletaccount)) == 0 ) - wacct = iguana_waccountcreate(myinfo,coin,walletaccount); - if ( wacct != 0 ) - waddr = iguana_waddresscreate(myinfo,coin,wacct,coinaddr,redeemScript); - return(waddr); - }*/ -#ifdef testing - char *bitcoin_cltvtx(struct iguana_info *coin,char *changeaddr,char *senderaddr,char *senders_otheraddr,char *otheraddr,uint32_t locktime,uint64_t satoshis,bits256 txid,int32_t vout,uint64_t inputsatoshis,bits256 privkey) - { - uint64_t change; char *rawtxstr,*signedtx; struct vin_info V; bits256 cltxid,signedtxid; - int32_t cltvlen,len; uint32_t timestamp; char ps2h_coinaddr[65]; cJSON *txobj; - uint8_t p2sh_rmd160[20],cltvscript[1024],paymentscript[64],rmd160[20],secret160[20],addrtype; - timestamp = (uint32_t)time(NULL); - bitcoin_addr2rmd160(&addrtype,secret160,senders_otheraddr); - cltvlen = bitcoin_cltvscript(coin->chain->p2shtype,ps2h_coinaddr,p2sh_rmd160,cltvscript,0,senderaddr,otheraddr,secret160,locktime); - txobj = bitcoin_createtx(coin,locktime); - len = bitcoin_p2shspend(paymentscript,0,p2sh_rmd160); - bitcoin_addoutput(coin,txobj,paymentscript,len,satoshis); - bitcoin_addinput(coin,txobj,txid,vout,locktime); - if ( inputsatoshis > (satoshis + 10000) ) - { - change = inputsatoshis - (satoshis + 10000); - if ( changeaddr != 0 && changeaddr[0] != 0 ) - { - bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); - if ( addrtype == coin->chain->pubtype ) - len = bitcoin_standardspend(paymentscript,0,rmd160); - else if ( addrtype == coin->chain->p2shtype ) - len = bitcoin_standardspend(paymentscript,0,rmd160); - else - { - printf("error with mismatched addrtype.%02x vs (%02x %02x)\n",addrtype,coin->chain->pubtype,coin->chain->p2shtype); - return(0); - } - bitcoin_addoutput(coin,txobj,paymentscript,len,change); - } - else - { - printf("error no change address when there is change\n"); - return(0); - } - } - rawtxstr = bitcoin_json2hex(coin,&cltxid,txobj); - char str[65]; printf("CLTV.%s (%s)\n",bits256_str(str,cltxid),rawtxstr); - memset(&V,0,sizeof(V)); - V.signers[0].privkey = privkey; - bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,&V); - free(rawtxstr); - if ( signedtx != 0 ) - printf("signed CLTV.%s (%s)\n",bits256_str(str,signedtxid),signedtx); - else printf("error generating signedtx\n"); - free_json(txobj); - return(signedtx); - } -#endif - - char *refstr = "01000000\ - 01\ - eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2\ - 01000000\ - 8c\ - 4930460221009e0339f72c793a89e664a8a932df073962a3f84eda0bd9e02084a6a9567f75aa022100bd9cbaca2e5ec195751efdfac164b76250b1e21302e51ca86dd7ebd7020cdc0601410450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6\ - ffffffff\ - 01\ - 605af40500000000\ - 19\ - 76a914097072524438d003d23a2f23edb65aae1bb3e46988ac\ - 00000000"; - - cJSON *bitcoin_txtest(struct iguana_info *coin,char *rawtxstr,bits256 txid) - { - struct iguana_msgtx msgtx; char str[65],str2[65]; bits256 checktxid,blockhash,signedtxid; - cJSON *retjson,*txjson; uint8_t *serialized,*serialized2; uint32_t firstvout; - struct vin_info *V; char vpnstr[64],*txbytes,*signedtx; int32_t n,txstart,height,n2,maxsize,len; - rawtxstr = refstr; - len = (int32_t)strlen(rawtxstr); - maxsize = len + 32768; - serialized = calloc(1,maxsize); - serialized2 = calloc(1,maxsize); - len >>= 1; - V = 0; - vpnstr[0] = 0; - memset(&msgtx,0,sizeof(msgtx)); - if ( len < maxsize ) - { - decode_hex(serialized,len,rawtxstr); - txjson = cJSON_CreateObject(); - retjson = cJSON_CreateObject(); - if ( (n= iguana_rwmsgtx(coin,0,txjson,serialized,maxsize,&msgtx,&txid,vpnstr)) < 0 ) - { - printf("bitcoin_txtest len.%d: n.%d from (%s)\n",len,n,rawtxstr); - free(serialized), free(serialized2); - return(cJSON_Parse("{\"error\":\"cant parse txbytes\"}")); - } - V = calloc(msgtx.tx_in,sizeof(*V)); - { - //char *pstr; int32_t plen; - decode_hex(V[0].signers[0].privkey.bytes,sizeof(V[0].signers[0].privkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725"); - //pstr = "0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6"; - //plen = (int32_t)strlen(pstr); - //decode_hex(V[0].signers[0].pubkey,plen,pstr); - } - if ( bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,V) != 0 ) - printf("bitcoin_verifytx error\n"); - jadd(retjson,"result",txjson); - if ( (firstvout= iguana_unspentindfind(coin,&height,txid,0,coin->bundlescount-1)) != 0 ) - { - if ( height >= 0 ) - { - blockhash = iguana_blockhash(coin,height); - jaddnum(retjson,"height",height); - jaddnum(retjson,"confirmations",coin->longestchain - height); - jaddbits256(retjson,"blockhash",blockhash); - } - } - //printf("retjson.(%s) %p\n",jprint(retjson,0),retjson); - memset(checktxid.bytes,0,sizeof(checktxid)); - if ( (n2= iguana_rwmsgtx(coin,1,0,serialized2,maxsize,&msgtx,&checktxid,vpnstr)) < 0 || n != n2 ) - { - printf("bitcoin_txtest: n.%d vs n2.%d\n",n,n2); - free(serialized), free(serialized2), free(V); - return(retjson); - } - if ( bits256_cmp(checktxid,txid) != 0 ) - { - printf("bitcoin_txtest: txid.%s vs check.%s\n",bits256_str(str,txid),bits256_str(str2,checktxid)); - } - checktxid = iguana_parsetxobj(coin,&txstart,serialized,maxsize,&msgtx,jobj(retjson,"result")); - if ( bits256_cmp(checktxid,txid) != 0 ) - { - printf("bitcoin_txtest: txid.%s vs check2.%s\n",bits256_str(str,txid),bits256_str(str2,checktxid)); - } - if ( msgtx.allocsize != 0 ) - { - txbytes = malloc(msgtx.allocsize*2 + 1); - init_hexbytes_noT(txbytes,&serialized[txstart],msgtx.allocsize); - if ( strcmp(txbytes,rawtxstr) != 0 ) - printf("bitcoin_txtest: reconstruction error: %s != %s\n",rawtxstr,txbytes); - else printf("reconstruction PASSED\n"); - free(txbytes); - } else printf("bitcoin_txtest: zero msgtx allocsize\n"); - free(serialized), free(serialized2), free(V); - return(retjson); - } - free(serialized), free(serialized2); - return(cJSON_Parse("{\"error\":\"testing bitcoin txbytes\"}")); - } - - - /*int32_t btc_priv2wif(char *wifstr,uint8_t privkey[32],uint8_t addrtype) - { - uint8_t tmp[128]; char hexstr[67]; cstring *btc_addr; - memcpy(tmp,privkey,32); - tmp[32] = 1; - init_hexbytes_noT(hexstr,tmp,32); - if ( (btc_addr= base58_encode_check(addrtype,true,tmp,33)) != 0 ) - { - strcpy(wifstr,btc_addr->str); - cstr_free(btc_addr,true); - } - //printf("-> (%s) -> wif.(%s) addrtype.%02x\n",hexstr,wifstr,addrtype); - return(0); - } - - cstring *base58_encode_check(uint8_t addrtype,bool have_addrtype,const void *data,size_t data_len) - { - uint8_t i,buf[64]; bits256 hash; cstring *s_enc;//,*s = cstr_new_sz(data_len + 1 + 4); - buf[0] = addrtype; - memcpy(buf+1,data,data_len); - hash = bits256_doublesha256(0,buf,(int32_t)data_len+1); - //bu_Hash4(md32,buf,(int32_t)data_len+1); - for (i=0; i<4; i++) - { - buf[data_len+i+1] = hash.bytes[31-i]; - //printf("(%02x %02x) ",hash.bytes[31-i],md32[i]); - } - //printf("hash4 cmp\n"); - s_enc = base58_encode(buf,data_len+5); - return s_enc; - } - */ - /*if ( fieldstr != 0 && valuestr != 0 ) - { - flag = 0; - if ( (len= is_hexstr(fieldstr,0)) > 0 ) - { - if ( strlen(fieldstr) == 20*2 ) - decode_hex(rmd160,sizeof(rmd160),fieldstr); - else - { - len >>= 1; - decode_hex(script,len,valuestr); - calc_rmd160_sha256(rmd160,script,len); - bitcoin_address(p2shaddr,coin->chain->p2shtype,rmd160,20); - fprintf(fp,"%s %s %32s=%d # addr=%s # p2sh\n",valuestr,utc_str(str,(uint32_t)time(NULL)),account,i+1,p2shaddr); - flag = 1; - } - } else bitcoin_addr2rmd160(&addrtype,rmd160,fieldstr); - if ( flag == 0 ) - { - privkey = bits256_conv(valuestr); - bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); - bitcoin_address(coinaddr,coin->chain->pubtype,rmd160,20); - fprintf(fp,"%s %s %32s=%d # addr=%s\n",wifstr,utc_str(str,(uint32_t)time(NULL)),account,i+1,coinaddr); - } - - wiftype = 188; - for (j=0; jchain != 0 ) - { - if ( addrtype == coin->chain->pubtype ) - { - wiftype = coin->chain->wiftype; - privkey = bits256_conv(privkeystr); - if ( bits256_nonz(privkey) != 0 && bitcoin_priv2wif(wifstr,privkey,wiftype) > 0 ) - { - fprintf(fp,"%s %s %32s=%d # addr=%s\n",wifstr,utc_str(str,(uint32_t)time(NULL)),account,i+1,coinaddr); - } - break; - } - else if ( addrtype == coin->chain->p2shtype ) - { - fprintf(fp,"%s %s %32s=%d # addr=%s # p2sh\n",privkeystr,utc_str(str,(uint32_t)time(NULL)),account,i+1,p2shaddr); - break; - } - } - } - }*/ - /*coinaddr = child->string; - privkeystr = child->valuestring; - if ( coinaddr != 0 && privkeystr != 0 ) - { - if ( (wacct= iguana_waccountcreate(myinfo,coin,account)) != 0 ) - { - if ( iguana_waddresssearch(myinfo,coin,&tmp,coinaddr) == 0 ) - { - memset(&waddr,0,sizeof(waddr)); - strcpy(waddr.coinaddr,coinaddr); - waddr.addrtype = coin->chain->p2shtype; - if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == sizeof(rmd160) && addrtype == coin->chain->p2shtype ) - iguana_waddressadd(myinfo,coin,wacct,&waddr,privkeystr); - else - { - waddr.addrtype = coin->chain->pubtype; - privkey = bits256_conv(privkeystr); - if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&waddr,privkey) != 0 ) - iguana_waddressadd(myinfo,coin,wacct,&waddr,0); - } - } else printf("dup.(%s) ",coinaddr); - len = (int32_t)strlen(privkeystr); - for (j=0; jwallet,wacct,tmp) - { - if ( account != 0 && strcmp(account,"*") != 0 && strcmp(account,wacct->account) != 0 ) - continue; - HASH_ITER(hh,wacct->waddr,waddr,tmp2) - { - if ( waddr->addrtype != coin->chain->pubtype || (bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0) ) - continue; - if ( waddr->balance > 0 ) - { - remains -= waddr->balance; - waddrs[num++] = waddr; - if ( num >= maxwaddrs || remains <= 0 ) - break; - } - } - if ( num >= maxwaddrs || remains <= 0 ) - break; - } - - /*int64_t iguana_unspentset(struct supernet_info *myinfo,struct iguana_info *coin) - { - int64_t sum = 0,total; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; int32_t n,numunspents = 0; cJSON *addresses = cJSON_CreateArray(); - HASH_ITER(hh,myinfo->wallet,wacct,tmp) - { - HASH_ITER(hh,wacct->waddr,waddr,tmp2) - { - if ( waddr->addrtype != coin->chain->pubtype || (bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0) ) - continue; - jaddstr(array,waddr->coinaddr); - total = 0; - n = 0; - iguana_pkhasharray(myinfo,coin,0,coin->minconfirms,coin->longestchain,&total,0,coin->bundlescount,waddr->rmd160,waddr->coinaddr,waddr->pubkey,coin->blocks.hwmchain.height - coin->minconfirms,(uint64_t *)coin->blockspace,&n,(int32_t)(coin->blockspacesize/sizeof(*waddr->unspents))-1000); - if ( n > 0 ) - { - if ( waddr->unspents == 0 || waddr->maxunspents < n ) - { - waddr->unspents = realloc(waddr->unspents,sizeof(*waddr->unspents) * n); - waddr->maxunspents = n; - } - memcpy(waddr->unspents,coin->blockspace,sizeof(*waddr->unspents) * n); - waddr->numunspents = n; - waddr->balance = total; - sum += total; - numunspents += n; - } - } - } - //printf("available %.8f\n",dstr(sum)); - return(sum); - }*/ - - /*int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs) - { - int32_t len,maxsize,retval = -1; uint8_t *serialized,*serialized2; - struct iguana_msgtx msgtx; bits256 txid; char vpnstr[64]; - len = (int32_t)strlen(rawtxstr); - maxsize = len + 32768; - serialized = calloc(1,maxsize), serialized2 = calloc(1,maxsize); - len >>= 1; - vpnstr[0] = 0; - decode_hex(serialized,len,rawtxstr); - memset(&msgtx,0,sizeof(msgtx)); - if ( iguana_rwmsgtx(coin,0,0,serialized,maxsize,&msgtx,&txid,vpnstr) > 0 && numinputs == msgtx.tx_in ) - { - if ( bitcoin_verifyvins(coin,signedtxidp,signedtx,&msgtx,serialized2,maxsize,V,SIGHASH_ALL) == 0 ) - retval = 0; - else printf("bitcoin_verifytx: bitcoin_verifyvins error\n"); - } else printf("bitcoin_verifytx: error iguana_rwmsgtx\n"); - free(serialized), free(serialized2); - return(retval); - } - - cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins) - { - int32_t i,j,m,n,plen; char *rawtxstr,*pubkeystr,*spendstr; struct vin_info *V,*vp; bits256 txid; struct iguana_waccount *wacct; struct iguana_waddress *waddr; cJSON *vitem,*vinsobj,*pubkeys; - V = calloc(spend->numinputs,sizeof(*V)); - if ( *signedtxp != 0 ) - { - if ( txobj != 0 ) - free_json(txobj); - txobj = bitcoin_hex2json(coin,&txid,0,*signedtxp); - if ( vins != 0 ) - { - if ( jobj(txobj,"vin") != 0 ) - jdelete(txobj,"vin"); - jadd(txobj,"vin",iguana_createvins(myinfo,coin,txobj,vins)); - } - //printf("bitcoin_hex2json (%s)\n",jprint(txobj,0)); - free(*signedtxp); - } - vinsobj = jarray(&n,txobj,"vin"); - for (i=0; inuminputs; i++) // N times less efficient, but for small number of inputs ok - { - vp = &V[i]; - if ( i < n ) - { - if ( (vitem= jitem(vinsobj,i)) != 0 && ((spendstr= jstr(vitem,"scriptPub")) != 0 || (spendstr= jstr(vitem,"scriptPubKey")) != 0) ) - { - vp->spendlen = (int32_t)strlen(spendstr) >> 1; - decode_hex(vp->spendscript,vp->spendlen,spendstr); - } else spendstr = 0; - } - else vitem = 0; - vp->N = vp->M = 1; - if ( (rawtxstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) - { - for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) - { - if ( bits256_nonz(spend->inputs[i].privkeys[j]) != 0 ) - { - vp->signers[j].privkey = spend->inputs[i].privkeys[j]; - bitcoin_pubkey33(coin->ctx,vp->signers[j].pubkey,vp->signers[j].privkey); - } - else - { - vp->signers[j].pubkey[0] = 0; - break; - } - } - if ( vitem != 0 && (pubkeys= jarray(&m,vitem,"pubkeys")) != 0 )//spend->inputs[i].numpubkeys > 0 ) - { - for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) - { - if ( j < m && (pubkeystr= jstr(jitem(pubkeys,j),0)) != 0 && is_hexstr(pubkeystr,(int32_t)strlen(pubkeystr)) > 0 ) - decode_hex(vp->signers[j].pubkey,(int32_t)strlen(pubkeystr)>>1,pubkeystr); - else if ( (plen= bitcoin_pubkeylen(spend->inputs[i].pubkeys[j])) > 0 ) - memcpy(vp->signers[j].pubkey,spend->inputs[i].pubkeys[j],plen); - } - } - //if ( spend->inputs[i].spendlen > 0 ) - // { - // memcpy(vp->spendscript,spend->inputs[i].spendscript,spend->inputs[i].spendlen); - // vp->spendlen = spend->inputs[i].spendlen; - // } - if ( spend->inputs[i].p2shlen > 0 ) - { - memcpy(vp->p2shscript,spend->inputs[i].p2shscript,spend->inputs[i].p2shlen); - vp->p2shlen = spend->inputs[i].p2shlen; - } - for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) - { - if ( vp->signers[j].coinaddr[0] == 0 && (plen= bitcoin_pubkeylen(spend->inputs[i].pubkeys[j])) > 0 ) - { - bitcoin_address(vp->signers[j].coinaddr,coin->chain->pubtype,spend->inputs[i].pubkeys[j],plen); - } - } - if ( myinfo->expiration != 0 ) - { - for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) - { - if ( bits256_nonz(vp->signers[j].privkey) == 0 && vp->signers[j].coinaddr[0] != 0 ) - { - if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,vp->signers[j].coinaddr)) != 0 ) - vp->signers[j].privkey = waddr->privkey; - } - } - } - vp->sequence = spend->inputs[i].sequence; - //printf("json2hex.(%s)\n",rawtxstr); - } - } - bitcoin_verifytx(coin,txidp,signedtxp,rawtxstr,V,spend->numinputs); - //printf("json2hex.(%s)\n",rawtxstr); - free(rawtxstr); - if ( *signedtxp != 0 && i != spend->numinputs ) - free(*signedtxp), *signedtxp = 0; - free(V); - return(txobj); - }*/ - /*int64_t iguana_availunspents(struct supernet_info *myinfo,uint64_t **unspentsp,int32_t *nump,struct iguana_info *coin,int32_t minconf,char *account,void *ptr,int32_t maxsize) - { - int32_t i,j,num,numwaddrs; struct iguana_waddress **waddrs,*waddr; uint64_t *unspents,value,avail=0; - *unspentsp = unspents = 0; - *nump = num = 0; - waddrs = (struct iguana_waddress **)ptr; - numwaddrs = iguana_unspentslists(myinfo,coin,waddrs,(int32_t)(maxsize/sizeof(*waddrs)),(uint64_t)1 << 62,minconf); - if ( numwaddrs > 0 ) - { - unspents = (uint64_t *)((long)ptr + sizeof(*waddrs)*numwaddrs); - for (i=num=0; inumunspents > 0 ) - { - for (j=0; jnumunspents; j++) - { - if ( (value= iguana_unspentavail(coin,waddr->unspents[j],minconf,coin->longestchain)) != 0 ) - { - unspents[num << 1] = waddr->unspents[j]; - unspents[(num << 1) + 1] = value; - num++; - avail += value; - printf("([%d].u%u) ",(uint32_t)(waddr->unspents[j]>>32),(uint32_t)waddr->unspents[j]); - } - } - printf("(%s %.8f)\n",waddr->coinaddr,dstr(waddr->balance)); - } - } - } - *unspentsp = unspents; - *nump = num; - return(avail); - }*/ - - instantdex_addevent(s,*n,"BOB_sentprivs","BTCprivs","BTCprivs","BOB_waitfee"); - instantdex_addevent(s,*n,"BOB_sentprivs","BTCdeckC","BTCprivs","BOB_waitfee"); - instantdex_addevent(s,*n,"BOB_sentprivs","BTCprivC","BTCprivs","BOB_waitfee"); - instantdex_addevent(s,*n,"BOB_sentprivs","poll","BTCprivs","BOB_waitfee"); - - s = instantdex_statecreate(s,n,"ALICE_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"ALICE_sentprivs","BTCprivs","BTCprivs","Alice_waitfee"); - instantdex_addevent(s,*n,"ALICE_sentprivs","BTCdeckC","BTCprivs","Alice_waitfee"); - instantdex_addevent(s,*n,"ALICE_sentprivs","BTCprivC","BTCprivs","Alice_waitfee"); - instantdex_addevent(s,*n,"ALICE_sentprivs","poll","BTCprivs","Alice_waitfee"); - - s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"BOB_waitfee","feefound","BTCdeptx","BOB_sentdeposit"); - instantdex_addevent(s,*n,"BOB_waitfee","BTCdeckC","BTCprivs","BOB_waitfee"); - instantdex_addevent(s,*n,"BOB_waitfee","BTCprivs","poll","BOB_waitfee"); - instantdex_addevent(s,*n,"BOB_waitfee","poll","BTCprivs","BOB_waitfee"); - - s = instantdex_statecreate(s,n,"Alice_waitfee",ALICE_waitfeefunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"Alice_waitfee","feefound","BTCprivs","ALICE_waitdeposit"); - instantdex_addevent(s,*n,"Alice_waitfee","BTCdeckC","BTCprivs","Alice_waitfee"); - instantdex_addevent(s,*n,"Alice_waitfee","BTCprivs","poll","Alice_waitfee"); - instantdex_addevent(s,*n,"Alice_waitfee","poll","BTCprivs","Alice_waitfee"); - - s = instantdex_statecreate(s,n,"ALICE_waitdeposit",ALICE_waitdepositfunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"ALICE_waitdeposit","depfound","BTCalttx","ALICE_sentalt"); - instantdex_addevent(s,*n,"ALICE_waitdeposit","feefound","poll","ALICE_waitdeposit"); - instantdex_addevent(s,*n,"ALICE_waitdeposit","poll","BTCprivs","ALICE_waitdeposit"); - - s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaimed",0,0); - instantdex_addevent(s,*n,"BOB_sentdeposit","BTCalttx","poll","BOB_altconfirm"); - instantdex_addevent(s,*n,"BOB_sentdeposit","poll","poll","BOB_sentdeposit"); - - s = instantdex_statecreate(s,n,"BOB_altconfirm",BOB_waitaltconfirmfunc,0,"BOB_reclaimed",0,0); - instantdex_addevent(s,*n,"BOB_altconfirm","altfound","BTCpaytx","BOB_sentpayment"); - instantdex_addevent(s,*n,"BOB_altconfirm","poll","poll","BOB_altconfirm"); - - // [BLOCKING: BTCpaytx] now Alice's turn to make sure payment is confrmed and send in claim or see bob's reclaim and reclaim - s = instantdex_statecreate(s,n,"ALICE_sentalt",ALICE_waitBTCpaytxfunc,0,"ALICE_reclaimed",0,0); - instantdex_addevent(s,*n,"ALICE_sentalt","BTCpaytx","poll","ALICE_waitconfirms"); - instantdex_addevent(s,*n,"ALICE_sentalt","poll","poll","ALICE_sentalt"); - - s = instantdex_statecreate(s,n,"ALICE_waitconfirms",ALICE_waitconfirmsfunc,0,"ALICE_reclaimed",0,0); - instantdex_addevent(s,*n,"ALICE_waitconfirms","altfound","BTCprivM","ALICE_claimedbtc"); - instantdex_addevent(s,*n,"ALICE_waitconfirms","poll","poll","ALICE_checkbobreclaim"); - - /*cJSON *BTC_waitdeckCfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - strcmp(swap->expectedcmdstr,"BTCdeckC"); - return(newjson); - } - - cJSON *BTC_waitprivCfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - strcmp(swap->expectedcmdstr,"BTCprivC"); - printf("call privkey extract from serdatalen.%d\n",*serdatalenp); - instantdex_privkeyextract(myinfo,swap,*serdatap,*serdatalenp); - *serdatap = 0, *serdatalenp = 0; - return(newjson); - } - - cJSON *ALICE_waitfeefunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - struct iguana_info *coinbtc; - coinbtc = iguana_coinfind("BTC"); - *serdatap = 0, *serdatalenp = 0; - strcpy(swap->waitfortx,"fee"); - if ( coinbtc != 0 && swap->otherfee != 0 ) - jaddstr(newjson,"virtevent","feefound"); - return(newjson); - } - - cJSON *BTC_waitprivsfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; struct iguana_info *coin = iguana_coinfind("BTC"); - if ( coin != 0 ) - { - strcmp(swap->expectedcmdstr,"BTCprivs"); - instantdex_privkeyextract(myinfo,swap,*serdatap,*serdatalenp); - } - return(newjson); - } - - cJSON *ALICE_waitBTCpaytxfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - strcmp(swap->expectedcmdstr,"BTCpaytx"); - return(newjson); - } - - cJSON *BOB_waitprivMfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - char *retstr; - strcmp(swap->expectedcmdstr,"BTCprivM"); - if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,iguana_coinfind(swap->mine.offer.base),swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"altfound",0)) != 0 ) - { - free(retstr); - jaddstr(newjson,"virtevent","altfound"); - } - printf("search for payment spend in blockchain\n"); - *serdatap = 0, *serdatalenp = 0; - return(newjson); - } - - cJSON *BOB_waitaltconfirmfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - char *retstr; struct iguana_info *altcoin; - altcoin = iguana_coinfind(swap->mine.offer.base); - *serdatap = 0, *serdatalenp = 0; - strcpy(swap->waitfortx,"alt"); - //reftime = (uint32_t)(ap->offer.expiration - INSTANTDEX_LOCKTIME*2); - if ( altcoin != 0 && swap->altpayment != 0 && swap->otherchoosei >= 0 && (retstr= BTC_txconfirmed(myinfo,altcoin,swap,newjson,swap->altpayment->txid,&swap->altpayment->numconfirms,"altfound",altcoin->chain->minconfirms)) != 0 ) - { - if ( swap->payment != 0 || (swap->payment= instantdex_bobtx(myinfo,swap,altcoin,swap->mypubs[1],swap->otherpubs[0],swap->privkeys[swap->otherchoosei],swap->reftime,swap->BTCsatoshis,0)) != 0 ) - { - free(retstr); - jaddstr(newjson,"virtevent","altfound"); - } - } - return(newjson); - } - - cJSON *ALICE_waitconfirmsfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - char *retstr; double btcconfirms; struct iguana_info *coinbtc; - coinbtc = iguana_coinfind("BTC"); - *serdatap = 0, *serdatalenp = 0; - if ( swap->BTCsatoshis < SATOSHIDEN/10 ) - btcconfirms = 0; - else btcconfirms = 1. + sqrt((double)swap->BTCsatoshis / SATOSHIDEN); - if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"payfound",btcconfirms)) != 0 ) - { - free(retstr); - jaddstr(newjson,"virtevent","payfound"); - // if bobreclaimed is there, then reclaim altpayment - printf("search for Bob's reclaim in blockchain\n"); - } - return(newjson); - } - - cJSON *ALICE_checkbobreclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - char *retstr; double btcconfirms; struct iguana_info *coinbtc; - coinbtc = iguana_coinfind("BTC"); - *serdatap = 0, *serdatalenp = 0; - if ( swap->BTCsatoshis < SATOSHIDEN/10 ) - btcconfirms = 0; - else btcconfirms = sqrt((double)swap->BTCsatoshis / SATOSHIDEN); - if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"payfound",btcconfirms)) != 0 ) - { - free(retstr); - jaddstr(newjson,"virtevent","payfound"); - // if bobreclaimed is there, then reclaim altpayment - printf("search for Bob's reclaim in blockchain\n"); - } - return(newjson); - } - - cJSON *BTC_idlerecvfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - jaddstr(newjson,"error","need to cleanup"); - return(newjson); - } - */ - - cJSON *BOB_reclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - if ( swap->deposit != 0 ) - printf("reclaim deposit.(%s) to %s\n",swap->deposit->txbytes,swap->deposit->destaddr); - strcpy(swap->waitfortx,"bre"); - // reclaim deposit - return(newjson); - } - - cJSON *BOB_feereclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - if ( swap->myfee != 0 ) - printf("reclaim fee.(%s) -> %s\n",swap->myfee->txbytes,swap->myfee->destaddr); - strcpy(swap->waitfortx,"bfr"); - // reclaim deposit - return(newjson); - } - - cJSON *BOB_claimaltfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - if ( 0 && swap->altpayment != 0 ) - printf("spend altpayment.(%s) -> %s\n",swap->altpayment->txbytes,swap->altpayment->destaddr); - strcpy(swap->waitfortx,"bcl"); - // spend altpayment - return(newjson); - } - - cJSON *ALICE_reclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - // reclaim altpayment - if ( swap->altpayment != 0 ) - printf("reclaim altpayment.(%s) -> %s\n",swap->altpayment->txbytes,swap->altpayment->destaddr); - strcpy(swap->waitfortx,"are"); - return(newjson); - } - - cJSON *ALICE_feereclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - // reclaim fee - if ( swap->myfee != 0 ) - printf("reclaim fee.(%s) -> %s\n",swap->myfee->txbytes,swap->myfee->destaddr); - strcpy(swap->waitfortx,"afr"); - return(newjson); - } - - cJSON *ALICE_claimdepositfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - if ( swap->deposit != 0 ) - printf("reclaim deposit.(%s) -> %s\n",swap->deposit->txbytes,swap->deposit->destaddr); - strcpy(swap->waitfortx,"adp"); - // reclaim deposit - return(newjson); - } - - cJSON *ALICE_claimbtcfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - if ( swap->payment != 0 ) - printf("spend BTC payment.(%s) -> %s\n",swap->payment->txbytes,swap->payment->destaddr); - strcpy(swap->waitfortx,"acl"); - // spend BTC - return(newjson); - } - - /* - s = instantdex_statecreate(s,n,"ALICE_claimedbtc",ALICE_claimbtcfunc,0,0,0,0); - instantdex_addevent(s,*n,"ALICE_claimedbtc","aclfound","poll","BTC_cleanup"); - instantdex_addevent(s,*n,"ALICE_claimedbtc","poll","poll","ALICE_claimedbtc"); - - s = instantdex_statecreate(s,n,"BOB_depclaimed",BOB_reclaimfunc,0,0,0,0); // deposit back - instantdex_addevent(s,*n,"BOB_depclaimed","brefound","poll","BTC_cleanup"); - instantdex_addevent(s,*n,"BOB_depclaimed","poll","poll","BOB_depclaimed"); - - s = instantdex_statecreate(s,n,"BOB_claimedalt",BOB_claimaltfunc,0,0,0,0); - instantdex_addevent(s,*n,"BOB_claimedalt","bclfound","poll","BOB_depclaimed"); - instantdex_addevent(s,*n,"BOB_claimedalt","poll","poll","BOB_claimedalt"); - - // if things go wrong, bob gets his deposit and fee back - s = instantdex_statecreate(s,n,"BOB_feereclaimed",BOB_feereclaimfunc,0,0,0,0); - instantdex_addevent(s,*n,"BOB_feereclaimed","bfrfound","poll","BTC_cleanup"); - instantdex_addevent(s,*n,"BOB_feereclaimed","poll","poll","BOB_feereclaimed"); - - s = instantdex_statecreate(s,n,"BOB_reclaimed",BOB_reclaimfunc,0,0,0,0); // deposit back - instantdex_addevent(s,*n,"BOB_reclaimed","brefound","poll","BOB_feereclaimed"); - instantdex_addevent(s,*n,"BOB_reclaimed","poll","poll","BOB_reclaimed"); - - // if things go wrong, alice reclaims her altpayment or claims the deposit and then fee - s = instantdex_statecreate(s,n,"ALICE_feereclaimed",ALICE_feereclaimfunc,0,0,0,0); - instantdex_addevent(s,*n,"ALICE_feereclaimed","afrfound","poll","BTC_cleanup"); - instantdex_addevent(s,*n,"ALICE_feereclaimed","poll","poll","ALICE_feereclaimed"); - - s = instantdex_statecreate(s,n,"ALICE_reclaimed",ALICE_reclaimfunc,0,0,0,0); // altpayment - instantdex_addevent(s,*n,"ALICE_reclaimed","arefound","poll","ALICE_feereclaimed"); - instantdex_addevent(s,*n,"ALICE_reclaimed","poll","poll","ALICE_reclaimed"); - s = instantdex_statecreate(s,n,"ALICE_depositclaimed",ALICE_claimdepositfunc,0,0,0,0); // altpayment - instantdex_addevent(s,*n,"ALICE_depositclaimed","adpfound","poll","ALICE_feereclaimed"); - instantdex_addevent(s,*n,"ALICE_depositclaimed","poll","poll","ALICE_depositclaimed"); - s = instantdex_statecreate(s,n,"ALICE_checkbobreclaim",ALICE_checkbobreclaimfunc,0,"ALICE_reclaimed",0,0);*/ - // end terminal [BLOCKING] states - - // need to create states before they can be referred to, that way a one pass FSM compile is possible - //s = instantdex_statecreate(s,n,"BOB_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1); - //s = instantdex_statecreate(s,n,"ALICE_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1); - //s = instantdex_statecreate(s,n,"BOB_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); - //s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0,0); - //s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaimed",0,0); - //s = instantdex_statecreate(s,n,"BOB_altconfirm",BOB_waitaltconfirmfunc,0,"BOB_reclaimed",0,0); - //s = instantdex_statecreate(s,n,"BOB_sentpayment",BOB_waitprivMfunc,0,"BOB_reclaimed",0,0); - //s = instantdex_statecreate(s,n,"ALICE_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); - //s = instantdex_statecreate(s,n,"Alice_waitfee",ALICE_waitfeefunc,0,"BTC_cleanup",0,0); - //s = instantdex_statecreate(s,n,"ALICE_waitdeposit",ALICE_waitdepositfunc,0,"BTC_cleanup",0,0); - //s = instantdex_statecreate(s,n,"ALICE_sentalt",ALICE_waitBTCpaytxfunc,0,"ALICE_reclaimed",0,0); - //s = instantdex_statecreate(s,n,"ALICE_waitconfirms",ALICE_waitconfirmsfunc,0,"ALICE_reclaimed",0,0); - - /*if ( 0 ) // following are implicit states and events handled externally to setup datastructures - { - instantdex_addevent(s,*n,"BOB_idle","usrorder","BTCoffer","BTC_waitdeck"); // send deck - instantdex_addevent(s,*n,"ALICE_idle","usrorder","BTCoffer","BTC_waitdeck"); - } - s = instantdex_statecreate(s,n,"BOB_idle",BTC_checkdeckfunc,0,"BTC_cleanup",0,1); - s = instantdex_statecreate(s,n,"ALICE_idle",BTC_checkdeckfunc,0,"BTC_cleanup",0,1); - instantdex_addevent(s,*n,"BOB_idle","BTCoffer","poll","BTC_waitdeck"); // send deck + Chose - instantdex_addevent(s,*n,"ALICE_idle","BTCoffer","poll","BTC_waitdeck");*/ - - char *basilisk_issuebalances(struct supernet_info *myinfo,char *remoteaddr,int32_t basilisktag,char *symbol,int32_t lastheight,int32_t minconf,cJSON *addresses,int32_t timeoutmillis) - { - struct iguana_info *coin; char *retstr = 0; cJSON *retjson,*args = 0; - if ( (coin= iguana_coinfind(symbol)) != 0 ) - { - if ( coin->basilisk_balances != 0 ) - { - if ( (retstr= (*coin->basilisk_balances)(myinfo,coin,remoteaddr,basilisktag,&args,lastheight,minconf,addresses,timeoutmillis)) != 0 ) - { - retjson = basilisk_resultsjson(myinfo,symbol,remoteaddr,basilisktag,timeoutmillis,retstr,args); - free(retstr); - retstr = jprint(retjson,1); - } - } - } - return(retstr); - } - - char *basilisk_issuevalue(struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,bits256 txid,int16_t vout,char *coinaddr,int32_t timeoutmillis) - { - struct iguana_info *coin; char *retstr = 0; cJSON *retjson,*args = 0; - if ( (coin= iguana_coinfind(symbol)) != 0 ) - { - if ( coin->basilisk_value != 0 ) - { - if ( (retstr= (*coin->basilisk_value)(myinfo,coin,remoteaddr,basilisktag,&args,txid,vout,coinaddr,timeoutmillis)) != 0 ) - { - retjson = basilisk_resultsjson(myinfo,symbol,remoteaddr,basilisktag,timeoutmillis,retstr,args); - free(retstr); - retstr = jprint(retjson,1); - } - } - } - return(retstr); - } - - int32_t basilisk_submit(struct supernet_info *myinfo,cJSON *reqjson,int32_t timeout,int32_t fanout,struct basilisk_item *ptr) - { - int32_t i,j,k,l,r2,r,n; struct iguana_peer *addr; struct iguana_info *coin; char *reqstr; cJSON *tmpjson; - tmpjson = basilisk_json(myinfo,reqjson,ptr->basilisktag,timeout); - reqstr = jprint(tmpjson,1); - //printf("basilisk_submit.(%s)\n",reqstr); - if ( fanout <= 0 ) - fanout = BASILISK_MINFANOUT; - else if ( fanout > BASILISK_MAXFANOUT ) - fanout = BASILISK_MAXFANOUT; - r2 = rand(); - for (l=n=0; lpeers.active[j]) != 0 && addr->supernet != 0 && addr->usock >= 0 ) - { - ptr->submit = (uint32_t)time(NULL); - printf("submit to (%s)\n",addr->ipaddr); - iguana_send_supernet(addr,reqstr,0); - if ( n++ > fanout ) - break; - } - } - } - } - free(reqstr); - return(n); - } - - /*cJSON *basilisk_json(struct supernet_info *myinfo,cJSON *hexjson,uint32_t basilisktag,int32_t timeout) - { - char *str,*buf; cJSON *retjson; - if ( jobj(hexjson,"basilisktag") != 0 ) - jdelete(hexjson,"basilisktag"); - jaddnum(hexjson,"basilisktag",basilisktag); - str = jprint(hexjson,0); - buf = malloc(strlen(str)*2 + 1); - init_hexbytes_noT(buf,(uint8_t *)str,(int32_t)strlen(str)); - free(str); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"hexmsg",buf); - free(buf); - jaddstr(retjson,"agent","SuperNET"); - jaddstr(retjson,"method","DHT"); - jaddnum(retjson,"request",1); - jaddnum(retjson,"plaintext",1); - jaddbits256(retjson,"categoryhash",myinfo->basilisk_category); - jaddnum(retjson,"timeout",timeout); - return(retjson); - } - if ( strcmp(type,"BID") == 0 || strcmp(type,"ASK") == 0 ) - { - instantdex_quotep2p(myinfo,0,addr,data,datalen); - } - else if ( (argjson= cJSON_Parse((char *)data)) != 0 ) - { - jaddstr(argjson,"agent","basilisk"); - jaddnum(argjson,"basilisktag",basilisktag); - if ( strcmp(type,"RET") == 0 ) - { - jaddstr(argjson,"method","return"); - } - else if ( strcmp(type,"RAW") == 0 ) - { - jaddstr(argjson,"method","rawtx"); - } - else if ( strcmp(type,"VAL") == 0 ) - { - jaddstr(argjson,"method","value"); - } - jsonstr = jprint(argjson,1); - if ( (retstr= basilisk_hexmsg(myinfo,0,(void *)jsonstr,(int32_t)strlen(jsonstr)+1,remoteaddr)) != 0 ) - free(retstr); - free(jsonstr); - char *basilisk_results(uint32_t basilisktag,cJSON *valsobj) - { - cJSON *resultobj = cJSON_CreateObject(); - jadd(resultobj,"vals",valsobj); - jaddstr(resultobj,"agent","basilisk"); - jaddstr(resultobj,"method","result"); - jaddnum(resultobj,"plaintext",1); - if ( jobj(resultobj,"basilisktag") != 0 ) - jdelete(resultobj,"basilisktag"); - jaddnum(resultobj,"basilisktag",basilisktag); - return(jprint(resultobj,1)); - } - - cJSON *basilisk_resultsjson(struct supernet_info *myinfo,char *symbol,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,char *retstr) - { - cJSON *hexjson=0,*retjson=0; - if ( retstr != 0 ) - { - if ( remoteaddr != 0 && remoteaddr[0] != 0 ) - { - hexjson = cJSON_CreateObject(); - jaddstr(hexjson,"agent","basilisk"); - jaddstr(hexjson,"method","result"); - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - jadd(hexjson,"vals",retjson); - retjson = basilisk_json(myinfo,hexjson,basilisktag,timeoutmillis); - free_json(hexjson); - printf("resultsjson.(%s)\n",jprint(retjson,0)); - } - else // local request - retjson = cJSON_Parse(retstr); - } - return(retjson); - }*/ - /* cJSON *array=0,*result,*item,*retjson,*hexjson; int32_t i,n,besti=-1; char *coinaddr,*balancestr=0,*retstr=0; int64_t total=0,amount,most=0; struct basilisk_item *ptr; - array = cJSON_CreateArray(); - if ( coin != 0 && basilisk_bitcoinavail(coin) != 0 ) - { - if ( (n= cJSON_GetArraySize(addresses)) > 0 ) - { - for (i=0; iVALIDATENODE != 0 || coin->FULLNODE != 0 ) - balancestr = iguana_balance(myinfo,coin,0,remoteaddr,coin->symbol,coinaddr,lastheight,minconf); - //else balancestr = bitcoin_balance(coin,coinaddr,lastheight,minconf); - if ( balancestr != 0 ) - { - if ( (result= cJSON_Parse(balancestr)) != 0 ) - { - if ( jobj(result,"balance") != 0 ) - { - item = cJSON_CreateObject(); - amount = SATOSHIDEN * jdouble(result,"balance"); - total += amount; - jaddnum(item,coinaddr,dstr(amount)); - jaddi(array,item); - } - free_json(result); - } - free(balancestr); - } - } - } - } - else - { - hexjson = cJSON_CreateObject(); - jaddnum(hexjson,"basilisktag",basilisktag); - jadd(hexjson,"addresses",jduplicate(addresses)); - jaddnum(hexjson,"minconf",minconf); - jaddnum(hexjson,"lastheight",lastheight); - jaddstr(hexjson,"agent","basilisk"); - jaddstr(hexjson,"method","balances"); - if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 ) - { - for (i=0; inumresults; i++) - { - if ( ptr->results[i] == 0 ) - continue; - if ( retstr != 0 && strcmp(ptr->results[i],retstr) == 0 ) - ptr->numexact++; - if ( (retjson= cJSON_Parse(ptr->results[i])) != 0 ) - { - if ( (total= j64bits(retjson,"balance")) > most ) - { - most = total; - besti = i; - } - free_json(retjson); - } - } - retstr = basilisk_finish(ptr,arrayp,besti); - } - free_json(hexjson); - } - *arrayp = array; - return(most);*/ - if ( agent != 0 && method != 0 && strcmp(agent,"SuperNET") == 0 && strcmp(method,"DHT") == 0 && (hexmsg= jstr(remotejson,"hexmsg")) != 0 ) - { - n = (int32_t)(strlen(hexmsg) >> 1); - tmpstr = calloc(1,n + 1); - decode_hex((void *)tmpstr,n,hexmsg); - free_json(remotejson); - printf("NESTED.(%s)\n",tmpstr); - if ( (remotejson= cJSON_Parse(tmpstr)) == 0 ) - { - printf("couldnt parse decoded hexmsg.(%s)\n",tmpstr); - free(tmpstr); - return(0); - } - free(tmpstr); - agent = jstr(remotejson,"agent"); - method = jstr(remotejson,"method"); - } - - char *basilisk_hexmsg(struct supernet_info *myinfo,struct category_info *dontuse,void *ptr,int32_t len,char *remoteaddr) // incoming - { - char *method,*retstr = 0; uint8_t *data=0; cJSON *array,*valsobj; struct iguana_info *coin=0; uint32_t basilisktag,datalen=0,jsonlen; - array = 0; - if ( (valsobj= cJSON_Parse((char *)ptr)) != 0 ) - { - jsonlen = (int32_t)strlen((char *)ptr) + 1; - if ( len > jsonlen ) - data = (uint8_t *)((long)ptr + jsonlen), datalen = len - jsonlen; - basilisktag = juint(valsobj,"basilisktag"); - printf("basilisk.(%s)\n",jprint(valsobj,0)); - if ( jobj(valsobj,"coin") != 0 ) - coin = iguana_coinfind(jstr(valsobj,"coin")); - if ( (method= jstr(valsobj,"method")) != 0 && coin != 0 ) - { - if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) // iguana node - { - if ( strcmp(method,"rawtx") == 0 ) - retstr = basilisk_rawtx(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); - else if ( strcmp(method,"balances") == 0 ) - retstr = basilisk_balances(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); - else if ( strcmp(method,"value") == 0 ) - retstr = basilisk_value(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); - if ( retstr != 0 ) - free(retstr); - retstr = 0; - // should automatically send to remote requester - } - else // basilisk node - { - if ( strcmp(method,"result") == 0 ) - retstr = basilisk_result(myinfo,coin,0,remoteaddr,basilisktag,valsobj); - } - } else printf("basilisk_hexmsg no coin\n"); - free_json(valsobj); - } - printf("unhandled bitcoin_hexmsg.(%d) from %s (%s)\n",len,remoteaddr,(char *)ptr); - return(retstr); - } - - int32_t basilisk_hashstamps(struct iguana_info *btcd,struct hashstamp *BTCDstamps,struct basilisk_sequence *seq,int32_t max,uint32_t reftimestamp) - { - uint32_t i,timestamp; struct iguana_block *block; - block = &btcd->blocks.hwmchain; - while ( block != 0 && (timestamp= block->RO.timestamp) > reftimestamp ) - block = iguana_blockfind("hashstamps",btcd,block->RO.prev_block); - if ( block == 0 ) - return(-1); - for (i=0; iRO.hash2; - BTCDstamps[i].timestamp = block->RO.timestamp; - BTCDstamps[i].height = block->height; - if ( (block= iguana_blockfind("hashstamps",btcd,block->RO.prev_block)) == 0 ) - return(i+1); - } - return(i); - } - //printf("mapped Soffset.%ld\n",(long)mapchain->data->Soffset); - /*iguana_ramchain_link(&R,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); - if ( 1 ) // unix issues? - { - if ( (err= iguana_ramchain_cmp(ramchain,mapchain,0)) != 0 ) - fpos = -1, printf("error.%d comparing ramchains\n",err); - else - { - ptr = mapchain->fileptr; fsize = mapchain->filesize; - mapchain->fileptr = 0, mapchain->filesize = 0; - iguana_ramchain_free(coin,mapchain,1); - memset(&R,0,sizeof(R)); - R.H.data = (void *)(long)((long)ptr + fpos), R.filesize = fsize; - iguana_ramchain_link(&R,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); - } - } - if ( (err= iguana_ramchain_cmp(ramchain,&R,0)) != 0 ) - { - fpos = -1; - block->issued = 0; - block->RO.recvlen = 0; - printf("error.%d comparing REMAP ramchains\n",err); - } - else - { - iguana_ramchain_extras(coin,&R,0,0); - if ( (err= iguana_ramchain_iterate(coin,0,&R,bp,bundlei)) != 0 ) - printf("err.%d iterate ",err); - //printf("SUCCESS REMAP\n"); - bp->numtxids += rdata->numtxids; - bp->numunspents += rdata->numunspents; - bp->numspends += rdata->numspends; - //bp->rawscriptspace += rdata->scriptspace; - } - iguana_ramchain_free(coin,&R,1); - if ( err != 0 ) - iguana_blockunmark(coin,block,bp,bundlei,1);*/ - - char *basilisk_respond_setfield(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk) - { - struct iguana_info *virt; struct iguana_block *prevblock,*prev2,*newblock,block; char chainname[BASILISK_MAXNAMELEN],str[65],*blocktx; uint32_t nBits,timestamp,nonce; cJSON *retjson; bits256 btcdhash; - if ( datalen <= 0 ) - return(clonestr("{\"error\":\"no data specified\"}")); - if ( (virt= basilisk_chain(myinfo,chainname,valsobj)) == 0 ) - return(clonestr("{\"error\":\"couldnt get basilisk_chain\"}")); - printf("from.(%s) SET.(%s) datalen.%d prev.%s\n",remoteaddr,jprint(valsobj,0),datalen,bits256_str(str,prevhash)); - if ( bits256_nonz(prevhash) == 0 ) - prevhash = virt->blocks.hwmchain.RO.hash2; - if ( (prevblock= iguana_blockfind("setfield",virt,prevhash)) == 0 ) - return(clonestr("{\"error\":\"couldnt find prevhash\"}")); - if ( (prev2= iguana_blockfind("setfield",virt,prevblock->RO.prev_block)) == 0 ) - return(clonestr("{\"error\":\"couldnt find prevhash2\"}")); - timestamp = juint(valsobj,"timestamp"); - nonce = juint(valsobj,"nonce"); - nBits = iguana_targetbits(virt,(struct iguana_block *)&virt->blocks.hwmchain,prevblock,prev2,1,virt->chain->targetspacing,virt->chain->targettimespan); - blocktx = basilisk_block(myinfo,virt,&block,1,timestamp,&nonce,prevhash,nBits,prevblock->height+1,0,0,data,datalen,btcdhash,jobj(valsobj,"coinbase")); - retjson = cJSON_CreateObject(); - jaddbits256(retjson,"hash",block.RO.hash2); - jaddstr(retjson,"data",blocktx); - if ( (newblock= _iguana_chainlink(virt,&block)) != 0 ) - { - jaddstr(retjson,"result","chain extended"); - jaddnum(retjson,"ht",block.height); - } else jaddstr(retjson,"error","couldnt extend chain"); - free(blocktx); - return(jprint(retjson,1)); - } - - char *basilisk_respond_getfield(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk) - { - struct iguana_info *coin; cJSON *retjson; char chainname[BASILISK_MAXNAMELEN]; - if ( (coin= basilisk_chain(myinfo,chainname,valsobj)) == 0 ) - return(clonestr("{\"error\":\"couldnt get basilisk_chain\"}")); - printf("getfield\n"); - retjson = cJSON_CreateObject(); - return(jprint(retjson,1)); - } - /*int32_t basilisk_sendPUB(struct supernet_info *myinfo,uint32_t basilisktag,uint8_t *data,int32_t datalen) // data must be offset by sizeof(iguana_msghdr)+sizeof(basilisktag) - { - int32_t i,j,r,r2,s,k,val,l,n=0; uint32_t *alreadysent; struct iguana_info *coin; struct iguana_peer *addr; - alreadysent = calloc(IGUANA_MAXPEERS * IGUANA_MAXCOINS,sizeof(*alreadysent)); - r = rand(), r2 = rand(); - for (k=0; kpeers.active[i]) != 0 && addr->ipbits != 0 && addr->usock >= 0 && addr->basilisk != 0 ) - { - for (s=0; sipbits ) - break; - if ( s == n ) - { - printf("pub (%s) addr->supernet.%u to (%s).%d\n",(char *)&data[4],addr->supernet,addr->ipaddr,addr->A.port); - if ( (val= iguana_queue_send(addr,0,&data[-sizeof(struct iguana_msghdr)],"SuperNETpub",datalen)) >= datalen ) - { - alreadysent[n++] = (uint32_t)addr->ipbits; - if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) - break; - } - } - } - } - if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) - break; - } - free(alreadysent); - return(n); - }*/ - - struct iguana_info *_iguana_coinadd(char *symbol,cJSON *argjson) - { - struct iguana_info *coin; char *privatechain; int32_t pval,i = 0; - if ( symbol == 0 ) - { - printf("_iguana_coinadd deprecated null symbol\n"); - exit(-1); - } - else - { - for (i=0; i= sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) ) - break; - //printf("Hardcoded_coins[i][0] %s vs.(%s)\n",Hardcoded_coins[i][0],symbol); - //if ( symbol[0] == 0 ) - // getchar(); - if ( strcmp("endmarker",Hardcoded_coins[i][0]) == 0 || strcmp(symbol,Hardcoded_coins[i][0]) == 0 ) - { - if ( coin->chain == 0 ) - { - if ( i < sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) ) - strcpy(coin->name,Hardcoded_coins[i][1]); - else if (argjson != 0 ) - { - if ( jstr(argjson,"name") != 0 ) - safecopy(coin->name,jstr(argjson,"name"),sizeof(coin->name)); - else strcpy(coin->name,symbol); - } - } - return(coin); - } - } - } - return(0); - } - - void basilisk_pending_result(struct supernet_info *myinfo,struct basilisk_item *ptr,struct basilisk_item *pending) - { - int32_t n; basilisk_metricfunc metricfunc; - if ( (n= pending->numresults) < sizeof(pending->results)/sizeof(*pending->results) ) - { - pending->numresults++; - if ( (metricfunc= pending->metricfunc) == 0 ) - pending->metrics[n] = n + 1; - else if ( (pending->metrics[n]= (*metricfunc)(myinfo,pending,ptr->retstr)) != 0. ) - pending->childrendone++; - printf("%s.%u Add results[%d] <- metric %f\n",pending->CMD,pending->basilisktag,n,pending->metrics[n]); - pending->results[n] = ptr->retstr, ptr->retstr = 0; - /*if ( strcmp(ptr->CMD,"SEQ") == 0 ) - { - if ( (retjson= cJSON_Parse(ptr->retstr)) != 0 ) - { - gecko_seqresult(myinfo,ptr->retstr); - free_json(retjson); - } - } - else*/ - if ( strcmp(ptr->CMD,"RET") == 0 || strcmp(ptr->CMD,"GET") == 0 ) - { - printf("got return for tag.%d parent.%p\n",pending->basilisktag,pending->parent); - /*if ( (parent= pending->parent) != 0 ) - { - pending->parent = 0; - parent->childrendone++; - }*/ - if ( strcmp(ptr->CMD,"GET") == 0 ) - basilisk_geckoresult(myinfo,ptr->retstr); - } - } - } - - int32_t basilisk_issued_iteration(struct supernet_info *myinfo,struct basilisk_item *pending) - { - basilisk_metricfunc metricfunc; int32_t i,flag = 0; - //printf("pending.%u numresults.%d m %f func.%p\n",pending->basilisktag,pending->numresults,pending->metrics[0],pending->metricfunc); - if ( (metricfunc= pending->metricfunc) != 0 ) - { - for (i=0; inumresults; i++) - if ( pending->metrics[i] == 0. && pending->results[i] != 0 ) - { - if ( (pending->metrics[i]= (*metricfunc)(myinfo,pending,pending->results[i])) != 0 ) - pending->childrendone++; - // printf("iter.%d %p.[%d] poll metrics.%u metric %f\n",iter,pending,i,pending->basilisktag,pending->metrics[i]); - flag++; - } - } - /*basilisk_iscomplete(myinfo,pending); - if ( OS_milliseconds() > pending->expiration ) - { - if ( pending->finished == 0 ) - { - if ( (parent= pending->parent) != 0 ) - { - pending->parent = 0; - parent->childrendone++; - } - pending->finished = (uint32_t)time(NULL); - if ( pending->retstr == 0 ) - pending->retstr = clonestr("{\"error\":\"basilisk timeout\"}"); - fprintf(stderr,"timeout.%s call metrics.%u lag %f - %f\n",pending->CMD,pending->basilisktag,OS_milliseconds(),pending->expiration); - for (i=0; inumresults; i++) - if ( (metricfunc= pending->metricfunc) != 0 && pending->metrics[i] == 0. ) - pending->metrics[i] = (*metricfunc)(myinfo,pending,pending->results[i]); - flag++; - } - }*/ - //fprintf(stderr,"c"); - if ( pending->finished != 0 && time(NULL) > pending->finished+60 ) - { - if ( pending->dependents == 0 || pending->childrendone >= pending->numchildren ) - { - HASH_DELETE(hh,myinfo->basilisks.issued,pending); - if ( pending->dependents != 0 ) - free(pending->dependents); - //fprintf(stderr,"HASH_DELETE free ptr.%u refcount.%d\n",pending->basilisktag,pending->refcount); - for (i=0; inumresults; i++) - if ( pending->results[i] != 0 ) - free(pending->results[i]), pending->results[i] = 0; - //if ( pending->vals != 0 ) - // free_json(pending->vals), pending->vals = 0; - free(pending); - flag++; - } - } - return(flag); - } - - - int32_t basilisk_besti(struct basilisk_item *ptr) - { - int32_t i,besti = -1; double metric,bestmetric=-1.; - for (i=0; inumresults; i++) - { - if ( (metric= ptr->metrics[i]) > 0. ) - { - if ( (ptr->metricdir < 0 && (bestmetric < 0. || metric < bestmetric)) || (ptr->metricdir > 0 && (bestmetric < 0. || metric > bestmetric)) || (ptr->metricdir == 0 && bestmetric < 0.) ) - { - bestmetric = metric; - besti = i; - } - } - } - if ( besti >= 0 ) - { - for (ptr->numexact=i=0; inumresults; i++) - if ( fabs(ptr->metrics[i] - bestmetric) < SMALLVAL ) - ptr->numexact++; - } - return(besti); - } - - char *basilisk_iscomplete(struct supernet_info *myinfo,struct basilisk_item *ptr) - { - int32_t i,numvalid,besti=-1; char *errstr = 0,*retstr = 0; - if ( ptr->childrendone < ptr->numchildren ) - return(0); - if ( ptr->retstr != 0 || ptr->finished != 0 ) - return(ptr->retstr); - if ( (numvalid= ptr->numresults) >= ptr->numrequired ) - { - for (i=numvalid=0; inumresults; i++) - { - if ( ptr->metrics[i] != 0. ) - numvalid++; - } - } - if ( numvalid < ptr->numrequired ) - { - //printf("%u: numvalid.%d < required.%d m %f\n",ptr->basilisktag,numvalid,ptr->numrequired,ptr->metrics[0]); - return(0); - } - if ( ptr->uniqueflag == 0 && ptr->numexact != ptr->numresults && ptr->numexact < (ptr->numresults >> 1) ) - besti = -1, errstr = "[{\"error\":\"basilisk non-consensus results\"}]"; - else besti = basilisk_besti(ptr), errstr = "[{\"error\":\"basilisk no valid results\"}]"; - //printf("%u complete besti.%d\n",ptr->basilisktag,besti); - retstr = basilisk_finish(myinfo,ptr,besti,errstr); - //printf("%u besti.%d numexact.%d numresults.%d -> (%s)\n",ptr->basilisktag,besti,ptr->numexact,ptr->numresults,retstr); - return(retstr); - } - - char *basilisk_finish(struct supernet_info *myinfo,struct basilisk_item *ptr,int32_t besti,char *errstr) - { - char *str,*retstr = 0; int32_t i; struct basilisk_item *parent; cJSON *retarray,*item; - if ( ptr->retstr != 0 ) - return(ptr->retstr); - /*if ( besti >= 0 && besti < ptr->numresults ) - { - retstr = ptr->results[besti]; - ptr->results[besti] = 0; - } else printf("besti.%d vs numresults.%d retstr.%p\n",besti,ptr->numresults,retstr); - */ - if ( ptr->numresults > 0 ) - { - retarray = cJSON_CreateArray(); - for (i=0; inumresults; i++) - if ( (str= ptr->results[i]) != 0 ) - { - ptr->results[i] = 0; - if ( (item= cJSON_Parse(str)) != 0 ) - { - if ( jobj(item,"myip") == 0 ) - jaddstr(item,"myip",myinfo->ipaddr); - jaddi(retarray,item); - } else printf("couldnt parse.(%s)\n",str); - free(str); - } - retstr = jprint(retarray,1); - } - if ( retstr == 0 ) - retstr = clonestr(errstr); - ptr->retstr = retstr; - ptr->finished = (uint32_t)time(NULL); - if ( (parent= ptr->parent) != 0 ) - { - ptr->parent = 0; - parent->childrendone++; - } - return(retstr); - } - - char *basilisk_check(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) - { - if ( symbol != 0 && symbol[0] != 0 && vals != 0 ) - { - if ( *basilisktagp == 0 ) - *basilisktagp = rand(); - if ( (*timeoutmillisp= jint(vals,"timeout")) < 0 ) - *timeoutmillisp = BASILISK_TIMEOUT; - return(0); - } else return(clonestr("{\"error\":\"missing activecoin or vals\"}")); - } - - char *basilisk_standardcmd(struct supernet_info *myinfo,char *CMD,char *activecoin,char *remoteaddr,uint32_t basilisktag,cJSON *vals,basilisk_func func,basilisk_metricfunc metric) - { - char *retstr; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; struct iguana_info *coin; - if ( (retstr= basilisk_check(&timeoutmillis,&basilisktag,activecoin,vals)) == 0 ) - { - if ( (coin= iguana_coinfind(activecoin)) != 0 ) - { - if ( (ptr= basilisk_issuecmd(&Lptr,func,metric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) - { - return(basilisk_waitresponse(myinfo,CMD,coin->symbol,remoteaddr,&Lptr,vals,ptr)); - } - else return(clonestr("{\"error\":\"null return from basilisk_issuecmd\"}")); - } else return(clonestr("{\"error\":\"couldnt get coin\"}")); - } else return(retstr); - } - - char *_basilisk_value(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) - { - struct iguana_info *coin; char *symbol; - if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) - { - if ( (coin= iguana_coinfind(symbol)) != 0 ) - return(basilisk_standardcmd(myinfo,"VAL",symbol,remoteaddr,basilisktag,valsobj,coin->basilisk_value,coin->basilisk_valuemetric)); - } - return(clonestr("{\"error\":\"couldnt get coin\"}")); - } - - char *_basilisk_balances(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) - { - struct iguana_info *coin; char *symbol; - if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) - { - if ( (coin= iguana_coinfind(symbol)) != 0 ) - return(basilisk_standardcmd(myinfo,"BAL",symbol,remoteaddr,basilisktag,valsobj,coin->basilisk_balances,coin->basilisk_balancesmetric)); - } - return(clonestr("{\"error\":\"couldnt get coin\"}")); - } - - char *_basilisk_rawtx(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) - { - char *retstr,strbuf[4096],*symbol,*str = 0; struct iguana_info *coin; - if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) - { - if ( (coin= iguana_coinfind(symbol)) != 0 ) - { - printf("remote rawtx.(%s)\n",jprint(valsobj,0)); - basilisk_addhexstr(&str,valsobj,strbuf,sizeof(strbuf),data,datalen); - retstr = basilisk_rawtx(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); - if ( str != 0 ) - free(str); - return(retstr); - } - } - return(clonestr("{\"error\":\"couldnt get coin\"}")); - } - - char *basilisk_waitresponse(struct supernet_info *myinfo,char *CMD,char *symbol,char *remoteaddr,struct basilisk_item *Lptr,cJSON *vals,struct basilisk_item *ptr) - { - char *retstr = 0; - if ( ptr == Lptr ) - { - //if ( (retstr= Lptr->retstr) == 0 ) - // retstr = clonestr("{\"result\":\"null return from local basilisk_issuecmd\"}"); - //ptr = basilisk_itemcreate(myinfo,CMD,symbol,Lptr->basilisktag,Lptr->numrequired,vals,OS_milliseconds() - Lptr->expiration,0);//Lptr->metricfunc); - //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - retstr = Lptr->retstr; - } - else - { - //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - while ( OS_milliseconds() < ptr->expiration ) - { - //if ( (retstr= basilisk_iscomplete(ptr)) != 0 ) - if ( ptr->numresults >= ptr->numrequired || (retstr= ptr->retstr) != 0 ) - break; - usleep(50000); - } - if ( retstr == 0 ) - { - //ptr->finished = (uint32_t)time(NULL); - //retstr = clonestr("[{\"error\":\"basilisk wait timeout\"}]"); - free(ptr); - return(0); - } - } - basilisk_sendback(myinfo,CMD,symbol,remoteaddr,ptr->basilisktag,retstr); - return(retstr); - } - struct basilisk_item *basilisk_issuecmd(struct basilisk_item *Lptr,basilisk_func func,basilisk_metricfunc metricfunc,struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,int32_t timeoutmillis,cJSON *vals) - { - struct iguana_info *coin; struct basilisk_item *ptr; - memset(Lptr,0,sizeof(*Lptr)); - if ( (coin= iguana_coinfind(symbol)) != 0 ) - { - if ( func != 0 ) - { - if ( (ptr= (*func)(Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) - { - strcpy(ptr->symbol,symbol); - ptr->basilisktag = basilisktag; - ptr->expiration = OS_milliseconds() + timeoutmillis; - return(ptr); - } else Lptr->retstr = clonestr("{\"error\":\"error issuing basilisk command\"}"); - } else Lptr->retstr = clonestr("{\"error\":\"null basilisk function\"}"); - } else Lptr->retstr = clonestr("{\"error\":\"error missing coin\"}"); - return(Lptr); - } - /*int32_t gecko_chainvals(struct supernet_info *myinfo,char *CMD,cJSON *valsobj) - { - struct iguana_info *virt; struct gecko_chain *chain; bits256 hash,prevhash; struct iguana_block *block; char chainname[GECKO_MAXNAMELEN]; - if ( strcmp(CMD,"SET") == 0 || strcmp(CMD,"GET") == 0 ) - { - if ( (chain= gecko_chain(myinfo,chainname,valsobj)) == 0 || (virt= chain->info) == 0 ) - clonestr("{\"error\":\"cant find gecko chain\"}"); - if ( strcmp(CMD,"SET") == 0 ) - { - hash = GENESIS_PUBKEY; - if ( jobj(valsobj,"prev") != 0 ) - { - prevhash = jbits256(valsobj,"prev"); - if ( (block= iguana_blockfind("basilisk",virt,prevhash)) == 0 ) - { - char str[65]; printf("warning couldnt find %s in %s\n",bits256_str(str,prevhash),chainname); - prevhash = virt->blocks.hwmchain.RO.hash2; - } - } else prevhash = virt->blocks.hwmchain.RO.hash2; - hash = prevhash; - if ( jobj(valsobj,"prev") != 0 ) - jdelete(valsobj,"prev"); - } - return(0); - } - return(-1); - } - - cJSON *gecko_genesisargs(char *symbol,char *chainname,char *chain,char *keystr,char *genesishash,char *genesisblock,char *magicstr,uint16_t port,uint16_t blocktime,char *nbitstr,char *pubval,char *p2shval,char *wifval,uint32_t isPoS) - { - int32_t timespan,targetspacing; cJSON *argvals = cJSON_CreateObject(); - if ( genesishash != 0 && genesishash[0] != 0 ) - jaddstr(argvals,"genesishash",genesishash); - if ( genesisblock != 0 && genesisblock[0] != 0 ) - jaddstr(argvals,"genesisblock",genesisblock); - jaddstr(argvals,"netmagic",magicstr); - jaddstr(argvals,"symbol",symbol); - jaddstr(argvals,"name",chainname); - if ( pubval == 0 || is_hexstr(pubval,0) != 2 ) - pubval = "00"; - jaddstr(argvals,"pubval",pubval); - if ( p2shval == 0 || is_hexstr(p2shval,0) != 2 ) - p2shval = "05"; - jaddstr(argvals,"p2shval",p2shval); - if ( wifval == 0 || is_hexstr(wifval,0) != 2 ) - wifval = "80"; - jaddstr(argvals,"wifval",wifval); - if ( nbitstr == 0 || nbitstr[0] == 0 ) - nbitstr = GECKO_DEFAULTDIFFSTR; - jaddstr(argvals,"nBits",nbitstr); - jaddstr(argvals,"chain",chain); - if ( keystr != 0 ) - jaddstr(argvals,"key",keystr); - jaddnum(argvals,"isPoS",isPoS); - //printf("argvals isPoS.%d\n",isPoS); - if ( port == 0 ) - { - jaddstr(argvals,"geckochain",chainname); - jaddnum(argvals,"services",128); - } - else - { - jaddnum(argvals,"services",129); - jaddnum(argvals,"portp2p",port); - } - if ( blocktime == 0 ) - blocktime = 1; - jaddnum(argvals,"blocktime",blocktime); - if ( blocktime != 0 && 0 ) - { - if ( blocktime == 0xffff ) - targetspacing = 24 * 60 * 60; // one day - else targetspacing = blocktime; // one minute - jaddnum(argvals,"targetspacing",targetspacing); - if ( (timespan= sqrt(604800 / targetspacing)) < 7 ) - timespan = 7; - jaddnum(argvals,"targettimespan",targetspacing * timespan); - } - return(argvals); - } - - cJSON *gecko_genesisjson(struct supernet_info *myinfo,struct iguana_info *btcd,int32_t isPoS,char *symbol,char *chainname,cJSON *valsobj,char *magicstr,uint16_t blocktime) - { - char str2[64],hashstr[65],argbuf[1024],*pubstr,*p2shstr,*wifvalstr,*nbitstr,*blockstr; uint8_t buf[4]; int32_t i; uint32_t nBits; struct iguana_block genesis; - if ( (nbitstr= jstr(valsobj,"nBits")) == 0 ) - { - nBits = GECKO_DEFAULTDIFF; - nbitstr = GECKO_DEFAULTDIFFSTR; - } - else - { - for (i=0; i<4; i++) - decode_hex(&buf[3-i],1,&nbitstr[i*2]); - memcpy(&nBits,buf,sizeof(nBits)); - } - if ( (blocktime= juint(valsobj,"blocktime")) == 0 ) - blocktime = 1; - if ( (pubstr= jstr(valsobj,"pubval")) == 0 ) - pubstr = "00"; - if ( (p2shstr= jstr(valsobj,"p2shval")) == 0 ) - p2shstr = "05"; - if ( (wifvalstr= jstr(valsobj,"wifval")) == 0 ) - wifvalstr = "80"; - printf("json netmagic.%s\n",magicstr); - memset(&genesis,0,sizeof(genesis)); - genesis.RO.version = GECKO_DEFAULTVERSION; - genesis.RO.bits = nBits; - if ( (blockstr= gecko_createblock(myinfo,blocktime,0,btcd,isPoS,&genesis,symbol,0,0,10000,0,0)) != 0 ) - { - bits256_str(hashstr,genesis.RO.hash2); - sprintf(argbuf,"{\"isPoS\":%d,\"name\":\"%s\",\"symbol\":\"%s\",\"netmagic\":\"%s\",\"port\":%u,\"blocktime\":%u,\"pubval\":\"%s\",\"p2shval\":\"%s\",\"wifval\":\"%s\",\"isPoS\":%u,\"unitval\":\"%02x\",\"genesishash\":\"%s\",\"genesis\":{\"version\":1,\"timestamp\":%u,\"nBits\":\"%s\",\"nonce\":%d,\"merkle_root\":\"%s\"},\"genesisblock\":\"%s\"}",isPoS,chainname,symbol,magicstr,juint(valsobj,"port"),blocktime,pubstr,p2shstr,wifvalstr,juint(valsobj,"isPoS"),(nBits >> 24) & 0xff,hashstr,genesis.RO.timestamp,nbitstr,genesis.RO.nonce,bits256_str(str2,genesis.RO.merkle_root),blockstr); - free(blockstr); - printf("argbuf.(%s) hash.%s\n",argbuf,hashstr); - return(cJSON_Parse(argbuf)); - } else return(cJSON_Parse("{\"error\":\"couldnt create block\"}")); - } - - cJSON *gecko_genesisissue(char *symbol,char *chainname,char *chainstr,cJSON *valsobj) - { - printf("issue blocktime.%d\n",juint(valsobj,"blocktime")); - return(gecko_genesisargs(symbol,chainname,chainstr,jstr(valsobj,"key"),jstr(valsobj,"genesishash"),jstr(valsobj,"genesisblock"),jstr(valsobj,"netmagic"),juint(valsobj,"port"),juint(valsobj,"blocktime"),jstr(valsobj,"nBits"),jstr(valsobj,"pubval"),jstr(valsobj,"p2shval"),jstr(valsobj,"wifval"),juint(valsobj,"isPoS"))); - }*/ - /*char *basilisk_respond_newgeckochain(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk) - { - struct iguana_info *virt,*btcd; struct gecko_chain *chain; char fname[512],*symbol,*retstr,*chainstr,chainname[GECKO_MAXNAMELEN],*genesises; cJSON *chainjson,*retjson,*genesisjson; long filesize; FILE *fp; - if ( (chain= gecko_chain(myinfo,chainname,valsobj)) != 0 && (virt= chain->info) != 0 ) - { - //printf("%s already exists\n",chainname); - return(clonestr("{\"error\":\"cant create duplicate geckochain\"}")); - } - if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(valsobj,"symbol")) != 0 && (chainstr= jstr(valsobj,"chain")) != 0 ) - { - if ( (virt= basilisk_geckochain(myinfo,symbol,chainname,valsobj)) != 0 ) - { - chain->info = virt; - if ( (retjson= gecko_genesisissue(symbol,chainname,chainstr,valsobj)) != 0 ) - { - jaddstr(retjson,"result","success"); - retstr = jprint(retjson,0); - sprintf(fname,"genesis/%s",symbol); - genesisjson = 0; - filesize = 0; - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( fwrite(retstr,1,strlen(retstr),fp) == strlen(retstr) ) - { - if ( (genesises= OS_filestr(&filesize,"genesis/list")) != 0 ) - { - genesisjson = cJSON_Parse(genesises); - free(genesises); - } else genesisjson = cJSON_CreateArray(); - chainjson = cJSON_CreateObject(); - jaddstr(chainjson,"chain",chainname); - jaddstr(chainjson,"symbol",symbol); - jaddstr(chainjson,"agent","basilisk"); - jaddstr(chainjson,"method","newgeckochain"); - jadd(chainjson,"vals",retjson); - jaddi(genesisjson,chainjson); - } - fclose(fp); - } - if ( genesisjson != 0 ) - { - genesises = jprint(genesisjson,1); - if ( strlen(genesises) > filesize ) - { - if ( (fp= fopen("genesis/list","wb")) != 0 ) - { - fwrite(genesises,1,strlen(genesises),fp); - fclose(fp); - } - } - } else free_json(retjson); - return(retstr); - } else return(clonestr("{\"error\":\"couldnt create gecko genesis\"}")); - } - } - return(clonestr("{\"error\":-22}")); - } - - int32_t gecko_genesises(struct supernet_info *myinfo,cJSON *array) - { - char *chainstr,chainname[GECKO_MAXNAMELEN],*symbol; int32_t i,n,num=0; cJSON *item,*valsobj; struct iguana_info *btcd,*virt; struct gecko_chain *chain; - if ( (btcd= iguana_coinfind("BTCD")) == 0 ) - return(0); - if ( array != 0 && (n= cJSON_GetArraySize(array)) != 0 ) - { - for (i=0; iinfo) != 0 ) - { - //printf("%s %s already exists\n",chainname,symbol); - continue; - } - if ( (virt= basilisk_geckochain(myinfo,symbol,chainname,valsobj)) != 0 ) - { - myinfo->genesisresults++; - chain->info = virt; - num++; - } - } - } - } - return(num); - } - - char *basilisk_respond_geckogenesis(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 txid,int32_t from_basilisk) - { - long filesize; - return(OS_filestr(&filesize,"genesis/list")); - }*/ - /*HASH_ARRAY_STRING(basilisk,sequence,hash,vals,hexstr) - { - return(basilisk_standardservice("SEQ",myinfo,hash,vals,hexstr,1)); - } - - HASH_ARRAY_STRING(basilisk,newgeckochain,hash,vals,hexstr) - { - char chainname[GECKO_MAXNAMELEN],magicstr[9],*retstr=0,*symbol,*chainstr; struct iguana_info *btcd; cJSON *argjson,*argvals,*retjson=0; int32_t i,isPoS; uint32_t magic; struct gecko_chain *chain; - if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 && (chainstr= jstr(vals,"chain")) != 0 ) - { - if ( iguana_coinfind(symbol) == 0 && (chain= gecko_chain(myinfo,chainname,vals)) != 0 && chain->info != 0 ) - { - printf("%s already exists\n",chainname); - return(clonestr("{\"error\":\"cant create duplicate geckochain\"}")); - } - if ( jobj(vals,"netmagic") == 0 ) - { - OS_randombytes((void *)&magic,sizeof(magic)); - for (i=0; iFULLNODE != 0 || btcd->VALIDATENODE != 0 ) - { - basilisk_wait(myinfo,0); - retstr = basilisk_respond_newgeckochain(myinfo,"NEW",0,0,0,argvals,0,0,GENESIS_PUBKEY,0); - } - if ( retstr == 0 ) - retstr = basilisk_standardservice("NEW",myinfo,GENESIS_PUBKEY,argvals,0,1); - free_json(argvals); - if ( (argvals= cJSON_Parse(retstr)) != 0 ) - { - if ( jobj(argvals,"result") != 0 && strcmp(jstr(argvals,"result"),"success") == 0 ) - { - if ( basilisk_geckochain(myinfo,symbol,chainname,argvals) != 0 ) - jaddstr(argvals,"status","active"); - } else jaddstr(argvals,"error","couldnt initialize geckochain"); - free(retstr); - return(jprint(argvals,1)); - } - if ( retjson != 0 ) - free_json(retjson); - free_json(argvals); - return(retstr); - } else return(clonestr("{\"error\":\"couldnt create genesis_block\"}")); - } - return(clonestr("{\"error\":\"need symbol and chain and BTCD to create new gecko chain\"}")); - }*/ - - /*HASH_ARRAY_STRING(basilisk,geckogenesis,hash,vals,hexstr) - { - long filesize; int32_t i,j,n,m; struct iguana_info *btcd; char *ref,*symbol,*retstr=0; cJSON *item,*array = 0,*arrayB = 0; FILE *fp; - if ( (btcd= iguana_coinfind("BTCD")) != 0 ) - { - if ( (retstr= basilisk_standardservice("GEN",myinfo,hash,vals,hexstr,1)) != 0 ) - { - arrayB = cJSON_Parse(retstr); - free(retstr); - } - if ( btcd->FULLNODE != 0 || btcd->VALIDATENODE != 0 ) - { - if ( (retstr= OS_filestr(&filesize,"genesis/list")) != 0 ) - { - array = cJSON_Parse(retstr); - free(retstr); - } - if ( array == 0 ) - array = arrayB; - else if ( arrayB != 0 ) - { - if ( (n= cJSON_GetArraySize(array)) > 0 ) - { - if ( (m= cJSON_GetArraySize(arrayB)) > 0 ) - { - for (j=0; j> 1; - if ( siglen < sizeof(sig) ) - { - decode_hex(sig,siglen,sigstr); - vcalc_sha256(0,txhash2.bytes,data,datalen); - memset(pubkey33,0,33); - if ( bitcoin_recoververify(myinfo->ctx,"BTCD",sig,txhash2,pubkey33) == 0 ) - { - // compare with existing - init_hexbytes_noT(pubstr,pubkey33,33); - printf(" verified relay data siglen.%d pub33.%s\n",siglen,pubstr); - if ( (retstr= basilisk_addrelay_info(myinfo,pubkey33,(uint32_t)calc_ipbits(remoteaddr),hash)) != 0 ) - free(retstr); - n = (int32_t)(datalen / sizeof(uint32_t)); - for (i=len=0; irelaybits)]; cJSON *vals; bits256 hash; char *retstr,hexstr[sizeof(myinfo->relaybits)*2 + 1]; - //printf("skip sending relays\n"); - if ( 0 && myinfo != 0 ) - { - vals = cJSON_CreateObject(); - hash = myinfo->myaddr.persistent; - for (i=0; inumrelays; i++) - len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&myinfo->relaybits[i]); - init_hexbytes_noT(hexstr,serialized,len); - //printf("send relays.(%s)\n",hexstr); - vcalc_sha256(0,txhash2.bytes,serialized,len); - if ( 0 && bits256_nonz(myinfo->persistent_priv) != 0 && (siglen= bitcoin_sign(myinfo->ctx,"BTCD",sig,txhash2,myinfo->persistent_priv,1)) > 0 ) - { - init_hexbytes_noT(strbuf,sig,siglen); - jaddstr(vals,"sig",strbuf); - } - if ( (retstr= basilisk_standardservice("RLY",myinfo,hash,vals,hexstr,0)) != 0 ) - free(retstr); - free_json(vals); - return(0); - } else return(-1); - } - - char *basilisk_respond_relays(struct supernet_info *myinfo,char *CMD,void *_addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) - { - uint32_t *ipbits = (uint32_t *)data; int32_t num,i,j,n = datalen >> 2; - for (i=num=0; inumrelays; j++) - if ( ipbits[i] == myinfo->relays[j].ipbits ) - break; - if ( j == myinfo->numrelays ) - { - num++; - printf("i.%d j.%d ensure new relay.(%s)\n",i,j,remoteaddr); - basilisk_ensurerelay(iguana_coinfind("BTCD"),ipbits[i]); - } - } - if ( num == 0 ) - return(clonestr("{\"result\":\"no new relays found\"}")); - else return(clonestr("{\"result\":\"relay added\"}")); - }*/ - - /*char *basilisk_checkrawtx(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) - { - cJSON *addresses=0; char *changeaddr,*spendscriptstr; int32_t i,n; - *timeoutmillisp = -1; - changeaddr = jstr(vals,"changeaddr"); - spendscriptstr = jstr(vals,"spendscript"); - addresses = jarray(&n,vals,"addresses"); - if ( addresses == 0 || changeaddr == 0 || changeaddr[0] == 0 ) - return(clonestr("{\"error\":\"invalid addresses[] or changeaddr\"}")); - else - { - for (i=0; ibasilisk_rawtx,coin->basilisk_rawtxmetric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) - { - if ( (ptr->numrequired= juint(vals,"numrequired")) == 0 ) - ptr->numrequired = 1; - //ptr->uniqueflag = 1; - //ptr->metricdir = -1; - return(basilisk_waitresponse(myinfo,"RAW",coin->symbol,remoteaddr,&Lptr,vals,ptr)); - } else return(clonestr("{\"error\":\"error issuing basilisk rawtx\"}")); - } //else return(retstr);*/ - /*int32_t basilisk_request_pending(struct supernet_info *myinfo,struct basilisk_request *rp,uint32_t requestid) - { - int32_t i,j,n,alreadystarted = 0; struct basilisk_relay *relay; uint32_t quoteid; - portable_mutex_lock(&myinfo->DEX_reqmutex); - for (j=0; jnumrelays; j++) - { - relay = &myinfo->relays[j]; - if ( (n= relay->numrequests) > 0 ) - { - for (i=0; irequests[i].requestid == requestid && relay->requests[i].quoteid == quoteid ) - { - alreadystarted = 1; - break; - } - } - } - } - portable_mutex_unlock(&myinfo->DEX_reqmutex); - return(alreadystarted); - } - - void basilisk_request_check(struct supernet_info *myinfo,struct basilisk_request *rp) - { - double retvals[4],aveprice; struct basilisk_request R; struct iguana_info *src,*dest; char message[128]; uint32_t quoteid; - if ( (src= iguana_coinfind(rp->src)) != 0 && (dest= iguana_coinfind(rp->dest)) != 0 ) - { - if ( basilisk_request_pending(myinfo,&R,rp->requestid) == 0 ) - { - aveprice = instantdex_avehbla(myinfo,retvals,rp->src,rp->dest,dstr(rp->srcamount)); - quoteid = rp->requestid ^ myinfo->myaddr.persistent.uints[0]; - sprintf(message,"{\"price\":%.8f,\"requestid\":%u,\"quoteid\":%u}",aveprice,rp->requestid,quoteid); - if ( basilisk_request_enqueue(myinfo,rp->hash,rp->src,rp->srcamount*aveprice,myinfo->myaddr.persistent,rp->dest,rp->srcamount*aveprice,message,quoteid) != rp->requestid ) - printf("error creating quoteid\n"); - } - } - }*/ - - /*double basilisk_bitcoin_rawtxmetric_dependents(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_item *ptr,struct bitcoin_rawtxdependents *dependents) - { - int32_t i,j,numaddrs,notfinished = 0; cJSON *childjson,*addresses; struct basilisk_item *child; double metric = 0.; char *childstr,*coinaddr; int64_t inputsum,value,txfee; - for (i=0; inumptrs; i++) - { - if ( (child= dependents->ptrs[i]) != 0 ) - { - if ( ptr->finished != 0 ) - { - //printf("parent finished\n"); - if ( child->finished == 0 ) - { - ptr->childrendone++; - child->finished = (uint32_t)time(NULL); - } - } - else if ( child->finished == 0 ) - notfinished++; - } - } - if ( notfinished != 0 ) - { - if ( ptr->finished != 0 ) - return(-13.); - else return(0.); - } - else if ( ptr->vals != 0 ) - { - if ( (txfee= j64bits(ptr->vals,"txfee")) == 0 ) - txfee = coin->chain->txfee; - if ( txfee == 0 ) - txfee = 10000; - addresses = jarray(&numaddrs,ptr->vals,"addresses"); - printf("got all inputs:\n"); - for (inputsum=i=0; inumptrs; i++) - { - if ( (child= dependents->ptrs[i]) != 0 && (childstr= child->retstr) != 0 ) - { - printf("childi.%d (%s)\n",i,childstr); - coinaddr = &dependents->coinaddrs[64*i]; - if ( (childjson= cJSON_Parse(childstr)) != 0 ) - { - if ( (value= j64bits(childjson,"satoshis")) != 0 ) - { - inputsum += value; - for (j=0; jretstr = 0; - } - } - if ( (inputsum - dependents->outputsum) != txfee ) - { - printf("inputsum %.8f - outputsum %.8f = %.8f != txfee %.8f\n",dstr(inputsum),dstr(dependents->outputsum),dstr(inputsum)-dstr(dependents->outputsum),dstr(txfee)); - return(-1001.); // error - } - //printf("dependents cost %lld\n",(long long)dependents->cost); - return(dstr(dependents->cost)); - } else return(-666.); // no vals?? - } - - double basilisk_bitcoin_rawtxmetric(struct supernet_info *myinfo,struct basilisk_item *ptr,char *resultstr) - { - cJSON *txobj,*vouts,*vin,*sobj,*addrs,*vins,*argvals,*resultsobj,*addresses; int64_t outputsum=0,amount=0,cost = 0; int32_t i,m,numaddrs,spendlen,n; struct iguana_msgtx msgtx; uint8_t extraspace[8192],script[IGUANA_MAXSCRIPTSIZE],serialized[16384],asmtype; struct vin_info V; char *scriptstr,*changeaddr,*coinaddr,*rawtx,*spendscriptstr; bits256 txid; struct iguana_info *coin; struct basilisk_item Lsubptr,*child; struct bitcoin_rawtxdependents *dependents=0; double metric; uint32_t locktime; - if ( (coin= iguana_coinfind(ptr->symbol)) != 0 ) - { - if ( (dependents= ptr->dependents) != 0 ) - { - if ( (metric= basilisk_bitcoin_rawtxmetric_dependents(myinfo,coin,ptr,dependents)) != 0. ) - { - for (i=0; inumptrs; i++) - if ( (child= dependents->ptrs[i]) != 0 ) - child->parent = 0; - } - return(metric); - } - if ( (resultsobj= cJSON_Parse(resultstr)) == 0 || (vins= jobj(resultsobj,"vins")) == 0 || (rawtx= jstr(resultsobj,"rawtx")) == 0 ) - { - if ( resultsobj != 0 ) - free_json(resultsobj); - printf("resultstr error.(%s)\n",resultstr); - return(-1.); // error - } - if ( (spendscriptstr= jstr(ptr->vals,"spendscript")) != 0 ) - { - spendlen = (int32_t)strlen(spendscriptstr) >> 1; - decode_hex(script,spendlen,spendscriptstr); - } - changeaddr = jstr(ptr->vals,"changeaddr"); - locktime = juint(ptr->vals,"locktime"); - amount = j64bits(ptr->vals,"satoshis"); - addresses = jarray(&numaddrs,ptr->vals,"addresses"); - if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,rawtx,extraspace,sizeof(extraspace),serialized)) != 0 ) - { - //printf("GOT VINS.(%s) rawtx.(%s) out0 %.8f\n",jprint(vins,0),rawtx,dstr(msgtx.vouts[0].value)); - if ( juint(txobj,"locktime") != locktime ) - { - printf("locktime mismatch %u != %u\n",juint(txobj,"locktime"),locktime); - return(-2.); // error - } - else if ( jobj(txobj,"error") == 0 && cJSON_GetArraySize(vins) == msgtx.tx_in ) - { - dependents = calloc(1,sizeof(*dependents) + msgtx.tx_in*(sizeof(*dependents->results) + sizeof(*dependents->ptrs) + 64)); - dependents->results = (void *)&dependents->ptrs[msgtx.tx_in]; - dependents->coinaddrs = (void *)&dependents->results[msgtx.tx_in]; - dependents->numptrs = msgtx.tx_in; - ptr->dependents = dependents; - ptr->numchildren = dependents->numptrs; - for (i=0; i> 1; - decode_hex(V.spendscript,V.spendlen,scriptstr); - asmtype = _iguana_calcrmd160(coin,&V); - coinaddr = &dependents->coinaddrs[64 * i]; - //if ( asmtype == IGUANA_SCRIPT_76A988AC || asmtype == IGUANA_SCRIPT_AC || asmtype == IGUANA_SCRIPT_76AC || asmtype == IGUANA_SCRIPT_P2SH ) - bitcoin_address(coinaddr,coin->chain->pubtype,V.rmd160,20); - if ( (argvals= cJSON_CreateObject()) != 0 ) - { - jaddbits256(argvals,"txid",jbits256(vin,"txid")); - jaddnum(argvals,"timeout",ptr->expiration - OS_milliseconds()); - jaddnum(argvals,"vout",jint(vin,"vout")); - jaddstr(argvals,"address",coinaddr); - if ( (dependents->ptrs[i]= basilisk_bitcoinvalue(&Lsubptr,myinfo,coin,0,rand(),(ptr->expiration - OS_milliseconds()) * .777,argvals)) != 0 ) - { - if ( dependents->ptrs[i] == &Lsubptr ) - { - dependents->results[i] = Lsubptr.retstr; - dependents->ptrs[i] = 0; - } - else dependents->ptrs[i]->parent = ptr; - } - free_json(argvals); - } - } else printf("cant find spend info.(%s)\n",jprint(vin,0)); - } - if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n == msgtx.tx_out ) - { - for (i=0; ispentsatoshis = msgtx.vouts[i].value; - continue; - } - else - { - if ( (sobj= jobj(jitem(vouts,i),"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 ) - { - if ( m == 1 && strcmp(jstri(addrs,0),changeaddr) == 0 ) - { - dependents->change = msgtx.vouts[i].value; - printf("verify it is normal spend for %s %.8f\n",changeaddr,dstr(msgtx.vouts[i].value)); - continue; - } - } - } - cost += msgtx.vouts[i].value; - //printf("boost cost %.8f\n",dstr(msgtx.vouts[i].value)); - } - } - } - free_json(txobj); - } - } - if ( dependents->spentsatoshis != amount ) - { - printf("spentsatoshis %.8f != expected %.8f, change %.8f\n",dstr(dependents->spentsatoshis),dstr(amount),dstr(dependents->change)); - return(-1000.); // error - } - if ( (dependents->outputsum= outputsum) <= 0 ) - { - printf("illegal outputsum %.8f\n",dstr(outputsum)); - return(-1001.); // error - } - if ( cost == 0 ) - cost = 1; - dependents->cost = cost; - return(0.); - }*/ - /*n = queue_size(&validateQ) / IGUANA_NUMHELPERS + 1; - printf("vQ is n.%d\n",n); - for (iter=0; iterbp) != 0 && (coin= ptr->coin) != 0 && coin->active != 0 ) - { - printf("helper.%d validate.[%d] %d vs %d\n",helperid,bp->hdrsi,coin->blocks.hwmchain.height/coin->chain->bundlesize,(coin->longestchain-1)/coin->chain->bundlesize); - if ( coin->blocks.hwmchain.height/coin->chain->bundlesize >= (coin->longestchain-1)/coin->chain->bundlesize ) - flag += iguana_bundlevalidate(coin,bp,0); - else - { - usleep(10000); - printf("requeue vQ.[%d]\n",bp->hdrsi); - iguana_validateQ(coin,bp); - } - } - else if ( coin->active != 0 ) - printf("helper validate missing param? %p %p\n",ptr->coin,ptr->bp); - myfree(ptr,ptr->allocsize); - flag++; - }*/ - - /*int32_t iguana_inv2poll(struct supernet_info *myinfo,struct iguana_info *coin) - { - struct exchange_info *exchange; int32_t i,n=0; struct iguana_peer *addr; char myipaddr[64]; - expand_ipbits(myipaddr,myinfo->myaddr.myipbits); - //printf("iguana_inv2poll exchange.%p %s maxpeers.%d\n",exchanges777_find("bitcoin"),coin->symbol,coin->MAXPEERS); - if ( coin != 0 && coin->peers != 0 && (exchange= exchanges777_find("bitcoin")) != 0 && strcmp(coin->symbol,"BTCD") == 0 ) - { - if ( time(NULL) > coin->lastinv2+10 ) - { - coin->lastinv2 = (uint32_t)time(NULL); - for (i=n=0; iMAXPEERS; i++) - { - addr = &coin->peers->active[i]; - if ( addr->supernet != 0 ) - { - //printf("iguana_inv2poll (%s) usock.%d dead.%u ready.%u ipbits.%u supernet.%d\n",addr->ipaddr,addr->usock,addr->dead,addr->ready,(uint32_t)addr->ipbits,addr->supernet); - if ( addr->usock >= 0 && addr->dead == 0 && addr->ready != 0 && addr->ipbits != 0 && strcmp(addr->ipaddr,myipaddr) != 0 ) - { - instantdex_inv2data(myinfo,coin,addr,exchange); - n++; - } - } - } - } - } - return(n); - }*/ - - continue; - for (i=bp->hdrsi; i>=0; i--) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - ramchain = 0; - if ( iguana_pkhashfind(coin,&ramchain,&deposits,&lastunspentind,&p,rmd160,i,i) != 0 && (rdata= ramchain->H.data) != 0 ) - { - spent = 0; - deposits = 0; - unspentind = lastunspentind; - U = RAMCHAIN_PTR(rdata,Uoffset); - T = RAMCHAIN_PTR(rdata,Toffset); - while ( unspentind > 0 ) - { - if ( iguana_spentflag(myinfo,coin,&RTspend,&spentheight,ramchain,i,unspentind,lastheight,0,1<<31,U[unspentind].value) == 0 ) - deposits += U[unspentind].value; - else spent += U[unspentind].value; - unspentind = U[unspentind].prevunspentind; - } - weights[pkind] += (deposits - spent); - /*if ( (A2= ramchain->A2) != 0 && p.pkind > 0 && p.pkind < rdata->numpkinds && (U2= ramchain->Uextras) != 0 ) - { - T = RAMCHAIN_PTR(rdata,Toffset); - U = RAMCHAIN_PTR(rdata,Uoffset); - unspentind = A2[p.pkind].lastunspentind; - while ( unspentind > 0 ) - { - uheight = iguana_uheight(coin,ramchain->height,T,rdata->numtxids,&U[unspentind]); - if ( uheight < lastheight ) - spent += U[unspentind].value; - unspentind = U2[unspentind].prevunspentind; - } - weights[pkind] -= spent; - } else printf("PoS.[%d] rdata.%p or A2.%p error [%d] pkind.%d\n",pkind,rdata,A2,i,p.pkind);*/ - if ( weights[pkind] != 0 ) - printf("wt %.8f P.%d -> [%d] pkind.%d deposits %.8f spent %.8f\n",dstr(weights[pkind]),pkind,i,p.pkind,dstr(deposits),dstr(spent)); - } - } - /*if ( (retstr= iguana_orderbook("bitfinex","BTC","USD",10)) != 0 ) - { - if ( (aveprice= tradebots_update(&Fbtc_usd,"bitfinex","BTC","USD",retstr,1)) != 0 ) - { - Fbtc = _pairaved(avebtc,aveprice); - avebtc = _pairaved(Ebtc,Fbtc); - } - free(retstr); - } - if ( (retstr= iguana_orderbook("btce","BTC","USD",10)) != 0 ) - { - if ( (aveprice= tradebots_update(&Ebtc_usd,"btce","BTC","USD",retstr,1)) != 0 ) - { - Ebtc = _pairaved(avebtc,aveprice); - avebtc = _pairaved(Ebtc,Fbtc); - } - free(retstr); - } - if ( (retstr= iguana_orderbook("bittrex","SBD","BTC",10)) != 0 ) - { - if ( (aveprice= tradebots_update(&Bsbd_btc,"bittrex","SBD","BTC",retstr,10)) != 0 ) - { - Bsbd = _pairaved(avesbd,aveprice); - avesbd = _pairaved(Bsbd,Psbd); - } - free(retstr); - } - if ( (retstr= iguana_orderbook("poloniex","SBD","BTC",10)) != 0 ) - { - if ( (aveprice= tradebots_update(&Psbd_btc,"poloniex","SBD","BTC",retstr,10)) != 0 ) - { - Psbd = _pairaved(avesbd,aveprice); - avesbd = _pairaved(Bsbd,Psbd); - } - free(retstr); - } - if ( (retstr= iguana_orderbook("bittrex","STEEM","BTC",10)) != 0 ) - { - if ( (aveprice= tradebots_update(&Bsteem_btc,"bittrex","STEEM","BTC",retstr,100)) != 0 ) - { - Bsteem = _pairaved(avesteem,aveprice); - avesteem = _pairaved(Bsteem,Psteem); - } - free(retstr); - } - if ( (retstr= iguana_orderbook("poloniex","STEEM","BTC",10)) != 0 ) - { - //printf("retstr.(%s)\n",retstr); - if ( (aveprice= tradebots_update(&Psteem_btc,"poloniex","STEEM","BTC",retstr,100)) != 0 ) - { - Psteem = _pairaved(avesteem,aveprice); - avesteem = _pairaved(Bsteem,Psteem); - } - free(retstr); - }*/ - - uint32_t basilisk_msgid(struct supernet_info *myinfo,uint32_t channel,bits256 hash,uint8_t *data,int32_t datalen) - { - struct message_info *mp; bits256 msghash; uint32_t now; int32_t i,j,firstj,firsti = -1; - vcalc_sha256(0,msghash.bytes,data,datalen); - //msghash.bytes[0] = channel & 0xff; - //msghash.bytes[1] = (channel >> 8) & 0xff; - //msghash.bytes[2] = (channel >> 16) & 0xff; - now = (uint32_t)time(NULL); - for (i=0; imsgids)/sizeof(*myinfo->msgids); i++) - { - mp = &myinfo->msgids[i]; - if ( mp->msgcount != 0 ) - { - if ( bits256_cmp(hash,mp->refhash) == 0 ) - { - firstj = -1; - for (j=0; jmsgcount; j++) - { - if ( mp->timestamps[j] != 0 ) - { - if ( now > mp->timestamps[j]+30 ) - memset(mp,0,sizeof(*mp)); - else if ( bits256_cmp(msghash,mp->msghashes[j]) == 0 ) - return(j + 1); - } - if ( firstj < 0 && mp->timestamps[j] == 0 ) - firstj = j; - } - if ( firstj >= 0 ) - { - mp->msghashes[firstj] = msghash; - mp->timestamps[firstj] = (uint32_t)time(NULL); - return(firstj + 1); - } - if ( mp->msgcount < sizeof(mp->msghashes)/sizeof(*mp->msghashes) ) - { - j = mp->msgcount++; - mp->msghashes[j] = msghash; - mp->timestamps[j] = (uint32_t)time(NULL); - return(j + 1); - } else return(0); - } - } else if ( firsti < 0 ) - firsti = i; - } - if ( firsti >= 0 ) - { - mp = &myinfo->msgids[firsti]; - mp->msghashes[0] = msghash; - mp->timestamps[0] = (uint32_t)time(NULL); - mp->msgcount = 1; - mp->refhash = hash; - return(1); - } else return(0); - } -#endif -#endif - //#define ENABLE_RAMCHAIN - -#ifdef oldway - void iguana_RTramchainfree(struct iguana_info *coin,struct iguana_bundle *bp) - { - //return; -#ifdef ENABLE_RAMCHAIN - int32_t hdrsi; - //portable_mutex_lock(&coin->RTmutex); - if ( coin->utxotable != 0 ) - { - printf("free RTramchain\n"); - //iguana_utxoupdate(coin,-1,0,0,0,0,-1,0); // free hashtables - coin->lastRTheight = coin->RTheight = 0;//(coin->bundlescount-1) * coin->chain->bundlesize; - coin->RTgenesis = 0; - iguana_utxoaddrs_purge(coin); - iguana_ramchain_free(coin,&coin->RTramchain,1); - if ( bp != 0 ) - bp->ramchain = coin->RTramchain; - iguana_mempurge(&coin->RTmem); - iguana_mempurge(&coin->RThashmem); - for (hdrsi=coin->bundlescount-1; hdrsi>0; hdrsi--) - if ( (bp= coin->bundles[hdrsi]) == 0 && bp != coin->current ) - { - iguana_volatilespurge(coin,&bp->ramchain); - if ( iguana_volatilesmap(coin,&bp->ramchain) != 0 ) - printf("error mapping bundle.[%d]\n",hdrsi); - } - coin->RTdatabad = 0; - printf("done RTramchain\n"); - } - //portable_mutex_unlock(&coin->RTmutex); -#endif - } - - void *iguana_ramchainfile(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *R,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block) - { - //return(0); -#ifdef ENABLE_RAMCHAIN - char fname[1024]; long filesize; int32_t err; void *ptr=0; - if ( block == bp->blocks[bundlei] && (ptr= iguana_bundlefile(coin,fname,&filesize,bp,bundlei)) != 0 ) - { - if ( iguana_mapchaininit(fname,coin,R,bp,bundlei,block,ptr,filesize) >= 0 ) - { - if ( dest != 0 && dest->H.data != 0 ) - err = iguana_ramchain_iterate(myinfo,coin,dest,R,bp,bundlei); - else err = 0; - if ( err != 0 || dest->H.data == 0 || bits256_cmp(R->H.data->firsthash2,block->RO.hash2) != 0 ) - { - char str[65]; - printf("ERROR [%d:%d] %s vs ",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); - printf("mapped.%s\n",bits256_str(str,R->H.data->firsthash2)); - } else return(ptr); - } - iguana_blockunmark(coin,block,bp,bundlei,1); - iguana_ramchain_free(coin,R,1); - } //else printf("ramchainfile ptr.%p block.%p\n",ptr,block); -#endif - return(0); - } - - void iguana_RTramchainalloc(char *fname,struct iguana_info *coin,struct iguana_bundle *bp) - { - //return; -#ifdef ENABLE_RAMCHAIN - uint32_t i,changed = 0; struct iguana_ramchaindata *rdata; struct iguana_ramchain *dest = &coin->RTramchain; struct iguana_blockRO *B; struct iguana_bundle *tmpbp; - //portable_mutex_lock(&coin->RTmutex); - if ( (rdata= dest->H.data) != 0 ) - { - i = 0; - if ( coin->RTheight != coin->lastRTheight ) - changed++; - else - { - B = RAMCHAIN_PTR(rdata,Boffset); - for (i=0; inumblocks; i++) - if ( bits256_cmp(B[i].hash2,bp->hashes[i]) != 0 ) - { - char str[65],str2[65]; printf("mismatched hash2 at %d %s vs %s\n",bp->bundleheight+i,bits256_str(str,B[i].hash2),bits256_str(str2,bp->hashes[i])); - changed++; - iguana_blockunmark(coin,bp->blocks[i],bp,i,1); - break; - } - } - if ( changed != 0 ) - { - printf("RTramchain changed %d bundlei.%d | coin->RTheight %d != %d bp->bundleheight + %d coin->RTramchain.H.data->numblocks\n",coin->RTheight,i,coin->RTheight,bp->bundleheight,rdata->numblocks); - iguana_RTramchainfree(coin,bp); - } - } - if ( coin->RTramchain.H.data == 0 ) - { - iguana_ramchainopen(fname,coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); - printf("ALLOC RTramchain.(%s) RTrdata %p rdata.%p\n",fname,coin->RTramchain.H.data,bp->ramchain.H.data); - dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; - dest->externalind = dest->H.stacksize = 0; - dest->H.scriptoffset = 1; - if ( 1 ) - { - for (i=0; ihdrsi; i++) - if ( (tmpbp= coin->bundles[i]) != 0 ) - { - iguana_volatilespurge(coin,&tmpbp->ramchain); - iguana_volatilesmap(coin,&tmpbp->ramchain); - } - sleep(1); - } - } - //portable_mutex_unlock(&coin->RTmutex); -#endif - } - - void iguana_rdataset(struct iguana_ramchain *dest,struct iguana_ramchaindata *rdest,struct iguana_ramchain *src) - { - //return; -#ifdef ENABLE_RAMCHAIN - *dest = *src; - dest->H.data = rdest; - *rdest = *src->H.data; - rdest->numpkinds = src->pkind; - rdest->numexternaltxids = src->externalind; - rdest->numtxids = src->H.txidind; - rdest->numunspents = src->H.unspentind; - rdest->numspends = src->H.spendind; - //printf("RT set numtxids.%u numspends.%u\n",rdest->numtxids,rdest->numspends); -#endif - } - - void iguana_rdatarestore(struct iguana_ramchain *dest,struct iguana_ramchaindata *rdest,struct iguana_ramchain *src) - { - //return; -#ifdef ENABLE_RAMCHAIN - *src = *dest; - *src->H.data = *rdest; - src->pkind = rdest->numpkinds; - src->externalind = rdest->numexternaltxids; - src->H.txidind = rdest->numtxids; - src->H.unspentind = rdest->numunspents; - src->H.spendind = rdest->numspends; - printf("RT restore numtxids.%u numspends.%u\n",rdest->numtxids,rdest->numspends); -#endif - } - - void iguana_RThdrs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t numaddrs) - { - //return; -#ifdef ENABLE_RAMCHAIN - int32_t datalen,i; uint8_t serialized[512]; char str[65]; struct iguana_peer *addr; - if ( coin->peers == 0 ) - return; - datalen = iguana_gethdrs(coin,serialized,coin->chain->gethdrsmsg,bits256_str(str,bp->hashes[0])); - for (i=0; ipeers->numranked; i++) - { - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); - if ( coin->chain->hasheaders == 0 ) - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,coin->blocks.hwmchain.RO.hash2)),1); - if ( (addr= coin->peers->ranked[i]) != 0 && addr->usock >= 0 && addr->dead == 0 && datalen > 0 ) - { - iguana_send(coin,addr,serialized,datalen); - //addr->pendhdrs++; - } - } -#endif - } - - void iguana_RTspendvectors(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp) - { - //return; -#ifdef ENABLE_RAMCHAIN - int32_t iterate,lasti,num,hdrsi,orignumemit; struct iguana_ramchain R; struct iguana_ramchaindata RDATA; - if ( bp->hdrsi <= 0 ) - return; - printf("RTspendvectors [%d]\n",bp->hdrsi); - bp->ramchain = coin->RTramchain; - iguana_rdataset(&R,&RDATA,&coin->RTramchain); - if ( (lasti= (coin->RTheight - ((coin->RTheight/bp->n)*bp->n))) >= bp->n-1 ) - lasti = bp->n - 1; - orignumemit = bp->numtmpspends; - iterate = 0; - if ( iguana_spendvectors(myinfo,coin,bp,&coin->RTramchain,coin->RTstarti%coin->chain->bundlesize,lasti,0,iterate) < 0 ) - { - printf("RTutxo error -> RTramchainfree\n"); - coin->RTdatabad = 1; - return; - } - else - { - //printf("RTspendvectors calculated to %d [%d]\n",coin->RTheight,bp->hdrsi); - bp->converted = 1; - for (hdrsi=num=0; hdrsihdrsi; hdrsi++) - { -#ifdef __APPLE__ - if ( coin->bundles[hdrsi]->lastprefetch == 0 ) - { - iguana_ramchain_prefetch(coin,&coin->bundles[hdrsi]->ramchain,2); - coin->bundles[hdrsi]->lastprefetch = (uint32_t)time(NULL); - } -#endif - num += iguana_convert(coin,IGUANA_NUMHELPERS,coin->bundles[hdrsi],1,orignumemit); - } - //printf("RTspendvectors converted.%d to %d\n",num,coin->RTheight); - //iguana_rdatarestore(&R,&RDATA,&bp->ramchain); - bp->converted = (uint32_t)time(NULL); - if ( iguana_balancegen(coin,1,bp,coin->RTstarti,coin->RTheight > 0 ? coin->RTheight-1 : bp->bundleheight+bp->n-1,orignumemit) < 0 ) - { - printf("balancegen error\n"); - coin->RTdatabad = 1; - } - else if ( coin->RTgenesis == 0 && coin->firstRTgenesis == 0 ) - coin->firstRTgenesis++, printf(">>>>>> IGUANA %s READY FOR REALTIME RPC <<<<<<\n",coin->symbol); - //printf("iguana_balancegen [%d] (%d to %d)\n",bp->hdrsi,coin->RTstarti,(coin->RTheight-1)%bp->n); - coin->RTstarti = coin->RTheight; - } -#endif - } - - int32_t iguana_realtime_update(struct supernet_info *myinfo,struct iguana_info *coin) - { - int32_t flag = 0; - //return(0); -#ifdef ENABLE_RAMCHAIN - double startmillis0; static double totalmillis0; static int32_t num0; - struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t offset,bundlei,i,n; bits256 hash2,*ptr; struct iguana_peer *addr; - struct iguana_block *block=0; struct iguana_blockRO *B; struct iguana_ramchain *dest=0,blockR; - if ( coin->peers == 0 && coin->virtualchain == 0 ) - return(0); - offset = 0;//(strcmp("BTC",coin->symbol) != 0); - if ( coin->RTheight >= (coin->current->hdrsi+1)*coin->chain->bundlesize ) - { - printf("inversion RT %d >= %d\n",coin->RTheight,(coin->current->hdrsi+1)*coin->chain->bundlesize); - coin->lastRTheight = coin->RTheight = coin->current->hdrsi*coin->chain->bundlesize; - iguana_utxoaddrs_purge(coin); - } - if ( coin->current != 0 && (coin->blocks.hwmchain.height % coin->chain->bundlesize) == coin->chain->bundlesize-1 && coin->blocks.hwmchain.height/coin->chain->bundlesize == coin->longestchain/coin->chain->bundlesize ) - { - block = coin->current->blocks[coin->current->n - 1]; - if ( _iguana_chainlink(coin,block) <= 0 ) - { - printf("RT edge case couldnt link\n"); - } - else - { - printf("RT edge case.%d\n",block->height); - if ( (bp= coin->bundles[coin->RTheight / coin->chain->bundlesize]) != 0 ) - iguana_spendvectors(myinfo,coin,bp,&bp->ramchain,0,bp->n,0,0); - iguana_update_balances(coin); - } - } - if ( coin->spendvectorsaved <= 1 ) - { - //printf("%s spendvectorsaved not yet\n",coin->symbol); - usleep(100000); - return(0); - } - //portable_mutex_lock(&coin->RTmutex); - for (i=0; ibundlescount-1; i++) - { - if ( (bp= coin->bundles[i]) != 0 && (i > 0 && bp->utxofinish == 0) && bp != coin->current ) - { - if ( iguana_spendvectors(myinfo,coin,bp,&bp->ramchain,0,bp->n,0,0) < 0 ) - { - //portable_mutex_unlock(&coin->RTmutex); - printf("error generating spendvectors.[%d], skipping\n",i); - return(0); - } // else printf("generated UTXO.[%d]\n",i); - coin->spendvectorsaved = 1; - } - } - //portable_mutex_unlock(&coin->RTmutex); - bp = coin->current; - if ( bp == 0 )//|| iguana_validated(coin) < bp->hdrsi ) - { - //printf("bp.%p validated.%d vs hdrsi.%d\n",bp,iguana_validated(coin),bp->hdrsi); - return(0); - } - if ( 0 && coin->RTheight > 0 && coin->spendvectorsaved != 1 && coin->bundlescount-1 != coin->balanceswritten ) - { - printf("RT mismatch %d != %d\n",coin->bundlescount-1,coin->balanceswritten); - iguana_RTramchainfree(coin,coin->current); - coin->spendvectorsaved = 0; - coin->lastRTheight = coin->RTheight = 0; - iguana_utxoaddrs_purge(coin); - /*while ( coin->spendvectorsaved <= 1 ) - { - fprintf(stderr,"wait for spendvectorsaved\n"); - sleep(3); - }*/ - return(0); - } - if ( coin->RTdatabad == 0 && bp->hdrsi >= (coin->longestchain/coin->chain->bundlesize)-1 && bp->hdrsi >= coin->balanceswritten-2 && ((coin->RTheight < coin->blocks.hwmchain.height-offset && time(NULL) > bp->lastRT) || time(NULL) > bp->lastRT+1) ) //coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n && - { - if ( coin->RTheight < bp->hdrsi*coin->chain->bundlesize ) - { - coin->lastRTheight = coin->RTheight = bp->hdrsi*coin->chain->bundlesize; - iguana_utxoaddrs_purge(coin); - } - if ( (block= bp->blocks[0]) == 0 || block->txvalid == 0 || block->mainchain == 0 ) - { - if ( block != 0 ) - { - if ( _iguana_chainlink(coin,block) <= 0 ) - { - iguana_blockunmark(coin,block,bp,0,0); - bp->issued[0] = 0; - hash2 = bp->hashes[0]; - //char str[65]; printf("RT[0] [%d:%d] %s %p\n",bp->hdrsi,0,bits256_str(str,hash2),block); - if ( coin->peers != 0 ) - { - addr = coin->peers->ranked[rand() % 8]; - if ( addr != 0 && addr->usock >= 0 && addr->dead == 0 ) - iguana_sendblockreqPT(coin,addr,bp,0,hash2,0); - } - } - } - } - //char str[65]; printf("check longest.%d RTheight.%d hwm.%d %s %p\n",coin->longestchain,coin->RTheight,coin->blocks.hwmchain.height,bits256_str(str,bp->hashes[0]),block); - if ( bits256_cmp(coin->RThash1,bp->hashes[1]) != 0 ) - coin->RThash1 = bp->hashes[1]; - //bp->lastRT = (uint32_t)time(NULL); - if ( coin->peers != 0 && coin->RTheight <= coin->longestchain-offset && coin->peers->numranked > 0 && time(NULL) > coin->RThdrstime+16 ) - { - iguana_RThdrs(coin,bp,coin->peers->numranked); - coin->RThdrstime = (uint32_t)time(NULL); - } - bp->lastRT = (uint32_t)time(NULL); - iguana_RTramchainalloc("RTbundle",coin,bp); - bp->isRT = 1; - //printf("%s rdata.%p RTheight.%d hwm.%d RTdatabad.%d\n",coin->symbol,coin->RTramchain.H.data,coin->RTheight,coin->blocks.hwmchain.height,coin->RTdatabad); - while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height-offset && coin->RTdatabad == 0 ) - { - dest = &coin->RTramchain; - B = RAMCHAIN_PTR(rdata,Boffset); - bundlei = (coin->RTheight % coin->chain->bundlesize); - if ( (block= iguana_bundleblock(coin,&hash2,bp,bundlei)) != 0 ) - { - iguana_bundlehashadd(coin,bp,bundlei,block); - //printf("RT.%d vs hwm.%d starti.%d bp->n %d block.%p/%p ramchain.%p databad.%d prevnonz.%d\n",coin->RTheight,coin->blocks.hwmchain.height,coin->RTstarti,bp->n,block,bp->blocks[bundlei],dest->H.data,coin->RTdatabad,bits256_nonz(block->RO.prev_block)); - } - else - { - //printf("cant find bundleblock [%d:%d]\n",bp->hdrsi,bundlei); - iguana_blockQ("RTmissing",coin,bp,bundlei,hash2,1); - break; - } - if ( coin->RTdatabad == 0 && block != 0 && (block->height == 0 || bits256_nonz(block->RO.prev_block) != 0) ) - { - //printf("bundlei.%d blockht.%d RTheight.%d\n",bundlei,block->height,coin->RTheight); - iguana_blocksetcounters(coin,block,dest); - startmillis0 = OS_milliseconds(); - if ( iguana_ramchainfile(myinfo,coin,dest,&blockR,bp,bundlei,block) == 0 ) - { - for (i=0; in; i++) - if ( GETBIT(bp->haveblock,i) == 0 ) - bp->issued[i] = 0; - if ( (n= iguana_bundleissuemissing(coin,bp,3,1.)) > 0 ) - printf("RT %s issued %d priority requests [%d] to unstick stuckiters.%d\n",coin->symbol,n,bp->hdrsi,coin->stuckiters); - for (i=bundlei; in; i++) - { - block = iguana_bundleblock(coin,&hash2,bp,i); - if ( bits256_nonz(hash2) != 0 && (block == 0 || block->txvalid == 0) ) - { - uint8_t serialized[512]; int32_t len; struct iguana_peer *addr; - //char str[65]; printf("RT error [%d:%d] %s %p\n",bp->hdrsi,i,bits256_str(str,hash2),block); - if ( coin->peers != 0 ) - { - addr = coin->peers->ranked[rand() % 8]; - if ( addr != 0 && addr->usock >= 0 && addr->dead == 0 && (len= iguana_getdata(coin,serialized,MSG_BLOCK,&hash2,1)) > 0 ) - iguana_send(coin,addr,serialized,len); - } - coin->RTgenesis = 0; - } - if ( bits256_nonz(hash2) != 0 ) - iguana_blockQ("RTerr",coin,bp,i,hash2,1); - //break; - } - return(-1); - } else iguana_ramchain_free(coin,&blockR,1); - B[bundlei] = block->RO; - totalmillis0 += (OS_milliseconds() - startmillis0); - num0++; - flag++; - //coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; - coin->RTheight++; - coin->lastRTheight = coin->RTheight; - //printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); - if ( coin->RTramchain.H.data != 0 ) - coin->RTramchain.H.data->numblocks = bundlei + 1; - else break; - } else break; - } - } - else - { - if ( coin->virtualchain == 0 ) - { - //printf("%s skip RT.(%d %d %d %d %d %d %d %u)\n",coin->symbol,coin->RTdatabad,bp->hdrsi,coin->longestchain/coin->chain->bundlesize,coin->balanceswritten,coin->RTheight,bp->bundleheight,coin->blocks.hwmchain.height,bp->lastRT); - //sleep(1); - } - } - n = 0; - if ( coin->RTdatabad == 0 && dest != 0 && flag != 0 && coin->RTheight >= coin->blocks.hwmchain.height-offset ) - { - printf("ramchainiterate.[%d] ave %.2f micros, total %.2f seconds starti.%d num.%d\n",num0,(totalmillis0*1000.)/num0,totalmillis0/1000.,coin->RTstarti,coin->RTheight%bp->n); - if ( (n= iguana_walkchain(coin,1)) == coin->RTheight-1+offset ) - { - //printf("RTgenesis verified\n"); - if ( (coin->RTheight % coin->chain->bundlesize) > 3 ) - { - //portable_mutex_lock(&coin->RTmutex); - iguana_RTspendvectors(myinfo,coin,bp); - //portable_mutex_unlock(&coin->RTmutex); - coin->RTgenesis = (uint32_t)time(NULL); - } - } - else - { - printf("walkchain error n.%d != %d\n",n,coin->RTheight-1+offset); - coin->RTdatabad = 1; - } - } - if ( dest != 0 && flag != 0 ) - printf("<<<< flag.%d RT.%d:%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld balance %.8f + %.8f - %.8f = supply %.8f\n",flag,coin->RTheight,n,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,dest->H.data!=0?(long)dest->H.data->allocsize:-1,dstr(coin->histbalance),dstr(coin->RTcredits),dstr(coin->RTdebits),dstr(coin->histbalance + coin->RTcredits - coin->RTdebits)); - if ( coin->RTdatabad != 0 ) - { - bits256 lastbundle; - //portable_mutex_lock(&coin->RTmutex); - printf("START DATABAD fixing\n"); - iguana_RTramchainfree(coin,bp); - if ( coin->RTdatabad < 0 ) - { - memset(lastbundle.bytes,0,sizeof(lastbundle)); - iguana_initfinal(myinfo,coin,lastbundle); - } - coin->RTdatabad = 0; - //memset(bp->hashes,0,sizeof(bp->hashes)); - memset(bp->blocks,0,sizeof(bp->blocks)); - if ( 0 && bp->speculative != 0 ) - { - ptr = bp->speculative; - bp->speculative = 0; - memset(ptr,0,sizeof(*bp->speculative)*bp->n); - myfree(ptr,(bp->n+1)*sizeof(*bp->speculative)); - } - iguana_RTramchainalloc("RTbundle",coin,bp); - printf("DONE DATABAD fixing\n"); - //portable_mutex_unlock(&coin->RTmutex); - } -#endif - return(flag); - } -#endif - /*if ( (checklen= iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[rdata->scriptspace],Kspace,s)) != vinscriptlen || (vinscript != 0 && memcmp(_script,vinscript,vinscriptlen) != 0) ) - { - static uint64_t counter; - if ( counter++ < 100 ) - { - for (i=0; iH.scriptoffset += metalen; - - - /*static uint64_t good,bad; - if ( 0 && iguana_metascript(coin,RAMCHAIN_ARG,s,vinscript,vinscriptlen,0) < 0 ) - { - static long errlen,err2len; char errbuf[1024]; - errlen += vinscriptlen; - if ( iguana_metascript(coin,RAMCHAIN_ARG,s,vinscript,vinscriptlen,1) < 0 ) - { - err2len += vinscriptlen; - errbuf[0] = 0; - for (i=0; i 138 ) - { - errbuf[0] = 0; - for (i=0; ihdrsi = hdrsi; - //s->bundlei = bundlei; - //char str[65]; printf("%s set prevout.%d -> %d\n",bits256_str(str,prev_hash),prev_vout,s->prevout); - - //if ( pkind != 0 ) - // s->prevspendind = A[pkind].lastspendind; - // respond to incoming RID, ACC, DEX, QST - - /*char *basilisk_respond_RID(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) - { - return(basilisk_respond_requests(myinfo,hash,juint(valsobj,"requestid"),0)); - } - - char *basilisk_respond_SWP(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) - { - return(basilisk_respond_swapstatus(myinfo,hash,juint(valsobj,"requestid"),juint(valsobj,"quoteid"))); - } - - char *basilisk_respond_ACC(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) - { - uint32_t requestid,quoteid; - if ( (requestid= juint(valsobj,"requestid")) != 0 && (quoteid= juint(valsobj,"quoteid")) != 0 ) - return(basilisk_respond_accept(myinfo,requestid,quoteid)); - else return(clonestr("{\"error\":\"need nonzero requestid and quoteid\"}")); - } - - char *basilisk_respond_DEX(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) - { - char *retstr=0,buf[256]; struct basilisk_request R; - if ( basilisk_request_create(&R,valsobj,hash,juint(valsobj,"timestamp")) == 0 ) - { - char str[65]; printf("DEX.(%s %.8f) -> %s %s\n",R.src,dstr(R.srcamount),R.dest,bits256_str(str,hash)); - if ( basilisk_request_enqueue(myinfo,&R) != 0 ) - { - sprintf(buf,"{\"result\":\"DEX request added\",\"requestid\":%u}",R.requestid); - retstr = clonestr(buf); - } else retstr = clonestr("{\"error\":\"DEX quote couldnt be created\"}"); - } else retstr = clonestr("{\"error\":\"missing or invalid fields\"}"); - return(retstr); - }*/ - - int32_t dpow_message_utxo(uint8_t *senderpub,bits256 *hashmsgp,bits256 *txidp,int32_t *voutp,bits256 *commitp,cJSON *json) - { - cJSON *msgobj,*item; uint8_t key[BASILISK_KEYSIZE],data[4096]; char *keystr,*hexstr; int32_t i,n,datalen,retval = -1; //,str[65],str2[65] - *voutp = -1; - memset(txidp,0,sizeof(*txidp)); - if ( (msgobj= jarray(&n,json,"messages")) != 0 ) - { - //printf("messages.(%s)\n",jprint(msgobj,0)); - for (i=0; i 0 ) - { - decode_hex(key,BASILISK_KEYSIZE,keystr); - datalen >>= 1; - decode_hex(data,datalen,hexstr); - retval = dpow_rwutxobuf(0,data,hashmsgp,txidp,voutp,commitp,senderpub); - //printf("notary.%d hashmsg.(%s) txid.(%s) v%d\n",i,bits256_str(str,*hashmsgp),bits256_str(str2,*txidp),*voutp); - } - } - } - return(retval); - } - int32_t dpow_message_most(struct dpow_sigentry *dsigs,int32_t num,cJSON *json,int32_t lastflag) - { - cJSON *msgobj,*item; uint8_t key[BASILISK_KEYSIZE]; struct dpow_sigentry dsig; char *keystr,*hexstr; uint8_t data[sizeof(struct dpow_sigentry)]; int32_t duplicate,i,j,n,datalen,most = 0; - if ( (msgobj= jarray(&n,json,"messages")) != 0 ) - { - for (i=0; i 0 ) - { - decode_hex(key,BASILISK_KEYSIZE,keystr); - datalen >>= 1; - if ( datalen <= sizeof(data) ) - { - decode_hex(data,datalen,hexstr); - dpow_rwsigentry(0,data,&dsig); - for (j=duplicate=0; j= maxlen.%d\n",datalen,(int32_t)sizeof(data)); - } - } - } - if ( lastflag != 0 && num > 0 ) - { - for (j=0; j most ) - { - most = n; - dsigs[num] = dsigs[j]; - } - printf("lastflag.%d num.%d most.%d n.%d refcount.%d\n",lastflag,num,most,n,dsigs[j].refcount); - } - } - return(num); - } - /*int32_t dpow_mostsignedtx(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,uint64_t *maskp,int32_t *lastkp,struct dpow_block *bp,int32_t myind) - { - uint64_t mostmask=0,refmask = 0; struct dpow_entry *ep; int32_t nonz,k,i,mostk = -1,most = 0; - for (k=0; knumnotaries; k++) - { - for (refmask=i=nonz=0; inumnotaries; i++) - { - ep = &bp->notaries[i]; - if ( ep->masks[k] != 0 ) - { - if ( nonz == 0 ) - { - refmask = ep->masks[k], nonz++; - printf("refmask.%llx\n",(long long)refmask); - } - else if ( ep->masks[k] != refmask ) - printf("refk.%d refmask.%llx but got %llx\n",k,(long long)refmask,(long long)ep->masks[k]); - } - } - if ( nonz > most ) - { - most = nonz; - mostmask = refmask; - mostk = k; - } - printf("k.%d nonz.%d vs most.%d mostk.%d mostmask.%llx\n",k,nonz,most,mostk,(long long)mostmask); - } - if ( most > 0 ) - { - *lastkp = mostk; - *maskp = mostmask; - bp->signedtxid = dpow_notarytx(bp->signedtx,coin->chain->isPoS,bp,mostmask,mostk,dp->symbol); - } else printf("mostsignedtx most.%d\n",most); - return(most); - }*/ - /*if ( (m= dpow_mostsignedtx(myinfo,dp,coin,&mask,&k,bp,myind)) > 0 ) - { - if ( m >= bp->numnotaries/2+1 ) - { - if ( (retstr= dpow_sendrawtransaction(myinfo,coin,bp->signedtx)) != 0 ) - { - dp->destupdated = 0; - printf("sendrawtransaction.(%s)\n",retstr); - free(retstr); - } - bp->state = 0xffffffff; - } - else - { - dpow_signedtxgen(myinfo,coin,bp,mask,k,myind,opret_symbol); - } - }*/ - int32_t dpow_sigbufcmp(int32_t *duplicatep,struct dpow_sigentry *dsig,struct dpow_sigentry *refdsig) - { - if ( dsig->lastk == refdsig->lastk && dsig->siglen == refdsig->siglen && dsig->mask == refdsig->mask && memcmp(dsig->sig,refdsig->sig,dsig->siglen) == 0 && memcmp(dsig->beacon.bytes,refdsig->beacon.bytes,sizeof(dsig->beacon)) == 0 ) - { - if ( dsig->senderind == refdsig->senderind ) - { - (*duplicatep)++; - return(0); - } - else - { - refdsig->refcount++; - return(-1); - } - } - return(-1); - } - int32_t dpow_numsigs(struct dpow_block *bp,int32_t lastk,uint64_t mask) - { - int32_t j,m,i; - for (j=m=0; jnumnotaries; j++) - { - i = ((bp->height % bp->numnotaries) + j) % bp->numnotaries; - if ( bp->notaries[i].siglens[lastk] >= 64 ) //((1LL << i) & mask) != 0 && - { - if ( ++m >= DPOW_M(bp) ) - return(m); - } - } - return(-1); - } - - /*void dpow_handler(struct supernet_info *myinfo,struct basilisk_message *msg) - { - bits256 srchash,desthash; uint32_t channel,height; - basilisk_messagekeyread(msg->key,&channel,&height,&srchash,&desthash); - dpow_datahandler(myinfo,0,channel,height,msg->data,msg->datalen); - } - - void dpow_channelget(struct supernet_info *myinfo,struct dpow_block *bp,uint32_t channel) - { - bits256 zero; cJSON *retarray,*item,*item2,*messages; char *datastr; int32_t i,n,j,m,datalen; uint8_t data[32768]; - memset(zero.bytes,0,sizeof(zero)); - if ( (retarray= basilisk_channelget(myinfo,zero,zero,channel,bp->height,1)) != 0 ) - { - if ( (n= cJSON_GetArraySize(retarray)) > 0 ) - { - for (i=0; i>= 1; - decode_hex(data,datalen,datastr); - dpow_datahandler(myinfo,bp,channel,bp->height,data,datalen); - } - } - } - } - } - free_json(retarray); - } - }*/ - - /*if ( vins == 0 && bitweight(bestmask) == DPOW_M(bp) ) - { - if ( (rawtx2= dpow_decoderawtransaction(myinfo,coin,rawtx)) != 0 ) - { - if ( (txobj= cJSON_Parse(rawtx2)) != 0 ) - { - vins = jduplicate(jobj(txobj,"vin")); - free_json(txobj); - //printf("generated vins.(%s)\n",jprint(vins,0)); - } - free(rawtx2); - } - if ( vins != 0 ) - { - flag = 1; - n = cJSON_GetArraySize(vins); - k = (bp->height % bp->numnotaries) % bp->numnotaries; - for (i=0; i= bp->numnotaries ) - k = 0; - item = jitem(vins,i); - //printf("(%s) i.%d of %d, (%d) k.%d bestmask.%llx\n",jprint(item,0),i,n,(bp->height % bp->numnotaries) % bp->numnotaries,k,(long long)bestmask); - if ( bits256_nonz(bp->notaries[k].prev_hash) == 0 ) - { - bp->notaries[k].prev_hash = jbits256(item,"txid"); - if ( bits256_nonz(bp->notaries[k].prev_hash) != 0 ) - { - bp->notaries[k].prev_vout = jint(item,"vout"); - bp->recvmask |= (1LL << k); - printf(">>>>>>>> rawtx utxo.%d %s/v%d %llx\n",k,bits256_str(str,bp->notaries[k].prev_hash),bp->notaries[k].prev_vout,(long long)bp->recvmask); - } - } - if ( i < n-1 ) - k++; - } - if ( k != bestk ) - printf("extracted uxto k.%d != bestk.%d %llx\n",k,bestk,(long long)bestmask); - } - }*/ - void dpow_oldstatemachinestart(void *ptr) - { - struct supernet_info *myinfo; struct dpow_info *dp; struct dpow_checkpoint checkpoint; void **ptrs = ptr; - int32_t i,n,myind = -1; struct iguana_info *src,*dest; char str[65],coinaddr[64]; bits256 zero; struct dpow_block *srcbp,*destbp,*bp; uint32_t starttime = (uint32_t)time(NULL); - memset(&zero,0,sizeof(zero)); - myinfo = ptrs[0]; - dp = ptrs[1]; - dp->destupdated = 0; // prevent another state machine till next BTC block - memcpy(&checkpoint,&ptrs[2],sizeof(checkpoint)); - printf("statemachinestart %s->%s %s ht.%d\n",dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height); - src = iguana_coinfind(dp->symbol); - dest = iguana_coinfind(dp->dest); - if ( (destbp= dp->destblocks[checkpoint.blockhash.height]) == 0 ) - { - destbp = calloc(1,sizeof(*destbp)); - destbp->coin = iguana_coinfind(dp->dest); - destbp->opret_symbol = dp->symbol; - destbp->bestk = -1; - dp->destblocks[checkpoint.blockhash.height] = destbp; - destbp->beacon = rand256(0); - vcalc_sha256(0,destbp->commit.bytes,destbp->beacon.bytes,sizeof(destbp->beacon)); - if ( (bp= dp->destblocks[checkpoint.blockhash.height - 100]) != 0 ) - { - printf("purge %s.%d\n",dp->dest,checkpoint.blockhash.height - 100); - dp->destblocks[checkpoint.blockhash.height - 100] = 0; - free(bp); - } - } - if ( (srcbp= dp->srcblocks[checkpoint.blockhash.height]) == 0 ) - { - srcbp = calloc(1,sizeof(*srcbp)); - srcbp->coin = iguana_coinfind(dp->symbol); - srcbp->opret_symbol = dp->symbol; - srcbp->bestk = -1; - dp->srcblocks[checkpoint.blockhash.height] = srcbp; - srcbp->beacon = destbp->beacon; - srcbp->commit = destbp->commit; - printf("create srcbp[%d]\n",checkpoint.blockhash.height); - if ( (bp= dp->srcblocks[checkpoint.blockhash.height - 1000]) != 0 ) - { - printf("purge %s.%d\n",dp->symbol,checkpoint.blockhash.height - 1000); - dp->srcblocks[checkpoint.blockhash.height - 1000] = 0; - free(bp); - } - } - n = (int32_t)(sizeof(Notaries)/sizeof(*Notaries)); - srcbp->numnotaries = destbp->numnotaries = n; - for (i=0; inotaries[i].pubkey,33,Notaries[i][1]); - decode_hex(destbp->notaries[i].pubkey,33,Notaries[i][1]); - if ( memcmp(destbp->notaries[i].pubkey,myinfo->DPOW.minerkey33,33) == 0 ) - myind = i; - } - bitcoin_address(coinaddr,src->chain->pubtype,myinfo->DPOW.minerkey33,33); - printf(" myaddr.%s\n",coinaddr); - if ( myind < 0 ) - { - printf("statemachinestart this node %s is not official notary\n",coinaddr); - free(ptr); - return; - } - dp->checkpoint = checkpoint; - srcbp->height = destbp->height = checkpoint.blockhash.height; - srcbp->timestamp = destbp->timestamp = checkpoint.timestamp; - srcbp->hashmsg = destbp->hashmsg = checkpoint.blockhash.hash; - printf("DPOW statemachine checkpoint.%d %s\n",checkpoint.blockhash.height,bits256_str(str,checkpoint.blockhash.hash)); - while ( time(NULL) < starttime+300 && src != 0 && dest != 0 && (srcbp->state != 0xffffffff || destbp->state != 0xffffffff) ) - { - sleep(1); - if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) - { - printf("abort ht.%d due to new checkpoint.%d\n",checkpoint.blockhash.height,dp->checkpoint.blockhash.height); - break; - } - if ( destbp->state != 0xffffffff ) - { - //printf("dp->ht.%d ht.%d DEST.%08x %s\n",dp->checkpoint.blockhash.height,checkpoint.blockhash.height,deststate,bits256_str(str,srchash.hash)); - destbp->state = dpow_statemachineiterate(myinfo,dp,dest,destbp,myind,1); - if ( destbp->state == 0xffffffff ) - { - srcbp->btctxid = destbp->signedtxid; - printf("SET BTCTXID.(%s)\n",bits256_str(str,srcbp->btctxid)); - } - } - if ( destbp->state == 0xffffffff && bits256_nonz(srcbp->btctxid) != 0 ) - { - if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) - { - printf("abort ht.%d due to new checkpoint.%d\n",checkpoint.blockhash.height,dp->checkpoint.blockhash.height); - break; - } - if ( srcbp->state != 0xffffffff ) - { - //printf("dp->ht.%d ht.%d SRC.%08x %s\n",dp->checkpoint.blockhash.height,checkpoint.blockhash.height,srcbp->state,bits256_str(str,srcbp->btctxid)); - srcbp->state = dpow_statemachineiterate(myinfo,dp,src,srcbp,myind,0); - } - } - } - free(ptr); - } - uint64_t dpow_maskmin(uint64_t refmask,struct dpow_block *bp,int32_t *lastkp) - { - int32_t j,m,k; uint64_t mask = 0; - for (j=m=0; jnumnotaries; j++) - { - k = ((bp->height % bp->numnotaries) + j) % bp->numnotaries; - if ( bits256_nonz(bp->notaries[k].prev_hash) != 0 ) - { - mask |= (1LL << k); - if ( ++m >= DPOW_M(bp) ) - { - *lastkp = k; - break; - } - } - } - return(mask); - } - - - int32_t dpow_dsigs_match(struct dpow_entry notaries[DPOW_MAXRELAYS],int32_t numnotaries,struct dpow_sigentry *dsigs,int32_t num,int32_t refk,uint64_t refmask,int32_t refheight) - { - struct dpow_sigentry dsig; int32_t i,senderind,matches = 0; - for (i=0; i= 0 && dsig.lastk == refk && dsig.mask == refmask ) - { - if ( (notaries[senderind].siglen= dsig.siglen) < sizeof(notaries[senderind].sig) ) - { - notaries[senderind].k = refk; - notaries[senderind].mask = refmask; - notaries[senderind].beacon = dsig.beacon; - memcpy(notaries[senderind].sig,dsig.sig,dsig.siglen); - int32_t j; for (j=0; j 0 ) - printf(" <- sender.%d siglen.%d\n",i,dsig.siglen); - matches++; - } - } else printf("skip senderind.%d numnotaries.%d lastk.%d refk.%d mask.%llx refmask.%llx refheight.%d\n",senderind,numnotaries,dsig.lastk,refk,(long long)dsig.mask,(long long)refmask,refheight); - } - //printf("matches.%d num.%d k.%d %llx refht.%d\n",matches,num,refk,(long long)refmask,refheight); - return(matches); - } - - /*int32_t komodo_blockindexcheck(CBlockIndex *pindex,uint32_t *nBitsp) - { - // 1 -> valid notary block, change nBits to KOMODO_MINDIFF_NBITS - // -1 -> invalid, ie, prior to notarized block - CBlock block; int32_t i,height; char *coinbasestr; - if ( pindex == 0 ) - return(0); - if ( ReadBlockFromDisk(block,pindex,1) == 0 ) - return(0); - if ( block.vtx.size() > 0 ) - { - height = pindex->nHeight; - coinbasestr = (char *)block.vtx[0].vout[0].scriptPubKey.ToString().c_str(); - for (i=0; i<64; i++) - { - if ( Notaries[i][0] == 0 || Notaries[i][1] == 0 || Notaries[i][0][0] == 0 || Notaries[i][1][0] == 0 ) - break; - if ( strncmp(Notaries[i][1],coinbasestr,66) == 0 ) - { - //printf("Notary.[%d] %s ht.%d (%s)\n",i,Notaries[i][0],height,coinbasestr); - //*nBitsp = KOMODO_MINDIFF_NBITS; - return(1); - } - } - } - // compare against elected notary pubkeys as of height - return(0); - } - - int32_t komodo_is_notaryblock(CBlockHeader& blockhdr) - { - //uint32_t nBits = 0; - //return(komodo_blockindexcheck(mapBlockIndex[blockhdr.GetHash()],&nBits)); - return(0); - } - - int32_t komodo_blockhdrcheck(CBlockHeader& blockhdr,uint32_t *nBitsp) - { - int32_t retval; - if ( (retval= komodo_is_notaryblock(blockhdr)) > 0 ) - *nBitsp = KOMODO_MINDIFF_NBITS; - return(retval); - } - - int32_t komodo_blockcheck(CBlock& block,uint32_t *nBitsp) - { - return(komodo_blockhdrcheck(block,nBitsp)); - }*/ - if ( (retstr= komodo_issuemethod((char *)"listtransactions",0,7771)) != 0 ) - { - //printf("LIST.(%s)\n",retstr); - if ( (listobj= cJSON_Parse(retstr)) != 0 ) - { - if ( (array= jarray(&num,listobj,(char *)"result")) != 0 ) - { - for (i=0; ihh.next; - while ( pax != 0 && pax != tmp && n++ < 1000000 ) - { - printf("PAX.[%p %p] pax.%p marked.%d fiat %.8f KMD %.8f\n",PAX->hh.next,PAX->hh.prev,pax,pax->marked,dstr(pax->fiatoshis),dstr(pax->komodoshis)); - if ( pax->marked == 0 ) - { - if ( komodo_is_issuer() != 0 ) - total += pax->fiatoshis; - else total += pax->komodoshis; - } - tmp = pax; - pax = (struct pax_transaction *)pax->hh.next; - } - } - pthread_mutex_unlock(&komodo_mutex); - if ( n >= 1000000 ) - printf("komodo_paxtotal n.%d iterations?\n",n);*/ - void dpow_sync(struct supernet_info *myinfo,int32_t forceflag,struct dpow_info *dp,struct dpow_block *bp,int8_t bestk,uint64_t refmask,int32_t myind,bits256 srchash,int32_t src_or_dest) - { - int8_t lastk; uint64_t mask; - if ( bestk < 0 ) - mask = dpow_maskmin(refmask,bp,&lastk); - else - { - lastk = bestk; - mask = refmask; - } - //dpow_utxosync(myinfo,bp,mask,myind,srchash); - if ( forceflag || bp->notaries[myind].masks[lastk] == 0 ) - { - //printf("dpow sync update signedtxgen\n"); - dpow_signedtxgen(myinfo,dp,(src_or_dest != 0) ? bp->destcoin : bp->srccoin,bp,lastk,mask,myind,src_or_dest != 0 ? DPOW_SIGBTCCHANNEL : DPOW_SIGCHANNEL,src_or_dest,0); - } - } - /*if ( channel == DPOW_ENTRIESCHANNEL ) - { - struct dpow_entry notaries[DPOW_MAXRELAYS]; uint8_t n; int8_t bestk; struct dpow_coinentry *ptr,*refptr; - rlen = 0; - bestk = data[rlen++]; - n = data[rlen++]; - rlen += iguana_rwbignum(0,&data[rlen],sizeof(hashmsg),hashmsg.bytes); - //printf("got ENTRIES bestk.%d (%d %llx) recv.%llx numnotaries.%d\n",bestk,bp->bestk,(long long)bp->bestmask,(long long)bp->recvmask,n); - if ( bits256_cmp(hashmsg,bp->hashmsg) == 0 ) - { - memset(notaries,0,sizeof(notaries)); - for (i=0; i<64; i++) - notaries[i].bestk = -1; - rlen += dpow_rwcoinentrys(0,&data[rlen],notaries,n,bestk); - //printf("matched hashmsg rlen.%d vs datalen.%d\n",rlen,datalen); - for (i=0; inotaries[i].dest : &bp->notaries[i].src; - if ( bits256_nonz(ptr->prev_hash) != 0 ) - { - if ( bits256_nonz(refptr->prev_hash) == 0 ) - { - printf(">>>>>>>>> %s got utxo.[%d] indirectly <<<<<<<<<<<\n",iter!=0?"dest":"src",i); - refptr->prev_hash = ptr->prev_hash; - refptr->prev_vout = ptr->prev_vout; - if ( iter == 1 && bits256_nonz(notaries[i].src.prev_hash) != 0 ) - bp->recvmask |= (1LL << i); - } - } - if ( (bestk= notaries[i].bestk) >= 0 ) - { - if ( ptr->siglens[bestk] > 0 && refptr->siglens[bestk] == 0 ) - { - printf(">>>>>>>>>> got %s siglen.%d for [%d] indirectly bestk.%d <<<<<<<<<<\n",iter!=0?"dest":"src",ptr->siglens[bestk],i,bestk); - memcpy(refptr->sigs[bestk],ptr->sigs[bestk],ptr->siglens[bestk]); - refptr->siglens[bestk] = ptr->siglens[bestk]; - if ( iter != 0 ) - bp->destsigsmasks[bestk] |= (1LL << i); - else bp->srcsigsmasks[bestk] |= (1LL << i); - } - } - } - } - } - } - else if ( channel == DPOW_UTXOCHANNEL ) - { - src_or_dest = 1; - coin = (src_or_dest != 0) ? bp->destcoin : bp->srccoin; - memset(&U,0,sizeof(U)); - if ( dpow_rwutxobuf(0,data,&U,bp) < 0 ) - { - printf("error from rwutxobuf\n"); - return(0); - } - if ( bits256_cmp(U.hashmsg,bp->hashmsg) != 0 && bits256_nonz(bp->hashmsg) != 0 ) - { - printf("unexpected mismatch hashmsg.%s vs %s\n",bits256_str(str,U.hashmsg),bits256_str(str2,bp->hashmsg)); - return(0); - } - if ( (ep= dpow_notaryfind(myinfo,bp,height,&senderind,U.pubkey)) != 0 ) - { - dpow_utxo2entry(bp,ep,&U); - if ( ((1LL << senderind) & bp->recvmask) == 0 ) - { - dpow_utxosync(myinfo,dp,bp,0,myind,srchash); - bp->recvmask |= (1LL << senderind); - } - dpow_sync(myinfo,0,dp,bp,-1,ep->recvmask,myind,srchash,src_or_dest); - flag = 1; - } - //printf("bestk.%d %llx vs recv.%llx\n",bp->bestk,(long long)bp->bestmask,(long long)bp->recvmask); - if ( 0 && flag == 0 && bp != 0 ) - printf("ep.%p sender.%d UTXO.%d hashmsg.(%s) txid.(%s) v%d %llx\n",ep,senderind,height,bits256_str(str,U.hashmsg),bits256_str(str2,src_or_dest!=0?U.desthash:U.srchash),src_or_dest!=0?U.destvout:U.srcvout,(long long)bp->recvmask); - } - else if ( channel == DPOW_SIGCHANNEL || channel == DPOW_SIGBTCCHANNEL ) - { - if ( dpow_rwsigentry(0,data,&dsig) < 0 ) - { - printf("rwsigentry error\n"); - return(0); - } - //printf("got sig.%x (%d %d) <<<<<<<<<< from.%d (%d %llx) sigs.%llx\n",channel,channel == DPOW_SIGCHANNEL,channel == DPOW_SIGBTCCHANNEL,dsig.senderind,dsig.lastk,(long long)dsig.mask,(long long)(dsig.lastk>=0?bp->destsigsmasks[dsig.lastk]:0)); - if ( channel == DPOW_SIGBTCCHANNEL ) - { - src_or_dest = 1; - coin = bp->destcoin; - cp = &bp->notaries[dsig.senderind].dest; - //printf("gotsig %s channel.%x from %d bestk.%d %llx\n",coin->symbol,channel,dsig.senderind,dsig.lastk,(long long)dsig.mask); - } - else - { - src_or_dest = 0; - coin = bp->srccoin; - cp = &bp->notaries[dsig.senderind].src; - } - if ( dsig.senderind >= 0 && dsig.senderind < DPOW_MAXRELAYS ) - { - if ( dsig.lastk < bp->numnotaries && dsig.senderind < bp->numnotaries && (ep= dpow_notaryfind(myinfo,bp,height,&senderind,dsig.senderpub)) != 0 ) - { - vcalc_sha256(0,commit.bytes,dsig.beacon.bytes,sizeof(dsig.beacon)); - if ( memcmp(dsig.senderpub,bp->notaries[dsig.senderind].pubkey,33) == 0 ) - { - //if ( ep->masks[dsig.lastk] == 0 ) - { - ep->masks[src_or_dest][dsig.lastk] = dsig.mask; - cp->siglens[dsig.lastk] = dsig.siglen; - memcpy(cp->sigs[dsig.lastk],dsig.sig,dsig.siglen); - ep->beacon = dsig.beacon; - if ( src_or_dest != 0 ) - { - bp->destsigsmasks[dsig.lastk] |= (1LL << dsig.senderind); - if ( bp->bestk >= 0 && bp->bestk == dsig.lastk && (bp->bestmask & bp->destsigsmasks[dsig.lastk]) == bp->bestmask ) - { - dpow_sigscheck(myinfo,dp,bp,DPOW_SIGBTCCHANNEL,myind,1); - } - } - else - { - bp->srcsigsmasks[dsig.lastk] |= (1LL << dsig.senderind); - if ( bp->bestk >= 0 && bp->bestk == dsig.lastk && (bp->bestmask & bp->srcsigsmasks[dsig.lastk]) == bp->bestmask ) - { - dpow_sigscheck(myinfo,dp,bp,DPOW_SIGCHANNEL,myind,0); - } - } - //printf(" ht.%d (%d %llx) <<<<<<<< %s from.%d got lastk.%d %llx/%llx siglen.%d >>>>>>>>>\n",bp->height,bp->bestk,(long long)bp->bestmask,coin->symbol,dsig.senderind,dsig.lastk,(long long)dsig.mask,(long long)bp->destsigsmasks[dsig.lastk],dsig.siglen); - dpow_sync(myinfo,1,dp,bp,dsig.lastk,dsig.mask,myind,srchash,src_or_dest); - flag = 1; - } - } else printf("%s pubkey mismatch for senderind.%d %llx vs %llx\n",coin->symbol,dsig.senderind,*(long long *)dsig.senderpub,*(long long *)bp->notaries[dsig.senderind].pubkey); - } else printf("%s illegal lastk.%d or senderind.%d or senderpub.%llx\n",coin->symbol,dsig.lastk,dsig.senderind,*(long long *)dsig.senderpub); - } else printf("couldnt find senderind.%d height.%d channel.%x\n",dsig.senderind,height,channel); - //if ( 0 && bp != 0 ) - // printf("%s SIG.%d sender.%d lastk.%d mask.%llx siglen.%d recv.%llx\n",coin->symbol,height,dsig.senderind,dsig.lastk,(long long)dsig.mask,dsig.siglen,(long long)bp->recvmask); - } - else*/ - int32_t dpow_update(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint32_t txidchannel,bits256 srchash,int32_t myind) - { - struct dpow_entry *ep; int32_t i,k,len,src_or_dest,sendutxo = 0; uint8_t data[sizeof(struct dpow_entry)+2]; struct dpow_utxoentry U; - ep = &bp->notaries[myind]; - if ( bp->state < 1000 ) - { - src_or_dest = 1; - bp->bestmask = dpow_maskmin(bp->recvmask,bp,&bp->bestk); - if ( bp->bestk >= 0 ) - { - sendutxo = 0; - for (i=0; inumnotaries; i++) - { - k = DPOW_MODIND(bp,i); - if ( k == myind ) - continue; - if ( ((1LL << k) & bp->recvmask) != 0 && (bp->notaries[k].recvmask & (1LL << myind)) == 0 ) - { - //printf("other notary.%d doesnt have our.%d utxo yet\n",k,myind); - sendutxo = 1; - break; - } - } - if ( ep->masks[src_or_dest][bp->bestk] == 0 ) - { - //printf("dpow update signedtxgen\n"); - dpow_signedtxgen(myinfo,dp,(src_or_dest != 0) ? bp->destcoin : bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGBTCCHANNEL,src_or_dest,0); - } - if ( bp->bestk >= 0 && (rand() % 10) == 0 ) - dpow_sigsend(myinfo,dp,bp,myind,bp->bestk,bp->bestmask,srchash,DPOW_SIGBTCCHANNEL); - } else sendutxo = 1; - if ( sendutxo != 0 ) - { - memset(&U,0,sizeof(U)); - dpow_entry2utxo(&U,bp,&bp->notaries[myind]); - if ( (len= dpow_rwutxobuf(1,data,&U,bp)) > 0 ) - dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,DPOW_UTXOCHANNEL,bp->height,data,len); - } - if ( bp->bestk >= 0 && ep->masks[src_or_dest][bp->bestk] == 0 ) - { - //printf("dpow update2 signedtxgen\n"); - dpow_signedtxgen(myinfo,dp,(src_or_dest != 0) ? bp->destcoin : bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGBTCCHANNEL,src_or_dest,0); - } - if ( bp->bestk >= 0 && (rand() % 10) == 0 ) - { - dpow_sigsend(myinfo,dp,bp,myind,bp->bestk,bp->bestmask,srchash,DPOW_SIGBTCCHANNEL); - for (i=0; inumnotaries; i++) - if ( bp->notaries[i].bestk >= 0 && bp->notaries[i].bestk != bp->bestk && bitweight(bp->notaries[i].recvmask & bp->recvmask) >= 7 ) - dpow_sigsend(myinfo,dp,bp,myind,bp->notaries[i].bestk,bp->recvmask,srchash,DPOW_SIGBTCCHANNEL); - } - } - else if ( bp->state != 0xffffffff ) - { - src_or_dest = 0; - if ( bp->bestk >= 0 && ep->masks[src_or_dest][bp->bestk] == 0 ) - { - //printf("dpow update src signedtxgen\n"); - dpow_signedtxgen(myinfo,dp,(src_or_dest != 0) ? bp->destcoin : bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGCHANNEL,src_or_dest,0); - } - if ( bp->bestk >= 0 && (rand() % 10) == 0 ) - dpow_sigsend(myinfo,dp,bp,myind,bp->bestk,bp->bestmask,srchash,DPOW_SIGCHANNEL); - } - if ( (rand() % 20) == 0 ) - { - if ( bp->isratify != 0 ) - { - uint64_t sigsmask,srcmask; - if ( bp->bestk < 0 ) - sigsmask = srcmask = 0; - else sigsmask = bp->destsigsmasks[bp->bestk], srcmask = bp->srcsigsmasks[bp->bestk]; - printf("notary[%d] %s numips.%d isratify.%d ht.%d FSM.%08x masks.%llx best.(%d %llx) sigsmask.%llx %llx src.%llx\n",myind,src_or_dest != 0 ? bp->destcoin->symbol : bp->srccoin->symbol,myinfo->numdpowipbits,bp->isratify,bp->height,bp->state,(long long)bp->recvmask,bp->bestk,(long long)bp->bestmask,(long long)sigsmask,(long long)(sigsmask & bp->bestmask),(long long)srcmask); - } - if ( bp->isratify != 0 ) - { - bp->bestmask = dpow_maskmin(bp->recvmask,bp,&bp->bestk); - dpow_sendcoinentrys(myinfo,dp,bp); - if ( bp->bestk >= 0 ) - { - //printf("dpow update ratify signedtxgen\n"); - dpow_signedtxgen(myinfo,dp,(bp->state < 1000) ? bp->destcoin : bp->srccoin,bp,bp->bestk,bp->bestmask,myind,bp->state < 1000 ? DPOW_SIGBTCCHANNEL : DPOW_SIGCHANNEL,bp->state < 1000,0); - } - printf("ht.%d numnotaries.%d BEST.%llx from RECV.%llx bestk.%d sigsmask.%llx missing.%llx\n",bp->height,bp->numnotaries,(long long)bp->bestmask,(long long)bp->recvmask,bp->bestk,bp->bestk>=0?(long long)bp->destsigsmasks[bp->bestk]:0,bp->bestk>=0?(long long)(bp->bestmask & ~bp->destsigsmasks[bp->bestk]):0); - if ( bp->height < DPOW_FIRSTRATIFY ) - dp->blocks[bp->height] = bp; - } - } - if ( bp->state < 1000 && bp->bestk >= 0 && (bp->destsigsmasks[bp->bestk] & bp->bestmask) == bp->bestmask ) - { - dpow_sigscheck(myinfo,dp,bp,myind,1); - } - else if ( bp->state != 0xffffffff && bp->bestk >= 0 && (bp->srcsigsmasks[bp->bestk] & bp->bestmask) == bp->bestmask ) - { - dpow_sigscheck(myinfo,dp,bp,myind,0); - } - return(bp->state); - } - - uint32_t dpow_statemachineiterate(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,struct dpow_block *bp,int32_t myind,int32_t src_or_dest) - { - int32_t j,incr; char *opret_symbol,coinaddr[64]; uint32_t channel,sigchannel,txidchannel; bits256 srchash,zero; - if ( 0 && bp->numnotaries > 8 ) - incr = sqrt(bp->numnotaries) + 1; - else incr = 1; - memset(zero.bytes,0,sizeof(zero)); - channel = DPOW_UTXOCHANNEL; - if ( bits256_nonz(bp->desttxid) == 0 ) - { - sigchannel = DPOW_SIGBTCCHANNEL; - txidchannel = DPOW_BTCTXIDCHANNEL; - opret_symbol = ""; - } - else - { - sigchannel = DPOW_SIGCHANNEL; - txidchannel = DPOW_TXIDCHANNEL; - opret_symbol = dp->symbol; - } - bitcoin_address(coinaddr,coin->chain->pubtype,dp->minerkey33,33); - if ( bits256_nonz(bp->hashmsg) == 0 && bp->height >= DPOW_FIRSTRATIFY ) - { - printf("null hashmsg\n"); - return(0); - } - for (j=0; jminerkey33[j+1]; - bp->bestk = dpow_bestk(bp,&bp->bestmask); - if ( bp->state < 7 ) - { - dpow_utxosync(myinfo,dp,bp,0,myind,srchash); - bp->state++; - } - else - { - dpow_update(myinfo,dp,bp,txidchannel,srchash,myind); - if ( bits256_nonz(bp->srctxid) != 0 ) - bp->state = 0xffffffff; - } - return(bp->state); - } - /*int32_t dpow_voutratify(struct dpow_block *bp,uint8_t *serialized,int32_t m,uint8_t pubkeys[][33],int32_t numratified) - { - uint64_t satoshis; uint32_t locktime = 0; uint32_t numvouts; int32_t i,len = 0; - numvouts = numratified + 1; - len += iguana_rwvarint32(1,&serialized[len],&numvouts); - satoshis = DPOW_UTXOSIZE; - len += iguana_rwnum(1,&serialized[len],sizeof(satoshis),&satoshis); - serialized[len++] = 35; - serialized[len++] = 33; - decode_hex(&serialized[len],33,CRYPTO777_PUBSECPSTR), len += 33; - serialized[len++] = CHECKSIG; - satoshis = DPOW_MINOUTPUT; - for (i=0; iprev_hash),src->prev_hash.bytes); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(src->prev_vout),(uint32_t *)&src->prev_vout); - len += iguana_rwbignum(rwflag,&serialized[len],sizeof(dest->prev_hash),dest->prev_hash.bytes); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(dest->prev_vout),(uint32_t *)&dest->prev_vout); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(*bestkp),(uint32_t *)bestkp); - if ( (bestk= *bestkp) >= 0 ) - { - for (iter=0; iter<2; iter++) - { - ptr = (iter == 0) ? src : dest; - len += iguana_rwnum(rwflag,&serialized[len],sizeof(ptr->siglens[bestk]),(uint32_t *)&ptr->siglens[bestk]); - if ( (siglen= ptr->siglens[bestk]) > 0 ) - { - if ( rwflag != 0 ) - memcpy(&serialized[len],ptr->sigs[bestk],siglen); - else memcpy(ptr->sigs[bestk],&serialized[len],siglen); - len += siglen; - } - } - } - return(len); - } - - int32_t dpow_rwcoinentrys(int32_t rwflag,uint8_t *serialized,struct dpow_entry notaries[DPOW_MAXRELAYS],uint8_t numnotaries,int8_t bestk) - { - int32_t i,len = 0; - for (i=0; i>>>>>>>>>>>> dpow_sendcoinentrys (%d %llx) <- %llx\n",bp->height,bp->bestk,(long long)bp->bestmask,(long long)bp->recvmask); - data[len++] = bp->bestk; - data[len++] = bp->numnotaries; - len += iguana_rwbignum(1,&data[len],sizeof(bp->hashmsg),bp->hashmsg.bytes); - len += dpow_rwcoinentrys(1,&data[len],bp->notaries,bp->numnotaries,bp->bestk); - dpow_send(myinfo,dp,bp,zero,bp->hashmsg,DPOW_ENTRIESCHANNEL,bp->height,data,len); - return(len); - } - - int32_t dpow_rwutxobuf(int32_t rwflag,uint8_t *data,struct dpow_utxoentry *up,struct dpow_block *bp) - { - uint8_t numnotaries; uint64_t othermask; int32_t i,len = 0; - len += iguana_rwbignum(rwflag,&data[len],sizeof(up->hashmsg),up->hashmsg.bytes); - len += iguana_rwbignum(rwflag,&data[len],sizeof(up->srchash),up->srchash.bytes); - len += iguana_rwbignum(rwflag,&data[len],sizeof(up->desthash),up->desthash.bytes); - if ( bits256_nonz(up->srchash) == 0 || bits256_nonz(up->desthash) == 0 ) - { - printf("dpow_rwutxobuf null src.%d or dest.%d\n",bits256_nonz(up->srchash),bits256_nonz(up->desthash)); - return(-1); - } - len += iguana_rwbignum(rwflag,&data[len],sizeof(up->commit),up->commit.bytes); - len += iguana_rwnum(rwflag,&data[len],sizeof(up->recvmask),(uint8_t *)&up->recvmask); - len += iguana_rwnum(rwflag,&data[len],sizeof(up->height),(uint8_t *)&up->height); - len += iguana_rwnum(rwflag,&data[len],sizeof(up->srcvout),&up->srcvout); - len += iguana_rwnum(rwflag,&data[len],sizeof(up->destvout),&up->destvout); - len += iguana_rwnum(rwflag,&data[len],sizeof(up->bestk),&up->bestk); - if ( rwflag != 0 ) - { - for (i=0; i<33; i++) - data[len++] = up->pubkey[i]; - data[len++] = bp->numnotaries; - for (i=0; inumnotaries; i++) - len += iguana_rwnum(rwflag,&data[len],sizeof(*up->othermasks),(uint8_t *)&up->othermasks[(int32_t)i]); - } - else - { - for (i=0; i<33; i++) - up->pubkey[i] = data[len++]; - numnotaries = data[len++]; - if ( numnotaries <= bp->numnotaries ) - { - for (i=0; inotaries[(int32_t)i].othermask |= othermask; - } - } else return(-1); - } - return(len); - } - /*void dpow_utxosync(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint64_t recvmask,int32_t myind,bits256 srchash) - { - uint32_t i,j,r; int32_t len; struct dpow_utxoentry U; uint8_t utxodata[sizeof(U)+2]; - if ( (bp->recvmask ^ recvmask) != 0 ) - { - if ( ((1LL << myind) & recvmask) == 0 ) - { - i = myind; - //printf("utxosync bp->%llx != %llx, myind.%d\n",(long long)bp->recvmask,(long long)recvmask,myind); - } - else - { - r = (rand() % bp->numnotaries); - for (j=0; jnumnotaries; j++) - { - i = DPOW_MODIND(bp,j+r); - if ( ((1LL << i) & bp->recvmask) != 0 && ((1LL << i) & recvmask) == 0 ) - break; - } - //printf("utxosync bp->%llx != %llx, random pick.%d\n",(long long)bp->recvmask,(long long)recvmask,i); - } - memset(&U,0,sizeof(U)); - dpow_entry2utxo(&U,bp,&bp->notaries[i]); - //char str[65],str2[65]; - //printf("send.(%s %s)\n",bits256_str(str,bp->notaries[i].dest.prev_hash),bits256_str(str2,bp->notaries[i].src.prev_hash)); - if ( (len= dpow_rwutxobuf(1,utxodata,&U,bp)) > 0 ) - dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,DPOW_UTXOCHANNEL,bp->height,utxodata,len); - } - }*/ - - /*else if ( strcmp(dp->symbol,"KMD") == 0 ) - { - bp->bestk = -1; - bp->bestmask = 0; - bp->height = ((dp->checkpoint.blockhash.height / 10) % (DPOW_FIRSTRATIFY/10)) * 10; - printf("new rotation ht.%d\n",bp->height); - dp->blocks[checkpoint.blockhash.height] = 0; - checkpoint.blockhash.height = dp->checkpoint.blockhash.height; - dp->blocks[checkpoint.blockhash.height] = bp; - }*/ - - /*if ( Minerids[height] >= -1 ) - { - printf("cached[%d] -> %d\n",height,Minerids[height]); - return(Minerids[height]); - } - if ( depth < 1 ) - { - if ( (pindex= chainActive[height]) != 0 ) - { - depth++; - komodo_index2pubkey33(pubkey33,pindex,height); - komodo_chosennotary(¬aryid,height,pubkey33); - if ( notaryid >= -1 ) - { - Minerids[height] = notaryid; - if ( Minerfp != 0 ) - { - fseek(Minerfp,height,SEEK_SET); - fputc(Minerids[height],Minerfp); - fflush(Minerfp); - } - } - depth--; - return(notaryid); - } - } - return(-2);*/ - if ( Minerids[height-i] == -2 ) - { - Minerids[height-i] = komodo_minerid(height-i); - if ( Minerids[height - i] == -2 ) - { - fprintf(stderr,"second -2 for Minerids[%d] current.%d\n",height-i,height); - return(-2); - } - } - if ( Minerids[height-i] == notaryid ) - return(-1); - /*if ( i == 0 && j == 0 && komodo_chosennotary(&nid,height,scriptbuf + 1) >= 0 ) - { - if ( height < sizeof(Minerids)/sizeof(*Minerids) ) - { - if ( (Minerids[height]= nid) >= -1 ) - { - if ( Minerfp != 0 ) - { - fseek(Minerfp,height,SEEK_SET); - fputc(Minerids[height],Minerfp); - fflush(Minerfp); - } - } - } - }*/ - uint8_t pubkeys[64][33]; - if ( pindex->nHeight > 73673 && komodo_notaries(pubkeys,76000) == 35 ) - { - static int32_t didinit; - if ( didinit == 0 ) - { - if ( (pindex= chainActive[73673]) != 0 ) - { - komodo_connectpindex(pindex); - } - didinit = 73673; - } - } - if ( i != 0 && notaryid >= 0 && notaryid < 64 && voutmask != 0 ) - { - //komodo_stateupdate(height,0,0,notaryid,txhash,voutmask,numvouts,0,0,0,0,0,0,0); - } - - /*if ( (k= komodo_nutxofind(height,block.vtx[i].vin[j].prevout.hash,block.vtx[i].vin[j].prevout.n)) >= 0 ) - signedmask |= (1LL << k); - else if ( signedmask != 0 ) - printf("signedmask.%llx but ht.%d i.%d j.%d not found (%s %d)\n",(long long)signedmask,height,i,j,block.vtx[i].vin[j].prevout.hash.ToString().c_str(),block.vtx[i].vin[j].prevout.n);*/ - /*memset(Minerids,0xfe,sizeof(Minerids)); - if ( (Minerfp= fopen(fname2,"rb+")) == 0 ) - { - if ( (Minerfp= fopen(fname2,"wb")) != 0 ) - { - fwrite(Minerids,1,sizeof(Minerids),Minerfp); - fclose(Minerfp); - } - Minerfp = fopen(fname2,"rb+"); - } - if ( Minerfp != 0 && fread(Minerids,1,sizeof(Minerids),Minerfp) != sizeof(Minerids) ) - printf("read error Minerids\n");*/ - /*#define issue_curl2(cmdstr) bitcoind_RPC(0,(char *)"curl",(char *)"http://127.0.0.1:7778",0,0,(char *)(cmdstr)) - - void komodo_iteration(char *symbol) - { - char *retstr,*base,*coinaddr,*txidstr,cmd[512]; uint64_t value,fiatoshis; cJSON *array,*item; int32_t i,n,vout,shortflag,height,fiatheight; bits256 txid; uint8_t rmd160[20],addrtype; - //if ( ASSETCHAINS_SYMBOL[0] == 0 ) - { - sprintf(cmd,"{\"agent\":\"dpow\",\"method\":\"pending\",\"fiat\":\"%s\"}",symbol); - if ( (retstr= issue_curl2(cmd)) != 0 ) - { - if ( (array= cJSON_Parse(retstr)) != 0 ) - { - if ( (n= cJSON_GetArraySize(array)) > 0 ) - { - for (i=0; i 0 && height > 0 ) - { - fiatoshis = jdouble(item,base) * SATOSHIDEN; - decode_hex((uint8_t *)&txid,sizeof(txid),txidstr); - bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); - //komodo_gateway_deposit(coinaddr,value,shortflag,base,fiatoshis,rmd160,txid,vout,height,fiatheight); - } - } - } - } - printf("retstr.(%s)\n",retstr); - free(retstr); - } - } - }*/ - /*void komodo_nutxoadd(int32_t height,int32_t notaryid,uint256 txhash,uint64_t voutmask,int32_t numvouts) - { - struct nutxo_entry *np; - if ( numvouts > 1 && notaryid < 64 ) - { - pthread_mutex_lock(&komodo_mutex); - np = (struct nutxo_entry *)calloc(1,sizeof(*np)); - np->height = height; - np->txhash = txhash; - np->voutmask = voutmask; - np->notaryid = notaryid; - HASH_ADD_KEYPTR(hh,NUTXOS,&np->txhash,sizeof(np->txhash),np); - //printf("Add NUTXO[%d] <- %s notaryid.%d t%u %s %llx\n",Num_nutxos,Notaries[notaryid][0],notaryid,komodo_txtime(txhash),txhash.ToString().c_str(),(long long)voutmask); - Num_nutxos++; - pthread_mutex_unlock(&komodo_mutex); - } - } - - int32_t komodo_nutxofind(int32_t height,uint256 txhash,int32_t vout) - { - struct nutxo_entry *np; - pthread_mutex_lock(&komodo_mutex); - HASH_FIND(hh,NUTXOS,&txhash,sizeof(txhash),np); - pthread_mutex_unlock(&komodo_mutex); - if ( np != 0 && ((1LL << vout) & np->voutmask) != 0 ) - return(np->notaryid); - return(-1); - }*/ - - /*void komodo_eventadd_utxo(struct komodo_state *sp,char *symbol,int32_t height,uint8_t notaryid,uint256 txid,uint64_t voutmask,uint8_t numvouts) - { - struct komodo_event_utxo U; - memset(&U,0,sizeof(U)); - U.txid = txid; - U.voutmask = voutmask; - U.numvouts = numvouts; - komodo_eventadd(height,symbol,KOMODO_EVENT_UTXO,(uint8_t *)&U,sizeof(U)); - if ( sp != 0 ) - komodo_nutxoadd(height,notaryid,txid,voutmask,numvouts); - }*/ - /*if ( didinit == 0 ) - { - for (baseid=0; baseid<=32; baseid++) - komodo_userpass(userpass[baseid],CURRENCIES[baseid]); - didinit = 1; - }*/ - /*if ( (retstr= komodo_issuemethod(userpass[baseid],(char *)"getinfo",0,port)) != 0 ) - { - if ( (infoobj= cJSON_Parse(retstr)) != 0 ) - { - if ( (result= jobj(infoobj,(char *)"result")) != 0 ) - { - blocks = juint(result,(char *)"blocks"); - longest = juint(result,(char *)"longestchain"); - //printf("%s.(%d L%d) ",base,blocks,longest); - if ( blocks > 0 && blocks == longest ) - isrealtime = 1; - } - free_json(infoobj); - } - else printf("[%s] %s (%s)\n",ASSETCHAINS_SYMBOL,base,retstr); - free(retstr); - } // else printf("%s port.%u no getinfo\n",base,port);*/ -#ifdef pollmethod - void komodo_gateway_voutupdate(char *symbol,int32_t isspecial,int32_t height,int32_t txi,bits256 txid,int32_t vout,int32_t numvouts,uint64_t value,uint8_t *script,int32_t len) - { - int32_t i,opretlen,offset = 0; uint256 zero,utxid; const char *typestr; - typestr = "unknown"; - memcpy(&utxid,&txid,sizeof(utxid)); - if ( script[offset++] == 0x6a ) - { - offset += komodo_scriptitemlen(&opretlen,&script[offset]); - if ( isspecial != 0 && len >= offset+32*2+4 && strcmp((char *)&script[offset+32*2+4],ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL) == 0 ) - typestr = "notarized"; - else if ( txi == 0 && vout == 1 && opretlen == 149 ) - { - typestr = "pricefeed"; - komodo_paxpricefeed(height,&script[offset],opretlen); - //printf("height.%d pricefeed len.%d\n",height,opretlen); - } - else komodo_stateupdate(height,0,0,0,utxid,0,0,0,0,0,0,value,&script[offset],opretlen,vout); - } - else if ( numvouts >= KOMODO_MINRATIFY ) - typestr = "ratify"; - } - - int32_t komodo_gateway_tx(char *symbol,int32_t height,int32_t txi,char *txidstr,uint32_t port) - { - char *retstr,params[256],*hexstr; uint8_t script[10000]; cJSON *oldpub,*newpub,*json,*result,*vouts,*item,*sobj; int32_t vout,n,len,isspecial,retval = -1; uint64_t value; bits256 txid; - sprintf(params,"[\"%s\", 1]",txidstr); - if ( (retstr= komodo_issuemethod((char *)"getrawtransaction",params,port)) != 0 ) - { - if ( (json= cJSON_Parse(retstr)) != 0 ) - { - if ( (result= jobj(json,(char *)"result")) != 0 ) - { - oldpub = jobj(result,(char *)"vpub_old"); - newpub = jobj(result,(char *)"vpub_new"); - retval = 0; - if ( oldpub == 0 && newpub == 0 && (vouts= jarray(&n,result,(char *)"vout")) != 0 ) - { - isspecial = 0; - txid = jbits256(result,(char *)"txid"); - for (vout=0; vout> 1; - if ( vout == 0 && ((memcmp(&hexstr[2],CRYPTO777_PUBSECPSTR,66) == 0 && len == 35) || (memcmp(&hexstr[6],CRYPTO777_RMD160STR,40) == 0 && len == 25)) ) - isspecial = 1; - else if ( len <= sizeof(script) ) - { - decode_hex(script,len,hexstr); - komodo_gateway_voutupdate(symbol,isspecial,height,txi,txid,vout,n,value,script,len); - } - } - } - } - } - } else printf("error getting txids.(%s) %p\n",retstr,result); - free_json(json); - } - free(retstr); - } - return(retval); - } - - int32_t komodo_gateway_block(char *symbol,int32_t height,uint16_t port) - { - char *retstr,*retstr2,params[128],*txidstr; int32_t i,n,retval = -1; cJSON *json,*tx=0,*result=0,*result2; - sprintf(params,"[%d]",height); - if ( (retstr= komodo_issuemethod((char *)"getblockhash",params,port)) != 0 ) - { - if ( (result= cJSON_Parse(retstr)) != 0 ) - { - if ( (txidstr= jstr(result,(char *)"result")) != 0 && strlen(txidstr) == 64 ) - { - sprintf(params,"[\"%s\"]",txidstr); - if ( (retstr2= komodo_issuemethod((char *)"getblock",params,port)) != 0 ) - { - //printf("getblock.(%s)\n",retstr2); - if ( (json= cJSON_Parse(retstr2)) != 0 ) - { - if ( (result2= jobj(json,(char *)"result")) != 0 && (tx= jarray(&n,result2,(char *)"tx")) != 0 ) - { - for (i=0; i= kmdheight ) - sp->KOMODO_REALTIME = (uint32_t)time(NULL); - } - free_json(infoobj); - } - free(retstr); - } - else - { - printf("error from %s\n",symbol); - sleep(30); - } - } - - void komodo_iteration(char *symbol) - { - char *retstr,*base,*coinaddr,*txidstr,cmd[512]; uint64_t value,fiatoshis; cJSON *array,*item; int32_t i,n,vout,shortflag,height,fiatheight; uint256 txid; uint8_t rmd160[20],addrtype; - if ( ASSETCHAINS_SYMBOL[0] == 0 ) - { - sprintf(cmd,"{\"agent\":\"dpow\",\"method\":\"pending\",\"fiat\":\"%s\"}",symbol); - if ( (retstr= issue_curl(cmd)) != 0 ) - { - if ( (array= cJSON_Parse(retstr)) != 0 ) - { - if ( (n= cJSON_GetArraySize(array)) > 0 ) - { - for (i=0; i 0 && height > 0 ) - { - fiatoshis = jdouble(item,base) * COIN; - decode_hex((uint8_t *)&txid,sizeof(txid),txidstr); - bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); - komodo_gateway_deposit(coinaddr,value,shortflag,base,fiatoshis,rmd160,txid,vout,height,fiatheight); - } - } - } - } - //printf("retstr.(%s)\n",retstr); - free(retstr); - } - } - } -#else - diff --git a/etomic_build/autoprice b/etomic_build/autoprice new file mode 100755 index 000000000..4ef086a75 --- /dev/null +++ b/etomic_build/autoprice @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"ETH\",\"rel\":\"KMD\",\"margin\":0.05,\"refbase\":\"ethereum\",\"refrel\":\"coinmarketcap\"}" diff --git a/etomic_build/buy b/etomic_build/buy new file mode 100755 index 000000000..379d03813 --- /dev/null +++ b/etomic_build/buy @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"buy\",\"base\":\"ETH\",\"rel\":\"KMD\",\"relvolume\":1,\"price\":300}" diff --git a/etomic_build/client b/etomic_build/client new file mode 100755 index 000000000..fb4f0c935 --- /dev/null +++ b/etomic_build/client @@ -0,0 +1,5 @@ +#!/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/coins b/etomic_build/coins new file mode 100755 index 000000000..988b79784 --- /dev/null +++ b/etomic_build/coins @@ -0,0 +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}]" +#, {\"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 new file mode 100755 index 000000000..0bcf62166 --- /dev/null +++ b/etomic_build/enable @@ -0,0 +1,5 @@ +#!/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\"}" diff --git a/etomic_build/orderbook b/etomic_build/orderbook new file mode 100755 index 000000000..dba91c284 --- /dev/null +++ b/etomic_build/orderbook @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"orderbook\",\"base\":\"ETH\",\"rel\":\"KMD\"}" diff --git a/etomic_build/passphrase b/etomic_build/passphrase new file mode 100644 index 000000000..eb00095d6 --- /dev/null +++ b/etomic_build/passphrase @@ -0,0 +1 @@ +export passphrase="" diff --git a/etomic_build/run b/etomic_build/run new file mode 100755 index 000000000..b757bb993 --- /dev/null +++ b/etomic_build/run @@ -0,0 +1,5 @@ +#!/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/setpassphrase b/etomic_build/setpassphrase new file mode 100755 index 000000000..b3df81427 --- /dev/null +++ b/etomic_build/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/stop b/etomic_build/stop new file mode 100755 index 000000000..d13a70243 --- /dev/null +++ b/etomic_build/stop @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"stop\"}" diff --git a/etomic_build/userpass b/etomic_build/userpass new file mode 100644 index 000000000..d097e0445 --- /dev/null +++ b/etomic_build/userpass @@ -0,0 +1,2 @@ +#export userpass="" +export userpass="c3d8c2a364b7d18c1f9d7321d017b92e9f9c791e4f5c741214fefdea8a071256" diff --git a/gecko/gecko_miner.c b/gecko/gecko_miner.c index 4e2628255..f7b3eb169 100755 --- a/gecko/gecko_miner.c +++ b/gecko/gecko_miner.c @@ -204,7 +204,7 @@ char *gecko_blockconstruct(struct supernet_info *myinfo,struct iguana_info *virt } if ( (coinbasestr= gecko_coinbasestr(myinfo,virt,&txids[0],newblock->RO.timestamp,minerpubkey,blockreward,coinbase,coinbaselen,coinbasespend)) != 0 ) { - newblock->RO.merkle_root = iguana_merkle(txids,txn_count + 1); + newblock->RO.merkle_root = iguana_merkle("GECKO",txids,txn_count + 1); newblock->RO.txn_count = (txn_count + 1); if ( txn_count > 0 ) { diff --git a/iguana/Kashi/json_extracta b/iguana/Kashi/json_extracta deleted file mode 100755 index a76453978..000000000 Binary files a/iguana/Kashi/json_extracta and /dev/null differ diff --git a/iguana/Readme.md b/iguana/Readme.md index 596952081..db6a82af2 100755 --- a/iguana/Readme.md +++ b/iguana/Readme.md @@ -191,3 +191,14 @@ struct iguana_account // 12 bytes uint64_t balance; uint32_t lastunspentind; } __attribute__((packed)); // pkind +# Cmake build of marketmaker with linked etomic lib for ETH/ERC20 atomic swaps: +1. Clone this repository. +1. `git checkout etomic` +1. `git submodule update --init --recursive` +1. `mkdir build` +1. `cd build` +1. `cmake ..` +1. `cmake --build . --target marketmaker` +1. `cd exchanges/iguana` +1. `export BOB_PK=YOUR_PRIVATE_KEY` +1. `./marketmaker` \ No newline at end of file diff --git a/iguana/acsplit b/iguana/acsplit new file mode 100755 index 000000000..6bf73d890 --- /dev/null +++ b/iguana/acsplit @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\""${1}"\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":"${2}"}" diff --git a/iguana/build_static_nanomsg.sh b/iguana/build_static_nanomsg.sh new file mode 100755 index 000000000..104025c79 --- /dev/null +++ b/iguana/build_static_nanomsg.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +#Check if libnanomsg-static.a file is already exists or not +if [[ "$OSTYPE" == "linux-gnu" ]]; then + echo "Linux" + file="../OSlibs/linux/$(uname -m)/libnanomsg-static.a" + makedir="../OSlibs/linux/$(uname -m)/" + copytarget="../OSlibs/linux/$(uname -m)/libnanomsg-static.a" +elif [[ "$OSTYPE" == "darwin"* ]]; then + # Mac OSX + echo "Mac OSX" + file="../OSlibs/osx/$(uname -m)/libnanomsg-static.a" + makedir="../OSlibs/osx/$(uname -m)/" + copytarget="../OSlibs/osx/$(uname -m)/libnanomsg-static.a" +fi + +if [ ! -f "$file" ] +then + echo "$0: File '${file}' not found." + #Download nanomsg library 1.0 stable + rm -rf nanomsgsrc + git clone https://github.com/nanomsg/nanomsg.git nanomsgsrc + + #Create destination folder + mkdir nanomsglib + + #Switch into nanomsgsrc folder + cd nanomsgsrc + + #Create build directory and switch into it + mkdir build && cd build + + #Compile + cmake .. -DCMAKE_INSTALL_PREFIX=../../nanomsglib/ -DCMAKE_BUILD_TYPE=Debug -DNN_STATIC_LIB=1 + cmake --build . + ctest -C Debug . + cmake --build . --target install + + cd ../.. + pwd + mkdir -p $makedir + cp -av nanomsglib/lib/libnanomsg.a $copytarget +fi + + diff --git a/iguana/coins/ninja_7776 b/iguana/coins/ninja_7776 new file mode 100755 index 000000000..a2426825a --- /dev/null +++ b/iguana/coins/ninja_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"NINJA.conf\",\"path\":\"${HOME#"/"}/.komodo/NINJA\",\"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\":\"NINJA\",\"name\":\"NINJA\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"78a7bd45\",\"p2p\":8426,\"rpc\":8427,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"192.241.134.19\"}" diff --git a/iguana/coins/oot_7776 b/iguana/coins/oot_7776 new file mode 100755 index 000000000..96fcc954b --- /dev/null +++ b/iguana/coins/oot_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"OOT.conf\",\"path\":\"${HOME#"/"}/.komodo/OOT\",\"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\":\"OOT\",\"name\":\"OOT\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"a75b4bad\",\"p2p\":12466,\"rpc\":12467,\"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/vote2018_7776 b/iguana/coins/vote2018_7776 new file mode 100755 index 000000000..07086b667 --- /dev/null +++ b/iguana/coins/vote2018_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"VOTE2018.conf\",\"path\":\"${HOME#"/"}/.komodo/VOTE2018\",\"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\":\"VOTE2018\",\"name\":\"VOTE2018\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"e6f918ae\",\"p2p\":15487,\"rpc\":15488,\"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/vote_7776 b/iguana/coins/vote_7776 new file mode 100755 index 000000000..1502351cf --- /dev/null +++ b/iguana/coins/vote_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"VOTE.conf\",\"path\":\"${HOME#"/"}/.komodo/VOTE\",\"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\":\"VOTE\",\"name\":\"VOTE\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"c29923dc\",\"p2p\":8011,\"rpc\":8012,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/dPoW.h b/iguana/dPoW.h index ba9e5c00e..7862fe36d 100755 --- a/iguana/dPoW.h +++ b/iguana/dPoW.h @@ -23,7 +23,7 @@ #define DPOW_MIN_ASSETCHAIN_SIGS 11 //#define DPOW_M(bp) ((bp)->minsigs) // (((bp)->numnotaries >> 1) + 1) #define DPOW_MODIND(bp,offset) (((((bp)->height / DPOW_CHECKPOINTFREQ) % (bp)->numnotaries) + (offset)) % (bp)->numnotaries) -#define DPOW_VERSION 0x0781 +#define DPOW_VERSION 0x1781 #define DPOW_UTXOSIZE 50000 #define DPOW_MINOUTPUT 6000 #define DPOW_DURATION 600 @@ -47,7 +47,7 @@ #define DPOW_MAXSIGLEN 128 #define DEX_VERSION 0x0105 -#define DPOW_SOCK 7775 +#define DPOW_SOCKPORT 7775 #define DEX_SOCK 7774 #define PUB_SOCK 7773 #define REP_SOCK 7772 @@ -104,12 +104,12 @@ struct dpow_checkpoint struct dpow_block { - bits256 hashmsg,desttxid,srctxid,beacon,commit; + bits256 hashmsg,desttxid,srctxid,beacon,commit,MoM; 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]; struct dpow_entry notaries[DPOW_MAXRELAYS]; - uint32_t state,starttime,timestamp,waiting,sigcrcs[2],txidcrcs[2],utxocrcs[2],lastepoch,paxwdcrc; + uint32_t MoMdepth,state,starttime,timestamp,waiting,sigcrcs[2],txidcrcs[2],utxocrcs[2],lastepoch,paxwdcrc; int32_t rawratifiedlens[2],height,numnotaries,numerrors,completed,minsigs,duration,numratified,isratify,require0,scores[DPOW_MAXRELAYS]; int8_t myind,bestk,ratifybestk,pendingbestk,pendingratifybestk; cJSON *ratified; @@ -142,14 +142,14 @@ struct dpow_info struct dpow_block **blocks; }; uint64_t dpow_notarybestk(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp); -int32_t dpow_paxpending(uint8_t *hex,uint32_t *paxwdcrcp); +int32_t dpow_paxpending(uint8_t *hex,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth); 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); -int32_t dpow_getchaintip(struct supernet_info *myinfo,bits256 *blockhashp,uint32_t *blocktimep,bits256 *txs,uint32_t *numtxp,struct iguana_info *coin); +int32_t dpow_getchaintip(struct supernet_info *myinfo,bits256 *merklerootp,bits256 *blockhashp,uint32_t *blocktimep,bits256 *txs,uint32_t *numtxp,struct iguana_info *coin); void dpow_send(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgbits,uint8_t *data,int32_t datalen); int32_t dpow_nanomsg_update(struct supernet_info *myinfo); -int32_t dpow_haveutxo(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr); +int32_t dpow_haveutxo(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr,char *srccoin); void komodo_assetcoins(int32_t fullnode,uint64_t mask); int32_t iguana_isnotarychain(char *symbol); diff --git a/iguana/dexscripts.win32/1-client.cmd b/iguana/dexscripts.win32/1-client.cmd index 21bec2717..487565d03 100644 --- a/iguana/dexscripts.win32/1-client.cmd +++ b/iguana/dexscripts.win32/1-client.cmd @@ -6,10 +6,16 @@ rem set COINS=[{\"coin\":\"REVS\",\"active\":1,\"asset\":\"REVS\",\"rpcport\":10 rem marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\", \"passphrase\":\"mypassphrase\", \"coins\":%COINS%}" set COINS=\"\" -set /p PASSPHRASE= marketmaker.log 2>&1 -marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\", \"passphrase\":\"%PASSPHRASE%\"}" +rem marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\", \"passphrase\":\"%PASSPHRASE%\"}" 1> marketmaker.log 2>&1 + +rem echo "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\", \"passphrase\":\"%PASSPHRASE%\"}" +rem marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\", \"passphrase\":\"%PASSPHRASE%\"}" + +marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\",\"passphrase\":\"default\"}" + diff --git a/iguana/dexscripts.win32/2-getuserpass.cmd b/iguana/dexscripts.win32/2-getuserpass.cmd index 87e633339..b6d7347a2 100644 --- a/iguana/dexscripts.win32/2-getuserpass.cmd +++ b/iguana/dexscripts.win32/2-getuserpass.cmd @@ -1,7 +1,17 @@ @echo off -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":null,\"method\":\"enable\",\"coin\":\" \"}" -s > userpass.json -for /f "tokens=2 delims=:," %%a in (' find "userpass" "userpass.json" ') do ( +rem first time call to any method after started markemaker will return default userpass 1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f +rem by-default userpass is 1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f from "default" passphrase + +rem first time call to marketmaker don't return anything now, so we disable it +rem curl --url "http://127.0.0.1:7783" --data "{\"userpass\":null,\"method\":\"enable\",\"coin\":\"\"}" -s > default_userpass.json +rem curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f\",\"method\":\"hello\"}" -s > default_userpass.json + +rem echo - First time call to MM API finished, default userpass received +set /p PASSPHRASE= userpass.json +echo Getting userpass related to your passphrase finished +for /f "tokens=4 delims=:," %%a in (' find "userpass" "userpass.json" ') do ( echo UserPass: %%~a echo %%~a > userpass ) -del userpass.json \ No newline at end of file diff --git a/iguana/dexscripts.win32/curl.exe b/iguana/dexscripts.win32/curl.exe deleted file mode 100644 index a9851eb05..000000000 Binary files a/iguana/dexscripts.win32/curl.exe and /dev/null differ diff --git a/iguana/dpow/dpow_fsm.c b/iguana/dpow/dpow_fsm.c index effcf3914..ccd30bbec 100755 --- a/iguana/dpow/dpow_fsm.c +++ b/iguana/dpow/dpow_fsm.c @@ -91,25 +91,25 @@ int32_t dpow_datahandler(struct supernet_info *myinfo,struct dpow_info *dp,struc { //printf("verify (%s) it is properly signed! set ht.%d signedtxid to %s\n",coin->symbol,height,bits256_str(str,txid)); /*if ( channel == DPOW_BTCTXIDCHANNEL ) - { - if ( bp->state < 1000 ) - { - bp->desttxid = txid; - bp->state = 1000; - dp->destupdated = 0; - dpow_signedtxgen(myinfo,dp,bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGCHANNEL,0,bp->isratify); - //dpow_sigscheck(myinfo,dp,bp,DPOW_SIGCHANNEL,myind,0); - } - } - else - { - if ( bp->state != 0xffffffff ) - { - bp->srctxid = txid; - printf("set state elapsed %d COMPLETED %s.(%s) %s.(%s)\n",(int32_t)(time(NULL) - bp->starttime),dp->symbol,bits256_str(str,bp->desttxid),dp->dest,bits256_str(str2,txid)); - bp->state = 0xffffffff; - } - }*/ + { + if ( bp->state < 1000 ) + { + bp->desttxid = txid; + bp->state = 1000; + dp->destupdated = 0; + dpow_signedtxgen(myinfo,dp,bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGCHANNEL,0,bp->isratify); + //dpow_sigscheck(myinfo,dp,bp,DPOW_SIGCHANNEL,myind,0); + } + } + else + { + if ( bp->state != 0xffffffff ) + { + bp->srctxid = txid; + printf("set state elapsed %d COMPLETED %s.(%s) %s.(%s)\n",(int32_t)(time(NULL) - bp->starttime),dp->symbol,bits256_str(str,bp->desttxid),dp->dest,bits256_str(str2,txid)); + bp->state = 0xffffffff; + } + }*/ } else { @@ -121,7 +121,7 @@ int32_t dpow_datahandler(struct supernet_info *myinfo,struct dpow_info *dp,struc return(0); } -int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr) +int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr,char *srccoin) { int32_t haveutxo,completed,minutxo,n; bits256 signedtxid; cJSON *addresses; char *rawtx,*sendtx; if ( strcmp("BTC",coin->symbol) == 0 ) @@ -129,12 +129,17 @@ int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct minutxo = 199; n = 10; } + else if ( strcmp("KMD",coin->symbol) == 0 ) + { + minutxo = 512; + n = 256; + } else { minutxo = 49; - n = 10; + n = 50; } - if ( (haveutxo= dpow_haveutxo(myinfo,coin,txidp,voutp,coinaddr)) <= minutxo && time(NULL) > dp->lastsplit+bp->duration && (bp->myind != 0 || dp->ratifying == 0) ) + if ( (haveutxo= dpow_haveutxo(myinfo,coin,txidp,voutp,coinaddr,srccoin)) <= minutxo && time(NULL) > dp->lastsplit+bp->duration && (bp->myind != 0 || dp->ratifying == 0) ) { addresses = cJSON_CreateArray(); jaddistr(addresses,coinaddr); @@ -155,12 +160,225 @@ int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct return(haveutxo); } +uint32_t Numallocated; + +int32_t dpow_opreturn_parsesrc(bits256 *blockhashp,int32_t *heightp,bits256 *txidp,char *symbol,bits256 *MoMp,uint32_t *MoMdepthp,uint8_t *opret,int32_t opretlen) +{ + int32_t i,c,len,offset = 0; uint8_t op; + symbol[0] = 0; + memset(blockhashp->bytes,0,sizeof(*blockhashp)); + memset(heightp,0,sizeof(*heightp)); + memset(txidp->bytes,0,sizeof(*txidp)); + memset(MoMp->bytes,0,sizeof(*MoMp)); + memset(MoMdepthp,0,sizeof(*MoMdepthp)); + if ( opret[offset++] == 0x6a ) + { + if ( (op= opret[offset++]) < 0x4c ) + len = op; + else if ( op == 0x4c ) + len = opret[offset++]; + else if ( op == 0x4d ) + { + len = opret[offset++]; + len = len + ((int32_t)opret[offset++] << 8); + } else return(-1); + offset += iguana_rwbignum(0,&opret[offset],sizeof(*blockhashp),blockhashp->bytes); + offset += iguana_rwnum(0,&opret[offset],sizeof(*heightp),(uint32_t *)heightp); + offset += iguana_rwbignum(0,&opret[offset],sizeof(*txidp),txidp->bytes); + for (i=0; i<65; i++) + { + if ( (c= opret[offset++]) == 0 ) + { + symbol[i] = 0; + break; + } + if ( offset > opretlen ) + break; + symbol[i] = c; + } + if ( offset+sizeof(bits256)+sizeof(uint32_t) <= opretlen ) + { + offset += iguana_rwbignum(0,&opret[offset],sizeof(*MoMp),MoMp->bytes); + offset += iguana_rwnum(0,&opret[offset],sizeof(*MoMdepthp),(uint32_t *)MoMdepthp); + } + ///printf("offset.%d vs len.%d\n",offset,len); + return(len); + } + return(-1); +} + +int32_t dpow_txhasnotarization(uint64_t *signedmaskp,int32_t *nothtp,struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t height) +{ + cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[256]; bits256 spenttxid; uint64_t notarymask=0; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0; + if ( (txobj= dpow_gettransaction(myinfo,coin,txid)) != 0 ) + { + if ( (vins= jarray(&numvins,txobj,"vin")) != 0 ) + { + if ( numvins >= DPOW_MIN_ASSETCHAIN_SIGS ) + { + notarymask = numnotaries = 0; + for (i=0; i>= 1; + decode_hex(script,len,hexstr); + if ( script[0] == 33 && script[34] == 0xac ) + { + for (j=0; j 0 ) + { + if ( numnotaries >= DPOW_MIN_ASSETCHAIN_SIGS ) + { + hasnotarization = 1; + *nothtp = 0; + if ( (vouts= jarray(&numvouts,txobj,"vout")) != 0 ) + { + bits256 blockhash,txid,MoM; uint32_t MoMdepth; char symbol[65];//,str[65],str2[65],str3[65]; + vout = jitem(vouts,numvouts-1); + if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) > 36*2 && len < sizeof(script)*2 ) + { + len >>= 1; + decode_hex(script,len,hexstr); + if ( dpow_opreturn_parsesrc(&blockhash,nothtp,&txid,symbol,&MoM,&MoMdepth,script,len) > 0 ) + { + if ( Notaries_port != DPOW_SOCKPORT ) + { + if ( bits256_nonz(MoM) == 0 || MoMdepth == 0 || *nothtp >= height || *nothtp < 0 ) + *nothtp = 0; + } + //printf("%s.%d notarizationht.%d %s -> %s MoM.%s [%d]\n",symbol,height,*nothtp,bits256_str(str,blockhash),bits256_str(str2,txid),bits256_str(str3,MoM),MoMdepth); + } + } + } + } + } + } + } + free_json(txobj); + } + if ( hasnotarization != 0 ) + (*signedmaskp) = notarymask; + return(hasnotarization); +} + +int32_t dpow_hasnotarization(uint64_t *signedmaskp,int32_t *nothtp,struct supernet_info *myinfo,struct iguana_info *coin,cJSON *blockjson,int32_t ht) +{ + int32_t i,n,hasnotarization = 0; bits256 txid; cJSON *txarray; + *nothtp = 0; + *signedmaskp = 0; + if ( (txarray= jarray(&n,blockjson,"tx")) != 0 ) + { + for (i=0; isymbol,height); + if ( (blockjson= dpow_getblock(myinfo,coin,blockhash)) != 0 ) + { + merkle = jbits256(blockjson,"merkleroot"); + free_json(blockjson); + if ( bits256_nonz(merkle) != 0 ) + { + merkles = calloc(4*maxdepth+1,sizeof(*merkles)); + merkles[MoMdepth++] = merkle; + ht = height - MoMdepth; + while ( MoMdepth < maxdepth && ht > breakht && ht > 0 ) + { + //fprintf(stderr,"%s.%d ",coin->symbol,ht); + blockhash = dpow_getblockhash(myinfo,coin,ht); + if ( (blockjson= dpow_getblock(myinfo,coin,blockhash)) != 0 ) + { + if ( breakht == 0 && dpow_hasnotarization(&signedmask,¬ht,myinfo,coin,blockjson,ht) > 0 ) + { + breakht = notht; + //free_json(blockjson); + printf("%s has notarization at %d for breakht.%d\n",coin->symbol,ht,notht); + } + merkle = jbits256(blockjson,"merkleroot"); + free_json(blockjson); + if ( bits256_nonz(merkle) != 0 ) + merkles[MoMdepth++] = merkle; + else + { + printf("%s MoMdepth.%d ht.%d from height.%d, null merkleroot\n",coin->symbol,MoMdepth,ht,height); + MoMdepth = 0; + break; + } + } + else + { + printf("%s MoMdepth.%d ht.%d from height.%d, no blockhash\n",coin->symbol,MoMdepth,ht,height); + MoMdepth = 0; + break; + } + ht = height - MoMdepth; + usleep(10000); + } + if ( MoMdepth > 0 ) + { + MoM = iguana_merkle(coin->symbol,merkles,MoMdepth); + char str[65]; printf("%s from height.%d ht.%d MoMdepth.%d -> MoM %s\n",coin->symbol,height,ht,MoMdepth,bits256_str(str,MoM)); + } + else + { + printf("unexpected %s from height.%d MoMdepth.%d vs max.%d\n",coin->symbol,height,MoMdepth,maxdepth); + MoMdepth = 0; + } + free(merkles); + } else printf("%s.ht%d null merkles\n",coin->symbol,height); + } else printf("%s.ht%d null block\n",coin->symbol,height); + *MoMdepthp = MoMdepth; + //printf("done MoM calc %s height.%d MoMdepth.%d\n",coin->symbol,height,MoMdepth); + return(MoM); +} + void dpow_statemachinestart(void *ptr) { void **ptrs = ptr; struct supernet_info *myinfo; struct dpow_info *dp; struct dpow_checkpoint checkpoint; - int32_t i,j,ht,extralen,destprevvout0,srcprevvout0,numratified=0,kmdheight,myind = -1; uint8_t extras[10000],pubkeys[64][33]; cJSON *ratified=0,*item; struct iguana_info *src,*dest; char *jsonstr,*handle,*hexstr,str[65],str2[65],srcaddr[64],destaddr[64]; bits256 zero,srchash,destprevtxid0,srcprevtxid0; struct dpow_block *bp; struct dpow_entry *ep = 0; uint32_t duration,minsigs,starttime,srctime; + int32_t i,j,ht,extralen,destprevvout0,srcprevvout0,numratified=0,kmdheight,myind = -1; uint8_t extras[10000],pubkeys[64][33]; cJSON *ratified=0,*item; struct iguana_info *src,*dest; char *jsonstr,*handle,*hexstr,str[65],str2[65],srcaddr[64],destaddr[64]; bits256 zero,MoM,merkleroot,srchash,destprevtxid0,srcprevtxid0; struct dpow_block *bp; struct dpow_entry *ep = 0; uint32_t MoMdepth,duration,minsigs,starttime,srctime; memset(&zero,0,sizeof(zero)); + MoM = zero; srcprevtxid0 = destprevtxid0 = zero; srcprevvout0 = destprevvout0 = -1; myinfo = ptrs[0]; @@ -172,20 +390,31 @@ void dpow_statemachinestart(void *ptr) memcpy(&checkpoint,&ptrs[5],sizeof(checkpoint)); src = iguana_coinfind(dp->symbol); dest = iguana_coinfind(dp->dest); - dpow_getchaintip(myinfo,&srchash,&srctime,dp->srctx,&dp->numsrctx,src); - dpow_getchaintip(myinfo,&srchash,&srctime,dp->desttx,&dp->numdesttx,dest); + dpow_getchaintip(myinfo,&merkleroot,&srchash,&srctime,dp->desttx,&dp->numdesttx,dest); + dpow_getchaintip(myinfo,&merkleroot,&srchash,&srctime,dp->srctx,&dp->numsrctx,src); if ( src == 0 || dest == 0 ) { printf("null coin ptr? (%s %p or %s %p)\n",dp->symbol,src,dp->dest,dest); + free(ptr); return; } + MoMdepth = 0; if ( strcmp(src->symbol,"KMD") == 0 ) kmdheight = checkpoint.blockhash.height; else if ( strcmp(dest->symbol,"KMD") == 0 ) + { kmdheight = dest->longestchain; + portable_mutex_lock(&src->MoM_mutex); + MoM = dpow_calcMoM(&MoMdepth,myinfo,src,checkpoint.blockhash.height); + portable_mutex_unlock(&src->MoM_mutex); + } if ( (bp= dp->blocks[checkpoint.blockhash.height]) == 0 ) { bp = calloc(1,sizeof(*bp)); + //printf("allocate bp for %s ht.%d -> %s\n",src->symbol,checkpoint.blockhash.height,dest->symbol); + Numallocated++; + bp->MoM = MoM; + bp->MoMdepth = MoMdepth; bp->minsigs = minsigs; bp->duration = duration; bp->srccoin = src; @@ -200,6 +429,8 @@ void dpow_statemachinestart(void *ptr) if ( numratified > 64 ) { fprintf(stderr,"cant ratify more than 64 notaries ratified has %d\n",numratified); + free(ptr); + free_json(ratified); return; } for (i=0; inumratified = numratified; bp->ratified = ratified; printf("numratified.%d %s\n",numratified,jprint(ratified,0)); - } - else - { - printf("i.%d numratified.%d\n",i,numratified); - free_json(ratified); - } + } else printf("i.%d numratified.%d\n",i,numratified); } + free_json(ratified); } bp->bestk = -1; dp->blocks[checkpoint.blockhash.height] = bp; bp->beacon = rand256(0); vcalc_sha256(0,bp->commit.bytes,bp->beacon.bytes,sizeof(bp->beacon)); - /*if ( checkpoint.blockhash.height >= DPOW_FIRSTRATIFY && dp->blocks[checkpoint.blockhash.height - DPOW_FIRSTRATIFY] != 0 ) - { - printf("purge %s.%d\n",dp->dest,checkpoint.blockhash.height - DPOW_FIRSTRATIFY); - free(dp->blocks[checkpoint.blockhash.height - DPOW_FIRSTRATIFY]); - dp->blocks[checkpoint.blockhash.height - DPOW_FIRSTRATIFY] = 0; - }*/ } if ( bp->isratify != 0 && dp->ratifying != 0 ) { @@ -336,6 +557,7 @@ void dpow_statemachinestart(void *ptr) printf("%02x",bp->ratified_pubkeys[0][i]); printf(" new, cant change notary0\n"); dp->ratifying -= bp->isratify; + free(ptr); return; } //printf(" myind.%d myaddr.(%s %s)\n",myind,srcaddr,destaddr); @@ -353,18 +575,18 @@ void dpow_statemachinestart(void *ptr) } else { - if ( dpow_checkutxo(myinfo,dp,bp,bp->destcoin,&ep->dest.prev_hash,&ep->dest.prev_vout,destaddr) < 0 ) + if ( dpow_checkutxo(myinfo,dp,bp,bp->destcoin,&ep->dest.prev_hash,&ep->dest.prev_vout,destaddr,src->symbol) < 0 ) { printf("dont have %s %s utxo, please send funds\n",dp->dest,destaddr); - free(ptr); dp->ratifying -= bp->isratify; + free(ptr); return; } - if ( dpow_checkutxo(myinfo,dp,bp,bp->srccoin,&ep->src.prev_hash,&ep->src.prev_vout,srcaddr) < 0 ) + if ( dpow_checkutxo(myinfo,dp,bp,bp->srccoin,&ep->src.prev_hash,&ep->src.prev_vout,srcaddr,"") < 0 ) { printf("dont have %s %s utxo, please send funds\n",dp->symbol,srcaddr); - free(ptr); dp->ratifying -= bp->isratify; + free(ptr); return; } if ( bp->isratify != 0 ) @@ -384,10 +606,11 @@ void dpow_statemachinestart(void *ptr) bp->myind = myind; while ( bp->isratify == 0 && dp->destupdated == 0 ) { - if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) + if ( (checkpoint.blockhash.height % 100) != 0 && dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) { - printf("abort %s ht.%d due to new checkpoint.%d\n",dp->symbol,checkpoint.blockhash.height,dp->checkpoint.blockhash.height); + //printf("abort %s ht.%d due to new checkpoint.%d\n",dp->symbol,checkpoint.blockhash.height,dp->checkpoint.blockhash.height); dp->ratifying -= bp->isratify; + free(ptr); return; } sleep(1); @@ -396,8 +619,8 @@ void dpow_statemachinestart(void *ptr) if ( bp->isratify == 0 ) { //if ( (starttime= checkpoint.timestamp) == 0 ) - bp->starttime = starttime; - extralen = dpow_paxpending(extras,&bp->paxwdcrc); + bp->starttime = starttime; + extralen = dpow_paxpending(extras,&bp->paxwdcrc,bp->MoM,bp->MoMdepth); 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\n",bp->paxwdcrc,bp->myind,bp->isratify,src->symbol,checkpoint.blockhash.height,bits256_str(str,checkpoint.blockhash.hash),starttime,bp->duration,time(NULL)); @@ -415,15 +638,14 @@ void dpow_statemachinestart(void *ptr) printf("break due to already ratifying\n"); break; } - extralen = dpow_paxpending(extras,&bp->paxwdcrc); + extralen = dpow_paxpending(extras,&bp->paxwdcrc,bp->MoM,bp->MoMdepth); bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc; } - sleep(13); - if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) + if ( (checkpoint.blockhash.height % 100) != 0 && dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) { if ( bp->isratify == 0 ) { - printf("abort %s ht.%d due to new checkpoint.%d\n",dp->symbol,checkpoint.blockhash.height,dp->checkpoint.blockhash.height); + //printf("abort %s ht.%d due to new checkpoint.%d\n",dp->symbol,checkpoint.blockhash.height,dp->checkpoint.blockhash.height); break; } } @@ -440,6 +662,7 @@ void dpow_statemachinestart(void *ptr) { printf("%s ht.%d %s got reorged to %s, abort notarization\n",bp->srccoin->symbol,bp->height,bits256_str(str,bp->hashmsg),bits256_str(str2,checkhash)); bp->state = 0xffffffff; + break; } } if ( bp->state != 0xffffffff ) @@ -457,12 +680,13 @@ void dpow_statemachinestart(void *ptr) printf("abort pending ratify\n"); break; } + sleep(30); } - printf("END isratify.%d:%d bestk.%d %llx sigs.%llx state.%x machine ht.%d completed state.%x %s.%s %s.%s recvmask.%llx paxwdcrc.%x %p %p\n",bp->isratify,dp->ratifying,bp->bestk,(long long)bp->bestmask,(long long)(bp->bestk>=0?bp->destsigsmasks[bp->bestk]:0),bp->state,bp->height,bp->state,dp->dest,bits256_str(str,bp->desttxid),dp->symbol,bits256_str(str2,bp->srctxid),(long long)bp->recvmask,bp->paxwdcrc,src,dest); - bp->state = 0xffffffff; + printf("[%d] END isratify.%d:%d bestk.%d %llx sigs.%llx state.%x machine ht.%d completed state.%x %s.%s %s.%s recvmask.%llx paxwdcrc.%x %p %p\n",Numallocated,bp->isratify,dp->ratifying,bp->bestk,(long long)bp->bestmask,(long long)(bp->bestk>=0?bp->destsigsmasks[bp->bestk]:0),bp->state,bp->height,bp->state,dp->dest,bits256_str(str,bp->desttxid),dp->symbol,bits256_str(str2,bp->srctxid),(long long)bp->recvmask,bp->paxwdcrc,src,dest); dp->lastrecvmask = bp->recvmask; dp->ratifying -= bp->isratify; - dp->blocks[bp->height] = 0; + // dp->blocks[bp->height] = 0; + bp->state = 0xffffffff; free(ptr); } diff --git a/iguana/dpow/dpow_network.c b/iguana/dpow/dpow_network.c index 0f6fb2c6a..bbbfcad68 100755 --- a/iguana/dpow/dpow_network.c +++ b/iguana/dpow/dpow_network.c @@ -13,6 +13,10 @@ * * ******************************************************************************/ +extern uint16_t Notaries_port; +extern int32_t Notaries_numseeds; +extern char *Notaries_seeds[]; + struct signed_nnpacket { uint8_t sig64[64]; @@ -24,14 +28,14 @@ struct signed_nnpacket void dex_init(struct supernet_info *myinfo) { - int32_t i,j,mask = 0; 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 i,j,mask = 0; OS_randombytes((void *)&i,sizeof(i)); srand(i); for (i=0; idexseed_ipaddrs)/sizeof(*myinfo->dexseed_ipaddrs); i++) { while ( 1 ) { - j = (rand() % (sizeof(seeds)/sizeof(*seeds))); + j = (rand() % Notaries_numseeds); if ( i < 2 ) j = i; if ( ((1 << j) & mask) == 0 ) @@ -41,8 +45,8 @@ void dex_init(struct supernet_info *myinfo) #ifdef NOTARY_TESTMODE seeds[j] = NOTARY_TESTMODE; #endif - printf("seed.[%d] <- %s\n",i,seeds[j]); - strcpy(myinfo->dexseed_ipaddrs[i],seeds[j]); + printf("seed.[%d] <- %s\n",i,Notaries_seeds[j]); + strcpy(myinfo->dexseed_ipaddrs[i],Notaries_seeds[j]); myinfo->dexipbits[i] = (uint32_t)calc_ipbits(myinfo->dexseed_ipaddrs[i]); } myinfo->numdexipbits = i; @@ -167,7 +171,7 @@ int32_t signed_nn_recv(void **freeptrp,struct supernet_info *myinfo,uint8_t nota struct dex_nanomsghdr { uint32_t crc32,size,datalen,timestamp; - char handler[8]; + char handler[64]; uint8_t version0,version1,packet[]; } PACKED; @@ -1002,8 +1006,8 @@ char *_dex_getnotaries(struct supernet_info *myinfo,char *symbol) } else { - extern const char *Notaries_elected[][2]; - myinfo->numnotaries = 64;//sizeof(Notaries_elected)/sizeof(*Notaries_elected); + extern char *Notaries_elected[][2]; extern int32_t Notaries_num; + myinfo->numnotaries = Notaries_num;//sizeof(Notaries_elected)/sizeof(*Notaries_elected); for (i=0; inumnotaries; i++) { decode_hex(myinfo->notaries[i],33,(char *)Notaries_elected[i][1]); @@ -1292,7 +1296,7 @@ int32_t dpow_addnotary(struct supernet_info *myinfo,struct dpow_info *dp,char *i if ( myinfo->IAMNOTARY == 0 ) return(-1); portable_mutex_lock(&myinfo->notarymutex); - if ( myinfo->dpowsock >= 0 && myinfo->dexsock >= 0 ) + if ( myinfo->dpowsock >= 0 )//&& myinfo->dexsock >= 0 ) { ipbits = (uint32_t)calc_ipbits(ipaddr); for (iter=0; iter<2; iter++) @@ -1315,9 +1319,9 @@ int32_t dpow_addnotary(struct supernet_info *myinfo,struct dpow_info *dp,char *i ptr[n] = ipbits; if ( iter == 0 && strcmp(ipaddr,myinfo->ipaddr) != 0 ) { - retval = nn_connect(myinfo->dpowsock,nanomsg_tcpname(0,str,ipaddr,DPOW_SOCK)); + retval = nn_connect(myinfo->dpowsock,nanomsg_tcpname(0,str,ipaddr,Notaries_port)); printf("NN_CONNECT to (%s)\n",str); - retval = nn_connect(myinfo->dexsock,nanomsg_tcpname(0,str,ipaddr,DEX_SOCK)); + //retval = nn_connect(myinfo->dexsock,nanomsg_tcpname(0,str,ipaddr,DEX_SOCK)); } n++; qsort(ptr,n,sizeof(uint32_t),_increasing_ipbits); @@ -1338,7 +1342,7 @@ int32_t dpow_addnotary(struct supernet_info *myinfo,struct dpow_info *dp,char *i void dpow_nanomsginit(struct supernet_info *myinfo,char *ipaddr) { - char str[512]; int32_t timeout,retval,maxsize,dpowsock,dexsock,repsock,pubsock; + char str[512],bindpoint[64]; int32_t timeout,retval,maxsize,dpowsock,dexsock,repsock,pubsock; if ( myinfo->ipaddr[0] == 0 ) { printf("need to set ipaddr before nanomsg\n"); @@ -1353,13 +1357,14 @@ void dpow_nanomsginit(struct supernet_info *myinfo,char *ipaddr) pubsock = myinfo->pubsock; if ( dpowsock < 0 && (dpowsock= nn_socket(AF_SP,NN_BUS)) >= 0 ) { - if ( nn_bind(dpowsock,nanomsg_tcpname(myinfo,str,myinfo->ipaddr,DPOW_SOCK)) < 0 ) + sprintf(bindpoint,"tcp://*:%u",Notaries_port); + if ( nn_bind(dpowsock,bindpoint) < 0 ) //nanomsg_tcpname(myinfo,str,myinfo->ipaddr,Notaries_port { - printf("error binding to dpowsock (%s)\n",nanomsg_tcpname(myinfo,str,myinfo->ipaddr,DPOW_SOCK)); + printf("error binding to dpowsock (%s)\n",bindpoint); nn_close(dpowsock); dpowsock = -1; } - else + else if ( 0 ) { printf("NN_BIND to %s\n",str); if ( dexsock < 0 && (dexsock= nn_socket(AF_SP,NN_BUS)) >= 0 ) @@ -1422,15 +1427,15 @@ void dpow_nanomsginit(struct supernet_info *myinfo,char *ipaddr) } } } - myinfo->dpowipbits[0] = (uint32_t)calc_ipbits(myinfo->ipaddr); - myinfo->numdpowipbits = 1; - timeout = 1; - nn_setsockopt(dpowsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - maxsize = 1024 * 1024; - printf("RCVBUF.%d\n",nn_setsockopt(dpowsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize))); - - myinfo->nanoinit = (uint32_t)time(NULL); } + myinfo->dpowipbits[0] = (uint32_t)calc_ipbits(myinfo->ipaddr); + myinfo->numdpowipbits = 1; + timeout = 1; + nn_setsockopt(dpowsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + maxsize = 1024 * 1024; + printf("%s RCVBUF.%d\n",bindpoint,nn_setsockopt(dpowsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize))); + + myinfo->nanoinit = (uint32_t)time(NULL); } //else printf("error creating nanosocket\n"); if ( myinfo->dpowsock != dpowsock ) myinfo->dpowsock = dpowsock; @@ -1529,7 +1534,7 @@ void dpow_nanoutxoset(struct supernet_info *myinfo,struct dpow_info *dp,struct d if ( err != 0 ) { bitcoin_address(coinaddr,bp->srccoin->chain->pubtype,dp->minerkey33,33); - if ( dpow_haveutxo(myinfo,bp->srccoin,&bp->notaries[bp->myind].ratifysrcutxo,&vout,coinaddr) > 0 ) + if ( dpow_haveutxo(myinfo,bp->srccoin,&bp->notaries[bp->myind].ratifysrcutxo,&vout,coinaddr,"") > 0 ) { bp->notaries[bp->myind].ratifysrcvout = vout; np->srcutxo = bp->notaries[bp->myind].ratifysrcutxo; @@ -1547,7 +1552,7 @@ void dpow_nanoutxoset(struct supernet_info *myinfo,struct dpow_info *dp,struct d if ( err != 0 ) { bitcoin_address(coinaddr,bp->destcoin->chain->pubtype,dp->minerkey33,33); - if ( dpow_haveutxo(myinfo,bp->destcoin,&bp->notaries[bp->myind].ratifydestutxo,&vout,coinaddr) > 0 ) + if ( dpow_haveutxo(myinfo,bp->destcoin,&bp->notaries[bp->myind].ratifydestutxo,&vout,coinaddr,bp->srccoin->symbol) > 0 ) { bp->notaries[bp->myind].ratifydestvout = vout; np->destutxo = bp->notaries[bp->myind].ratifydestutxo; @@ -1733,11 +1738,11 @@ void dpow_ratify_update(struct supernet_info *myinfo,struct dpow_info *dp,struct { bitcoin_address(srcaddr,bp->srccoin->chain->pubtype,dp->minerkey33,33); bitcoin_address(destaddr,bp->destcoin->chain->pubtype,dp->minerkey33,33); - if ( dpow_checkutxo(myinfo,dp,bp,bp->destcoin,&bp->notaries[i].dest.prev_hash,&bp->notaries[i].dest.prev_vout,destaddr) < 0 ) + if ( dpow_checkutxo(myinfo,dp,bp,bp->destcoin,&bp->notaries[i].dest.prev_hash,&bp->notaries[i].dest.prev_vout,destaddr,bp->srccoin->symbol) < 0 ) { printf("dont have %s %s utxo, please send funds\n",dp->dest,destaddr); } - if ( dpow_checkutxo(myinfo,dp,bp,bp->srccoin,&bp->notaries[i].src.prev_hash,&bp->notaries[i].src.prev_vout,srcaddr) < 0 ) + if ( dpow_checkutxo(myinfo,dp,bp,bp->srccoin,&bp->notaries[i].src.prev_hash,&bp->notaries[i].src.prev_vout,srcaddr,"") < 0 ) { printf("dont have %s %s utxo, please send funds\n",dp->symbol,srcaddr); } @@ -1869,7 +1874,7 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru bp->pendingbestk = bp->bestk; bp->pendingbestmask = bp->bestmask; dpow_signedtxgen(myinfo,dp,bp->destcoin,bp,bp->bestk,bp->bestmask,bp->myind,DPOW_SIGBTCCHANNEL,1,0); - printf("finished signing\n"); + //printf("finished signing\n"); } if ( bp->destsigsmasks[bp->bestk] == bp->bestmask ) // have all sigs { @@ -1895,8 +1900,9 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru if ( 0 && bp->myind <= 1 ) printf("mypaxcrc.%x\n",bp->paxwdcrc); } - if ( (rand() % 130) == 0 ) - printf("%p ht.%d [%d] ips.%d %s NOTARIZE.%d matches.%d paxmatches.%d bestmatches.%d bestk.%d %llx recv.%llx sigmasks.(%llx %llx) senderind.%d state.%x (%x %x %x) pax.%x\n",bp,bp->height,bp->myind,dp->numipbits,dp->symbol,bp->minsigs,matches,paxmatches,bestmatches,bp->bestk,(long long)bp->bestmask,(long long)bp->recvmask,(long long)(bp->bestk>=0?bp->destsigsmasks[bp->bestk]:0),(long long)(bp->bestk>=0?bp->srcsigsmasks[bp->bestk]:0),senderind,bp->state,bp->hashmsg.uints[0],bp->desttxid.uints[0],bp->srctxid.uints[0],bp->paxwdcrc); + char str[65]; + if ( (rand() % 130) == 0 || strcmp(dp->symbol,"CHIPS") == 0 ) + printf("%p ht.%d [%d] ips.%d %s NOTARIZE.%d matches.%d paxmatches.%d bestmatches.%d bestk.%d %llx recv.%llx sigmasks.(%llx %llx) senderind.%d state.%x (%x %x %x) MoM.%s [%d]\n",bp,bp->height,bp->myind,dp->numipbits,dp->symbol,bp->minsigs,matches,paxmatches,bestmatches,bp->bestk,(long long)bp->bestmask,(long long)bp->recvmask,(long long)(bp->bestk>=0?bp->destsigsmasks[bp->bestk]:0),(long long)(bp->bestk>=0?bp->srcsigsmasks[bp->bestk]:0),senderind,bp->state,bp->hashmsg.uints[0],bp->desttxid.uints[0],bp->srctxid.uints[0],bits256_str(str,bp->MoM),bp->MoMdepth); } } @@ -1938,7 +1944,7 @@ void dpow_send(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_blo //printf(" dpow_send.(%d) size.%d numipbits.%d myind.%d\n",datalen,size,np->numipbits,bp->myind); if ( bp->isratify == 0 ) { - extralen = dpow_paxpending(extras,&paxwdcrc); + extralen = dpow_paxpending(extras,&paxwdcrc,bp->MoM,bp->MoMdepth); bp->paxwdcrc = bp->notaries[bp->myind].paxwdcrc = np->notarize.paxwdcrc = paxwdcrc; //dpow_bestconsensus(bp); dpow_nanoutxoset(myinfo,dp,&np->notarize,bp,0); @@ -2009,7 +2015,7 @@ void dpow_ipbitsadd(struct supernet_info *myinfo,struct dpow_info *dp,uint32_t * if ( j == n ) missing++; } - if ( (numipbits == 1 || missing < matched || matched > 0) && missing > 0 ) + if ( (numipbits == 1 || missing < matched || matched >= 0) && missing > 0 ) { for (i=0; i 0 ) - printf("IGNORE from.%d RECV numips.%d numipbits.%d matched.%d missing.%d\n",fromid,numipbits,n,matched,missing); + printf("IGNORE from.%d RECV numips.%d numipbits.%d matched.%d missing.%d maxipbits.%d\n",fromid,numipbits,n,matched,missing,maxipbits); expand_ipbits(ipaddr,senderipbits); dpow_addnotary(myinfo,dp,ipaddr); expand_ipbits(ipaddr,myinfo->myaddr.myipbits); @@ -2093,7 +2099,7 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) } else flags |= 1; if ( freeptr != 0 ) nn_freemsg(freeptr), np = 0, freeptr = 0; - if ( myinfo->dexsock >= 0 ) // from servers + if ( 0 && myinfo->dexsock >= 0 ) // from servers { freeptr = 0; if ( (flags & 2) == 0 && (size= signed_nn_recv(&freeptr,myinfo,myinfo->notaries,myinfo->numnotaries,myinfo->dexsock,&dexp)) > 0 ) @@ -2111,7 +2117,7 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) if ( freeptr != 0 ) nn_freemsg(freeptr), dexp = 0, freeptr = 0; } - if ( myinfo->repsock >= 0 ) // from clients + if ( 0 && myinfo->repsock >= 0 ) // from clients { dexp = 0; if ( (flags & 4) == 0 && (size= nn_recv(myinfo->repsock,&dexp,NN_MSG,0)) > 0 ) @@ -2237,7 +2243,7 @@ int32_t dpow_rwopret(int32_t rwflag,uint8_t *opret,bits256 *hashmsg,int32_t *hei { memcpy(&opret[opretlen],extras,extralen); opretlen += extralen; - printf("added extra.%d opreturn for withdraws paxwdcrc.%08x\n",extralen,calc_crc32(0,extras,extralen)); + //printf("added extra.%d crc.%08x\n",extralen,calc_crc32(0,extras,extralen)); } } else @@ -2357,7 +2363,7 @@ uint16_t komodo_port(char *symbol,uint64_t supply,uint32_t *magicp) } #define MAX_CURRENCIES 32 -extern char CURRENCIES[][8]; +extern char CURRENCIES[][65]; void komodo_assetcoins(int32_t fullnode,uint64_t mask) { diff --git a/iguana/dpow/dpow_prices.c b/iguana/dpow/dpow_prices.c index d83da8dd1..92ceea179 100755 --- a/iguana/dpow/dpow_prices.c +++ b/iguana/dpow/dpow_prices.c @@ -270,7 +270,7 @@ void pax_rank(uint64_t *ranked,uint32_t *pvals) #define YAHOO_METALS "XAU", "XAG", "XPT", "XPD" static char *Yahoo_metals[] = { YAHOO_METALS }; -char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies +char CURRENCIES[][65] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies "XAU", "XAG", "XPT", "XPD", // metals, gold must be first "BTCD", "BTC", "NXT", "ETC", "ETH", "KMD", "BTS", "MAID", "XCP", "XMR" // cryptos @@ -330,7 +330,7 @@ int32_t PAX_ispair(char *base,char *rel,char *contract) int32_t PAX_basenum(char *_base) { - int32_t i,j; char base[64]; + int32_t i,j; char base[65]; strcpy(base,_base); touppercase(base); if ( 1 ) @@ -936,7 +936,7 @@ int32_t PAX_calcmatrix(double matrix[MAX_CURRENCIES][MAX_CURRENCIES]) int32_t PAX_getmatrix(double *basevals,struct PAX_data *dp,double Hmatrix[32][32],double *RTprices,char *contracts[],int32_t num) { - int32_t i,j,c; char name[16]; double btcusd,kmdbtc; + int32_t i,j,c; char name[65]; double btcusd,kmdbtc; memcpy(Hmatrix,dp->ecbmatrix,sizeof(dp->ecbmatrix)); PAX_calcmatrix(Hmatrix); /*for (i=0; i<32; i++) @@ -1839,7 +1839,7 @@ int32_t PAX_idle(struct supernet_info *myinfo)//struct PAX_data *argdp,int32_t i { static double lastupdate,lastdayupdate; static uint32_t didinit; static char *userhome; int32_t idlegap = 10; FILE *fp; long filesize; char fname[512]; double splineval; uint32_t pvals[128],timestamp; int32_t i,datenum,seconds,c; struct tai t; struct PAX_data *dp; uint8_t data[512]; - if ( Currencymasks[0] == 0 ) + if ( 1 || Currencymasks[0] == 0 ) // disable pax price gatherings return(0); if ( time(NULL) > didinit+12*3600 ) { diff --git a/iguana/dpow/dpow_rpc.c b/iguana/dpow/dpow_rpc.c index 5f695f84a..07822f642 100755 --- a/iguana/dpow/dpow_rpc.c +++ b/iguana/dpow/dpow_rpc.c @@ -15,13 +15,34 @@ #define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0,0) +char *bitcoind_getinfo(char *symbol,char *serverport,char *userpass,char *getinfostr) +{ + char buf[1],*retstr; cJSON *retjson; + buf[0] = 0; + if ( getinfostr[0] == 0 ) + strcpy(getinfostr,"getinfo"); + retstr = bitcoind_passthru(symbol,serverport,userpass,getinfostr,buf); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,"error") != 0 && strcmp(getinfostr,"getinfo") == 0 ) + { + strcpy(getinfostr,"getblockchaininfo"); + free(retstr); + retstr = bitcoind_passthru(symbol,serverport,userpass,getinfostr,buf); + printf("switch to getblockchaininfo -> (%s)\n",retstr); + } + free(retjson); + } + return(retstr); +} + cJSON *dpow_getinfo(struct supernet_info *myinfo,struct iguana_info *coin) { char buf[128],*retstr=0; cJSON *json = 0; if ( coin->FULLNODE < 0 ) { buf[0] = 0; - retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getinfo",buf); + retstr = bitcoind_getinfo(coin->symbol,coin->chain->serverport,coin->chain->userpass,coin->getinfostr); usleep(10000); } else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) @@ -49,78 +70,79 @@ cJSON *dpow_getinfo(struct supernet_info *myinfo,struct iguana_info *coin) } return(json); } -const char *Notaries_elected[][2] = + +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)),Notaries_num,Notaries_BTCminsigs = DPOW_MINSIGS,Notaries_minsigs = DPOW_MIN_ASSETCHAIN_SIGS; +uint16_t Notaries_port = DPOW_SOCKPORT; +char *Notaries_seeds[65]; + +int32_t komodo_initjson(char *fname) { - { "0_jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, - { "0_jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" }, - { "0_kolo_testA", "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" }, - { "artik_AR", "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, - { "artik_EU", "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, - { "artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, - { "artik_SH", "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, - { "badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, - { "badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, - { "badass_SH", "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" }, - { "crackers_EU", "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, // 10 - { "crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, - { "crackers_SH", "02be28310e6312d1dd44651fd96f6a44ccc269a321f907502aae81d246fabdb03e" }, - { "durerus_EU", "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" }, - { "etszombi_AR", "031c79168d15edabf17d9ec99531ea9baa20039d0cdc14d9525863b83341b210e9" }, - { "etszombi_EU", "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, - { "etszombi_SH", "025d7a193c0757f7437fad3431f027e7b5ed6c925b77daba52a8755d24bf682dde" }, - { "farl4web_EU", "0300ecf9121cccf14cf9423e2adb5d98ce0c4e251721fa345dec2e03abeffbab3f" }, - { "farl4web_SH", "0396bb5ed3c57aa1221d7775ae0ff751e4c7dc9be220d0917fa8bbdf670586c030" }, - { "fullmoon_AR", "0254b1d64840ce9ff6bec9dd10e33beb92af5f7cee628f999cb6bc0fea833347cc" }, - { "fullmoon_NA", "031fb362323b06e165231c887836a8faadb96eda88a79ca434e28b3520b47d235b" }, // 20 - { "fullmoon_SH", "030e12b42ec33a80e12e570b6c8274ce664565b5c3da106859e96a7208b93afd0d" }, - { "grewal_NA", "03adc0834c203d172bce814df7c7a5e13dc603105e6b0adabc942d0421aefd2132" }, - { "grewal_SH", "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" }, - { "indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, - { "indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, - { "indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, - { "indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, - { "jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, - { "jsgalt_NA", "027b3fb6fede798cd17c30dbfb7baf9332b3f8b1c7c513f443070874c410232446" }, - { "karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, // 30 - { "kashifali_EU", "033777c52a0190f261c6f66bd0e2bb299d30f012dcb8bfff384103211edb8bb207" }, - { "kolo_AR", "03016d19344c45341e023b72f9fb6e6152fdcfe105f3b4f50b82a4790ff54e9dc6" }, - { "kolo_SH", "02aa24064500756d9b0959b44d5325f2391d8e95c6127e109184937152c384e185" }, - { "metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, - { "movecrypto_AR", "022783d94518e4dc77cbdf1a97915b29f427d7bc15ea867900a76665d3112be6f3" }, - { "movecrypto_EU", "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" }, - { "movecrypto_NA", "02efb12f4d78f44b0542d1c60146738e4d5506d27ec98a469142c5c84b29de0a80" }, - { "movecrypto_SH", "031f9739a3ebd6037a967ce1582cde66e79ea9a0551c54731c59c6b80f635bc859" }, - { "muros_AR", "022d77402fd7179335da39479c829be73428b0ef33fb360a4de6890f37c2aa005e" }, - { "noashh_AR", "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" }, // 40 - { "noashh_EU", "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" }, - { "noashh_NA", "033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" }, - { "nxtswe_EU", "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" }, - { "polycryptoblog_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, - { "pondsea_AR", "032e1c213787312099158f2d74a89e8240a991d162d4ce8017d8504d1d7004f735" }, - { "pondsea_EU", "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" }, - { "pondsea_NA", "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" }, - { "pondsea_SH", "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" }, - { "popcornbag_AR", "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, - { "popcornbag_NA", "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, // 50 - { "ptytrader_NA", "0328c61467148b207400b23875234f8a825cce65b9c4c9b664f47410b8b8e3c222" }, - { "ptytrader_SH", "0250c93c492d8d5a6b565b90c22bee07c2d8701d6118c6267e99a4efd3c7748fa4" }, - { "rnr_AR", "029bdb08f931c0e98c2c4ba4ef45c8e33a34168cb2e6bf953cef335c359d77bfcd" }, - { "rnr_EU", "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" }, - { "rnr_NA", "02e17c5f8c3c80f584ed343b8dcfa6d710dfef0889ec1e7728ce45ce559347c58c" }, - { "rnr_SH", "037536fb9bdfed10251f71543fb42679e7c52308bcd12146b2568b9a818d8b8377" }, - { "titomane_AR", "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" }, - { "titomane_EU", "02e41feded94f0cc59f55f82f3c2c005d41da024e9a805b41105207ef89aa4bfbd" }, - { "titomane_SH", "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" }, - { "vanbreuk_EU", "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" }, // 60 - { "xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, - { "xxspot1_XX", "02ef445a392fcaf3ad4176a5da7f43580e8056594e003eba6559a713711a27f955" }, - { "xxspot2_XX", "03d85b221ea72ebcd25373e7961f4983d12add66a92f899deaf07bab1d8b6f5573" } -}; + char *fstr,*field,*hexstr; cJSON *argjson,*array,*item; long fsize; uint16_t port; int32_t i,n,num,retval = -1; + for (i=0; i Notaries_BTCminsigs ) + Notaries_BTCminsigs = num; + if ( (num= juint(argjson,"minsigs")) > Notaries_minsigs ) + Notaries_minsigs = num; + if ( (array= jarray(&n,argjson,"seeds")) != 0 && n <= 64 ) + { + for (i=0; i 0 ) + { + for (i=0; iFULLNODE < 0 ) @@ -569,7 +600,7 @@ char *dpow_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *c jaddistr(array,signedtx); paramstr = jprint(array,1); retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"sendrawtransaction",paramstr); - printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr); + printf(">>>>>>>>>>> %s dpow_sendrawtransaction (%s)\n",coin->symbol,retstr); free(paramstr); return(retstr); } @@ -724,7 +755,7 @@ void init_alladdresses(struct supernet_info *myinfo,struct iguana_info *coin) } } -int32_t dpow_getchaintip(struct supernet_info *myinfo,bits256 *blockhashp,uint32_t *blocktimep,bits256 *txs,uint32_t *numtxp,struct iguana_info *coin) +int32_t dpow_getchaintip(struct supernet_info *myinfo,bits256 *merklerootp,bits256 *blockhashp,uint32_t *blocktimep,bits256 *txs,uint32_t *numtxp,struct iguana_info *coin) { int32_t n,i,height = -1,maxtx = *numtxp; bits256 besthash,oldhash; cJSON *array,*json; *numtxp = *blocktimep = 0; @@ -736,6 +767,9 @@ int32_t dpow_getchaintip(struct supernet_info *myinfo,bits256 *blockhashp,uint32 { if ( (height= juint(json,"height")) != 0 && (*blocktimep= juint(json,"time")) != 0 ) { + *merklerootp = jbits256(json,"merkleroot"); + //if ( bits256_nonz(*merklerootp) == 0 ) + // printf("block has no merkle? (%s)\n",jprint(json,0)); coin->lastbestheight = height; if ( height > coin->longestchain ) coin->longestchain = height; @@ -770,7 +804,7 @@ int32_t dpow_vini_ismine(struct supernet_info *myinfo,struct dpow_info *dp,cJSON return(-1); } -int32_t dpow_haveutxo(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr) +int32_t dpow_haveutxo(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr,char *srccoin) { int32_t vout,haveutxo = 0; uint32_t i,j,n,r; bits256 txid; cJSON *unspents,*item; uint64_t satoshis; char *str,*address; uint8_t script[35]; memset(txidp,0,sizeof(*txidp)); @@ -820,7 +854,7 @@ int32_t dpow_haveutxo(struct supernet_info *myinfo,struct iguana_info *coin,bits } } if ( haveutxo == 0 ) - printf("no %s utxo: need to fund address.(%s) or wait for splitfund to confirm\n",coin->symbol,coinaddr); + printf("no (%s -> %s) utxo: need to fund address.(%s) or wait for splitfund to confirm\n",srccoin,coin->symbol,coinaddr); } //else printf("null utxo array size\n"); free_json(unspents); } else printf("null return from dpow_listunspent\n"); @@ -1243,7 +1277,9 @@ int32_t dpow_issuer_iteration(struct dpow_info *dp,struct iguana_info *coin,int3 if ( height <= 0 ) height = 1; *isrealtimep = 0; - if ( (retstr= dpow_issuemethod(coin->chain->userpass,(char *)"getinfo",0,port)) != 0 ) + if ( coin->getinfostr[0] == 0 ) + strcpy(coin->getinfostr,"getinfo"); + if ( (retstr= dpow_issuemethod(coin->chain->userpass,(char *)coin->getinfostr,0,port)) != 0 ) { if ( (infoobj= cJSON_Parse(retstr)) != 0 ) { diff --git a/iguana/dpow/dpow_tx.c b/iguana/dpow/dpow_tx.c index fac9033af..dad95859c 100755 --- a/iguana/dpow/dpow_tx.c +++ b/iguana/dpow/dpow_tx.c @@ -169,6 +169,8 @@ struct dpow_block *dpow_heightfind(struct supernet_info *myinfo,struct dpow_info int32_t r,h,incr = 100000; struct dpow_block *bp = 0; if ( height > dp->maxblocks ) { + if ( dp->maxblocks+incr < height+10000 ) + incr = (height+10000) - dp->maxblocks; dp->blocks = realloc(dp->blocks,sizeof(*dp->blocks) * (dp->maxblocks + incr)); memset(&dp->blocks[dp->maxblocks],0,sizeof(*dp->blocks) * incr); dp->maxblocks += incr; @@ -224,12 +226,18 @@ int32_t dpow_voutstandard(struct dpow_block *bp,uint8_t *serialized,int32_t m,in } printf("numvouts.%d len.%d RATIFY vouts\n",numvouts,len); } - if ( 0 && (src_or_dest == 0 || strcmp(bp->destcoin->symbol,"BTC") != 0) && (n= dpow_paxpending(extras,&paxwdcrc)) > 0 ) + if ( 0 && (src_or_dest == 0 || strcmp(bp->destcoin->symbol,"BTC") != 0) && (n= dpow_paxpending(extras,&paxwdcrc,bp->MoM,bp->MoMdepth)) > 0 ) { for (i=0; iMoMdepth > 0 && strcmp(bp->destcoin->symbol,"KMD") == 0 ) // only testnets for now + { + n = dpow_paxpending(extras,&paxwdcrc,bp->MoM,bp->MoMdepth); + //n += iguana_rwbignum(1,&extras[n],sizeof(bp->MoM),bp->MoM.bytes); + //n += iguana_rwnum(1,&extras[n],sizeof(bp->MoMdepth),(uint32_t *)&bp->MoMdepth); + } satoshis = 0; len += iguana_rwnum(1,&serialized[len],sizeof(satoshis),&satoshis); if ( bp->isratify != 0 ) diff --git a/iguana/elected b/iguana/elected new file mode 100644 index 000000000..c1481c8e1 --- /dev/null +++ b/iguana/elected @@ -0,0 +1 @@ +{"port":7775,"BTCminsigs":13,"minsigs":11,"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"],"notaries":[ { "0_jl777_testA":"03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, { "0_jl777_testB":"02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" }, { "0_kolo_testA":"0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" }, { "artik_AR":"029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, { "artik_EU":"03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, { "artik_NA":"0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, { "artik_SH":"02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, { "badass_EU":"0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, { "badass_NA":"02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, { "badass_SH":"026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" }, { "crackers_EU":"03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, { "crackers_NA":"03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, { "crackers_SH":"02be28310e6312d1dd44651fd96f6a44ccc269a321f907502aae81d246fabdb03e" }, { "durerus_EU":"02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" }, { "etszombi_AR":"031c79168d15edabf17d9ec99531ea9baa20039d0cdc14d9525863b83341b210e9" }, { "etszombi_EU":"0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, { "etszombi_SH":"025d7a193c0757f7437fad3431f027e7b5ed6c925b77daba52a8755d24bf682dde" }, { "farl4web_EU":"0300ecf9121cccf14cf9423e2adb5d98ce0c4e251721fa345dec2e03abeffbab3f" }, { "farl4web_SH":"0396bb5ed3c57aa1221d7775ae0ff751e4c7dc9be220d0917fa8bbdf670586c030" }, { "fullmoon_AR":"0254b1d64840ce9ff6bec9dd10e33beb92af5f7cee628f999cb6bc0fea833347cc" }, { "fullmoon_NA":"031fb362323b06e165231c887836a8faadb96eda88a79ca434e28b3520b47d235b" }, { "fullmoon_SH":"030e12b42ec33a80e12e570b6c8274ce664565b5c3da106859e96a7208b93afd0d" }, { "grewal_NA":"03adc0834c203d172bce814df7c7a5e13dc603105e6b0adabc942d0421aefd2132" }, { "grewal_SH":"03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" }, { "indenodes_AR":"02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, { "indenodes_EU":"0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, { "indenodes_NA":"02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, { "indenodes_SH":"0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, { "jeezy_EU":"023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, { "jsgalt_NA":"027b3fb6fede798cd17c30dbfb7baf9332b3f8b1c7c513f443070874c410232446" }, { "karasugoi_NA":"02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, { "kashifali_EU":"033777c52a0190f261c6f66bd0e2bb299d30f012dcb8bfff384103211edb8bb207" }, { "kolo_AR":"03016d19344c45341e023b72f9fb6e6152fdcfe105f3b4f50b82a4790ff54e9dc6" }, { "kolo_SH":"02aa24064500756d9b0959b44d5325f2391d8e95c6127e109184937152c384e185" }, { "metaphilibert_AR":"02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, { "movecrypto_AR":"022783d94518e4dc77cbdf1a97915b29f427d7bc15ea867900a76665d3112be6f3" }, { "movecrypto_EU":"021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" }, { "movecrypto_NA":"02efb12f4d78f44b0542d1c60146738e4d5506d27ec98a469142c5c84b29de0a80" }, { "movecrypto_SH":"031f9739a3ebd6037a967ce1582cde66e79ea9a0551c54731c59c6b80f635bc859" }, { "muros_AR":"022d77402fd7179335da39479c829be73428b0ef33fb360a4de6890f37c2aa005e" }, { "noashh_AR":"029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" }, { "noashh_EU":"02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" }, { "noashh_NA":"033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" }, { "nxtswe_EU":"032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" }, { "polycryptoblog_NA":"02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, { "pondsea_AR":"032e1c213787312099158f2d74a89e8240a991d162d4ce8017d8504d1d7004f735" }, { "pondsea_EU":"0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" }, { "pondsea_NA":"031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" }, { "pondsea_SH":"02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" }, { "popcornbag_AR":"02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, { "popcornbag_NA":"03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, { "ptytrader_NA":"0328c61467148b207400b23875234f8a825cce65b9c4c9b664f47410b8b8e3c222" }, { "ptytrader_SH":"0250c93c492d8d5a6b565b90c22bee07c2d8701d6118c6267e99a4efd3c7748fa4" }, { "rnr_AR":"029bdb08f931c0e98c2c4ba4ef45c8e33a34168cb2e6bf953cef335c359d77bfcd" }, { "rnr_EU":"03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" }, { "rnr_NA":"02e17c5f8c3c80f584ed343b8dcfa6d710dfef0889ec1e7728ce45ce559347c58c" }, { "rnr_SH":"037536fb9bdfed10251f71543fb42679e7c52308bcd12146b2568b9a818d8b8377" }, { "titomane_AR":"03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" }, { "titomane_EU":"02e41feded94f0cc59f55f82f3c2c005d41da024e9a805b41105207ef89aa4bfbd" }, { "titomane_SH":"035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" }, { "vanbreuk_EU":"024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" }, { "xrobesx_NA":"03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, { "xxspot1_XX":"02ef445a392fcaf3ad4176a5da7f43580e8056594e003eba6559a713711a27f955" }, { "xxspot2_XX":"03d85b221ea72ebcd25373e7961f4983d12add66a92f899deaf07bab1d8b6f5573" }]} diff --git a/iguana/exchanges/CMakeLists.txt b/iguana/exchanges/CMakeLists.txt new file mode 100644 index 000000000..793aeb5a4 --- /dev/null +++ b/iguana/exchanges/CMakeLists.txt @@ -0,0 +1,34 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +set(MM_SOURCES mm.c ../mini-gmp.c ../groestl.c ../segwit_addr.c ../keccak.c LP_etomic.c) +set(MM_LIBS curl pthread libcrypto777 libjpeg libsecp256k1) +if(WIN32) +link_directories(${CMAKE_SOURCE_DIR}/marketmaker_depends/curl/build_msvc_2015_win64/lib/Release ${CMAKE_SOURCE_DIR}/marketmaker_depends/pthread-win32/bin/x64_MSVC2015.Release ${CMAKE_SOURCE_DIR}/marketmaker_depends/nanomsg/build_msvc_2015_win64/Release) +set(MM_LIBS ${MM_LIBS} nanomsg) +endif() +add_executable(marketmaker-testnet ${MM_SOURCES}) +add_executable(marketmaker-mainnet ${MM_SOURCES}) +include_directories(../../crypto777) +if(WIN32) +target_compile_definitions(marketmaker-mainnet PRIVATE) +target_compile_definitions(marketmaker-testnet PRIVATE ETOMIC_TESTNET) +else() +target_compile_definitions(marketmaker-testnet PRIVATE ETOMIC_TESTNET USE_STATIC_NANOMSG) +target_compile_definitions(marketmaker-mainnet PRIVATE USE_STATIC_NANOMSG) +endif() +if(UNIX) + target_link_libraries(marketmaker-testnet m) + target_link_libraries(marketmaker-mainnet m) +endif() +if(WIN32) +add_definitions(-DNATIVE_WINDOWS) +add_definitions(-DIGUANA_LOG2PACKETSIZE=20) +add_definitions(-DIGUANA_MAXPACKETSIZE=1572864) +add_definitions(-D_CRT_SECURE_NO_WARNINGS) +include_directories("${CMAKE_SOURCE_DIR}/includes") +endif() +target_link_libraries(marketmaker-testnet ${MM_LIBS} etomiclib-testnet) +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 diff --git a/iguana/exchanges/LP_NXT.c b/iguana/exchanges/LP_NXT.c index 6bc320925..0f385323c 100644 --- a/iguana/exchanges/LP_NXT.c +++ b/iguana/exchanges/LP_NXT.c @@ -202,9 +202,7 @@ void NXTventure_liquidation() cJSON *LP_NXT_redeems() { char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[2][sizeof(assetids)/sizeof(*assetids)],mult,txnum,assetid,qty; int32_t i,ind,numtx=0,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; - //sleep 1; fiat/supernet sendtoaddress RNZZuQYu8xJLZHuekhd96hYfoQuiCMz99T 1001.44150000 # txnum.8537615468620726612 - //sleep 1; fiat/pangea sendtoaddress RWMdRaUmMZqKkEibwEhY6XS3RLCXJDWHTi 22.10910000 # txnum.2649622877615958504 - uint64_t txnum_marker = calc_nxt64bits("8537615468620726612"); // 2649622877615958504"); // set to most recent processed + uint64_t txnum_marker = calc_nxt64bits("2675953695997905027"); // 4114304329372848717, 8537615468620726612"); // set to most recent processed uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); // dont change, end marker char *passphrase = ""; char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c index 3d37c8a2e..97b90f5fa 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -132,7 +132,7 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums quoteid = juint(item,"quoteid"); LP_RTmetrics_pendingswap(srcpub,LP_kmdvalue(base,basesatoshis)); LP_RTmetrics_pendingswap(destpub,LP_kmdvalue(rel,relsatoshis)); - if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) // no need for this + if ( 0 && (retstr= basilisk_swapentry(1,requestid,quoteid,0)) != 0 ) // no need for this { if ( (swapjson= cJSON_Parse(retstr)) != 0 ) { diff --git a/iguana/exchanges/LP_bitcoin.c b/iguana/exchanges/LP_bitcoin.c index 0343acc0b..ab755de82 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -118,6 +118,7 @@ static struct bitcoin_opcode { UT_hash_handle hh; uint8_t opcode,flags,stackitem #define IGUANA_OP_SWAP 0x7c #define IGUANA_OP_TUCK 0x7d +#define IGUANA_OP_SIZE 0x82 #define IGUANA_OP_EQUAL 0x87 #define IGUANA_OP_EQUALVERIFY 0x88 @@ -1911,6 +1912,10 @@ int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) int32_t bitcoin_secret160verify(uint8_t *script,int32_t n,uint8_t secret160[20]) { + script[n++] = IGUANA_OP_SIZE; // add SIZE 32 EQUALVERIFY + script[n++] = 1; + script[n++] = 32; + script[n++] = SCRIPT_OP_EQUALVERIFY; script[n++] = SCRIPT_OP_HASH160; script[n++] = 0x14; memcpy(&script[n],secret160,0x14); @@ -2018,26 +2023,16 @@ char *bitcoind_passthrut(char *coinstr,char *serverport,char *userpass,char *met return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,timeout)); } -bits256 bits256_calctxid(char *symbol,uint8_t *serialized,int32_t len) -{ - bits256 txid,revtxid; int32_t i; - memset(txid.bytes,0,sizeof(txid)); - if ( strcmp(symbol,"GRS") != 0 ) - txid = bits256_doublesha256(0,serialized,len); - else - { - vcalc_sha256(0,revtxid.bytes,serialized,len); - for (i=0; i<32; i++) - txid.bytes[i] = revtxid.bytes[31 - i]; - } - return(txid); -} - bits256 bits256_calcaddrhash(char *symbol,uint8_t *serialized,int32_t len) { bits256 hash; + memset(hash.bytes,0,sizeof(hash)); if ( strcmp(symbol,"GRS") != 0 ) - hash = bits256_doublesha256(0,serialized,len); + { + if ( strcmp(symbol,"SMART") != 0 ) + hash = bits256_doublesha256(0,serialized,len); + else HashKeccak(hash.bytes,serialized,len); + } else { HashGroestl(hash.bytes,serialized,len); @@ -2052,11 +2047,14 @@ bits256 bits256_calcaddrhash(char *symbol,uint8_t *serialized,int32_t len) int32_t bitcoin_addr2rmd160(char *symbol,uint8_t taddr,uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr) { bits256 hash; uint8_t *buf,_buf[26],data5[128],rmd21[21]; char prefixaddr[64],hrp[64]; int32_t len,len5,offset; + *addrtypep = 0; + memset(rmd160,0,20); if ( coinaddr == 0 || coinaddr[0] == 0 ) - { - *addrtypep = 0; - memset(rmd160,0,20); return(0); + if ( coinaddr[0] == '0' && coinaddr[1] == 'x' && is_hexstr(coinaddr+2,0) == 40 ) // for ETH + { + decode_hex(rmd160,20,coinaddr+2); // not rmd160 hash but hopefully close enough; + return(20); } if ( strcmp(symbol,"BCH") == 0 )//&& strlen(coinaddr) == 42 ) { @@ -2088,12 +2086,12 @@ int32_t bitcoin_addr2rmd160(char *symbol,uint8_t taddr,uint8_t *addrtypep,uint8_ hash = bits256_calcaddrhash(symbol,buf,20+offset); *addrtypep = (taddr == 0) ? *buf : buf[1]; memcpy(rmd160,buf+offset,20); - if ( strcmp(symbol,"GRS") != 0 && (buf[20+offset]&0xff) == hash.bytes[31] && (buf[21+offset]&0xff) == hash.bytes[30] && (buf[22+offset]&0xff) == hash.bytes[29] && (buf[23+offset]&0xff) == hash.bytes[28] ) + if ( (buf[20+offset]&0xff) == hash.bytes[31] && (buf[21+offset]&0xff) == hash.bytes[30] && (buf[22+offset]&0xff) == hash.bytes[29] && (buf[23+offset]&0xff) == hash.bytes[28] ) { //printf("coinaddr.(%s) valid checksum addrtype.%02x\n",coinaddr,*addrtypep); return(20); } - else if ( strcmp(symbol,"GRS") == 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] ) + 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 { @@ -2110,11 +2108,46 @@ int32_t bitcoin_addr2rmd160(char *symbol,uint8_t taddr,uint8_t *addrtypep,uint8_ char *bitcoin_address(char *symbol,char *coinaddr,uint8_t taddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len) { - int32_t offset,i,len5; char prefixed[64]; uint8_t data[64],data5[64]; bits256 hash; + static void *ctx; + int32_t offset,i,len5; char prefixed[64]; uint8_t data[64],data5[64],bigpubkey[65]; bits256 hash; struct iguana_info *coin; +#ifndef NOTETOMIC + if ( (coin= LP_coinfind(symbol)) != 0 && coin->etomic[0] != 0 ) + { + if ( len == 20 ) + { + strcpy(coinaddr,"0x"); + init_hexbytes_noT(coinaddr+2,pubkey_or_rmd160,20); + return(coinaddr); + } + else if ( len == 33 || len == 65 ) + { + if ( len == 33 ) + { + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + bitcoin_expandcompressed(ctx,bigpubkey,pubkey_or_rmd160); + LP_etomic_pub2addr(coinaddr,bigpubkey+1); + /*for (i=0; i<33; i++) + printf("%02x",pubkey_or_rmd160[i]); + printf(" compressed -> "); + for (i=0; i<65; i++) + printf("%02x",bigpubkey[i]); + printf(" -> %s\n",coinaddr);*/ + } + else LP_etomic_pub2addr(coinaddr,pubkey_or_rmd160+1); + return(coinaddr); + } + } +#endif coinaddr[0] = 0; offset = 1 + (taddr != 0); if ( len != 20 ) + { calc_rmd160_sha256(data+offset,pubkey_or_rmd160,len); + //for (i=0; i<20; i++) + // printf("%02x",data[offset+i]); + //printf(" rmd160\n"); + } else memcpy(data+offset,pubkey_or_rmd160,20); if ( strcmp(symbol,"BCH") == 0 ) { @@ -2139,7 +2172,7 @@ char *bitcoin_address(char *symbol,char *coinaddr,uint8_t taddr,uint8_t addrtype data[1] = addrtype; } else data[0] = addrtype; hash = bits256_calcaddrhash(symbol,data,20+offset); - if ( strcmp(symbol,"GRS") != 0 ) + if ( strcmp(symbol,"GRS") != 0 && strcmp(symbol,"SMART") != 0 ) { for (i=0; i<4; i++) data[20+offset+i] = hash.bytes[31-i]; @@ -2151,6 +2184,7 @@ char *bitcoin_address(char *symbol,char *coinaddr,uint8_t taddr,uint8_t addrtype } if ( (coinaddr= bitcoin_base58encode(coinaddr,data,24+offset)) != 0 ) { + //printf("coinaddr.%p %s\n",coinaddr,coinaddr!=0?coinaddr:"null"); } else printf("null coinaddr taddr.%02x\n",taddr); return(coinaddr); } @@ -2203,7 +2237,7 @@ int32_t base58encode_checkbuf(char *symbol,uint8_t taddr,uint8_t addrtype,uint8_ //for (i=0; i<32; i++) // printf("%02x",hash.bytes[i]); //printf(" checkhash\n"); - if ( strcmp(symbol,"GRS") != 0 ) + if ( strcmp(symbol,"GRS") != 0 && strcmp(symbol,"SMART") != 0 ) { for (i=0; i<4; i++) data[data_len+i+offset] = hash.bytes[31-i]; @@ -2239,7 +2273,7 @@ int32_t bitcoin_wif2priv(char *symbol,uint8_t wiftaddr,uint8_t *addrtypep,bits25 ptr = buf; hash = bits256_calcaddrhash(symbol,ptr,len - 4); *addrtypep = (wiftaddr == 0) ? *ptr : ptr[1]; - if ( strcmp(symbol,"GRS") != 0 && (ptr[len - 4]&0xff) == hash.bytes[31] && (ptr[len - 3]&0xff) == hash.bytes[30] &&(ptr[len - 2]&0xff) == hash.bytes[29] && (ptr[len - 1]&0xff) == hash.bytes[28] ) + if ( (ptr[len - 4]&0xff) == hash.bytes[31] && (ptr[len - 3]&0xff) == hash.bytes[30] &&(ptr[len - 2]&0xff) == hash.bytes[29] && (ptr[len - 1]&0xff) == hash.bytes[28] ) { //int32_t i; for (i=0; i= BTC2_HARDFORK_HEIGHT ) hashtype |= (0x777 << 20); #endif + if ( btcpflag != 0 ) + { + hashtype = 0x2a41; + //printf("BTCP detected: hardcode hashtype to %08x\n",hashtype); + } len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype); if ( sbtcflag != 0 ) { @@ -3478,10 +3522,10 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht len += iguana_voutparse(1,&serialized[len],&dest.vouts[i]); outputhash = bits256_doublesha256(0,serialized,len); - char str[65]; printf("prevouthash.%s ",bits256_str(str,prevouthash)); - printf("seqhash.%s ",bits256_str(str,seqhash)); - printf("outputhash.%s ",bits256_str(str,outputhash)); - printf("vini.%d prev.%s/v%d\n",vini,bits256_str(str,dest.vins[vini].prev_hash),dest.vins[vini].prev_vout); + //char str[65]; printf("prevouthash.%s ",bits256_str(str,prevouthash)); + //printf("seqhash.%s ",bits256_str(str,seqhash)); + //printf("outputhash.%s ",bits256_str(str,outputhash)); + //printf("vini.%d prev.%s/v%d\n",vini,bits256_str(str,dest.vins[vini].prev_hash),dest.vins[vini].prev_vout); /*01000000 997c1040c67ee2f9ab21abf7457f7aec4503970e974e532b6578f326c270b7eb 445066705e799022b7095f7ceca255149f43acfc47e7f59e551f7bce2930b13b @@ -3572,7 +3616,7 @@ uint32_t LP_sighash(char *symbol,int32_t zcash) sighash |= SIGHASH_FORKID; sighash |= (LP_IS_BITCOINGOLD << 8); } - else if ( strcmp(symbol,"SBTC") == 0 ) + else if ( strcmp(symbol,"SBTC") == 0 || strcmp(symbol,"BTCP") == 0 ) sighash |= SIGHASH_FORKID; return(sighash); } diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c index 98bffda0d..7f04c2946 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -57,7 +57,7 @@ struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 tx tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest"); LP_destaddr(tx->outpoints[i].coinaddr,vout); //printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value)); - LP_address_utxoadd((uint32_t)time(NULL),"LP_create_transaction",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_create_transaction",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); } for (i=0; ioutpoints[spentvout].spendtxid = txid; tx->outpoints[spentvout].spendvini = i; tx->outpoints[spentvout].spendheight = height > 0 ? height : 1; - LP_address_utxoadd((uint32_t)time(NULL),"LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1); + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1); if ( 0 && strcmp(coin->symbol,"REVS") == 0 ) printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height); } @@ -159,29 +159,6 @@ void LP_cacheptrs_init(struct iguana_info *coin) OS_truncate(fname,len); } -bits256 iguana_merkle(char *symbol,bits256 *tree,int32_t txn_count) -{ - int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; - if ( txn_count == 1 ) - return(tree[0]); - prev = 0; - while ( txn_count > 1 ) - { - if ( (txn_count & 1) != 0 ) - tree[prev + txn_count] = tree[prev + txn_count-1], txn_count++; - n += txn_count; - for (i=0; i> 1)] = bits256_calctxid(symbol,serialized,sizeof(serialized)); - } - prev = n; - txn_count >>= 1; - } - return(tree[n]); -} - bits256 validate_merkle(int32_t pos,bits256 txid,cJSON *proofarray,int32_t proofsize) { int32_t i; uint8_t serialized[sizeof(bits256) * 2]; bits256 hash,proof; diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c index 4134936bf..e3a75cb8b 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -214,7 +214,7 @@ uint16_t LP_userpass(char *userpass,char *symbol,char *assetname,char *confroot, cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) { - struct electrum_info *ep; bits256 zero; int32_t notarized; uint64_t balance; char wifstr[128],ipaddr[64]; uint8_t tmptype; bits256 checkkey; cJSON *item = cJSON_CreateObject(); + struct electrum_info *ep; bits256 zero; int32_t notarized; uint64_t balance; char wifstr[128],ipaddr[72]; uint8_t tmptype; bits256 checkkey; cJSON *item = cJSON_CreateObject(); jaddstr(item,"coin",coin->symbol); if ( showwif != 0 ) { @@ -236,6 +236,14 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) jaddnum(item,"balance",dstr(balance)); jaddnum(item,"KMDvalue",dstr(LP_KMDvalue(coin,balance))); } +#ifndef NOTETOMIC + else if (coin->etomic[0] != 0) { + //balance = LP_etomic_get_balance(coin, coin->smartaddr); + jaddnum(item,"height",-1); + //jaddnum(item,"balance",dstr(balance)); + jaddnum(item,"balance",0); + } +#endif else { jaddnum(item,"height",-1); @@ -275,8 +283,8 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif) struct iguana_info *LP_conflicts_find(struct iguana_info *refcoin) { - struct iguana_info *coin=0,*tmp; - if ( refcoin != 0 ) + struct iguana_info *coin=0,*tmp; int32_t n; + if ( refcoin != 0 && (n= (int32_t)strlen(refcoin->serverport)) > 3 && strcmp(":80",&refcoin->serverport[n-3]) != 0 ) { HASH_ITER(hh,LP_coins,coin,tmp) { @@ -309,7 +317,7 @@ char *LP_getcoin(char *symbol) HASH_ITER(hh,LP_coins,coin,tmp) { if ( strcmp(symbol,coin->symbol) == 0 ) - item = LP_coinjson(coin,0); + item = LP_coinjson(coin,LP_showwif); if ( coin->inactive == 0 ) numenabled++; else numdisabled++; @@ -342,6 +350,7 @@ struct iguana_info *LP_coinadd(struct iguana_info *cdata) *coin = *cdata; portable_mutex_init(&coin->txmutex); portable_mutex_init(&coin->addrmutex); + portable_mutex_init(&coin->addressutxo_mutex); portable_mutex_lock(&LP_coinmutex); HASH_ADD_KEYPTR(hh,LP_coins,coin->symbol,strlen(coin->symbol),coin); portable_mutex_unlock(&LP_coinmutex); @@ -375,7 +384,8 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse if ( assetname != 0 && strcmp(name,assetname) == 0 ) { //printf("%s is assetchain\n",symbol); - coin->isassetchain = 1; + if ( strcmp(name,"BEER") != 0 && strcmp("PIZZA",name) != 0 ) + coin->isassetchain = 1; } if ( strcmp(symbol,"KMD") == 0 || (assetname != 0 && assetname[0] != 0) ) name2 = 0; diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 94186c659..d569ec81b 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -118,12 +118,12 @@ inventory(coin, reset=0, [passphrase=])\n\ lastnonce()\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[])\n\ +withdraw(coin, outputs[], broadcast=0)\n\ sendrawtransaction(coin, signedtx)\n\ -swapstatus(pending=0)\n\ +swapstatus(pending=0, fast=0)\n\ swapstatus(coin, limit=10)\n\ swapstatus(base, rel, limit=10)\n\ -swapstatus(requestid, quoteid, pending=0)\n\ +swapstatus(requestid, quoteid, pending=0, fast=0)\n\ recentswaps(limit=3)\n\ notarizations(coin)\n\ public API:\n \ @@ -140,6 +140,7 @@ balances(address)\n\ fundvalue(address="", holdings=[], divisor=0)\n\ orderbook(base, rel, duration=3600)\n\ getprices()\n\ +inuse()\n\ getmyprice(base, rel)\n\ getprice(base, rel)\n\ //sendmessage(base=coin, rel="", pubkey=zero, )\n\ @@ -159,32 +160,30 @@ bot_settings(botid, newprice, newvolume)\n\ bot_status(botid)\n\ bot_stop(botid)\n\ bot_pause(botid)\n\ +calcaddress(passphrase, coin=KMD)\n\ +convaddress(coin, address, destcoin)\n\ instantdex_deposit(weeks, amount, broadcast=1)\n\ instantdex_claim()\n\ +timelock(coin, duration, destaddr=(tradeaddr), amount)\n\ +unlockedspend(coin, txid)\n\ +opreturndecrypt(coin, txid, passphrase)\n\ +getendpoint(port=5555)\n\ +listtransactions(coin, address, count=10, skip=0)\n\ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ \"}")); - //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ - + if ( (base= jstr(argjson,"base")) == 0 ) base = ""; if ((rel= jstr(argjson,"rel")) == 0 ) rel = ""; if ( (coin= jstr(argjson,"coin")) == 0 ) coin = ""; - if ( G.USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 ) // protected localhost + if ( G.USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 && strcmp(method,"psock") != 0 ) // protected localhost { if ( G.USERPASS_COUNTER == 0 ) { - char pub33str[67]; G.USERPASS_COUNTER = 1; - retjson = cJSON_CreateObject(); - jaddstr(retjson,"userpass",G.USERPASS); - jaddbits256(retjson,"mypubkey",G.LP_mypub25519); - init_hexbytes_noT(pub33str,G.LP_pubsecp,33); - jaddstr(retjson,"pubsecp",pub33str); - jadd(retjson,"coins",LP_coinsjson(LP_showwif)); LP_cmdcount++; - return(jprint(retjson,1)); } // if passphrase api and passphrase is right, ignore userpass, use hass of passphrase if ( strcmp(method,"passphrase") == 0 && (passphrase= jstr(argjson,"passphrase")) != 0 ) @@ -195,7 +194,8 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ authenticated = 1; else printf("passhash %s != G %s\n",bits256_str(str,passhash),bits256_str(str2,G.LP_passhash)); } - if ( authenticated == 0 && ((userpass= jstr(argjson,"userpass")) == 0 || strcmp(userpass,G.USERPASS) != 0) ) + char passhashstr[65]; bits256_str(passhashstr,G.LP_passhash); + if ( authenticated == 0 && ((userpass= jstr(argjson,"userpass")) == 0 || (strcmp(userpass,G.USERPASS) != 0 && strcmp(userpass,passhashstr) != 0)) ) return(clonestr("{\"error\":\"authentication error you need to make sure userpass is set\"}")); if ( jobj(argjson,"userpass") != 0 ) jdelete(argjson,"userpass"); @@ -232,6 +232,45 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ } return(clonestr("{\"error\":\"cant find KMD\"}")); } + else if ( strcmp(method,"getendpoint") == 0 ) + { + int32_t err,mode; uint16_t wsport = 5555; char endpoint[64],bindpoint[64]; + if ( juint(argjson,"port") != 0 ) + wsport = juint(argjson,"port"); + retjson = cJSON_CreateObject(); + if ( IPC_ENDPOINT >= 0 ) + { + jaddstr(retjson,"error","IPC endpoint already exists"); + jaddnum(retjson,"socket",IPC_ENDPOINT); + } + else + { + if ( (IPC_ENDPOINT= nn_socket(AF_SP,NN_PAIR)) >= 0 ) + { + sprintf(bindpoint,"ws://*:%u",wsport); + sprintf(endpoint,"ws://127.0.0.1:%u",wsport); + if ( (err= nn_bind(IPC_ENDPOINT,bindpoint)) >= 0 ) + { + jaddstr(retjson,"result","success"); + jaddstr(retjson,"endpoint",endpoint); + jaddnum(retjson,"socket",IPC_ENDPOINT); + mode = NN_WS_MSG_TYPE_TEXT; + err = nn_setsockopt(IPC_ENDPOINT,NN_SOL_SOCKET,NN_WS_MSG_TYPE,&mode,sizeof(mode)); + jaddnum(retjson,"sockopt",err); + } + else + { + jaddstr(retjson,"error",(char *)nn_strerror(nn_errno())); + jaddstr(retjson,"bind",bindpoint); + jaddnum(retjson,"err",err); + jaddnum(retjson,"socket",IPC_ENDPOINT); + nn_close(IPC_ENDPOINT); + IPC_ENDPOINT = -1; + } + } else jaddstr(retjson,"error","couldnt get NN_PAIR socket"); + } + return(jprint(retjson,1)); + } else if ( strcmp(method,"instantdex_claim") == 0 ) { if ( (ptr= LP_coinsearch("KMD")) != 0 ) @@ -300,6 +339,50 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ { return(LP_portfolio()); } + else if ( strcmp(method,"calcaddress") == 0 ) + { + bits256 privkey,pub; uint8_t pubtype,wiftaddr,p2shtype,taddr,wiftype,pubkey33[33]; char *passphrase,coinaddr[64],wifstr[64],pubsecp[67]; + if ( (passphrase= jstr(argjson,"passphrase")) != 0 ) + { + conv_NXTpassword(privkey.bytes,pub.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + privkey.bytes[0] &= 248, privkey.bytes[31] &= 127, privkey.bytes[31] |= 64; + if ( (coin= jstr(argjson,"coin")) == 0 || (ptr= LP_coinfind(coin)) == 0 ) + { + coin = "KMD"; + taddr = 0; + pubtype = 60; + p2shtype = 85; + wiftype = 188; + wiftaddr = 0; + } + else + { + coin = ptr->symbol; + taddr = ptr->taddr; + pubtype = ptr->pubtype; + p2shtype = ptr->p2shtype; + wiftype = ptr->wiftype; + wiftaddr = ptr->wiftaddr; + } + retjson = cJSON_CreateObject(); + jaddstr(retjson,"passphrase",passphrase); + bitcoin_priv2pub(ctx,coin,pubkey33,coinaddr,privkey,taddr,pubtype); + init_hexbytes_noT(pubsecp,pubkey33,33); + jaddstr(retjson,"pubsecp",pubsecp); + jaddstr(retjson,"coinaddr",coinaddr); + bitcoin_priv2pub(ctx,coin,pubkey33,coinaddr,privkey,taddr,p2shtype); + jaddstr(retjson,"p2shaddr",coinaddr); + 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\"}")); + } else if ( strcmp(method,"statsdisp") == 0 ) { return(jprint(LP_statslog_disp(juint(argjson,"starttime"),juint(argjson,"endtime"),jstr(argjson,"gui"),jbits256(argjson,"pubkey"),jstr(argjson,"base"),jstr(argjson,"rel")),1)); @@ -319,12 +402,12 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ { uint32_t requestid,quoteid; if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) - return(basilisk_swapentry(requestid,quoteid,1)); + return(basilisk_swapentry(jint(argjson,"fast"),requestid,quoteid,1)); else if ( coin[0] != 0 ) - return(basilisk_swapentries(coin,0,jint(argjson,"limit"))); + return(basilisk_swapentries(1,coin,0,jint(argjson,"limit"))); else if ( base[0] != 0 && rel[0] != 0 ) - return(basilisk_swapentries(base,rel,jint(argjson,"limit"))); - else return(basilisk_swaplist(0,0,0,jint(argjson,"pending"))); + return(basilisk_swapentries(1,base,rel,jint(argjson,"limit"))); + else return(basilisk_swaplist(jint(argjson,"fast"),0,0,1,jint(argjson,"pending"))); } else if ( strcmp(method,"dynamictrust") == 0 ) { @@ -343,6 +426,8 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ } return(clonestr("{\"error\":\"cant find address\"}")); } + else if ( strcmp(method,"inuse") == 0 ) + return(jprint(LP_inuse_json(),1)); else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) return(retstr); if ( base[0] != 0 && rel[0] != 0 ) @@ -397,18 +482,30 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ } else if ( strcmp(method,"buy") == 0 ) { - //* + int32_t fomo = 0; double vol; + if ( jobj(argjson,"fomo") != 0 ) + { + fomo = 1; + price = 1.; + vol = jdouble(argjson,"fomo"); + } else vol = jdouble(argjson,"relvolume"); if ( price > SMALLVAL ) { - return(LP_autobuy(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0)); + 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)); } else return(clonestr("{\"error\":\"no price set\"}")); } else if ( strcmp(method,"sell") == 0 ) { - //* + int32_t fomo = 0; double vol; + if ( jobj(argjson,"dump") != 0 ) + { + fomo = 1; + price = 1.; + vol = jdouble(argjson,"dump"); + } else vol = jdouble(argjson,"basevolume"); if ( price > SMALLVAL ) { - return(LP_autobuy(ctx,myipaddr,pubsock,rel,base,1./price,jdouble(argjson,"basevolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0)); + 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)); } else return(clonestr("{\"error\":\"no price set\"}")); } } @@ -426,7 +523,7 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ //* if ( (ptr= LP_coinsearch(coin)) != 0 ) { - if ( ptr->userpass[0] == 0 ) + if ( ptr->userpass[0] == 0 && ptr->etomic[0] == 0 ) { cJSON *retjson = cJSON_CreateObject(); jaddstr(retjson,"error",LP_DONTCHANGE_ERRMSG0); @@ -435,23 +532,13 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ } if ( LP_conflicts_find(ptr) == 0 ) { + cJSON *array; ptr->inactive = 0; - cJSON *array; int32_t notarized; - if ( LP_getheight(¬arized,ptr) <= 0 ) - { - ptr->inactive = (uint32_t)time(NULL); - return(clonestr("{\"error\":\"coin cant be activated till synced\"}")); - } - else - { - if ( ptr->smartaddr[0] != 0 ) - LP_unspents_load(coin,ptr->smartaddr); + if ( ptr->smartaddr[0] != 0 ) LP_unspents_load(coin,ptr->smartaddr); - if ( strcmp(ptr->symbol,"KMD") == 0 ) - LP_importaddress("KMD",BOTS_BONDADDRESS); - } - if ( 0 && strcmp(coin,"BCH") == 0 ) - test_validate(ptr,"010000000110b365ea6b8a9f2d56dc12de868e382dc787b2e29355f9b357dcf764c5e29cb1010000006b483045022100c605b993f1db5f31046ebb9065bea0a047f478342bbad8fcfc6af81d05236bd502206e9993a737a8814b935b5e522e750c915e7d37e3bd8367f087d4510f66acac47412102ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92ffffffff014bc22900000000001976a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688ac00000000"); + LP_unspents_load(coin,ptr->smartaddr); + if ( strcmp(ptr->symbol,"KMD") == 0 ) + LP_importaddress("KMD",BOTS_BONDADDRESS); array = cJSON_CreateArray(); jaddi(array,LP_coinjson(ptr,0)); return(jprint(array,1)); @@ -509,20 +596,52 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ { return(LP_sendrawtransaction(coin,jstr(argjson,"signedtx"))); } + else if ( strcmp(method,"convaddress") == 0 ) + { + return(LP_convaddress(coin,jstr(argjson,"address"),jstr(argjson,"destcoin"))); + } + else if ( strcmp(method,"timelock") == 0 ) + { + return(LP_timelock(coin,juint(argjson,"duration"),jstr(argjson,"destaddr"),jdouble(argjson,"amount")*SATOSHIDEN)); + } + else if ( strcmp(method,"opreturndecrypt") == 0 ) + { + return(LP_opreturndecrypt(ctx,coin,jbits256(argjson,"txid"),jstr(argjson,"passphrase"))); + } + else if ( strcmp(method,"unlockedspend") == 0 ) + { + return(LP_unlockedspend(ctx,coin,jbits256(argjson,"txid"))); + } + // cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t count,int32_t skip) + else if ( strcmp(method,"listtransactions") == 0 ) + { + if ( (ptr= LP_coinfind(coin)) != 0 ) + return(jprint(LP_listtransactions(coin,jstr(argjson,"address"),juint(argjson,"count"),juint(argjson,"skip")),1)); + } else if ( strcmp(method,"getrawtransaction") == 0 ) { - return(jprint(LP_gettx(coin,jbits256(argjson,"txid"),0),1)); + return(jprint(LP_gettx("stats_JSON",coin,jbits256(argjson,"txid"),0),1)); } else if ( strcmp(method,"withdraw") == 0 ) { if ( (ptr= LP_coinsearch(coin)) != 0 ) { - if ( jobj(argjson,"outputs") == 0 ) + if ( jobj(argjson,"outputs") == 0 && jstr(argjson,"opreturn") == 0 ) return(clonestr("{\"error\":\"withdraw needs to have outputs\"}")); + else if ( ptr->etomic[0] != 0 ) + return(clonestr("{\"error\":\"use eth_withdraw for ETH/ERC20\"}")); else return(LP_withdraw(ptr,argjson)); } return(clonestr("{\"error\":\"cant find coind\"}")); } +#ifndef NOTETOMIC + else if ( strcmp(method,"eth_withdraw") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) { + return LP_eth_withdraw(ptr, argjson); + } + } +#endif else if ( strcmp(method,"setconfirms") == 0 ) { int32_t n; @@ -565,14 +684,14 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ } if ( strcmp(method,"inventory") == 0 ) { - struct iguana_info *ptr; + struct iguana_info *ptr; int32_t num; if ( (ptr= LP_coinfind(coin)) != 0 ) { LP_address(ptr,ptr->smartaddr); if ( jint(argjson,"reset") != 0 ) { ptr->privkeydepth = 0; - LP_address_utxo_reset(ptr); + LP_address_utxo_reset(&num,ptr); LP_passphrase_init(jstr(argjson,"passphrase"),G.gui,G.netid,G.seednode); } if ( bits256_nonz(G.LP_privkey) != 0 ) @@ -586,7 +705,7 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ //jadd(retjson,"alice",LP_inventory(coin)); //jadd(retjson,"bob",LP_inventory(coin,1)); //LP_smartutxos_push(ptr); - LP_address_utxo_reset(ptr); + LP_address_utxo_reset(&num,ptr); return(jprint(retjson,1)); } } @@ -643,7 +762,10 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ if ( strcmp(method,"swapstatus") == 0 ) return(LP_swapstatus_recv(argjson)); else if ( strcmp(method,"gettradestatus") == 0 ) - return(LP_gettradestatus(j64bits(argjson,"aliceid"),juint(argjson,"requestid"),juint(argjson,"quoteid"))); + { + retstr = clonestr("{\"error\":\"deprecated\"}"); + //return(LP_gettradestatus(j64bits(argjson,"aliceid"),juint(argjson,"requestid"),juint(argjson,"quoteid"))); + } else if ( strcmp(method,"postprice") == 0 ) return(LP_postprice_recv(argjson)); else if ( strcmp(method,"uitem") == 0 ) @@ -702,7 +824,7 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ else if ( strcmp(method,"tradestatus") == 0 ) { LP_tradecommand_log(argjson); - printf("%-4d tradestatus | aliceid.%llu RT.%d %d\n",(uint32_t)time(NULL) % 3600,(long long)j64bits(argjson,"aliceid"),LP_RTcount,LP_swapscount); + //printf("%-4d tradestatus | aliceid.%llu RT.%d %d\n",(uint32_t)time(NULL) % 3600,(long long)j64bits(argjson,"aliceid"),LP_RTcount,LP_swapscount); retstr = clonestr("{\"result\":\"success\"}"); } else if ( strcmp(method,"wantnotify") == 0 ) @@ -749,16 +871,21 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ { if ( strcmp(method,"psock") == 0 ) { - if ( myipaddr == 0 || myipaddr[0] == 0 || strcmp(myipaddr,"127.0.0.1") == 0 ) - { - if ( LP_mypeer != 0 ) - myipaddr = LP_mypeer->ipaddr; - else printf("LP_psock dont have actual ipaddr?\n"); - } - if ( jint(argjson,"ispaired") != 0 ) - return(LP_psock(myipaddr,jint(argjson,"ispaired"))); - else return(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); - } + int32_t psock; + if ( myipaddr == 0 || myipaddr[0] == 0 || strcmp(myipaddr,"127.0.0.1") == 0 ) + { + if ( LP_mypeer != 0 ) + myipaddr = LP_mypeer->ipaddr; + else printf("LP_psock dont have actual ipaddr?\n"); + } + if ( jint(argjson,"ispaired") != 0 && jobj(argjson,"netid") != 0 && juint(argjson,"netid") == G.netid ) + { + retstr = LP_psock(&psock,myipaddr,1,jint(argjson,"cmdchannel"),jbits256(argjson,"pubkey")); + //printf("LP_commands.(%s)\n",retstr); + return(retstr); + } + else return(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); + } } else { diff --git a/iguana/exchanges/LP_etomic.c b/iguana/exchanges/LP_etomic.c new file mode 100644 index 000000000..c6f135a42 --- /dev/null +++ b/iguana/exchanges/LP_etomic.c @@ -0,0 +1,723 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_etomic.c +// marketmaker +// + +// +// Created by artem on 24.01.18. +// +#include "LP_etomic.h" + +int32_t LP_etomic_wait_for_confirmation(char *txId) +{ + return(waitForConfirmation(txId)); +} + +void LP_etomic_pubkeystr_to_addr(char *pubkey, char *output) +{ + char *address = pubKey2Addr(pubkey); + strcpy(output, address); + free(address); +} + +char *LP_etomicalice_send_fee(struct basilisk_swap *swap) +{ + char amount[100], secretKey[70], dexaddr[50]; + satoshisToWei(amount, swap->myfee.I.amount); + 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)); + } else { + return(sendErc20(swap->I.alicetomic, dexaddr, amount, secretKey, 1)); + } +} + +uint8_t LP_etomic_verify_alice_fee(struct basilisk_swap *swap) +{ + if (waitForConfirmation(swap->otherfee.I.ethTxid) < 0) { + printf("Alice fee tx %s does not exist", swap->otherfee.I.ethTxid); + return(0); + } + EthTxData data = getEthTxData(swap->otherfee.I.ethTxid); + if (strcmp(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); + } + + char dexaddr[50]; + LP_etomic_pubkeystr_to_addr(INSTANTDEX_PUBKEY, dexaddr); + if ( strcmp(swap->I.alicestr,"ETH") == 0 ) { + if (strcmp(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); + return(0); + } + return(1); + } else { + if (strcmp(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)); + } +} + +char *LP_etomicalice_send_payment(struct basilisk_swap *swap) +{ + AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20; BasicTxData txData; + + // set input and txData fields from the swap data structure + memset(&txData,0,sizeof(txData)); + if ( strcmp(swap->I.alicestr,"ETH") == 0 ) + { + memset(&input,0,sizeof(input)); + strcpy(input.bobAddress, swap->I.etomicsrc); + uint8arrayToHex(input.bobHash, swap->I.secretBn, 20); + uint8arrayToHex(input.aliceHash, swap->I.secretAm, 20); + uint8arrayToHex(input.dealId, swap->alicepayment.I.actualtxid.bytes, 32); + + strcpy(txData.from, swap->I.etomicdest); + strcpy(txData.to, ETOMIC_ALICECONTRACT); + satoshisToWei(txData.amount, swap->I.alicesatoshis); + uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); + + return(aliceSendsEthPayment(input,txData)); + } + else + { + 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); + + 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) { + printf("Alice token allowance is too low, setting new allowance\n"); + ApproveErc20Input approveErc20Input; + strcpy(approveErc20Input.tokenAddress, swap->I.alicetomic); + strcpy(approveErc20Input.owner, swap->I.etomicdest); + strcpy(approveErc20Input.spender, ETOMIC_ALICECONTRACT); + + char *tokenBalance = getErc20BalanceHexWei(swap->I.etomicdest, swap->I.alicetomic); + strcpy(approveErc20Input.amount, tokenBalance); + free(tokenBalance); + strcpy(approveErc20Input.secret, txData.secretKey); + + char *allowTxId = approveErc20(approveErc20Input); + LP_etomic_wait_for_confirmation(allowTxId); + free(allowTxId); + } + + return(aliceSendsErc20Payment(input20,txData)); + } +} + +uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId) +{ + if (waitForConfirmation(txId) < 0) { + printf("Alice payment %s does not exist\n", txId); + return(0); + } + EthTxData data = getEthTxData(txId); + if (strcmp(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) { + 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); + return(0); + } + memset(&input,0,sizeof(input)); + strcpy(input.bobAddress, swap->I.etomicsrc); + uint8arrayToHex(input.bobHash, swap->I.secretBn, 20); + uint8arrayToHex(input.aliceHash, swap->I.secretAm, 20); + uint8arrayToHex(input.dealId, swap->alicepayment.I.actualtxid.bytes, 32); + + return(verifyAliceEthPaymentData(input, data.input)); + } else { + 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); + + return(verifyAliceErc20PaymentData(input20, data.input)); + } +} + +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); + return NULL; + } + EthTxReceipt receipt = getEthTxReceipt(swap->alicePaymentEthTx); + if (strcmp(receipt.status, "0x1") != 0) { + printf("Alice payment receipt status failed, can't reclaim\n"); + return NULL; + } + AliceReclaimsAlicePaymentInput input; + BasicTxData txData; + memset(&txData,0,sizeof(txData)); + memset(&input,0,sizeof(input)); + + struct iguana_info *ecoin; + bits256 privkey; + ecoin = LP_coinfind("ETOMIC"); + privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); + + uint8arrayToHex(input.dealId, swap->txids[BASILISK_ALICEPAYMENT].bytes, 32); + satoshisToWei(input.amount, swap->destamount); + + if (swap->alicetomic[0] != 0) { + strcpy(input.tokenAddress, swap->alicetomic); + } else { + strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); + } + strcpy(input.bobAddress, swap->etomicsrc); + uint8arrayToHex(input.aliceHash, swap->secretAm, 20); + bits256 invertedSecret; + int32_t i; + for (i=0; i<32; i++) { + invertedSecret.bytes[i] = swap->privBn.bytes[31 - i]; + } + uint8arrayToHex(input.bobSecret, invertedSecret.bytes, 32); + + strcpy(txData.from, swap->etomicdest); + strcpy(txData.to, ETOMIC_ALICECONTRACT); + strcpy(txData.amount, "0"); + uint8arrayToHex(txData.secretKey, privkey.bytes, 32); + return aliceReclaimsAlicePayment(input, txData); +} + +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); + return NULL; + } + EthTxReceipt receipt = getEthTxReceipt(swap->alicePaymentEthTx); + if (strcmp(receipt.status, "0x1") != 0) { + printf("Alice payment receipt status failed, can't spend\n"); + return NULL; + } + BobSpendsAlicePaymentInput input; + BasicTxData txData; + + memset(&txData,0,sizeof(txData)); + memset(&input,0,sizeof(input)); + + struct iguana_info *ecoin; + bits256 privkey; + ecoin = LP_coinfind("ETOMIC"); + privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); + + uint8arrayToHex(input.dealId, swap->txids[BASILISK_ALICEPAYMENT].bytes, 32); + satoshisToWei(input.amount, swap->destamount); + + if (swap->alicetomic[0] != 0) { + strcpy(input.tokenAddress, swap->alicetomic); + } else { + strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); + } + + strcpy(input.aliceAddress, swap->etomicdest); + bits256 invertedSecret; int32_t i; + for (i=0; i<32; i++) { + invertedSecret.bytes[i] = swap->privAm.bytes[31 - i]; + } + uint8arrayToHex(input.aliceSecret, invertedSecret.bytes, 32); + uint8arrayToHex(input.bobHash, swap->secretBn, 20); + + strcpy(txData.from, swap->etomicsrc); + strcpy(txData.to, ETOMIC_ALICECONTRACT); + strcpy(txData.amount, "0"); + uint8arrayToHex(txData.secretKey, privkey.bytes, 32); + return bobSpendsAlicePayment(input, txData); +} + +char *LP_etomicbob_sends_deposit(struct basilisk_swap *swap) +{ + BobSendsEthDepositInput input; + BobSendsErc20DepositInput input20; + BasicTxData txData; + memset(&txData,0,sizeof(txData)); + memset(&input,0,sizeof(input)); + memset(&input20,0,sizeof(input20)); + if ( strcmp(swap->I.bobstr,"ETH") == 0 ) { + uint8arrayToHex(input.depositId, swap->bobdeposit.I.actualtxid.bytes, 32); + strcpy(input.aliceAddress, swap->I.etomicdest); + uint8arrayToHex(input.bobHash, swap->I.secretBn, 20); + input.lockTime = swap->bobdeposit.I.locktime; + + strcpy(txData.from, swap->I.etomicsrc); + strcpy(txData.to, ETOMIC_BOBCONTRACT); + satoshisToWei(txData.amount, swap->bobdeposit.I.amount); + uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); + return bobSendsEthDeposit(input, txData); + } else { + 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); + strcpy(input20.tokenAddress, swap->I.bobtomic); + input20.lockTime = swap->bobdeposit.I.locktime; + + 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) { + printf("Bob token allowance is too low, setting new allowance\n"); + ApproveErc20Input approveErc20Input; + strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic); + strcpy(approveErc20Input.owner, swap->I.etomicsrc); + strcpy(approveErc20Input.spender, ETOMIC_BOBCONTRACT); + + char *tokenBalance = getErc20BalanceHexWei(swap->I.etomicsrc, swap->I.bobtomic); + strcpy(approveErc20Input.amount, tokenBalance); + free(tokenBalance); + strcpy(approveErc20Input.secret, txData.secretKey); + + char *allowTxId = approveErc20(approveErc20Input); + LP_etomic_wait_for_confirmation(allowTxId); + free(allowTxId); + } + + return bobSendsErc20Deposit(input20, txData); + } +} + +uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId) +{ + if (waitForConfirmation(txId) < 0) { + printf("Bob deposit txid %s does not exist\n", txId); + return(0); + } + EthTxData data = getEthTxData(txId); + if (strcmp(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) { + printf("Bob deposit txid %s was sent from wrong address %s\n", txId, data.from); + return(0); + } + BobSendsEthDepositInput input; + BobSendsErc20DepositInput input20; + memset(&input,0,sizeof(input)); + 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); + return(0); + } + uint8arrayToHex(input.depositId, swap->bobdeposit.I.actualtxid.bytes, 32); + strcpy(input.aliceAddress, swap->I.etomicdest); + uint8arrayToHex(input.bobHash, swap->I.secretBn, 20); + input.lockTime = swap->bobdeposit.I.locktime; + + return verifyBobEthDepositData(input, data.input); + } else { + 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); + strcpy(input20.tokenAddress, swap->I.bobtomic); + input20.lockTime = swap->bobdeposit.I.locktime; + + return verifyBobErc20DepositData(input20, data.input); + } +} + +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); + return NULL; + } + BobRefundsDepositInput input; + BasicTxData txData; + memset(&txData,0,sizeof(txData)); + memset(&input,0,sizeof(input)); + + struct iguana_info *ecoin; + bits256 privkey; + ecoin = LP_coinfind("ETOMIC"); + privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); + + EthTxReceipt receipt = getEthTxReceipt(swap->bobDepositEthTx); + if (strcmp(receipt.status, "0x1") != 0) { + printf("Bob deposit %s receipt status failed, can't refund\n", swap->bobDepositEthTx); + return NULL; + } + uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32); + strcpy(input.aliceAddress, swap->etomicdest); + + bits256 invertedSecret; + int32_t i; + for (i=0; i<32; i++) { + invertedSecret.bytes[i] = swap->privBn.bytes[31 - i]; + } + uint8arrayToHex(input.bobSecret, invertedSecret.bytes, 32); + + if (swap->bobtomic[0] != 0) { + strcpy(input.tokenAddress, swap->bobtomic); + } else { + strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); + } + satoshisToWei(input.amount, swap->values[BASILISK_BOBDEPOSIT]); + + strcpy(txData.from, swap->etomicsrc); + strcpy(txData.to, ETOMIC_BOBCONTRACT); + strcpy(txData.amount, "0"); + uint8arrayToHex(txData.secretKey, privkey.bytes, 32); + return bobRefundsDeposit(input, txData); +} + +char *LP_etomicbob_sends_payment(struct basilisk_swap *swap) +{ + BobSendsEthPaymentInput input; + BobSendsErc20PaymentInput input20; + BasicTxData txData; + memset(&txData,0,sizeof(txData)); + memset(&input,0,sizeof(input)); + memset(&input20,0,sizeof(input20)); + + if ( strcmp(swap->I.bobstr,"ETH") == 0 ) { + uint8arrayToHex(input.paymentId, swap->bobpayment.I.actualtxid.bytes, 32); + strcpy(input.aliceAddress, swap->I.etomicdest); + uint8arrayToHex(input.aliceHash, swap->I.secretAm, 20); + input.lockTime = swap->bobpayment.I.locktime; + + strcpy(txData.from, swap->I.etomicsrc); + strcpy(txData.to, ETOMIC_BOBCONTRACT); + satoshisToWei(txData.amount, swap->bobpayment.I.amount); + uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); + return bobSendsEthPayment(input, txData); + } else { + 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); + strcpy(input20.tokenAddress, swap->I.bobtomic); + input20.lockTime = swap->bobpayment.I.locktime; + + 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) { + printf("Bob token allowance is too low, setting new allowance\n"); + ApproveErc20Input approveErc20Input; + strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic); + strcpy(approveErc20Input.owner, swap->I.etomicsrc); + strcpy(approveErc20Input.spender, ETOMIC_BOBCONTRACT); + + char *tokenBalance = getErc20BalanceHexWei(swap->I.etomicsrc, swap->I.bobtomic); + strcpy(approveErc20Input.amount, tokenBalance); + free(tokenBalance); + strcpy(approveErc20Input.secret, txData.secretKey); + + char *allowTxId = approveErc20(approveErc20Input); + LP_etomic_wait_for_confirmation(allowTxId); + free(allowTxId); + } + + return bobSendsErc20Payment(input20, txData); + } +} + +uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId) +{ + if (waitForConfirmation(txId) < 0) { + printf("Bob payment %s is not found\n", txId); + return 0; + } + EthTxData data = getEthTxData(txId); + if (strcmp(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) { + 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); + return(0); + } + uint8arrayToHex(input.paymentId, swap->bobpayment.I.actualtxid.bytes, 32); + strcpy(input.aliceAddress, swap->I.etomicdest); + uint8arrayToHex(input.aliceHash, swap->I.secretAm, 20); + input.lockTime = swap->bobpayment.I.locktime; + + return verifyBobEthPaymentData(input, data.input); + } else { + 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); + strcpy(input20.tokenAddress, swap->I.bobtomic); + input20.lockTime = swap->bobpayment.I.locktime; + + return verifyBobErc20PaymentData(input20, data.input); + } +} + +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); + return NULL; + } + BobReclaimsBobPaymentInput input; + BasicTxData txData; + memset(&txData,0,sizeof(txData)); + memset(&input,0,sizeof(input)); + + struct iguana_info *ecoin; + bits256 privkey; + ecoin = LP_coinfind("ETOMIC"); + privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); + + EthTxReceipt receipt = getEthTxReceipt(swap->bobPaymentEthTx); + 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); + strcpy(input.aliceAddress, swap->etomicdest); + uint8arrayToHex(input.aliceHash, swap->secretAm, 20); + + if (swap->bobtomic[0] != 0) { + strcpy(input.tokenAddress, swap->bobtomic); + } else { + strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); + } + satoshisToWei(input.amount, swap->values[BASILISK_BOBPAYMENT]); + + strcpy(txData.from, swap->etomicsrc); + strcpy(txData.to, ETOMIC_BOBCONTRACT); + strcpy(txData.amount, "0"); + uint8arrayToHex(txData.secretKey, privkey.bytes, 32); + return bobReclaimsBobPayment(input, txData); +} + +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); + return NULL; + } + AliceSpendsBobPaymentInput input; + BasicTxData txData; + + memset(&txData,0,sizeof(txData)); + memset(&input,0,sizeof(input)); + EthTxReceipt receipt = getEthTxReceipt(swap->bobPaymentEthTx); + if (strcmp(receipt.status, "0x1") != 0) { + printf("Bob payment %s receipt status failed, can't spend\n", swap->bobPaymentEthTx); + return NULL; + } + struct iguana_info *ecoin; + bits256 privkey; + ecoin = LP_coinfind("ETOMIC"); + 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 (swap->bobtomic[0] != 0) { + strcpy(input.tokenAddress, swap->bobtomic); + } else { + strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); + } + + strcpy(input.bobAddress, swap->etomicsrc); + bits256 invertedSecret; int32_t i; + + for (i=0; i<32; i++) { + invertedSecret.bytes[i] = swap->privAm.bytes[31 - i]; + } + uint8arrayToHex(input.aliceSecret, invertedSecret.bytes, 32); + + strcpy(txData.from, swap->etomicdest); + strcpy(txData.to, ETOMIC_BOBCONTRACT); + strcpy(txData.amount, "0"); + uint8arrayToHex(txData.secretKey, privkey.bytes, 32); + return aliceSpendsBobPayment(input, txData); +} + +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); + return NULL; + } + AliceClaimsBobDepositInput input; + BasicTxData txData; + + memset(&txData,0,sizeof(txData)); + memset(&input,0,sizeof(input)); + EthTxReceipt receipt = getEthTxReceipt(swap->bobDepositEthTx); + if (strcmp(receipt.status, "0x1") != 0) { + printf("Bob deposit receipt status failed, can't claim\n"); + return NULL; + } + + struct iguana_info *ecoin; + bits256 privkey; + ecoin = LP_coinfind("ETOMIC"); + 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 (swap->bobtomic[0] != 0) { + strcpy(input.tokenAddress, swap->bobtomic); + } else { + strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); + } + + strcpy(input.bobAddress, swap->etomicsrc); + uint8arrayToHex(input.bobHash, swap->secretBn, 20); + + strcpy(txData.from, swap->etomicdest); + strcpy(txData.to, ETOMIC_BOBCONTRACT); + strcpy(txData.amount, "0"); + uint8arrayToHex(txData.secretKey, privkey.bytes, 32); + return aliceClaimsBobDeposit(input, txData); +} + +char *sendEthTx(struct basilisk_swap *swap, struct basilisk_rawtx *rawtx) +{ + if (rawtx == &swap->alicepayment && swap->I.alicetomic[0] != 0) { + return LP_etomicalice_send_payment(swap); + } else if (rawtx == &swap->bobdeposit && swap->I.bobtomic[0] != 0) { + return LP_etomicbob_sends_deposit(swap); + } else if (rawtx == &swap->bobpayment && swap->I.bobtomic[0] != 0) { + return LP_etomicbob_sends_payment(swap); + } else if (swap->I.iambob == 0 && rawtx == &swap->myfee && swap->I.alicetomic[0] != 0) { + return LP_etomicalice_send_fee(swap); + } else { + char *result = malloc(67); + strcpy(result, EMPTY_ETH_TX_ID); + return result; + } +} + +int32_t LP_etomic_priv2addr(char *coinaddr,bits256 privkey) +{ + char str[65],*addrstr; + bits256_str(str,privkey); + if ( (addrstr= privKey2Addr(str)) != 0 ) + { + strcpy(coinaddr,addrstr); + free(addrstr); + return(0); + } + return(-1); +} + +int32_t LP_etomic_priv2pub(uint8_t *pub64,bits256 privkey) +{ + char *pubstr,str[72]; int32_t retval = -1; + bits256_str(str,privkey); + if ( (pubstr= getPubKeyFromPriv(str)) != 0 ) + { + if ( strlen(pubstr) == 130 && pubstr[0] == '0' && pubstr[1] == 'x' ) + { + decode_hex(pub64,64,pubstr+2); + retval = 0; + } + free(pubstr); + } + return(retval); +} + +int32_t LP_etomic_pub2addr(char *coinaddr,uint8_t pub64[64]) +{ + char pubkeystr[131],*addrstr; + strcpy(pubkeystr,"0x"); + init_hexbytes_noT(pubkeystr+2,pub64,64); + if ( (addrstr= pubKey2Addr(pubkeystr)) != 0 ) + { + strcpy(coinaddr,addrstr); + free(addrstr); + return(0); + } + return(-1); +} + +uint8_t LP_etomic_is_empty_tx_id(char *txId) +{ + if (strcmp(txId, EMPTY_ETH_TX_ID) == 0) { + return 1; + } + return 0; +} + +uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr) +{ + if (coin->etomic[0] == 0) { + printf("Trying to get etomic balance for non-etomic coin %s!", coin->symbol); + return 0; + } + + if (strcmp(coin->symbol, "ETH") == 0) { + return getEthBalance(coinaddr); + } else { + return getErc20BalanceSatoshi(coinaddr, coin->etomic); + } +} diff --git a/iguana/exchanges/LP_etomic.h b/iguana/exchanges/LP_etomic.h new file mode 100644 index 000000000..af5de5f63 --- /dev/null +++ b/iguana/exchanges/LP_etomic.h @@ -0,0 +1,56 @@ +// +// Created by artem on 13.03.18. +// + +#ifndef SUPERNET_LP_ETOMIC_H +#define SUPERNET_LP_ETOMIC_H +#include "etomicswap/etomiclib.h" +#include "etomicswap/etomiccurl.h" +#include +#include "LP_include.h" + +int32_t LP_etomic_wait_for_confirmation(char *txId); + +char *LP_etomicalice_send_fee(struct basilisk_swap *swap); + +uint8_t LP_etomic_verify_alice_fee(struct basilisk_swap *swap); + +char *LP_etomicalice_send_payment(struct basilisk_swap *swap); + +uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId); + +char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap); + +char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap); + +char *LP_etomicbob_sends_deposit(struct basilisk_swap *swap); + +uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId); + +char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap); + +char *LP_etomicbob_sends_payment(struct basilisk_swap *swap); + +uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId); + +char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap); + +char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap); + +char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap); + +char *sendEthTx(struct basilisk_swap *swap, struct basilisk_rawtx *rawtx); + +int32_t LP_etomic_priv2addr(char *coinaddr,bits256 privkey); + +int32_t LP_etomic_priv2pub(uint8_t *pub64,bits256 privkey); + +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); + +void LP_etomic_pubkeystr_to_addr(char *pubkey, char *output); + +#endif //SUPERNET_LP_ETOMIC_H diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index 96a94c08d..ad95be0d9 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -22,9 +22,11 @@ #define LP_INCLUDE_H #ifndef LP_TECHSUPPORT -#define LP_TECHSUPPORT 0 +#define LP_TECHSUPPORT 1 #endif +#define LP_DONT_CMDCHANNEL + #ifdef FROMGUI #define printf dontprintf @@ -33,7 +35,7 @@ voind dontprintf(char *formatstr,...) {} #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "17763" +#define LP_BUILD_NUMBER "27772" #define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 1 @@ -52,11 +54,12 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #endif //#define LP_STRICTPEERS +//#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_AUTOTRADE_TIMEOUT 30 -#define LP_RESERVETIME 600 //(LP_AUTOTRADE_TIMEOUT * 2) +#define LP_RESERVETIME (LP_AUTOTRADE_TIMEOUT * 3) #define ELECTRUM_TIMEOUT 13 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 @@ -95,10 +98,10 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #define LP_SWAPSTEP_TIMEOUT 30 #define LP_MIN_TXFEE 1000 -#define LP_MINVOL 20 -#define LP_MINCLIENTVOL 200 +#define LP_MINVOL 100 +#define LP_MINCLIENTVOL 1000 #define LP_MINSIZE_TXFEEMULT 10 -#define LP_REQUIRED_TXFEE 0.8 +#define LP_REQUIRED_TXFEE 0.75 #define LP_DEXFEE(destsatoshis) ((destsatoshis) / INSTANTDEX_INSURANCEDIV) #define LP_DEPOSITSATOSHIS(satoshis) ((satoshis) + (satoshis >> 3)) @@ -199,7 +202,7 @@ struct basilisk_swap; struct basilisk_rawtxinfo { - char destaddr[64]; + char destaddr[64],ethTxid[75]; bits256 txid,signedtxid,actualtxid; int64_t amount,change,inputsum; int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys; @@ -232,7 +235,7 @@ struct basilisk_rawtx struct basilisk_swapinfo { struct basilisk_request req; - char bobstr[128],alicestr[128]; + char bobstr[128],alicestr[128],bobtomic[64],alicetomic[64],etomicsrc[65],etomicdest[65]; 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; @@ -263,7 +266,7 @@ struct basilisk_swapinfo #define BASILISK_ALICERECLAIM 9 #define BASILISK_ALICECLAIM 10 //0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0 -char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" }; +static char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" }; struct LP_swap_remember { @@ -273,7 +276,7 @@ struct LP_swap_remember 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 Agui[65],Bgui[65],gui[65],src[65],dest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)]; + char 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]; }; struct LP_outpoint @@ -297,12 +300,12 @@ struct LP_transaction struct iguana_info { UT_hash_handle hh; - portable_mutex_t txmutex,addrmutex; struct LP_transaction *transactions; struct LP_address *addresses; + portable_mutex_t txmutex,addrmutex,addressutxo_mutex; struct LP_transaction *transactions; struct LP_address *addresses; uint64_t txfee; - int32_t numutxos,notarized,longestchain,firstrefht,firstscanht,lastscanht,height; uint16_t busport; - uint32_t txversion,dPoWtime,loadedcache,electrumlist,lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime; + 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; - char symbol[128],smartaddr[64],userpass[1024],serverport[128],instantdex_address[64]; + char symbol[128],smartaddr[64],userpass[1024],serverport[128],instantdex_address[64],estimatefeestr[32],getinfostr[32],etomic[64]; // portfolio double price_kmd,force,perc,goal,goalperc,relvolume,rate; void *electrum; void *ctx; @@ -360,9 +363,10 @@ struct LP_address struct LP_peerinfo { UT_hash_handle hh; + bits256 pubkey; uint64_t ip_port; uint32_t recvtime,numrecv,ipbits,errortime,errors,numpeers,needping,lasttime,connected,lastutxos,lastpeers,diduquery,good,sessionid; - int32_t pushsock,subsock,isLP; + int32_t pushsock,subsock,isLP,pairsock; uint16_t port,netid; char ipaddr[64]; }; @@ -375,7 +379,7 @@ struct LP_quoteinfo uint64_t satoshis,txfee,destsatoshis,desttxfee,aliceid; uint32_t timestamp,quotetime,tradeid; int32_t vout,vout2,destvout,feevout,pair; - char srccoin[65],coinaddr[64],destcoin[65],destaddr[64],gui[64]; + char srccoin[65],coinaddr[64],destcoin[65],destaddr[64],gui[64],etomicsrc[65],etomicdest[65]; }; struct LP_endpoint { int32_t pair; char ipaddr[64]; uint16_t port; }; @@ -386,7 +390,7 @@ struct basilisk_swap struct LP_endpoint N; void (*balancingtrade)(struct basilisk_swap *swap,int32_t iambob); int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; - uint32_t lasttime,aborted,tradeid; + uint32_t lasttime,aborted,tradeid,received; FILE *fp; bits256 persistent_privkey,persistent_pubkey; struct basilisk_swapinfo I; @@ -430,7 +434,7 @@ struct LP_pubkey_info struct LP_pubswap *bobswaps,*aliceswaps; int64_t dynamictrust,unconfcredits; uint32_t timestamp,numerrors,lasttime,slowresponse; - int32_t istrusted; + int32_t istrusted,pairsock; uint8_t rmd160[20],sig[65],pubsecp[33],siglen; }; @@ -477,7 +481,7 @@ int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,bits256 pubkey,char struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port); uint64_t LP_value_extract(cJSON *obj,int32_t addinterest); int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vout); -char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen); +char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen,int32_t stats_JSONonly); int64_t LP_kmdvalue(char *symbol,int64_t satoshis); int64_t LP_komodo_interest(bits256 txid,int64_t value); void LP_availableset(bits256 txid,int32_t vout); @@ -485,7 +489,8 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock); int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item); void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag); -uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired); +uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired,int32_t cmdchannel,char *ipaddr); +void LP_failedmsg(uint32_t requestid,uint32_t quoteid,double val); //void LP_utxo_clientpublish(struct LP_utxoinfo *utxo); //int32_t LP_coinbus(uint16_t coin_busport); int32_t LP_nanomsg_recvs(void *ctx); @@ -493,6 +498,7 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid,uint32_t quoteid); void LP_autoprices_update(char *method,char *base,double basevol,char *rel,double relvol); cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len); +uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr); cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len); uint64_t LP_RTsmartbalance(struct iguana_info *coin); int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin); @@ -503,9 +509,13 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height); cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid); cJSON *LP_myzdebits(); +int32_t LP_opreturn_decrypt(uint16_t *ind16p,uint8_t *decoded,uint8_t *encoded,int32_t encodedlen,char *passphrase); +int32_t LP_opreturn_encrypt(uint8_t *dest,int32_t maxsize,uint8_t *data,int32_t datalen,char *passphrase,uint16_t ind16); +void LP_pendswap_add(uint32_t expiration,uint32_t requestid,uint32_t quoteid); int32_t _LP_utxos_remove(bits256 txid,int32_t vout); int32_t LP_utxos_remove(bits256 txid,int32_t vout); struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins); +char *bitcoin_address(char *symbol,char *coinaddr,uint8_t taddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len); void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid); uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen); struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr); @@ -515,6 +525,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_ //void LP_butxo_swapfields_set(struct LP_utxoinfo *butxo); struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout); int64_t LP_myzcredits(); +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); @@ -522,6 +533,7 @@ void LP_ports(uint16_t *pullportp,uint16_t *pubportp,uint16_t *busportp,uint16_t int32_t LP_destaddr(char *destaddr,cJSON *item); int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration); cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel); +uint32_t LP_claimtime(struct iguana_info *coin,uint32_t expiration); uint32_t LP_heighttime(char *symbol,int32_t height); uint64_t LP_unspents_load(char *symbol,char *addr); int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout); @@ -531,9 +543,9 @@ int32_t LP_mempoolscan(char *symbol,bits256 searchtxid); int32_t LP_txheight(struct iguana_info *coin,bits256 txid); int32_t LP_numpeers(); double LP_CMCbtcprice(double *price_usdp,char *symbol); -char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid,int32_t forceflag); +char *basilisk_swapentry(int32_t fastflag,uint32_t requestid,uint32_t quoteid,int32_t forceflag); int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance); -int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight); +int32_t LP_address_utxoadd(int32_t skipsearch,uint32_t timestamp,char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight); void LP_smartutxos_push(struct iguana_info *coin); void LP_cacheptrs_init(struct iguana_info *coin); cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret); @@ -542,15 +554,19 @@ void LP_postutxos(char *symbol,char *coinaddr); int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag); uint16_t LP_randpeer(char *destip); void LP_tradebot_pauseall(); +int32_t LP_etomic_pub2addr(char *coinaddr,uint8_t pub64[64]); void LP_portfolio_reset(); +int32_t LP_autoref_clear(char *base,char *rel); +int32_t bitcoin_addr2rmd160(char *symbol,uint8_t taddr,uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); +struct LP_pubkey_info *LP_pubkeyadd(bits256 pubkey); uint32_t LP_atomic_locktime(char *base,char *rel); struct LP_pubkey_info *LP_pubkeyfind(bits256 pubkey); -char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired); +char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired,int32_t cmdchannel); char *LP_unspents_filestr(char *symbol,char *addr); cJSON *bitcoin_data2json(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash); //int32_t LP_butxo_findeither(bits256 txid,int32_t vout); cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxid2); -int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid); +int32_t LP_gettx_presence(int32_t *numconfirmsp,char *symbol,bits256 expectedtxid,char *coinaddr); double LP_getestimatedrate(struct iguana_info *coin); struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout); struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid,int32_t vout); @@ -558,6 +574,7 @@ int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue); struct LP_address *LP_addressfind(struct iguana_info *coin,char *coinaddr); int64_t LP_outpoint_amount(char *symbol,bits256 txid,int32_t vout); void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint16_t myport,uint16_t netid,char *seednode); +int _decreasing_uint64(const void *a,const void *b); void LP_listunspent_query(char *symbol,char *coinaddr); int32_t bitcoin_priv2wif(char *symbol,uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype); @@ -565,5 +582,6 @@ int bech32_convert_bits(uint8_t *out,int32_t *outlen,int outbits,const uint8_t * int bech32_decode(char *hrp,uint8_t *data,int32_t *data_len,const char *input); int bech32_encode(char *output,const char *hrp,const uint8_t *data,int32_t data_len); void HashGroestl(void * buf, const void * pbegin, int len); +bits256 LP_privkey(char *symbol,char *coinaddr,uint8_t taddr); #endif diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c index e10f991ea..f3ddcb523 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -65,7 +65,8 @@ void LP_instantdex_deposituniq(FILE *fp,bits256 txid) for (i=0; iheight > 8 ) + { + heighttime = LP_heighttime(coin->symbol,coin->height-8); + printf("claimtime: now %u height.%d heighttime.%u expiration.%u\n",now,coin->height,heighttime,expiration); + if ( heighttime >= expiration ) + return(heighttime - 1); + } + return(0); +} + int32_t LP_deposit_addr(char *symbol,char *p2shaddr,uint8_t *script,uint8_t taddr,uint8_t p2shtype,uint32_t timestamp,uint8_t *pubsecp33) { uint8_t elsepub33[33],p2sh_rmd160[20]; int32_t n; @@ -283,10 +298,106 @@ int64_t LP_claimtx(void *ctx,struct iguana_info *coin,bits256 *claimtxidp,bits25 return(sum); } +char *LP_unlockedspend(void *ctx,char *symbol,bits256 utxotxid) +{ + cJSON *txjson,*vouts,*vout0,*opret,*sobj,*retjson; uint16_t utxovout; char *signedtx,*opretstr,vinaddr[64],destaddr[64]; uint32_t expiration,claimtime; uint8_t redeemscript[128]; bits256 signedtxid,sendtxid; int32_t numvouts,redeemlen; int64_t satoshis,destamount; struct iguana_info *coin; + if ( (coin= LP_coinfind(symbol)) == 0 ) + return(clonestr("{\"error\":\"cant find coin\"}")); + retjson = cJSON_CreateObject(); + utxovout = 0; + memset(&sendtxid,0,sizeof(sendtxid)); + if ( (txjson= LP_gettx("LP_unlockedspend",coin->symbol,utxotxid,1)) != 0 ) + { + if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts >= 2 ) + { + vout0 = jitem(vouts,0); + LP_destaddr(vinaddr,vout0); + satoshis = LP_value_extract(vout0,0); + opret = jitem(vouts,numvouts - 1); + jaddstr(retjson,"result","success"); + jaddbits256(retjson,"lockedtxid",utxotxid); + jaddnum(retjson,"amount",dstr(satoshis)); + if ( (sobj= jobj(opret,"scriptPubKey")) != 0 ) + { + if ( (opretstr= jstr(sobj,"hex")) != 0 ) + { + jaddstr(retjson,"opreturn",opretstr); + redeemlen = (int32_t)strlen(opretstr) >> 1; + if ( redeemlen == 34 ) + { + decode_hex(redeemscript,redeemlen,opretstr); + if ( redeemscript[0] == SCRIPT_OP_RETURN && redeemscript[1] == 32 && redeemscript[2] == 4 && redeemscript[7] == 0xb1 && redeemscript[8] == 0x75 && redeemscript[9] == 0x76 && redeemscript[10] == 0xa9 && redeemscript[11] == 0x14 && redeemscript[32] == 0x88 && redeemscript[33] == 0xac ) + { + expiration = 0; + expiration = (expiration << 8) | redeemscript[6]; + expiration = (expiration << 8) | redeemscript[5]; + expiration = (expiration << 8) | redeemscript[4]; + expiration = (expiration << 8) | redeemscript[3]; + bitcoin_address(symbol,destaddr,coin->taddr,coin->pubtype,&redeemscript[12],20); + jaddstr(retjson,"address",destaddr); + jaddnum(retjson,"expiration",expiration); + claimtime = LP_claimtime(coin,expiration); + jaddnum(retjson,"claimtime",claimtime); + if ( claimtime > expiration && strcmp(destaddr,coin->smartaddr) == 0 ) + { + char str[65]; //printf("LP_timespend satoshis %.8f %s/v%d\n",dstr(satoshis - coin->txfee),bits256_str(str,utxotxid),utxovout); + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,coin->txfee,"timespend",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript+2,redeemlen-2,0,0,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,0,coin->zcash)) != 0 ) + { + sendtxid = LP_broadcast("timespend",symbol,signedtx,signedtxid); + jaddstr(retjson,"signedtx",signedtx); + jaddbits256(retjson,"txid",signedtxid); + if ( bits256_cmp(sendtxid,signedtxid) == 0 ) + jaddbits256(retjson,"sendtxid",sendtxid); + else printf("error sending %s\n",bits256_str(str,signedtxid)); + free(signedtx); + } + else + { + printf("error doing timespend %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(satoshis)); + jaddstr(retjson,"error","couldnt sign timespend"); + } + } + } else jaddstr(retjson,"error","mismatched redeemscript"); + } + } + } + } + free_json(txjson); + } + return(jprint(retjson,1)); +} + +char *LP_timelock(char *symbol,uint32_t duration,char *destaddr,uint64_t satoshis) +{ + struct iguana_info *coin; uint32_t expiration; char *retstr,p2shaddr[64],redeemscript[256]; cJSON *argjson,*array,*item; int32_t n=0; uint8_t addrtype,rmd160[20],p2sh160[20],script[40]; + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + expiration = (uint32_t)time(NULL) + duration; + if ( destaddr == 0 ) + destaddr = coin->smartaddr; + bitcoin_addr2rmd160(symbol,coin->taddr,&addrtype,rmd160,destaddr); + n = bitcoin_timelockspend(script,0,rmd160,expiration); + init_hexbytes_noT(redeemscript,script,n); + calc_rmd160_sha256(p2sh160,script,n); + bitcoin_address(symbol,p2shaddr,coin->taddr,coin->p2shtype,p2sh160,20); + argjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + item = cJSON_CreateObject(); + jaddnum(item,p2shaddr,dstr(satoshis + coin->txfee)); + jaddi(array,item); + jadd(argjson,"outputs",array); + jaddstr(argjson,"opreturn",redeemscript); + //printf("deposit.(%s)\n",jprint(argjson,0)); + if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) + return(retstr); + else return(clonestr("{\"error\":\"timelock got null return from LP_withdraw\"}")); + } else return(clonestr("{\"error\":\"cant find coin\"}")); +} + int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info *coin,bits256 utxotxid) { uint8_t redeemscript[512]; bits256 claimtxid; cJSON *txjson,*vout0,*vout1,*vout2,*vouts,*item; int32_t numvouts; char str[65],vinaddr[64],destaddr[64],checkaddr[64]; int32_t j,utxovout,flagi = 0,redeemlen,weeki,iter; int64_t weeksatoshis,satoshis; uint32_t expiration,claimtime; - if ( (txjson= LP_gettx(coin->symbol,utxotxid,1)) != 0 ) + if ( (txjson= LP_gettx("LP_claim_submit",coin->symbol,utxotxid,1)) != 0 ) { if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts >= 3 ) { @@ -311,6 +422,7 @@ int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info { flagi = 1; claimtime = (uint32_t)time(NULL)-777; + //claimtime = LP_claimtime(coin,expiration); item = cJSON_CreateObject(); jaddbits256(item,"txid",utxotxid); jaddnum(item,"deposit",dstr(LP_value_extract(vout0,0))); @@ -403,7 +515,7 @@ int64_t LP_instantdex_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,in int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid,char *refaddr,char *origcoinaddr) { cJSON *txjson,*vouts,*txobj,*item; int64_t satoshis=0,amount64; int32_t weeki,numvouts; char destaddr[64],p2shaddr[64]; - if ( (txjson= LP_gettx(coin->symbol,txid,0)) != 0 ) + if ( (txjson= LP_gettx("LP_instantdex_creditcalc",coin->symbol,txid,0)) != 0 ) { // vout0 deposit, vout1 botsfee, vout2 smartaddress if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 && numvouts >= 3 && LP_destaddr(destaddr,jitem(vouts,2)) == 0 ) @@ -566,13 +678,13 @@ cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) struct iguana_info *bob,*alice; int32_t flag = 0; char *retstr,*swapstr; bits256 zero; cJSON *item,*reqjson,*swapjson; item = cJSON_CreateObject(); jaddnum(item,"iambob",iambob); - jaddnum(item,"aliceid",sp->aliceid); + jadd64bits(item,"aliceid",sp->aliceid); jaddnum(item,"requestid",sp->Q.R.requestid); jaddnum(item,"quoteid",sp->Q.R.quoteid); jaddstr(item,"base",sp->Q.srccoin); - jaddnum(item,"satoshis",sp->Q.satoshis); + jadd64bits(item,"satoshis",sp->Q.satoshis); jaddstr(item,"rel",sp->Q.destcoin); - jaddnum(item,"destsatoshis",sp->Q.destsatoshis); + jadd64bits(item,"destsatoshis",sp->Q.destsatoshis); jaddnum(item,"price",sp->Q.destsatoshis/((double)sp->Q.satoshis+1)); if ( LP_swap_finished(sp,1) == 0 ) { @@ -597,12 +709,15 @@ cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) } if ( flag != 0 ) { - reqjson = cJSON_CreateObject(); - jaddstr(reqjson,"method","gettradestatus"); - jadd64bits(reqjson,"aliceid",sp->aliceid); - memset(zero.bytes,0,sizeof(zero)); - LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); - if ( (swapstr= basilisk_swapentry(sp->Q.R.requestid,sp->Q.R.quoteid,0)) != 0 ) + if ( 0 ) + { + reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","gettradestatus"); + jadd64bits(reqjson,"aliceid",sp->aliceid); + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); + } + if ( (swapstr= basilisk_swapentry(1,sp->Q.R.requestid,sp->Q.R.quoteid,0)) != 0 ) { if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) { diff --git a/iguana/exchanges/LP_mmjson.c b/iguana/exchanges/LP_mmjson.c index 1239c4180..dcbd3de0c 100644 --- a/iguana/exchanges/LP_mmjson.c +++ b/iguana/exchanges/LP_mmjson.c @@ -46,17 +46,17 @@ #define MMJSON_ARRAY8 228 #define MMJSON_ARRAY16 227 #define MMJSON_ARRAY32 226 -#define MMJSON_BOUNDARY 98 int32_t MM_numfields; -char *MM_fields[256] = +char *MM_fields[] = { - "timestamp", "getdPoW", "dPoW", "aliceid", "src", "base", "basevol", "dest", "rel", "relvol", "price", "requestid", "quoteid", "finished", "expired", "bobdeposit", "alicepayment", "bobpayment", "paymentspent", "Apaymentspent", "depositspent", "ind", "method", "swapstatus", "method2", "gettradestatus", "coin", "rmd160", "pub", "pubsecp", "sig", "session", "notify", "pubkey", "price64", "credits", "utxocoin", "n", "bal", "min", "max", "postprice", "notarized", "notarizedhash", "notarizationtxid", "wantnotify", "isLP", "gui", "nogui", "tradeid", "address", "txid", "vout", "srchash", "txfee", "quotetime", "satoshis", "desthash", "txid2", "vout2", "destaddr", "desttxid", "destvout", "feetxid", "feevout", "desttxfee", "destsatoshis", "pending", "reserved", "broadcast", "ismine", "simplegui", "request", "proof", "connect", "expiration", "iambob", "Bgui", "", "Agui", "bob", "srcamount", "bobtxfee", "alice", "destamount", "alicetxfee", "sentflags", "values", "result", "success", "status", "finishtime", "tradestatus", "pair", "connected", "warning", "critical", "endcritical", + "timestamp", "getdPoW", "dPoW", "aliceid", "src", "base", "basevol", "dest", "rel", "relvol", "price", "requestid", "quoteid", "finished", "expired", "bobdeposit", "alicepayment", "bobpayment", "paymentspent", "Apaymentspent", "depositspent", "ind", "method", "swapstatus", "method2", "gettradestatus", "coin", "rmd160", "pub", "pubsecp", "sig", "session", "notify", "pubkey", "price64", "credits", "utxocoin", "n", "bal", "min", "max", "postprice", "notarized", "notarizedhash", "notarizationtxid", "wantnotify", "isLP", "gui", "nogui", "tradeid", "address", "txid", "vout", "srchash", "txfee", "quotetime", "satoshis", "desthash", "txid2", "vout2", "destaddr", "desttxid", "destvout", "feetxid", "feevout", "desttxfee", "destsatoshis", "pending", "reserved", "broadcast", "ismine", "simplegui", "request", "proof", "connect", "expiration", "iambob", "Bgui", "", "Agui", "bob", "srcamount", "bobtxfee", "alice", "destamount", "alicetxfee", "sentflags", "values", "result", "success", "status", "finishtime", "tradestatus", "pair", "connected", "warning", "critical", "endcritical", "cli", "etomic", "bobtomic", "alicetomic", "etomicsrc", "etomicdest" }; +#define MMJSON_BOUNDARY ((int32_t)(sizeof(MM_fields)/sizeof(*MM_fields))) -char *MM_coins[256] = +char *MM_coins[] = { - "KMD", "BTC", "CRC", "VOT", "INN", "MOON", "CRW", "EFL", "GBX", "BCO", "BLK", "BTG", "BCH", "ABY", "STAK", "XZC", "QTUM", "PURA", "DSR", "MNZ", "BTCZ", "MAGA", "BSD", "IOP", "BLOCK", "CHIPS", "888", "ARG", "GLT", "ZER", "HODLC", "UIS", "HUC", "PIVX", "BDL", "ARC", "ZCL", "VIA", "ERC", "FAIR", "FLO", "SXC", "CREA", "TRC", "BTA", "SMC", "NMC", "NAV", "EMC2", "SYS", "I0C", "DASH", "STRAT", "MUE", "MONA", "XMY", "MAC", "BTX", "XRE", "LBC", "SIB", "VTC", "REVS", "JUMBLR", "DOGE", "HUSH", "ZEC", "DGB", "ZET", "GAME", "LTC", "SUPERNET", "WLC", "PANGEA", "DEX", "BET", "CRYPTO", "HODL", "MSHARK", "BOTS", "MGW", "COQUI", "KV", "CEAL", "MESH", + "KMD", "BTC", "CRC", "VOT", "INN", "MOON", "CRW", "EFL", "GBX", "BCO", "BLK", "BTG", "BCH", "ABY", "STAK", "XZC", "QTUM", "PURA", "DSR", "MNZ", "BTCZ", "MAGA", "BSD", "IOP", "BLOCK", "CHIPS", "888", "ARG", "GLT", "ZER", "HODLC", "UIS", "HUC", "PIVX", "BDL", "ARC", "ZCL", "VIA", "ERC", "FAIR", "FLO", "SXC", "CREA", "TRC", "BTA", "SMC", "NMC", "NAV", "EMC2", "SYS", "I0C", "DASH", "STRAT", "MUE", "MONA", "XMY", "MAC", "BTX", "XRE", "LBC", "SIB", "VTC", "REVS", "JUMBLR", "DOGE", "HUSH", "ZEC", "DGB", "ZET", "GAME", "LTC", "SUPERNET", "WLC", "PANGEA", "DEX", "BET", "CRYPTO", "HODL", "MSHARK", "BOTS", "MGW", "COQUI", "KV", "CEAL", "MESH", "ETOMIC", "BTCH", "ETH" }; int32_t mmjson_coinfind(char *symbol) @@ -516,7 +516,9 @@ int32_t MMJSON_encodeval(uint8_t *linebuf,int32_t k,int32_t ind,char *v,uint32_t } if ( v[j] == 0 ) { - printf("unexpected missing string value.(%s)\n",v); + static uint32_t counter; + if ( counter++ < 3 ) + printf("unexpected missing string value.(%s)\n",v); //ind = mmadd(v); //printf("%s.<%s>.%d ",s,v,ind); //linebuf[k++] = ind; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 1fe39f0b9..6ad01bd30 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -85,7 +85,12 @@ void LP_millistats_update(struct LP_millistats *mp) } #include "LP_include.h" -portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex,LP_tradesmutex; + +#ifndef NOTETOMIC +#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; int32_t LP_canbind; char *Broadcaststr,*Reserved_msgs[2][1000]; int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; @@ -101,7 +106,7 @@ struct LP_trade *LP_trades,*LP_tradesQ; uint16_t LP_fixed_pairport;//,LP_publicport; uint32_t LP_lastnonce,LP_swap_endcritical,LP_swap_critical,LP_RTcount,LP_swapscount; int32_t LP_STOP_RECEIVED,LP_numactive_LP;//,LP_mybussock = -1; -int32_t LP_mypubsock = -1; +int32_t LP_mypubsock = -1,IPC_ENDPOINT = -1; int32_t LP_cmdcount,LP_mypullsock = -1; int32_t LP_numfinished,LP_showwif,IAMLP = 0; double LP_profitratio = 1.; @@ -192,21 +197,21 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_ #include "LP_messages.c" #include "LP_commands.c" -char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) +char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen,int32_t stats_JSONonly) { char *retstr=0; cJSON *retjson; bits256 zero; if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 ) return(0); - if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) + if ( stats_JSONonly != 0 || LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) { - if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,"127.0.0.1",0)) != 0 ) + if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,"127.0.0.1",stats_JSONonly)) != 0 ) { //printf("%s PULL.[%d]-> (%s)\n",myipaddr != 0 ? myipaddr : "127.0.0.1",datalen,retstr); //if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 && //LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0); } } - else if ( LP_statslog_parse() > 0 ) + else if ( LP_statslog_parse() > 0 && 0 ) { memset(zero.bytes,0,sizeof(zero)); if ( (retjson= LP_statslog_disp(2000000000,2000000000,"",zero,0,0))) // pending swaps @@ -250,7 +255,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, if ( duplicate != 0 ) dup++; else uniq++; - //portable_mutex_lock(&LP_commandmutex); + portable_mutex_lock(&LP_commandmutex); if ( (LP_rand() % 100000) == 0 ) printf("%s dup.%d (%u / %u) %.1f%% encrypted.%d recv.%u [%02x %02x] vs %02x %02x\n",typestr,duplicate,dup,dup+uniq,(double)100*dup/(dup+uniq),encrypted,crc32,ptr[0],ptr[1],crc32&0xff,(crc32>>8)&0xff); if ( duplicate == 0 ) @@ -303,7 +308,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, if ( jsonstr != 0 && argjson != 0 ) { len = (int32_t)strlen(jsonstr) + 1; - if ( (method= jstr(argjson,"method")) != 0 && strcmp(method,"broadcast") == 0 ) + if ( (method= jstr(argjson,"method")) != 0 && strcmp(method,"gettradestatus") != 0 && strcmp(method,"psock") != 0 && strcmp(method,"broadcast") == 0 ) { bits256 zero; cJSON *reqjson; char *cipherstr; int32_t cipherlen; uint8_t cipher[LP_ENCRYPTED_MAXSIZE]; if ( (reqjson= LP_dereference(argjson,"broadcast")) != 0 ) @@ -331,16 +336,17 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, } else { - if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 ) - { - } + LP_queuecommand(0,jsonstr,pubsock,0,0); + //if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 ) + //{ + //} } } if ( argjson != 0 ) free_json(argjson); } } //else printf("DUPLICATE.(%s)\n",(char *)ptr); - //portable_mutex_unlock(&LP_commandmutex); + portable_mutex_unlock(&LP_commandmutex); if ( jsonstr != 0 && (void *)jsonstr != (void *)ptr && encrypted == 0 ) free(jsonstr); return(retstr); @@ -349,7 +355,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock, int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int32_t sock,char *remoteaddr,int32_t maxdepth) { static char *line; - int32_t recvlen=1,msglen,nonz = 0; cJSON *argjson,*recvjson; void *ptr,*msg; char methodstr[64],*decodestr,*retstr,*str; struct nn_pollfd pfd; + int32_t recvlen=1,msglen,nonz = 0; cJSON *recvjson; void *ptr,*msg; char methodstr[64],*decodestr,*retstr,*str; struct nn_pollfd pfd; if ( line == 0 ) line = calloc(1,1024*1024); if ( sock >= 0 ) @@ -407,12 +413,14 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int { if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,msg,msglen,sock)) != 0 ) free(retstr); + if ( Broadcaststr != 0 ) { //printf("self broadcast.(%s)\n",Broadcaststr); str = Broadcaststr; Broadcaststr = 0; - if ( (argjson= cJSON_Parse(str)) != 0 ) + LP_queuecommand(0,str,pubsock,0,0); + /*if ( (argjson= cJSON_Parse(str)) != 0 ) { //portable_mutex_lock(&LP_commandmutex); if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,0,0) <= 0 ) @@ -422,7 +430,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int } //portable_mutex_unlock(&LP_commandmutex); free_json(argjson); - } + }*/ free(str); } } @@ -445,7 +453,7 @@ int32_t LP_nanomsg_recvs(void *ctx) int32_t n=0,nonz = 0; char *origipaddr; struct LP_peerinfo *peer,*tmp; if ( (origipaddr= LP_myipaddr) == 0 ) origipaddr = "127.0.0.1"; - //portable_mutex_lock(&LP_nanorecvsmutex); + portable_mutex_lock(&LP_nanorecvsmutex); HASH_ITER(hh,LP_peerinfos,peer,tmp) { if ( n++ > 0 && peer->errors >= LP_MAXPEER_ERRORS ) @@ -471,7 +479,7 @@ 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); + portable_mutex_unlock(&LP_nanorecvsmutex); return(nonz); } @@ -482,6 +490,11 @@ void command_rpcloop(void *ctx) command_rpcloop_stats.threshold = 2500.; while ( LP_STOP_RECEIVED == 0 ) { + if ( G.initializing != 0 ) + { + sleep(1); + continue; + } LP_millistats_update(&command_rpcloop_stats); nonz = LP_nanomsg_recvs(ctx); //if ( LP_mybussock >= 0 ) @@ -499,7 +512,7 @@ void command_rpcloop(void *ctx) void LP_coinsloop(void *_coins) { - struct LP_address *ap=0,*atmp; 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]; 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"); @@ -517,9 +530,9 @@ void LP_coinsloop(void *_coins) } while ( LP_STOP_RECEIVED == 0 ) { - if ( strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") == 0 ) + if ( G.initializing != 0 ) { - sleep(10); + sleep(1); continue; } if ( strcmp("BTC",coins) == 0 ) @@ -545,32 +558,26 @@ void LP_coinsloop(void *_coins) } if ( coin->smartaddr[0] == 0 ) { - printf("%s has no smartaddress??\n",coin->symbol); + //printf("%s has no smartaddress??\n",coin->symbol); continue; } memset(&zero,0,sizeof(zero)); if ( coin->inactive != 0 ) continue; + if ( coin->did_addrutxo_reset == 0 ) + { + int32_t num; + LP_address_utxo_reset(&num,coin); + coin->did_addrutxo_reset = 1; + } if ( coin->longestchain == 1 ) // special init value coin->longestchain = LP_getheight(¬arized,coin); if ( (ep= coin->electrum) != 0 ) { - /*if ( strcmp("KMD",coin->symbol) == 0 && coin->electrumzeroconf == 0 ) - { - LP_zeroconf_deposits(coin); - coin->electrumzeroconf = (uint32_t)time(NULL); - }*/ if ( (backupep= ep->prev) == 0 ) backupep = ep; if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1,zero,zero)) != 0 ) free_json(retjson); - HASH_ITER(hh,coin->addresses,ap,atmp) - { - break; - //printf("call unspent %s\n",ap->coinaddr); - if ( strcmp(coin->smartaddr,ap->coinaddr) != 0 && (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1,zero,zero)) != 0 ) - free_json(retjson); - } if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) { DL_FOREACH_SAFE(ap->utxos,up,tmp) @@ -642,7 +649,7 @@ void LP_coinsloop(void *_coins) coin->lastscanht = coin->firstscanht; continue; } - if ( strcmp(coin->symbol,"BTC") != 0 && strcmp(coin->symbol,"KMD") != 0 ) // SPV as backup + //if ( strcmp(coin->symbol,"BTC") != 0 && strcmp(coin->symbol,"KMD") != 0 ) // SPV as backup { nonz++; if ( strcmp("BTC",coins) == 0 )//&& coin->lastscanht < coin->longestchain-3 ) @@ -651,9 +658,8 @@ void LP_coinsloop(void *_coins) { if ( LP_blockinit(coin,coin->lastscanht) < 0 ) { - static uint32_t counter; - if ( counter++ < 3 ) - printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht); + printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht); + sleep(10); break; } coin->lastscanht++; @@ -666,7 +672,7 @@ void LP_coinsloop(void *_coins) } if ( coins == 0 ) return; - if ( nonz == 0 ) + //if ( nonz == 0 ) usleep(100000); } } @@ -795,7 +801,7 @@ void bech32_tests() void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) { - int32_t i,n,notarized; cJSON *item; char *symbol; struct iguana_info *coin; + int32_t i,n,notarized; cJSON *item; char *symbol,*etomic; struct iguana_info *coin; for (i=0; iinactive = (uint32_t)time(NULL); - else LP_unspents_load(coin->symbol,coin->smartaddr); + if ( (etomic= jstr(item,"etomic")) != 0 ) + safecopy(coin->etomic,etomic,sizeof(coin->etomic)); + else + { + if ( LP_getheight(¬arized,coin) <= 0 ) + coin->inactive = (uint32_t)time(NULL); + else LP_unspents_load(coin->symbol,coin->smartaddr); + } if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 ) coin->txfee = LP_MIN_TXFEE; if ( 0 && strcmp(coin->symbol,"BCH") == 0 ) { bech32_tests(); } + else if ( 0 && strcmp(coin->symbol,"SMART") == 0 ) + { + uint8_t txdata[8129]; int32_t len; bits256 txid,txid2,ktxid; char str[65]; + char *txstr = "0100000005c9a9c56f4e702766c582127587ee49695ba5b9e5c449290a4f8a0505c12beeb7000000006b483045022100867f85d9f8d7f543225448f1d2383ff7d60a325b5f643557ea36325372de9993022034ccd202ee017c3d8a2dfa615b72d661b891d2071b1c15d4d7ab063762c79d2f012103f9be43471012e3e6daaa7a91a68cbc667fa61791e4a93f8e8d53255a93b68d03ffffffffe062eb6845b69856d62ceb3fd9b7e05c383b8b88b9359bc7c8ac49cd7dd2b2bb010000006b483045022100d4ef1c6d5f24ad3877f57f8ae4a1c0f8aa2f6de5ccaa8ed8e10b2937a4316c1402200d41b154a892a98d40c4d39e619992cca1eba4b5939bbf2b418062cd1275a8b101210302649cc91eda9d5fbc9d41b4a14f98917a00cdc6fc952c9fdf8a98a544cfcca9ffffffff561ee4189323bf8f619bcedd1f9e02033adb588db31cb3dc7ec3bda23f73aac4000000006b483045022100d4a5ab03675f585cc055c76fdaa80333757c42583883dfcde08cb0aeb57f256a022063440e24ef4ef5b44dcb0e7aacaa4562effd80f9a1d9b273daa581066c8359fb0121035c0e6d900a5e8c27901ce7edcdc9bfafea44dbfb714274271114245d7e895198ffffffff56cf1fa6d5779fd2bded063d63455809373ff2bf79edf921be7e92f918ef43df010000006b48304502210091d15d5fcb518103f04fdc819513200d30033f9a1e29960458375e7c71247d31022064a233c4073ac88652a0324f6973914b08bfcf76e928afae0099dc2d7eb227750121032946d47c35c0a98ae7ccad30fee846007434fff25cf70973b5c76deb4be2a14fffffffff4754ee214a33da0116730b43238cc6ff0510b8cebc59a42b1f0609e2a10aa8c8000000006b483045022100f3cea95cd6451d706fb1766cec30450ef000649df15d7d7bebcecbfe6ec48e98022016e687a7d956d2ab089d76306046d33ce5ace55fcb4595021de3f97c4293d1b601210367db63755cf13760c81b8cb0c13eee10474064dfacc7c45a8c3271b5b058f0ccffffffff025e489467030000001976a9147283e4813a5e5fb8d723e75403ba10e05a7820db88ac60f71b00000000001976a914d740ff057317d3b12d5a6dadac5bb7ff87e48afe88ac578a0500"; + len = (int32_t)strlen(txstr) >> 1; + decode_hex(txdata,len,txstr); + vcalc_sha256(0,txid.bytes,txdata,len); + txid2 = bits256_doublesha256(0,txdata,len); + HashKeccak(ktxid.bytes,txdata,len); + printf("txid %s\n",bits256_str(str,txid)); + printf("txid2 %s\n",bits256_str(str,txid2)); + printf("ktxid %s\n",bits256_str(str,ktxid)); + } } } } @@ -891,7 +915,8 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint { printf("default seed nodes for netid.%d\n",netid); OS_randombytes((void *)&r,sizeof(r)); - for (j=0; j lasttime+100 ) @@ -922,21 +951,62 @@ void LP_pubkeysloop(void *ctx) } } +struct LP_pendswap +{ + struct LP_pendswap *next,*prev; + uint32_t expiration,requestid,quoteid,finished; +}; + +struct LP_pendswap *LP_pendingswaps; + +void LP_pendswap_add(uint32_t expiration,uint32_t requestid,uint32_t quoteid) +{ + struct LP_pendswap *sp; + printf("LP_pendswap_add expiration.%u %u-%u\n",expiration,requestid,quoteid); + portable_mutex_lock(&LP_pendswap_mutex); + sp = calloc(1,sizeof(*sp)); + sp->expiration = expiration; + sp->requestid = requestid; + sp->quoteid = quoteid; + DL_APPEND(LP_pendingswaps,sp); + portable_mutex_unlock(&LP_pendswap_mutex); +} + void LP_swapsloop(void *ctx) { - char *retstr; + char *retstr; cJSON *retjson; uint32_t requestid,quoteid; int32_t nonz; struct LP_pendswap *sp,*tmp; strcpy(LP_swapsloop_stats.name,"LP_swapsloop"); LP_swapsloop_stats.threshold = 605000.; - sleep(50); + if ( (retstr= basilisk_swapentry(0,0,0,1)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (requestid= juint(retjson,"requestid")) != 0 && (quoteid= juint(retjson,"quoteid")) != 0 && jobj(retjson,"error") == 0 ) + LP_pendswap_add(0,requestid,quoteid); + } + free(retstr); + } while ( LP_STOP_RECEIVED == 0 ) { - if ( strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") != 0 ) + if ( G.initializing != 0 ) { - LP_millistats_update(&LP_swapsloop_stats); - if ( (retstr= basilisk_swapentry(0,0,0)) != 0 ) - free(retstr); - sleep(600); - } else sleep(10); + sleep(1); + continue; + } + LP_millistats_update(&LP_swapsloop_stats); + nonz = 0; + DL_FOREACH_SAFE(LP_pendingswaps,sp,tmp) + { + if ( sp->finished == 0 ) + { + nonz++; + if ( (sp->finished= LP_swapwait(0,sp->requestid,sp->quoteid,-1,0)) != 0 ) + { + } + } + } + if ( nonz == 0 ) + sleep(60); } } @@ -947,6 +1017,11 @@ void gc_loop(void *ctx) LP_gcloop_stats.threshold = 11000.; while ( LP_STOP_RECEIVED == 0 ) { + if ( G.initializing != 0 ) + { + sleep(1); + continue; + } flag = 0; LP_millistats_update(&LP_gcloop_stats); portable_mutex_lock(&LP_gcmutex); @@ -982,8 +1057,12 @@ void queue_loop(void *ctx) queue_loop_stats.threshold = 1000.; while ( LP_STOP_RECEIVED == 0 ) { + if ( G.initializing != 0 ) + { + sleep(1); + continue; + } LP_millistats_update(&queue_loop_stats); - //printf("LP_Q.%p next.%p prev.%p\n",LP_Q,LP_Q!=0?LP_Q->next:0,LP_Q!=0?LP_Q->prev:0); n = nonz = flag = 0; DL_FOREACH_SAFE(LP_Q,ptr,tmp) { @@ -991,6 +1070,7 @@ void queue_loop(void *ctx) flag = 0; if ( ptr->sock >= 0 ) { + //printf("sock.%d len.%d notready.%d\n",ptr->sock,ptr->msglen,ptr->notready); if ( ptr->notready == 0 || (LP_rand() % ptr->notready) == 0 ) { if ( LP_sockcheck(ptr->sock) > 0 ) @@ -1017,27 +1097,38 @@ void queue_loop(void *ctx) { if ( (sentbytes= nn_send(ptr->sock,linebuf,k,0)) != k ) printf("%d LP_send mmjson sent %d instead of %d\n",n,sentbytes,k); - else flag++; + else + { + flag++; + ptr->sock = -1; + } } - //printf("k.%d SEND.(%s) sock.%d\n",k,(char *)ptr->msg,ptr->sock); + //printf("k.%d flag.%d SEND.(%s) sock.%d\n",k,flag,(char *)ptr->msg,ptr->sock); } free_json(json); } if ( flag == 0 ) { - //printf("len.%d SEND.(%s) sock.%d\n",ptr->msglen,(char *)ptr->msg,ptr->sock); + // printf("non-encoded len.%d SEND.(%s) sock.%d\n",ptr->msglen,(char *)ptr->msg,ptr->sock); if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen ) printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen); - else flag++; + else + { + flag++; + ptr->sock = -1; + } } - ptr->sock = -1; if ( ptr->peerind > 0 ) ptr->starttime = (uint32_t)time(NULL); } else { - if ( ptr->notready++ > 1000 ) + if ( ptr->notready++ > 100 ) + { flag = 1; + //printf("queue_loop sock.%d len.%d notready.%d, skip\n",ptr->sock,ptr->msglen,ptr->notready); + ptr->sock = -1; + } } } } @@ -1091,13 +1182,31 @@ void LP_reserved_msgs(void *ignore) LP_reserved_msgs_stats.threshold = 1000.; while ( LP_STOP_RECEIVED == 0 ) { + if ( G.initializing != 0 ) + { + sleep(1); + continue; + } nonz = 0; LP_millistats_update(&LP_reserved_msgs_stats); - if ( num_Reserved_msgs[0] > 0 || num_Reserved_msgs[1] > 0 ) + if ( num_Reserved_msgs[1] > 0 ) + { + nonz++; + portable_mutex_lock(&LP_reservedmutex); + if ( num_Reserved_msgs[1] > 0 ) + { + num_Reserved_msgs[1]--; + //printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]); + LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[1][num_Reserved_msgs[1]]); + Reserved_msgs[1][num_Reserved_msgs[1]] = 0; + } + portable_mutex_unlock(&LP_reservedmutex); + } + else if ( num_Reserved_msgs[0] > 0 ) { nonz++; flag = 0; - if ( LP_mypubsock >= 0 ) + if ( flag == 0 && LP_mypubsock >= 0 ) { memset(&pfd,0,sizeof(pfd)); pfd.fd = LP_mypubsock; @@ -1108,36 +1217,59 @@ void LP_reserved_msgs(void *ignore) if ( flag == 1 ) { portable_mutex_lock(&LP_reservedmutex); - if ( num_Reserved_msgs[1] > 0 ) - { - num_Reserved_msgs[1]--; -//printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]); - LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[1][num_Reserved_msgs[1]]); - Reserved_msgs[1][num_Reserved_msgs[1]] = 0; - } - else if ( num_Reserved_msgs[0] > 0 ) - { - num_Reserved_msgs[0]--; -//printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]); - LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[0][num_Reserved_msgs[0]]); - Reserved_msgs[0][num_Reserved_msgs[0]] = 0; - } + num_Reserved_msgs[0]--; + //printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]); + LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[0][num_Reserved_msgs[0]]); + Reserved_msgs[0][num_Reserved_msgs[0]] = 0; portable_mutex_unlock(&LP_reservedmutex); } } if ( ignore == 0 ) break; - if ( nonz != 0 ) - usleep(1000); - else usleep(5000); + if ( nonz == 0 ) + usleep(5000); } } int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,char *msg) { - int32_t n = 0; - if ( strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") == 0 ) + struct LP_pubkey_info *pubp; uint32_t timestamp; char *method; cJSON *argjson; int32_t skip,sentbytes,n = 0; + skip = 0; + if ( (argjson= cJSON_Parse(msg)) != 0 ) + { + if ( (method= jstr(argjson,"method")) != 0 ) + { + if ( strcmp(method,"gettradestatus") == 0 || strcmp(method,"wantnotify") == 0 || strcmp(method,"getdPoW") == 0 ) + skip = 1; + } + if ( (timestamp= juint(argjson,"timestamp")) != 0 && time(NULL) > timestamp+60 ) + skip = 1; + free_json(argjson); + } + if ( skip != 0 ) return(-1); + //if ( strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") == 0 ) + // return(-1); + if ( priority > 0 && bits256_nonz(pubkey) != 0 ) + { + if ( (pubp= LP_pubkeyfind(pubkey)) != 0 ) + { + if ( pubp->pairsock >= 0 ) + { + if ( (sentbytes= nn_send(pubp->pairsock,msg,(int32_t)strlen(msg)+1,0)) < 0 ) + { + //pubp->pairsock = -1; + //LP_peer_pairsock(pubkey); + //printf("mark cmdchannel %d closed sentbytes.%d\n",pubp->pairsock,sentbytes); + } + else + { + printf("sent %d bytes to cmdchannel.%d\n",sentbytes,pubp->pairsock); + return(sentbytes); + } + } + } + } portable_mutex_lock(&LP_reservedmutex); if ( num_Reserved_msgs[priority] < sizeof(Reserved_msgs[priority])/sizeof(*Reserved_msgs[priority]) ) { @@ -1147,7 +1279,7 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha if ( num_Reserved_msgs[priority] > max_Reserved_msgs[priority] ) { max_Reserved_msgs[priority] = num_Reserved_msgs[priority]; - if ( (max_Reserved_msgs[priority] % 100) == 0 ) + //if ( (max_Reserved_msgs[priority] % 100) == 0 ) printf("New priority.%d max_Reserved_msgs.%d\n",priority,max_Reserved_msgs[priority]); } portable_mutex_unlock(&LP_reservedmutex); @@ -1161,13 +1293,13 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu 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)); bitcoind_RPC_inittime = 1; - printf("%s %u\n",version,calc_crc32(0,version,(int32_t)strlen(version))); if ( LP_MAXPRICEINFOS > 256 ) { printf("LP_MAXPRICEINFOS %d wont fit in a uint8_t, need to increase the width of the baseind and relind for struct LP_pubkey_quote\n",LP_MAXPRICEINFOS); exit(-1); } LP_showwif = juint(argjson,"wif"); + printf("showwif.%d %s %u\n",LP_showwif,version,calc_crc32(0,version,(int32_t)strlen(version))); if ( passphrase == 0 || passphrase[0] == 0 ) { printf("jeezy says we cant use the nullstring as passphrase and I agree\n"); @@ -1234,6 +1366,10 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu portable_mutex_init(&LP_logmutex); portable_mutex_init(&LP_statslogmutex); portable_mutex_init(&LP_tradesmutex); + portable_mutex_init(&LP_commandQmutex); + portable_mutex_init(&LP_blockinit_mutex); + portable_mutex_init(&LP_pendswap_mutex); + portable_mutex_init(&LP_listmutex); myipaddr = clonestr("127.0.0.1"); #ifndef _WIN32 #ifndef FROM_JS @@ -1267,8 +1403,10 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu valid++; if ( valid > 0 ) { - timeout = 1; + timeout = 100; nn_setsockopt(LP_mypubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + //timeout = 10; + //nn_setsockopt(LP_mypubsock,NN_SOL_SOCKET,NN_MAXTTL,&timeout,sizeof(timeout)); } else { @@ -1304,10 +1442,10 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu //strcpy(LP_publicaddr,pushaddr); //LP_publicport = mypullport; //LP_mybussock = LP_coinbus(mybusport); - printf("got %s, initpeers. LP_mypubsock.%d pullsock.%d RPC_port.%u mypullport.%d mypubport.%d pushaddr.%s\n",myipaddr,LP_mypubsock,LP_mypullsock,RPC_port,mypullport,mypubport,pushaddr); + printf("got %s, initpeers. LP_mypubsock.%d pullsock.%d RPC_port.%u mypullport.%d mypubport.%d\n",myipaddr,LP_mypubsock,LP_mypullsock,RPC_port,mypullport,mypubport); LP_passphrase_init(passphrase,jstr(argjson,"gui"),juint(argjson,"netid"),jstr(argjson,"seednode")); #ifndef FROM_JS - if ( IAMLP != 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_psockloop,(void *)myipaddr) != 0 ) + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_psockloop,(void *)myipaddr) != 0 ) { printf("error launching LP_psockloop for (%s)\n",myipaddr); exit(-1); @@ -1367,6 +1505,11 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu printf("error launching LP_tradessloop for ctx.%p\n",ctx); exit(-1); } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_commandQ_loop,ctx) != 0 ) + { + printf("error launching LP_commandQ_loop for ctx.%p\n",ctx); + exit(-1); + } if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,ctx) != 0 ) { printf("error launching LP_swapsloop for ctx.%p\n",ctx); @@ -1379,14 +1522,19 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu { nonz = 0; G.waiting = 1; - while ( G.initializing != 0 && strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") == 0 ) + while ( G.initializing != 0 ) //&& strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") == 0 ) { //fprintf(stderr,"."); sleep(3); } + if ( G.initializing != 0 ) + { + sleep(1); + continue; + } if ( LP_mainloop_iter(ctx,myipaddr,mypeer,LP_mypubsock) != 0 ) nonz++; - if ( didremote == 0 && LP_cmdcount > 0 ) + if ( IAMLP != 0 && didremote == 0 && LP_cmdcount > 0 ) { didremote = 1; uint16_t myport2 = RPC_port-1; @@ -1439,7 +1587,10 @@ char *barterDEX(char *argstr) printf("barterDEX.(%s)\n",argstr); if ( (argjson= cJSON_Parse(argstr)) != 0 ) { - retstr = LP_command_process(ctx,LP_myipaddr,LP_mypubsock,argjson,(uint8_t *)argstr,(int32_t)strlen(argstr)); + LP_queuecommand(&retstr,argstr,LP_mypubsock); + //retstr = LP_command_process(ctx,LP_myipaddr,LP_mypubsock,argjson,(uint8_t *)argstr,(int32_t)strlen(argstr)); + while ( retstr == 0 ) + usleep(50000); free_json(argjson); } else retstr = clonestr("{\"error\":\"couldnt parse request\"}"); return(retstr); @@ -1469,7 +1620,7 @@ void LP_fromjs_iter() { LP_notify_pubkeys(ctx,LP_mypubsock); LP_privkey_updates(ctx,LP_mypubsock,0); - if ( (retstr= basilisk_swapentry(0,0,0)) != 0 ) + if ( (retstr= basilisk_swapentry(0,0,0,0)) != 0 ) free(retstr); } } diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c index 891cdd975..f5fb75a26 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -21,12 +21,12 @@ struct psock { uint32_t lasttime,lastping,errors; - int32_t publicsock,sendsock,ispaired; + int32_t publicsock,sendsock,ispaired,cmdchannel; uint16_t publicport,sendport; char sendaddr[128],publicaddr[128]; } *PSOCKS; -uint16_t Numpsocks,Psockport = MIN_PSOCK_PORT; +uint16_t Numpsocks,Psockport = MIN_PSOCK_PORT,Pcmdport = MAX_PSOCK_PORT; #ifdef FROM_JS @@ -102,29 +102,30 @@ char *nanomsg_transportname(int32_t bindflag,char *str,char *ipaddr,uint16_t por return(str); } -/*char *nanomsg_transportname2(int32_t bindflag,char *str,char *ipaddr,uint16_t port) -{ - sprintf(str,"ws://%s:%u",bindflag == 0 ? ipaddr : "*",port+10); - return(str); -} -int32_t _LP_send(int32_t sock,void *msg,int32_t sendlen,int32_t freeflag) -{ - int32_t sentbytes; - if ( sock < 0 ) - { - printf("LP_send.(%s) to illegal socket\n",(char *)msg); - if ( freeflag != 0 ) - free(msg); - return(-1); - } - if ( (sentbytes= nn_send(sock,msg,sendlen,0)) != sendlen ) - printf("LP_send sent %d instead of %d\n",sentbytes,sendlen); - else printf("SENT.(%s)\n",(char *)msg); - if ( freeflag != 0 ) - free(msg); - return(sentbytes); -}*/ +/*char *nanomsg_transportname2(int32_t bindflag,char *str,char *ipaddr,uint16_t port) + { + sprintf(str,"ws://%s:%u",bindflag == 0 ? ipaddr : "*",port+10); + return(str); + } + + int32_t _LP_send(int32_t sock,void *msg,int32_t sendlen,int32_t freeflag) + { + int32_t sentbytes; + if ( sock < 0 ) + { + printf("LP_send.(%s) to illegal socket\n",(char *)msg); + if ( freeflag != 0 ) + free(msg); + return(-1); + } + if ( (sentbytes= nn_send(sock,msg,sendlen,0)) != sendlen ) + printf("LP_send sent %d instead of %d\n",sentbytes,sendlen); + else printf("SENT.(%s)\n",(char *)msg); + if ( freeflag != 0 ) + free(msg); + return(sentbytes); + }*/ int32_t LP_sockcheck(int32_t sock) { @@ -267,22 +268,29 @@ int32_t LP_peerindsock(int32_t *peerindp) void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32_t msglen,int32_t needack) { - int32_t maxind,peerind = 0; //sentbytes, - if ( sock0 < 0 && sock1 < 0 ) + int32_t i,maxind,flag = 0,peerind = 0; //sentbytes, + for (i=0; i<2; i++) { - if ( (maxind= LP_numpeers()) > 0 ) - peerind = (LP_rand() % maxind) + 1; - else peerind = 1; - sock0 = LP_peerindsock(&peerind); - if ( (maxind= LP_numpeers()) > 0 ) - peerind = (LP_rand() % maxind) + 1; - else peerind = 1; - sock1 = LP_peerindsock(&peerind); + if ( sock0 < 0 && sock1 < 0 ) + { + if ( (maxind= LP_numpeers()) > 0 ) + peerind = (LP_rand() % maxind) + 1; + else peerind = 1; + sock0 = LP_peerindsock(&peerind); + if ( (maxind= LP_numpeers()) > 0 ) + peerind = (LP_rand() % maxind) + 1; + else peerind = 1; + sock1 = LP_peerindsock(&peerind); + flag = 1; + } + if ( sock0 >= 0 ) + _LP_sendqueueadd(crc32,sock0,msg,msglen,needack * peerind); + if ( sock1 >= 0 ) + _LP_sendqueueadd(crc32,sock1,msg,msglen,needack); + if ( flag == 0 ) + break; + sock0 = sock1 = -1; } - if ( sock0 >= 0 ) - _LP_sendqueueadd(crc32,sock0,msg,msglen,needack * peerind); - if ( sock1 >= 0 ) - _LP_sendqueueadd(crc32,sock1,msg,msglen,needack); } void LP_queuesend(uint32_t crc32,int32_t pubsock,char *base,char *rel,uint8_t *msg,int32_t msglen) @@ -299,20 +307,22 @@ void LP_queuesend(uint32_t crc32,int32_t pubsock,char *base,char *rel,uint8_t *m void LP_broadcast_finish(int32_t pubsock,char *base,char *rel,uint8_t *msg,cJSON *argjson,uint32_t crc32) { - int32_t msglen; + int32_t msglen; char *method; + if ( (method= jstr(argjson,"method")) == 0 ) + return; msg = (void *)jprint(argjson,0); msglen = (int32_t)strlen((char *)msg) + 1; if ( crc32 == 0 ) crc32 = calc_crc32(0,&msg[2],msglen - 2); //printf("crc32.%x IAMLP.%d pubsock.%d\n",crc32,G.LP_IAMLP,pubsock); #ifdef FROM_MARKETMAKER - if ( G.LP_IAMLP == 0 || pubsock < 0 ) + if ( (G.LP_IAMLP == 0 || pubsock < 0) && strcmp(method,"psock") != 0 ) #else - if ( IAMLP == 0 || pubsock < 0 ) + if ( (IAMLP == 0 || pubsock < 0) && strcmp(method,"psock") != 0 ) #endif { free(msg); -//printf("broadcast %s\n",jstr(argjson,"method")); + //printf("broadcast %s\n",jstr(argjson,"method")); jdelete(argjson,"method"); jaddstr(argjson,"method","broadcast"); if ( jobj(argjson,"timestamp") == 0 ) @@ -330,7 +340,7 @@ void LP_broadcast_finish(int32_t pubsock,char *base,char *rel,uint8_t *msg,cJSON } free(msg); } - + void LP_broadcast_message(int32_t pubsock,char *base,char *rel,bits256 destpub25519,char *msgstr) { uint8_t encoded[LP_ENCRYPTED_MAXSIZE],space[sizeof(encoded)],*msg,*nonce,*cipher; int32_t encrypted=0,msglen; uint32_t crc32=0; cJSON *argjson; char *methodstr,method[64],cipherstr[LP_ENCRYPTED_MAXSIZE*2+1]; @@ -386,7 +396,7 @@ void LP_broadcast_message(int32_t pubsock,char *base,char *rel,bits256 destpub25 if ( msgstr != 0 ) free(msgstr); } - + uint32_t LP_swapsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t nextbits,uint32_t crcs[2]) { uint8_t *buf; int32_t sentbytes,offset=0,i; @@ -411,11 +421,126 @@ uint32_t LP_swapsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbit free(buf); return(nextbits); } - -void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to work + +struct LP_queuedcommand +{ + struct LP_queuedcommand *next,*prev; + char **retstrp; + int32_t responsesock,msglen,stats_JSONonly; + uint32_t queueid; + char msg[]; +} *LP_commandQ; + +void LP_commandQ_loop(void *ctx) +{ + struct LP_queuedcommand *ptr,*tmp; int32_t len,size,nonz; char *retstr; cJSON *argjson,*retjson,*result; + while ( LP_STOP_RECEIVED == 0 ) + { + nonz = 0; + DL_FOREACH_SAFE(LP_commandQ,ptr,tmp) + { + nonz++; + portable_mutex_lock(&LP_commandQmutex); + DL_DELETE(LP_commandQ,ptr); + portable_mutex_unlock(&LP_commandQmutex); + if ( ptr->stats_JSONonly < 0 ) // broadcast passthrough + { + if ( 1 && ptr->responsesock >= 0 ) + { + if ( (result= cJSON_Parse(ptr->msg)) != 0 ) + { + retjson = cJSON_CreateObject(); + jaddnum(retjson,"queueid",0); + jadd(retjson,"result",result); + retstr = jprint(retjson,1); + if ( (size= nn_send(ptr->responsesock,retstr,(int32_t)strlen(retstr),0)) <= 0 ) + printf("error sending event\n"); + free(retstr); + } + } + } + else if ( (argjson= cJSON_Parse(ptr->msg)) != 0 ) + { + if ( (retstr= LP_command_process(ctx,"127.0.0.1",ptr->responsesock,argjson,(uint8_t *)ptr->msg,ptr->msglen,ptr->stats_JSONonly)) != 0 ) + { + if ( ptr->retstrp != 0 ) + (*ptr->retstrp) = retstr; + if ( 0 && ptr->queueid != 0 ) + printf("sock.%d queueid.%d processed.(%s) -> (%s)\n",ptr->responsesock,ptr->queueid,ptr->msg,retstr); + if ( ptr->responsesock >= 0 ) + { + if ( (result= cJSON_Parse(retstr)) != 0 && ptr->queueid != 0 ) + { + free(retstr); + retjson = cJSON_CreateObject(); + jaddnum(retjson,"queueid",ptr->queueid); + jadd(retjson,"result",result); + retstr = jprint(retjson,1); + //printf("send (%s)\n",retstr); + } + len = (int32_t)strlen(retstr); + if ( ptr->queueid == 0 ) + len++; + if ( (size= nn_send(ptr->responsesock,retstr,len,0)) <= 0 ) + printf("error sending result\n"); + } + if ( retstr != 0 ) + { + if ( ptr->retstrp == 0 ) + free(retstr); + } + } + else if ( ptr->retstrp != 0 ) + (*ptr->retstrp) = clonestr("{\"error\":\"timeout\"}"); + free_json(argjson); + } + free(ptr); + } + if ( nonz == 0 ) + usleep(50000); + } +} + +void LP_queuecommand(char **retstrp,char *buf,int32_t responsesock,int32_t stats_JSONonly,uint32_t queueid) +{ + struct LP_queuedcommand *ptr; int32_t msglen; + msglen = (int32_t)strlen(buf) + 1; + portable_mutex_lock(&LP_commandQmutex); + ptr = calloc(1,sizeof(*ptr) + msglen + 1); + if ( (ptr->retstrp= retstrp) != 0 ) + *retstrp = 0; + ptr->msglen = msglen; + ptr->queueid = queueid; + ptr->responsesock = responsesock; + ptr->stats_JSONonly = stats_JSONonly; + memcpy(ptr->msg,buf,msglen); + DL_APPEND(LP_commandQ,ptr); + portable_mutex_unlock(&LP_commandQmutex); +} + +void mynn_close(int32_t sock) +{ + struct nn_pollfd pfd; int32_t n; void *buf; + if ( sock >= 0 ) + { + while ( (n= nn_recv(sock,&buf,NN_MSG,0)) > 0 ) + printf("got n.%d bytes from nn_close(%d)\n",n,sock); + pfd.fd = sock; + pfd.events = POLLOUT; + while ( nn_poll(&pfd,1,100) > 0 ) + { + printf("cant send to nn_close(%d)\n",sock); + sleep(1); + } + if ( IAMLP != 0 ) + nn_close(sock); + } +} + +void LP_psockloop(void *_ptr) { static struct nn_pollfd *pfds; - int32_t i,n,nonz,iter,retval,sentbytes,size=0,sendsock = -1; uint32_t now; struct psock *ptr=0; void *buf=0; char keepalive[512]; + int32_t nexti=0,j,i,n,nonz,iter,retval,sentbytes,size=0,sendsock = -1; uint32_t now; struct psock *ptr=0; void *buf=0; char keepalive[512]; strcpy(LP_psockloop_stats.name,"LP_psockloop"); LP_psockloop_stats.threshold = 1000.; while ( LP_STOP_RECEIVED == 0 ) @@ -443,16 +568,19 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w { if ( pfds == 0 ) pfds = calloc(MAX_PSOCK_PORT,sizeof(*pfds)); + nexti = (rand() % Numpsocks); portable_mutex_lock(&LP_psockmutex); memset(pfds,0,sizeof(*pfds) * ((Numpsocks*2 <= MAX_PSOCK_PORT) ? Numpsocks*2 : MAX_PSOCK_PORT)); - for (iter=0; iter<2; iter++) + for (iter=j=0; iter<2; iter++) { - for (i=n=0; ipublicsock; + //printf("check sock.%d\n",ptr->publicsock); pfds[n].events = POLLIN; } else @@ -464,15 +592,18 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w } else if ( (pfds[n].revents & POLLIN) != 0 ) { - //printf("publicsock.%d %s has pollin\n",ptr->publicsock,ptr->publicaddr); + //printf("cmd.%d publicsock.%d %s has pollin\n",ptr->cmdchannel,ptr->publicsock,ptr->publicaddr); buf = 0; if ( (size= nn_recv(ptr->publicsock,&buf,NN_MSG,0)) > 0 ) { ptr->lasttime = now; - sendsock = ptr->sendsock; - break; + if ( ptr->cmdchannel == 0 ) + { + sendsock = ptr->sendsock; + break; + } else LP_queuecommand(0,(char *)buf,ptr->publicsock,0,0); } - else if ( buf != 0 ) + if ( buf != 0 ) { nn_freemsg(buf); buf = 0; @@ -481,105 +612,102 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w } } n++; - if ( iter == 0 ) - { - pfds[n].fd = ptr->sendsock; - pfds[n].events = POLLIN; - } - else + if ( ptr->sendsock > 0 ) { - if ( pfds[n].fd != ptr->sendsock ) + if ( iter == 0 ) { - printf("unexpected fd.%d mismatched sendsock.%d\n",pfds[n].fd,ptr->sendsock); - break; + pfds[n].fd = ptr->sendsock; + pfds[n].events = POLLIN; } - else if ( (pfds[n].revents & POLLIN) != 0 ) + else { - if ( (size= nn_recv(ptr->sendsock,&buf,NN_MSG,0)) > 0 ) + if ( pfds[n].fd != ptr->sendsock ) { - //printf("%s paired has pollin (%s)\n",ptr->sendaddr,(char *)buf); - ptr->lasttime = now; - if ( ptr->ispaired != 0 ) - { - sendsock = ptr->publicsock; - break; - } + printf("unexpected fd.%d mismatched sendsock.%d\n",pfds[n].fd,ptr->sendsock); + break; } - if ( buf != 0 ) + else if ( (pfds[n].revents & POLLIN) != 0 ) { - nn_freemsg(buf); - buf = 0; - size = 0; + if ( (size= nn_recv(ptr->sendsock,&buf,NN_MSG,0)) > 0 ) + { + //printf("%s paired has pollin (%s)\n",ptr->sendaddr,(char *)buf); + ptr->lasttime = now; + if ( ptr->ispaired != 0 ) + { + sendsock = ptr->publicsock; + break; + } + } + if ( buf != 0 ) + { + nn_freemsg(buf); + buf = 0; + size = 0; + } } } + n++; } - n++; } if ( iter == 0 ) { if ( (retval= nn_poll(pfds,n,1)) <= 0 ) { - if ( retval != 0 ) - printf("nn_poll retval.%d\n",retval); + //if ( retval != 0 ) + // printf("nn_poll retval.%d\n",retval); break; - } else printf("num pfds.%d retval.%d\n",n,retval); + } // else printf("num pfds.%d retval.%d\n",n,retval); } } - //free(pfds); - //printf("sendsock.%d Numpsocks.%d\n",sendsock,Numpsocks); if ( sendsock < 0 ) + usleep(10000); + if ( 0 && IAMLP != 0 && sendsock < 0 ) { + usleep(30000); for (i=nonz=0; icmdchannel == 0 && now > ptr->lasttime+PSOCK_KEEPALIVE ) + { + printf("PSOCKS[%d] of %d (%u %u) lag.%d IDLETIMEOUT\n",i,Numpsocks,ptr->publicport,ptr->sendport,now - ptr->lasttime); + if ( ptr->sendsock != ptr->publicsock && ptr->sendsock >= 0 ) + nn_close(ptr->sendsock), ptr->sendsock = -1; + if ( ptr->publicsock >= 0 ) + nn_close(ptr->publicsock), ptr->publicsock = -1; + nonz++; + } + } + if ( nonz > 0 ) + { + n = Numpsocks; + for (i=0; i ptr->lasttime+PSOCK_KEEPALIVE ) - { - printf("PSOCKS[%d] of %d (%u %u) lag.%d IDLETIMEOUT\n",i,Numpsocks,ptr->publicport,ptr->sendport,now - ptr->lasttime); - if ( ptr->publicsock >= 0 ) - nn_close(ptr->publicsock); - if ( ptr->sendsock >= 0 ) - nn_close(ptr->sendsock); - //portable_mutex_lock(&LP_psockmutex); - if ( Numpsocks > 1 ) - { - PSOCKS[i] = PSOCKS[--Numpsocks]; - memset(&PSOCKS[Numpsocks],0,sizeof(*ptr)); - } else Numpsocks = 0; - //portable_mutex_unlock(&LP_psockmutex); - break; - } - else if ( now > ptr->lastping+PSOCK_KEEPALIVE/2 && ptr->errors < 3 ) + if ( ptr->sendsock < 0 && ptr->publicsock < 0 ) { - ptr->lastping = now; - if ( 0 ) - { - sendsock = ptr->sendsock; - sprintf(keepalive,"{\"method\":\"keepalive\",\"endpoint\":\"%s\"}",ptr->sendaddr); - size = (int32_t)strlen(keepalive) + 1; - buf = keepalive; - printf("send keepalive.(%s)\n",keepalive); - } - break; + for (j=i; jispaired = ispaired; + ptr->cmdchannel = cmdchannel; ptr->publicsock = publicsock; ptr->publicport = recvport; ptr->sendsock = sendsock; @@ -589,7 +717,7 @@ void LP_psockadd(int32_t ispaired,int32_t publicsock,uint16_t recvport,int32_t s ptr->lasttime = (uint32_t)time(NULL); portable_mutex_unlock(&LP_psockmutex); } - + int32_t LP_psockmark(char *publicaddr) { int32_t i,retval = -1; struct psock *ptr; @@ -608,121 +736,190 @@ int32_t LP_psockmark(char *publicaddr) portable_mutex_unlock(&LP_psockmutex); return(retval); } - -char *LP_psock(char *myipaddr,int32_t ispaired) + +char *_LP_psock_create(int32_t *pullsockp,int32_t *pubsockp,char *ipaddr,uint16_t publicport,uint16_t subport,int32_t ispaired,int32_t cmdchannel,bits256 pubkey) { - char pushaddr[128],subaddr[128]; uint16_t i,publicport,subport,maxiters=100; int32_t timeout,pullsock=-1,pubsock=-1; cJSON *retjson=0; - retjson = cJSON_CreateObject(); - publicport = Psockport++; - subport = Psockport++; - for (i=0; ipairsock >= 0 ) + { + //printf("%s already has pairsock.%d\n",bits256_str(str,pubkey),pubp->pairsock); + portable_mutex_lock(&LP_psockmutex); + for (i=0; ipairsock ) + { + //PSOCKS[i].lasttime = (uint32_t)time(NULL) - PSOCK_KEEPALIVE - 1; + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"LPipaddr",ipaddr); + jaddstr(retjson,"connectaddr",PSOCKS[i].sendaddr); + jaddnum(retjson,"connectport",PSOCKS[i].sendport); + jaddnum(retjson,"ispaired",PSOCKS[i].ispaired); + jaddnum(retjson,"cmdchannel",PSOCKS[i].cmdchannel); + jaddstr(retjson,"publicaddr",PSOCKS[i].publicaddr); + jaddnum(retjson,"publicport",PSOCKS[i].publicport); + //printf("cmd.%d publicaddr.(%s) for subaddr.(%s), pullsock.%d pubsock.%d\n",cmdchannel,pushaddr,subaddr,pullsock,pubsock); + *pullsockp = pullsock; + *pubsockp = pubsock; + portable_mutex_unlock(&LP_psockmutex); + return(jprint(retjson,1)); + } + portable_mutex_unlock(&LP_psockmutex); + } + //printf("pairsock for %s <- %d\n",bits256_str(str,pubkey),pullsock); + //pubp->pairsock = pullsock; + } + } + nanomsg_transportname(bindflag,pushaddr,ipaddr,publicport); + nanomsg_transportname(bindflag,subaddr,ipaddr,subport); + if ( (pullsock= nn_socket(AF_SP,ispaired!=0?NN_PAIR:NN_PULL)) >= 0 && (cmdchannel != 0 ||(pubsock= nn_socket(AF_SP,ispaired!=0?NN_PAIR:NN_PAIR)) >= 0) ) + { + if ( nn_bind(pullsock,pushaddr) >= 0 && (cmdchannel != 0 || nn_bind(pubsock,subaddr) >= 0) ) + { + arg = 100; + nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_SNDTIMEO,&arg,sizeof(arg)); + if ( pubsock >= 0 ) + nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&arg,sizeof(arg)); + arg = 1; + nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&arg,sizeof(arg)); + if ( pubsock >= 0 ) + nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_RCVTIMEO,&arg,sizeof(arg)); + //arg = 2; + //nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_MAXTTL,&arg,sizeof(arg)); + //if ( pubsock >= 0 ) + // nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_MAXTTL,&arg,sizeof(arg)); + nanomsg_transportname(0,pushaddr,ipaddr,publicport); + nanomsg_transportname(0,subaddr,ipaddr,subport); + LP_psockadd(ispaired,pullsock,publicport,pubsock,subport,subaddr,pushaddr,cmdchannel); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"LPipaddr",ipaddr); + jaddstr(retjson,"connectaddr",subaddr); + jaddnum(retjson,"connectport",subport); + jaddnum(retjson,"ispaired",ispaired); + jaddnum(retjson,"cmdchannel",cmdchannel); + jaddstr(retjson,"publicaddr",pushaddr); + jaddnum(retjson,"publicport",publicport); + if ( bits256_nonz(pubkey) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 ) + pubp->pairsock = pullsock; + char str[65]; printf("PSOCK %s cmd.%d publicaddr.(%s) for subaddr.(%s), pullsock.%d pubsock.%d\n",bits256_str(str,pubkey),cmdchannel,pushaddr,subaddr,pullsock,pubsock); + *pullsockp = pullsock; + *pubsockp = pubsock; + return(jprint(retjson,1)); + } //else printf("bind error on %s or %s\n",pushaddr,subaddr); + if ( pullsock >= 0 ) + nn_close(pullsock); + if ( pubsock >= 0 ) + nn_close(pubsock); + } + return(0); +} + +char *LP_psock(int32_t *pullsockp,char *ipaddr,int32_t ispaired,int32_t cmdchannel,bits256 pubkey) +{ + char *retstr=0; uint16_t i,publicport,subport,maxport; int32_t pubsock=-1; + *pullsockp = -1; + //printf("LP_psock ipaddr.%s ispaird.%d cmdchannel.%d\n",ipaddr,ispaired,cmdchannel); + if ( cmdchannel == 0 ) + { + maxport = MAX_PSOCK_PORT; + publicport = Psockport++; + subport = Psockport++; + } + else + { + if ( cmdchannel != 0 && bits256_nonz(pubkey) == 0 ) + return(clonestr("{\"error\",\"cant do pairsock for null pubkey\"}")); + maxport = 65534; + publicport = subport = Pcmdport++; + } + for (i=0; i= 0 && (pubsock= nn_socket(AF_SP,ispaired!=0?NN_PAIR:NN_PAIR)) >= 0 ) + if ( (retstr= _LP_psock_create(pullsockp,&pubsock,ipaddr,publicport,subport,ispaired,cmdchannel,pubkey)) != 0 ) { - if ( nn_bind(pullsock,pushaddr) >= 0 && nn_bind(pubsock,subaddr) >= 0 ) - { - timeout = 1; - nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); - nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - if ( ispaired != 0 ) - { - //maxsize = 1024 * 1024; - //nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize)); - } - //if ( ispaired != 0 ) - { - nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); - nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - } - nanomsg_transportname(0,pushaddr,myipaddr,publicport); - nanomsg_transportname(0,subaddr,myipaddr,subport); - LP_psockadd(ispaired,pullsock,publicport,pubsock,subport,subaddr,pushaddr); - jaddstr(retjson,"result","success"); - jaddstr(retjson,"LPipaddr",myipaddr); - jaddstr(retjson,"connectaddr",subaddr); - jaddnum(retjson,"connectport",subport); - jaddnum(retjson,"ispaired",ispaired); - jaddstr(retjson,"publicaddr",pushaddr); - jaddnum(retjson,"publicport",publicport); - printf("i.%d publicaddr.(%s) for subaddr.(%s), pullsock.%d pubsock.%d\n",i,pushaddr,subaddr,pullsock,pubsock); - break; - } else printf("bind error on %s or %s\n",pushaddr,subaddr); - if ( pullsock >= 0 ) - nn_close(pullsock); - if ( pubsock >= 0 ) - nn_close(pubsock); + //printf("LP_psock returns.(%s)\n",retstr); + return(retstr); } + if ( cmdchannel == 0 ) + publicport+=2, subport+=2; + else publicport++, subport++; } - if ( Psockport > MAX_PSOCK_PORT ) + if ( Psockport >= MAX_PSOCK_PORT ) Psockport = MIN_PSOCK_PORT; - if ( i == maxiters ) - jaddstr(retjson,"error","cant find psock ports"); - return(jprint(retjson,1)); + if ( Pcmdport >= 65534 ) + Pcmdport = MAX_PSOCK_PORT; + return(clonestr("{\"error\",\"cant find psock ports\"}")); } - + /* LP_pushaddr_get makes transparent the fact that most nodes cannot bind()! The idea is to create an LP node NN_PAIR sock that the LP node binds to and client node connects to. Additionally, the LP node creates an NN_PULL that other nodes can NN_PUSH to and returns this address in pushaddr/retval for the client node to register with. The desired result is that other than the initial LP node, all the other nodes do a normal NN_PUSH, requiring no change to the NN_PUSH/NN_PULL logic. Of course, the initial LP node needs to autoforward all packets from the public NN_PULL to the NN_PUB - similar to LP_pushaddr_get, create an NN_PAIR for DEX atomic data, can be assumed to have a max lifetime of 2*INSTANTDEX_LOCKTIME + similar to LP_pushaddr_get, create an NN_PAIR for DEX atomic data, can be assumed to have a max lifetime of 2*INSTANTDEX_LOCKTIME both are combined in LP_psock_get - -*/ - -char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired) + + */ + +char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired,int32_t cmdchannel) { - char url[512],*retstr; - sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d",destip,destport-1,ispaired); + char str[65],url[512],*retstr; + sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d&cmdchannel=%d&pubkey=%s&netid=%d",destip,destport-1,ispaired,cmdchannel,bits256_str(str,G.LP_mypub25519),G.netid); //return(LP_issue_curl("psock",destip,destport,url)); - retstr = issue_curlt(url,LP_HTTP_TIMEOUT*3); - printf("issue_LP_psock got (%s) from %s\n",retstr,destip); + retstr = issue_curlt(url,LP_HTTP_TIMEOUT*10); + printf("issue_LP_psock got (%s) from %s\n",retstr,url); // this is needed?! return(retstr); } - -uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired) + +uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired,int32_t cmdchannel,char *ipaddr) { uint16_t publicport = 0; char *retstr,*addr; cJSON *retjson; struct LP_peerinfo *peer,*tmp; + connectaddr[0] = publicaddr[0] = 0; HASH_ITER(hh,LP_peerinfos,peer,tmp) { + if ( ipaddr != 0 && strcmp(ipaddr,peer->ipaddr) != 0 ) + continue; connectaddr[0] = publicaddr[0] = 0; - if ( peer->errors < LP_MAXPEER_ERRORS && (retstr= issue_LP_psock(peer->ipaddr,peer->port,ispaired)) != 0 ) + if ( peer->errors < LP_MAXPEER_ERRORS && (retstr= issue_LP_psock(peer->ipaddr,peer->port,ispaired,cmdchannel)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - printf("from %s:%u (%s)\n",peer->ipaddr,peer->port,retstr); + //printf("from %s:%u (%s)\n",peer->ipaddr,peer->port,retstr); if ( (addr= jstr(retjson,"publicaddr")) != 0 ) safecopy(publicaddr,addr,128); if ( (addr= jstr(retjson,"connectaddr")) != 0 ) safecopy(connectaddr,addr,128); - //if ( (addr= jstr(retjson,"connectaddr2")) != 0 ) - // safecopy(connectaddr2,addr,128); if ( publicaddr[0] != 0 && connectaddr[0] != 0 ) publicport = juint(retjson,"publicport"); free_json(retjson); } - printf("got.(%s) connect.%s public.%s\n",retstr,connectaddr,publicaddr); + //printf("got.(%s) connect.%s public.%s publicport.%u\n",retstr,connectaddr,publicaddr,publicport); free(retstr); - } else printf("error psock from %s:%u\n",peer->ipaddr,peer->port); - if ( publicport != 0 ) - break; + return(publicport); + } //else printf("error psock from %s:%u\n",peer->ipaddr,peer->port); } - return(publicport); + return(0); } - + int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char *myipaddr,uint16_t mypullport,int32_t ispaired) { int32_t nntype,pullsock,timeout; char bindaddr[128],connectaddr[128]; *mypullportp = mypullport; - //connectaddr2[0] = 0; if ( ispaired == 0 ) { if ( LP_canbind != 0 ) @@ -733,7 +930,6 @@ int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char { nanomsg_transportname(0,publicaddr,myipaddr,mypullport); nanomsg_transportname(1,bindaddr,myipaddr,mypullport); - //nanomsg_transportname2(1,bindaddr2,myipaddr,mypullport); } else { @@ -745,7 +941,7 @@ int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char } while ( *mypullportp == 0 ) { - if ( (*mypullportp= LP_psock_get(connectaddr,publicaddr,ispaired)) != 0 ) + if ( (*mypullportp= LP_psock_get(connectaddr,publicaddr,ispaired,0,0)) != 0 ) break; sleep(10); printf("try to get publicaddr again\n"); @@ -764,8 +960,6 @@ int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char } else { - //if ( connectaddr2[0] != 0 && nn_connect(pullsock,connectaddr2) > 0 ) - // printf("%s ",connectaddr2); printf("nntype.%d NN_PAIR.%d connect to %s connectsock.%d\n",nntype,NN_PAIR,connectaddr,pullsock); } } @@ -776,14 +970,10 @@ int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char printf("bind to %s error for %s: %s\n",bindaddr,publicaddr,nn_strerror(nn_errno())); exit(-1); } - //if ( nn_bind(pullsock,bindaddr2) >= 0 ) - // printf("bound to %s\n",bindaddr2); } - timeout = 1; + timeout = 100; nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); - //maxsize = 2 * 1024 * 1024; - //nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize)); if ( nntype == NN_SUB ) nn_setsockopt(pullsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); } diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c index 3ec680e96..baeffc595 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -24,6 +24,23 @@ bits256 LP_Alicedestpubkey,LP_bobs_reserved; uint32_t Alice_expiration,Bob_expiration; struct { uint64_t aliceid; double bestprice; uint32_t starttime,counter; } Bob_competition[512]; + +void LP_failedmsg(uint32_t requestid,uint32_t quoteid,double val) +{ + char *msg; cJSON *retjson; + if ( IPC_ENDPOINT >= 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"method","failed"); + jaddnum(retjson,"error",val); + jaddnum(retjson,"requestid",requestid); + jaddnum(retjson,"quoteid",quoteid); + msg = jprint(retjson,1); + LP_queuecommand(0,msg,IPC_ENDPOINT,-1,0); + free(msg); + } +} + double LP_bob_competition(int32_t *counterp,uint64_t aliceid,double price,int32_t counter) { int32_t i,firsti = -1; uint32_t now = (uint32_t)time(NULL); @@ -71,12 +88,12 @@ uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen) if ( txlen == 0 ) txlen = LP_AVETXSIZE; coin->rate = LP_getestimatedrate(coin); - if ( (txfee= SATOSHIDEN * coin->rate * txlen) <= LP_MIN_TXFEE ) + if ( (txfee= SATOSHIDEN * coin->rate * txlen) <= 20000 ) { - coin->rate = -1.; + //coin->rate = -1.; coin->rate = _LP_getestimatedrate(coin); - if ( (txfee= SATOSHIDEN * coin->rate * txlen) <= LP_MIN_TXFEE ) - txfee = LP_MIN_TXFEE; + if ( (txfee= SATOSHIDEN * coin->rate * txlen) <= 20000 ) + txfee = 20000; } } else txfee = coin->txfee; if ( txfee < LP_MIN_TXFEE ) @@ -103,27 +120,29 @@ int32_t LP_quote_checkmempool(struct LP_quoteinfo *qp,struct LP_utxoinfo *autxo, double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP_quoteinfo *qp,int32_t iambob) { - double qprice=0.; char str[65]; cJSON *txout; uint64_t txfee,desttxfee,srcvalue=0,srcvalue2=0,destvalue=0,destvalue2=0; - //printf(">>>>>>> quote satoshis.(%.8f %.8f) %s %.8f -> %s %.8f\n",dstr(qp->satoshis),dstr(qp->destsatoshis),qp->srccoin,dstr(qp->satoshis),qp->destcoin,dstr(qp->destsatoshis)); + double qprice=0.; char str[65],srccoin[65],destcoin[65],bobtomic[64],alicetomic[64]; cJSON *txout; uint64_t txfee,desttxfee,srcvalue=0,srcvalue2=0,destvalue=0,destvalue2=0; + LP_etomicsymbol(srccoin,bobtomic,qp->srccoin); + LP_etomicsymbol(destcoin,alicetomic,qp->destcoin); + //printf(">>>>>>> quote satoshis.(%.8f %.8f) %s %.8f -> %s %.8f\n",dstr(qp->satoshis),dstr(qp->destsatoshis),qp->srccoin,dstr(qp->satoshis),qp->destcoin,dstr(qp->destsatoshis)); if ( butxo != 0 ) { - if ( LP_iseligible(&srcvalue,&srcvalue2,1,qp->srccoin,qp->txid,qp->vout,qp->satoshis,qp->txid2,qp->vout2) == 0 ) + if ( LP_iseligible(&srcvalue,&srcvalue2,1,srccoin,qp->txid,qp->vout,qp->satoshis,qp->txid2,qp->vout2) == 0 ) { //printf("bob not eligible %s (%.8f %.8f)\n",jprint(LP_quotejson(qp),1),dstr(srcvalue),dstr(srcvalue2)); return(-2); } - if ( (txout= LP_gettxout(qp->srccoin,qp->coinaddr,qp->txid,qp->vout)) != 0 ) + if ( (txout= LP_gettxout(srccoin,qp->coinaddr,qp->txid,qp->vout)) != 0 ) free_json(txout); else { - printf("%s %s payment %s/v%d is spent\n",qp->srccoin,qp->coinaddr,bits256_str(str,qp->txid),qp->vout); + printf("%s %s payment %s/v%d is spent\n",srccoin,qp->coinaddr,bits256_str(str,qp->txid),qp->vout); return(-21); } - if ( (txout= LP_gettxout(qp->srccoin,qp->coinaddr,qp->txid2,qp->vout2)) != 0 ) + if ( (txout= LP_gettxout(srccoin,qp->coinaddr,qp->txid2,qp->vout2)) != 0 ) free_json(txout); else { - printf("%s %s deposit %s/v%d is spent\n",qp->srccoin,qp->coinaddr,bits256_str(str,qp->txid2),qp->vout2); + printf("%s %s deposit %s/v%d is spent\n",srccoin,qp->coinaddr,bits256_str(str,qp->txid2),qp->vout2); return(-22); } if ( bits256_cmp(butxo->deposit.txid,qp->txid2) != 0 || butxo->deposit.vout != qp->vout2 ) @@ -139,24 +158,24 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str } if ( autxo != 0 ) { - if ( LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 ) + if ( LP_iseligible(&destvalue,&destvalue2,0,destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 ) { //alice not eligible 0.36893923 -> dest 0.55020000 1.49130251 (0.61732249 0.00104324) 14b8b74808d2d34a70e5eddd1cad47d855858f8b23cac802576d4d37b5f8af8f/v1 abec6e76169bcb738235ca67fab02cc55390f39e422aa71f1badf8747c290cc4/v1 - //char str[65],str2[65]; printf("alice not eligible %.8f -> dest %.8f %.8f (%.8f %.8f) %s/v%d %s/v%d\n",dstr(qp->satoshis),dstr(qp->destsatoshis),(double)qp->destsatoshis/qp->satoshis,dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout); + char str[65],str2[65]; printf("alice not eligible %.8f -> dest %.8f %.8f (%.8f %.8f) %s/v%d %s/v%d\n",dstr(qp->satoshis),dstr(qp->destsatoshis),(double)qp->destsatoshis/qp->satoshis,dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout); return(-3); } - if ( (txout= LP_gettxout(qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout)) != 0 ) + if ( (txout= LP_gettxout(destcoin,qp->destaddr,qp->desttxid,qp->destvout)) != 0 ) free_json(txout); else { - printf("%s %s Apayment %s/v%d is spent\n",qp->destcoin,qp->destaddr,bits256_str(str,qp->desttxid),qp->destvout); + printf("%s %s Apayment %s/v%d is spent\n",destcoin,qp->destaddr,bits256_str(str,qp->desttxid),qp->destvout); return(-23); } - if ( (txout= LP_gettxout(qp->destcoin,qp->destaddr,qp->feetxid,qp->feevout)) != 0 ) + if ( (txout= LP_gettxout(destcoin,qp->destaddr,qp->feetxid,qp->feevout)) != 0 ) free_json(txout); else { - printf("%s %s dexfee %s/v%d is spent\n",qp->destcoin,qp->destaddr,bits256_str(str,qp->feetxid),qp->feevout); + printf("%s %s dexfee %s/v%d is spent\n",destcoin,qp->destaddr,bits256_str(str,qp->feetxid),qp->feevout); return(-24); } } @@ -180,16 +199,19 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str 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); } - if ( qp->satoshis != 0 ) - qprice = ((double)qp->destsatoshis / (qp->satoshis-qp->txfee)); LP_txfees(&txfee,&desttxfee,qp->srccoin,qp->destcoin); if ( txfee < qp->txfee ) txfee = qp->txfee; if ( desttxfee < qp->desttxfee ) desttxfee = qp->desttxfee; + if ( qp->satoshis != 0 ) + qprice = ((double)qp->destsatoshis / (qp->satoshis-qp->txfee)); //printf("qprice %.8f <- %.8f/%.8f txfees.(%.8f %.8f) vs (%.8f %.8f)\n",qprice,dstr(qp->destsatoshis),dstr(qp->satoshis),dstr(qp->txfee),dstr(qp->desttxfee),dstr(txfee),dstr(desttxfee)); if ( qp->txfee < LP_REQUIRED_TXFEE*txfee || qp->desttxfee < LP_REQUIRED_TXFEE*desttxfee ) + { + 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 ( qp->satoshis < (srcvalue / LP_MINVOL) || srcvalue < qp->txfee*LP_MINSIZE_TXFEEMULT ) @@ -230,7 +252,7 @@ int32_t LP_nanobind(void *ctx,char *pairstr) printf("error creating utxo->pair\n"); else { - for (i=0; i<10; i++) + for (i=0; i<10000; i++) { r = (10000 + (LP_rand() % 50000)) & 0xffff; if ( LP_fixed_pairport != 0 ) @@ -242,12 +264,15 @@ int32_t LP_nanobind(void *ctx,char *pairstr) //timeout = 1; //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - printf("nanobind %s to %d\n",pairstr,pairsock); + //printf("nanobind %s to %d\n",pairstr,pairsock); return(pairsock); - } else printf("error binding to %s for %s\n",bindaddr,pairstr); + } // else printf("error binding to %s for %s\n",bindaddr,pairstr); if ( LP_fixed_pairport != 0 ) break; } + printf("%d ports all used\n",i); + nn_close(pairsock); + pairsock = -1; } } else pairsock = LP_initpublicaddr(ctx,&mypullport,pairstr,"127.0.0.1",0,1); return(pairsock); @@ -301,7 +326,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a } if ( replacei >= 0 ) { - printf("REPLACE bestdist %.8f height %d with dist %.8f height %d\n",dstr(bestdist),bestup->U.height,dstr(utxos[replacei]->U.value - targetval),utxos[replacei]->U.height); + //printf("REPLACE bestdist %.8f height %d with dist %.8f height %d\n",dstr(bestdist),bestup->U.height,dstr(utxos[replacei]->U.value - targetval),utxos[replacei]->U.height); return(replacei); } } @@ -377,6 +402,13 @@ uint64_t LP_basesatoshis(double relvolume,double price,uint64_t txfee,uint64_t d struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct iguana_info *coin,char *coinaddr,uint64_t txfee,double relvolume,double price,uint64_t desttxfee) { struct LP_address *ap; uint64_t fee,targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; double ratio; + if ( coin->etomic[0] != 0 ) + { + if ( (coin= LP_coinfind("ETOMIC")) != 0 ) + coinaddr = coin->smartaddr; + } + if ( coin == 0 ) + return(0); memset(butxo,0,sizeof(*butxo)); if ( iambob != 0 ) { @@ -411,7 +443,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb { up = utxos[mini]; utxos[mini] = 0; - printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n",mini,dstr(up->U.value),dstr(targetval),dstr(targetval2),(double)up->U.value/targetval); + //printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n",mini,dstr(up->U.value),dstr(targetval),dstr(targetval2),(double)up->U.value/targetval); if ( (double)up->U.value/targetval < ratio-1 ) { @@ -430,68 +462,99 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb LP_butxo_set(butxo,iambob,coin,up,up2,targetval); return(butxo); } else printf("cant find utxos[mini %d]\n",mini); - } else printf("cant find targetval2 %.8f\n",dstr(targetval2)); - } else printf("failed ratio test %.8f\n",(double)up->U.value/targetval); + } //else printf("cant find targetval2 %.8f\n",dstr(targetval2)); + } //else printf("failed ratio test %.8f\n",(double)up->U.value/targetval); } else if ( targetval != 0 && mini >= 0 ) printf("targetval %.8f mini.%d\n",dstr(targetval),mini); if ( targetval == 0 || mini < 0 ) break; } - } else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr); - } else printf("address_myutxopair couldnt find %s %s\n",coin->symbol,coinaddr); + } //else printf("no %s %s utxos pass LP_address_utxo_ptrs filter %.8f %.8f\n",coin->symbol,coinaddr,dstr(targetval),dstr(targetval2)); + } + printf("address_myutxopair couldnt find %s %s targets %.8f %.8f\n",coin->symbol,coinaddr,dstr(targetval),dstr(targetval2)); return(0); } int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double price,struct LP_quoteinfo *qp) { - char pairstr[512],otheraddr[64]; cJSON *reqjson; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; struct basilisk_swap *swap; struct iguana_info *coin,*kmdcoin; + char pairstr[512],otheraddr[64]; cJSON *reqjson; bits256 privkey; int32_t i,pair=-1,retval = -1,DEXselector = 0; int64_t dtrust; struct basilisk_swap *swap; struct iguana_info *ecoin,*coin,*kmdcoin; qp->quotetime = (uint32_t)time(NULL); if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) { printf("cant find coin.%s\n",qp->srccoin); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-3000); return(-1); } privkey = LP_privkey(coin->symbol,coin->smartaddr,coin->taddr); + if ( coin->etomic[0] != 0 ) + { + if ( (ecoin= LP_coinfind("ETOMIC")) != 0 ) + privkey = LP_privkey(ecoin->symbol,ecoin->smartaddr,ecoin->taddr); + } if ( bits256_nonz(privkey) != 0 && bits256_cmp(G.LP_mypub25519,qp->srchash) == 0 ) { LP_requestinit(&qp->R,qp->srchash,qp->desthash,base,qp->satoshis-qp->txfee,rel,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); - if ( LP_pendingswap(qp->R.requestid,qp->R.quoteid) > 0 ) - { - printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid); - return(-1); - } - if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp,LP_dynamictrust(qp->othercredits,qp->desthash,LP_kmdvalue(qp->destcoin,qp->destsatoshis)) > 0)) == 0 ) + 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 ) { printf("cant initialize swap\n"); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-3001); return(-1); } if ( (pair= LP_nanobind(ctx,pairstr)) >= 0 ) { swap->N.pair = pair; - //utxo->S.swap = swap; - //swap->utxo = utxo; if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_bobloop,(void *)swap) == 0 ) { reqjson = LP_quotejson(qp); + LP_swapsfp_update(qp->R.requestid,qp->R.quoteid); jaddstr(reqjson,"method","connected"); jaddstr(reqjson,"pair",pairstr); if ( (kmdcoin= LP_coinfind("KMD")) != 0 ) jadd(reqjson,"proof",LP_instantdex_txids(0,kmdcoin->smartaddr)); - char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash)); - bits256 zero; - memset(zero.bytes,0,sizeof(zero)); - LP_reserved_msg(1,base,rel,zero,jprint(reqjson,0)); - sleep(1); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); - sleep(1); - LP_reserved_msg(0,base,rel,zero,jprint(reqjson,0)); - free_json(reqjson); + //char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash)); 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 ) + { + 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)); + } + 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); retval = 0; - } else printf("error launching swaploop\n"); - } else printf("couldnt bind to any port %s\n",pairstr); + } + else + { + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-3002); + printf("error launching swaploop\n"); + } + } + else + { + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-3003); + printf("couldnt bind to any port %s\n",pairstr); + } + } + else + { + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-3004); + printf("cant find privkey for %s\n",coin->smartaddr); } if ( retval < 0 ) { @@ -512,9 +575,10 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); if ( (qp->tradeid= tradeid) == 0 ) qp->tradeid = LP_rand(); + qp->srchash = destpubkey; 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\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),maxprice); + char str[65]; printf("LP_trade %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f etomicdest.(%s)\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),maxprice,qp->etomicdest); return(LP_recent_swaps(0)); } @@ -557,31 +621,16 @@ int32_t LP_alice_eligible(uint32_t quotetime) char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice { - cJSON *retjson; char otheraddr[64]; 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; - /*if ( LP_quoteparse(&Q,argjson) < 0 ) - { - LP_aliceid(Q.tradeid,Q.aliceid,"error0",0,0); - clonestr("{\"error\":\"cant parse quote\"}"); - }*/ + 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; 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); 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("calculated requestid.%u quoteid.%u\n",qp->R.requestid,qp->R.quoteid); - if ( LP_pendingswap(qp->R.requestid,qp->R.quoteid) > 0 ) - { - printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"error","swap already in progress"); - return(jprint(retjson,1)); - } - /*if ( LP_quotecmp(1,qp,&LP_Alicereserved) == 0 ) - { - printf("mismatched between reserved and connected\n"); - }*/ memset(&LP_Alicereserved,0,sizeof(LP_Alicereserved)); LP_aliceid(qp->tradeid,qp->aliceid,"connected",qp->R.requestid,qp->R.quoteid); autxo = &A; @@ -594,6 +643,7 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice LP_availableset(qp->desttxid,qp->vout); LP_availableset(qp->feetxid,qp->feevout); LP_aliceid(qp->tradeid,qp->aliceid,"error4",0,0); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,qprice); printf("quote %s/%s validate error %.0f\n",qp->srccoin,qp->destcoin,qprice); return(clonestr("{\"error\":\"quote validation error\"}")); } @@ -603,6 +653,7 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice LP_availableset(qp->desttxid,qp->vout); LP_availableset(qp->feetxid,qp->feevout); LP_aliceid(qp->tradeid,qp->aliceid,"error5",0,0); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-4002); return(clonestr("{\"error\":\"no price set\"}")); } //LP_RTmetrics_update(qp->srccoin,qp->destcoin); @@ -611,6 +662,7 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice if ( (coin= LP_coinfind(qp->destcoin)) == 0 ) { LP_aliceid(qp->tradeid,qp->aliceid,"error6",0,0); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-4003); return(clonestr("{\"error\":\"cant get alicecoin\"}")); } qp->privkey = LP_privkey(coin->symbol,qp->destaddr,coin->taddr); @@ -623,11 +675,13 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice LP_availableset(qp->desttxid,qp->vout); LP_availableset(qp->feetxid,qp->feevout); LP_aliceid(qp->tradeid,qp->aliceid,"error7",qp->R.requestid,qp->R.quoteid); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-4004); return(jprint(retjson,1)); } if ( pairstr == 0 || pairstr[0] == 0 || (pairsock= nn_socket(AF_SP,NN_PAIR)) < 0 ) { LP_aliceid(qp->tradeid,qp->aliceid,"error8",qp->R.requestid,qp->R.quoteid); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-4005); jaddstr(retjson,"error","couldnt create pairsock"); } else if ( nn_connect(pairsock,pairstr) >= 0 ) @@ -648,6 +702,13 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice { retjson = LP_quotejson(qp); jaddstr(retjson,"result","success"); + LP_swapsfp_update(qp->R.requestid,qp->R.quoteid); + if ( IPC_ENDPOINT >= 0 ) + { + msg = jprint(retjson,0); + LP_queuecommand(0,msg,IPC_ENDPOINT,-1,0); + free(msg); + } //jaddnum(retjson,"requestid",qp->R.requestid); //jaddnum(retjson,"quoteid",qp->R.quoteid); } @@ -655,14 +716,16 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice { LP_aliceid(qp->tradeid,qp->aliceid,"error9",qp->R.requestid,qp->R.quoteid); jaddstr(retjson,"error","couldnt aliceloop"); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-4006); } } else { LP_aliceid(qp->tradeid,qp->aliceid,"error10",qp->R.requestid,qp->R.quoteid); printf("connect error %s\n",nn_strerror(nn_errno())); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-4007); } - printf("connected result.(%s)\n",jprint(retjson,0)); + //printf("connected result.(%s)\n",jprint(retjson,0)); if ( jobj(retjson,"error") != 0 ) { LP_availableset(qp->desttxid,qp->vout); @@ -676,6 +739,7 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice LP_availableset(qp->feetxid,qp->feevout); LP_aliceid(qp->tradeid,qp->aliceid,"error11",0,0); printf("no privkey found coin.%s %s taddr.%u\n",qp->destcoin,qp->destaddr,coin->taddr); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-4008); return(clonestr("{\"error\",\"no privkey\"}")); } } @@ -702,7 +766,7 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) if ( vout < tx->numvouts && tx->height > 0 ) { printf("added missing utxo for SPV checking\n"); - LP_address_utxoadd((uint32_t)time(NULL),"LP_validSPV",coin,coinaddr,txid,vout,tx->outpoints[vout].value,tx->height,-1); + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_validSPV",coin,coinaddr,txid,vout,tx->outpoints[vout].value,tx->height,-1); } } } @@ -767,7 +831,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo qp->tradeid = LP_Alicequery.tradeid; LP_Alicereserved = *qp; LP_alicequery_clear(); - printf("send CONNECT\n"); + //printf("send CONNECT\n"); LP_query(ctx,myipaddr,mypubsock,"connect",qp); } else printf("LP_reserved %llu price %.8f vs maxprice %.8f\n",(long long)qp->aliceid,price,maxprice); } //else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(qp->quotetime),price,maxprice); @@ -805,7 +869,7 @@ double LP_trades_pricevalidate(struct LP_quoteinfo *qp,struct iguana_info *coin, memset(autxo,0,sizeof(*autxo)); memset(butxo,0,sizeof(*butxo)); LP_abutxo_set(autxo,butxo,qp); - if ( strcmp(qp->coinaddr,coin->smartaddr) != 0 ) + if ( coin->etomic[0] == 0 && strcmp(qp->coinaddr,coin->smartaddr) != 0 ) { printf("bob is patching qp->coinaddr %s mismatch != %s\n",qp->coinaddr,coin->smartaddr); strcpy(qp->coinaddr,coin->smartaddr); @@ -822,7 +886,7 @@ double LP_trades_pricevalidate(struct LP_quoteinfo *qp,struct iguana_info *coin, } if ( qprice < (price - 0.00000001) * 0.998 ) { - printf(" quote price %.8f too low vs %.8f for %s/%s %.8f < %.8f\n",qprice,price,qp->srccoin,qp->destcoin,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); } return(qprice); @@ -830,73 +894,129 @@ 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,qprice,myprice,bestprice,range,bid,ask; struct iguana_info *coin; struct LP_utxoinfo A,B,*autxo,*butxo; cJSON *reqjson; char str[65]; struct LP_address_utxo *utxos[1000]; int32_t r,counter,max = (int32_t)(sizeof(utxos)/sizeof(*utxos)); + 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)); *newqp = *qp; qp = newqp; - if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) + //printf("bob %s received REQUEST.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); + if ( (coin= LP_coinfind(qp->srccoin)) == 0 || (othercoin= LP_coinfind(qp->destcoin)) == 0 ) return(0); - //if ( strcmp(qp->srccoin,"GRS") == 0 || strcmp(qp->destcoin,"GRS") == 0 ) - // printf("LP_trades_gotrequest %s/%s myprice %.8f\n",qp->srccoin,qp->destcoin,LP_trades_bobprice(&bid,&ask,qp)); if ( (myprice= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) + { + printf("myprice %.8f bid %.8f ask %.8f\n",myprice,bid,ask); return(0); + } autxo = &A; butxo = &B; memset(autxo,0,sizeof(*autxo)); memset(butxo,0,sizeof(*butxo)); LP_abutxo_set(autxo,butxo,qp); + strcpy(qp->coinaddr,coin->smartaddr); if ( bits256_nonz(qp->srchash) == 0 || bits256_cmp(qp->srchash,G.LP_mypub25519) == 0 ) { qprice = (double)qp->destsatoshis / (qp->satoshis - qp->txfee); strcpy(qp->gui,G.gui); - strcpy(qp->coinaddr,coin->smartaddr); - strcpy(butxo->coinaddr,coin->smartaddr); + if ( coin->etomic[0] != 0 ) + strcpy(qp->etomicsrc,coin->smartaddr); + else if ( othercoin->etomic[0] != 0 ) + strcpy(qp->etomicsrc,othercoin->smartaddr); + if ( coin->etomic[0] != 0 )//|| othercoin->etomic[0] != 0 ) + { + struct iguana_info *ecoin; + if ( (ecoin= LP_coinfind("ETOMIC")) != 0 ) + strcpy(qp->coinaddr,ecoin->smartaddr); + else + { + printf("ETOMIC coin not found\n"); + return(0); + } + } + strcpy(butxo->coinaddr,qp->coinaddr); qp->srchash = G.LP_mypub25519; memset(&qp->txid,0,sizeof(qp->txid)); memset(&qp->txid2,0,sizeof(qp->txid2)); qp->vout = qp->vout2 = -1; } else return(0); - //if ( strcmp(qp->srccoin,"GRS") == 0 || strcmp(qp->destcoin,"GRS") == 0 ) - // printf("LP_trades_gotrequest qprice %.8f vs myprice %.8f\n",qprice,myprice); - if ( qprice > myprice ) + if ( qprice >= myprice ) { - r = (LP_rand() % 100); + r = (LP_rand() % 90) + 10; range = (qprice - myprice); - price = myprice + (r * range) / 100.; + price = myprice + ((r * range) / 100.); bestprice = LP_bob_competition(&counter,qp->aliceid,price,0); - printf("%llu >>>>>>> qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",(long long)qp->aliceid,qprice,r,range,price,bestprice,counter); - if ( counter > 3 && price >= bestprice+SMALLVAL ) // skip if late or bad price + printf("%llu >>>>>>> myprice %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",(long long)qp->aliceid,myprice,qprice,r,range,price,bestprice,counter); + if ( counter > 3 && price > bestprice+SMALLVAL ) // skip if late or bad price return(0); - } else return(0); + } + else + { + //printf("ignore as qprice %.8f vs myprice %.8f\n",qprice,myprice); + return(0); + } //LP_RTmetrics_update(qp->srccoin,qp->destcoin); if ( LP_RTmetrics_blacklisted(qp->desthash) >= 0 ) { printf("request from blacklisted %s, ignore\n",bits256_str(str,qp->desthash)); return(0); } - LP_address_utxo_reset(coin); - 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); + //printf("LP_address_utxo_reset.%s\n",coin->symbol); + //LP_address_utxo_reset(coin); + //printf("done LP_address_utxo_reset.%s\n",coin->symbol); + if ( coin->etomic[0] != 0 ) + strcpy(qp->etomicsrc,coin->smartaddr); + else if ( othercoin->etomic[0] != 0 ) + strcpy(qp->etomicsrc,othercoin->smartaddr); + if ( coin->etomic[0] != 0 )//|| othercoin->etomic[0] != 0 ) + { + struct iguana_info *ecoin; + if ( (ecoin= LP_coinfind("ETOMIC")) != 0 ) + strcpy(qp->coinaddr,ecoin->smartaddr); + else + { + printf("ETOMIC coin not found\n"); + return(0); + } } - else + i = 0; + while ( i < 33 && price >= myprice ) { - printf("cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f\n",(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 ( (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); + } + else + { + 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. ) + return(0); + if ( i == 0 && p < myprice ) + { + price = qprice; + printf("reset price <- qprice %.8f\n",qprice); + } + else + { + if ( qprice >= p ) + break; + price *= 0.995; + } + i++; } - if ( (qprice= LP_trades_pricevalidate(qp,coin,myprice)) < 0. ) - return(0); - //if ( strcmp(qp->srccoin,"GRS") == 0 || strcmp(qp->destcoin,"GRS") == 0 ) - // printf("final checks\n"); + printf("i.%d qprice %.8f myprice %.8f price %.8f [%.8f]\n",i,qprice,myprice,price,p); if ( LP_allocated(qp->txid,qp->vout) == 0 && LP_allocated(qp->txid2,qp->vout2) == 0 ) { + //printf("found unallocated txids\n"); reqjson = LP_quotejson(qp); LP_unavailableset(qp->txid,qp->vout,qp->timestamp + LP_RESERVETIME,qp->desthash); LP_unavailableset(qp->txid2,qp->vout2,qp->timestamp + LP_RESERVETIME,qp->desthash); @@ -905,16 +1025,12 @@ 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)); - if ( 0 )//if ( IAMLP == 0 ) - { - sleep(1); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); - } - //LP_reserved_msg(0,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); free_json(reqjson); + //printf("Send RESERVED id.%llu\n",(long long)qp->aliceid); return(qp); } else printf("request processing selected ineligible utxos?\n"); return(0); @@ -922,17 +1038,18 @@ 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; + char *retstr; double qprice; char str[65]; printf("alice %s received RESERVED.(%llu) %.8f\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid,(double)qp->destsatoshis/(qp->satoshis+1)); *newqp = *qp; qp = newqp; - if ( LP_trades_alicevalidate(ctx,qp) > 0. ) + if ( (qprice= LP_trades_alicevalidate(ctx,qp)) > 0. ) { + //printf("got qprice %.8f\n",qprice); LP_aliceid(qp->tradeid,qp->aliceid,"reserved",0,0); if ( (retstr= LP_quotereceived(qp)) != 0 ) free(retstr); return(qp); - } + } else LP_failedmsg(qp->R.requestid,qp->R.quoteid,qprice); return(0); } @@ -949,26 +1066,34 @@ struct LP_quoteinfo *LP_trades_gotconnect(void *ctx,struct LP_quoteinfo *qp,stru return(0); if ( LP_reservation_check(qp->txid,qp->vout,qp->desthash) == 0 && LP_reservation_check(qp->txid2,qp->vout2,qp->desthash) == 0 ) { + char str[65]; printf("bob %s received CONNECT.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); LP_connectstartbob(ctx,LP_mypubsock,qp->srccoin,qp->destcoin,qprice,qp); return(qp); - } else printf("connect message from non-reserved (%llu)\n",(long long)qp->aliceid); + } + else + { + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-1); + printf("connect message from non-reserved (%llu)\n",(long long)qp->aliceid); + } return(0); } struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) { - char *retstr; - char str[65]; printf("alice %s received CONNECTED.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); + 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); *newqp = *qp; qp = newqp; - if ( LP_trades_alicevalidate(ctx,qp) > 0. ) + if ( (val= LP_trades_alicevalidate(ctx,qp)) > 0. ) { - //printf("LP_trades_alicevalidate fine\n"); + printf("CONNECTED ALICE\n"); 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_alicequery_clear(); return(qp); - } + } else LP_failedmsg(qp->R.requestid,qp->R.quoteid,val); //printf("LP_trades_alicevalidate error\n"); return(0); } @@ -1012,12 +1137,64 @@ void LP_tradesloop(void *ctx) { struct LP_trade *qtp,*tp,*tmp; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t timeout,funcid,flag,nonz; struct iguana_info *coin; struct LP_pubkey_info *pubp; strcpy(LP_tradesloop_stats.name,"LP_tradesloop"); - LP_tradesloop_stats.threshold = 10000; + LP_tradesloop_stats.threshold = 30000; sleep(5); while ( LP_STOP_RECEIVED == 0 ) { LP_millistats_update(&LP_tradesloop_stats); nonz = 0; + HASH_ITER(hh,LP_trades,tp,tmp) + { + if ( tp->negotiationdone != 0 ) + continue; + timeout = LP_AUTOTRADE_TIMEOUT; + if ( (coin= LP_coinfind(tp->Q.srccoin)) != 0 && coin->electrum != 0 ) + timeout += LP_AUTOTRADE_TIMEOUT * .5; + if ( (coin= LP_coinfind(tp->Q.destcoin)) != 0 && coin->electrum != 0 ) + timeout += LP_AUTOTRADE_TIMEOUT * .5; + now = (uint32_t)time(NULL); + if ( now > tp->lastprocessed ) + { + if ( tp->iambob == 0 ) + { + if ( tp->bestprice > 0. ) + { + if ( tp->connectsent == 0 ) + { + LP_Alicemaxprice = tp->bestprice; + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT + tp->connectsent = now; + //printf("send LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); + } + else if ( now < tp->firstprocessed+timeout && ((tp->firstprocessed - now) % 20) == 19 ) + { + //LP_Alicemaxprice = tp->bestprice; + //LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT + //printf("mark slow LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); + if ( (pubp= LP_pubkeyfind(tp->Qs[LP_CONNECT].srchash)) != 0 ) + pubp->slowresponse++; + } + } + } + } + } + now = (uint32_t)time(NULL); + HASH_ITER(hh,LP_trades,tp,tmp) + { + timeout = LP_AUTOTRADE_TIMEOUT; + if ( (coin= LP_coinfind(tp->Q.srccoin)) != 0 && coin->electrum != 0 ) + timeout += LP_AUTOTRADE_TIMEOUT * .5; + if ( (coin= LP_coinfind(tp->Q.destcoin)) != 0 && coin->electrum != 0 ) + timeout += LP_AUTOTRADE_TIMEOUT * .5; + if ( now > tp->firstprocessed+timeout*10 ) + { + //printf("purge swap aliceid.%llu\n",(long long)tp->aliceid); + portable_mutex_lock(&LP_tradesmutex); + HASH_DELETE(hh,LP_trades,tp); + portable_mutex_unlock(&LP_tradesmutex); + free(tp); + } + } DL_FOREACH_SAFE(LP_tradesQ,qtp,tmp) { now = (uint32_t)time(NULL); @@ -1029,106 +1206,83 @@ void LP_tradesloop(void *ctx) HASH_FIND(hh,LP_trades,&qtp->aliceid,sizeof(qtp->aliceid),tp); if ( tp == 0 ) { - tp = qtp; - HASH_ADD(hh,LP_trades,aliceid,sizeof(tp->aliceid),tp); - portable_mutex_unlock(&LP_tradesmutex); - if ( tp->iambob != 0 && funcid == LP_REQUEST ) // bob maybe sends LP_RESERVED - { - if ( (qp= LP_trades_gotrequest(ctx,&Q,&tp->Qs[LP_REQUEST],tp->pairstr)) != 0 ) - tp->Qs[LP_RESERVED] = Q; - } - else if ( tp->iambob == 0 && funcid == LP_RESERVED ) // alice maybe sends LP_CONNECT - { - LP_trades_bestpricecheck(ctx,tp); - } - nonz++; - tp->firstprocessed = tp->lastprocessed = (uint32_t)time(NULL); -//printf("iambob.%d funcid.%d vs %d\n",tp->iambob,funcid,LP_REQUEST); - continue; - } - portable_mutex_unlock(&LP_tradesmutex); - tp->Q = qtp->Q; - if ( qtp->iambob == tp->iambob && qtp->pairstr[0] != 0 ) - safecopy(tp->pairstr,qtp->pairstr,sizeof(tp->pairstr)); -//printf("finished dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); - free(qtp); - if ( tp->negotiationdone != 0 ) - continue; - flag = 0; - if ( qtp->iambob == tp->iambob ) - { - if ( tp->iambob == 0 ) + if ( now > Q.timestamp+LP_AUTOTRADE_TIMEOUT*2 ) // eat expired + free(qtp); + else { - if ( funcid == LP_RESERVED ) + tp = qtp; + HASH_ADD(hh,LP_trades,aliceid,sizeof(tp->aliceid),tp); + portable_mutex_unlock(&LP_tradesmutex); + if ( tp->iambob != 0 && funcid == LP_REQUEST ) // bob maybe sends LP_RESERVED { - if ( tp->connectsent == 0 ) - flag = LP_trades_bestpricecheck(ctx,tp); + if ( (qp= LP_trades_gotrequest(ctx,&Q,&tp->Qs[LP_REQUEST],tp->pairstr)) != 0 ) + tp->Qs[LP_RESERVED] = Q; } - else if ( funcid == LP_CONNECTED && tp->connectsent != 0 && tp->negotiationdone == 0 ) // alice all done + else if ( tp->iambob == 0 && funcid == LP_RESERVED ) // alice maybe sends LP_CONNECT + { + LP_trades_bestpricecheck(ctx,tp); + } + else if ( tp->iambob == 0 && funcid == LP_CONNECTED ) { - flag = 1; tp->negotiationdone = now; + //printf("alice sets negotiationdone.%u\n",now); LP_trades_gotconnected(ctx,&tp->Q,&tp->Qs[LP_CONNECTED],tp->pairstr); } - } - else - { + nonz++; + tp->firstprocessed = tp->lastprocessed = (uint32_t)time(NULL); if ( funcid == LP_CONNECT && tp->negotiationdone == 0 ) // bob all done { - flag = 1; tp->negotiationdone = now; + //printf("bob sets negotiationdone.%u\n",now); LP_trades_gotconnect(ctx,&tp->Q,&tp->Qs[LP_CONNECT],tp->pairstr); } } - if ( flag != 0 ) + continue; + } + portable_mutex_unlock(&LP_tradesmutex); + tp->Q = qtp->Q; + if ( qtp->iambob == tp->iambob && qtp->pairstr[0] != 0 ) + safecopy(tp->pairstr,qtp->pairstr,sizeof(tp->pairstr)); +//printf("finished dequeue %p funcid.%d aliceid.%llu iambob.%d/%d done.%u\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob,tp->iambob,tp->negotiationdone); + free(qtp); + flag = 0; + if ( tp->iambob == 0 ) + { + if ( funcid == LP_RESERVED ) { - tp->lastprocessed = (uint32_t)time(NULL); - nonz++; + if ( tp->connectsent == 0 ) + flag = LP_trades_bestpricecheck(ctx,tp); + } + else if ( funcid == LP_CONNECTED && tp->negotiationdone == 0 ) // alice all done tp->connectsent != 0 && + { + flag = 1; + tp->negotiationdone = now; + LP_trades_gotconnected(ctx,&tp->Q,&tp->Qs[LP_CONNECTED],tp->pairstr); } } - } - HASH_ITER(hh,LP_trades,tp,tmp) - { - if ( tp->negotiationdone != 0 ) - continue; - timeout = LP_AUTOTRADE_TIMEOUT; - if ( (coin= LP_coinfind(tp->Q.srccoin)) != 0 && coin->electrum != 0 ) - timeout += LP_AUTOTRADE_TIMEOUT * .5; - if ( (coin= LP_coinfind(tp->Q.destcoin)) != 0 && coin->electrum != 0 ) - timeout += LP_AUTOTRADE_TIMEOUT * .5; - now = (uint32_t)time(NULL); - if ( now > tp->lastprocessed ) + else { - if ( tp->iambob == 0 ) + if ( funcid == LP_REQUEST ) // bob maybe sends LP_RESERVED { - if ( tp->bestprice > 0. ) + if ( (qp= LP_trades_gotrequest(ctx,&Q,&tp->Qs[LP_REQUEST],tp->pairstr)) != 0 ) { - if ( tp->connectsent == 0 ) - { - LP_Alicemaxprice = tp->bestprice; - LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT - tp->connectsent = now; - //printf("send LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); - } - else if ( now < tp->firstprocessed+timeout && ((tp->firstprocessed - now) % 10) == 9 ) - { - LP_Alicemaxprice = tp->bestprice; - LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT - printf("repeat LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); - if ( (pubp= LP_pubkeyfind(tp->Qs[LP_CONNECT].srchash)) != 0 ) - pubp->slowresponse++; - } + tp->Qs[LP_RESERVED] = Q; + flag = 1; } } - else if ( now > tp->firstprocessed+timeout*10 ) + else if ( funcid == LP_CONNECT && tp->negotiationdone == 0 ) // bob all done { - //printf("purge swap aliceid.%llu\n",(long long)tp->aliceid); - portable_mutex_lock(&LP_tradesmutex); - HASH_DELETE(hh,LP_trades,tp); - portable_mutex_unlock(&LP_tradesmutex); - free(tp); + flag = 1; + tp->negotiationdone = now; + //printf("bob sets negotiationdone.%u\n",now); + LP_trades_gotconnect(ctx,&tp->Q,&tp->Qs[LP_CONNECT],tp->pairstr); } } + if ( flag != 0 ) + { + tp->lastprocessed = (uint32_t)time(NULL); + nonz++; + } } if ( nonz == 0 ) sleep(1); @@ -1161,22 +1315,34 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) int32_t LP_tradecommand(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 num,DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; cJSON *proof; struct iguana_info *coin; struct LP_quoteinfo Q,Q2; int32_t counter,retval=-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; if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"reserved") == 0 ||strcmp(method,"connected") == 0 || strcmp(method,"request") == 0 || strcmp(method,"connect") == 0) ) { - LP_quoteparse(&Q,argjson); + if ( LP_quoteparse(&Q,argjson) < 0 ) + { + printf("ERROR parsing.(%s)\n",jprint(argjson,0)); + return(1); + } + 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); + rq = ((uint64_t)Q.R.requestid << 32) | Q.R.quoteid; + if ( Q.timestamp > 0 && time(NULL) > Q.timestamp + LP_AUTOTRADE_TIMEOUT*20 ) // eat expired packets, some old timestamps floating about? + { + printf("aliceid.%llu is expired by %d\n",(long long)Q.aliceid,(uint32_t)time(NULL) - (Q.timestamp + LP_AUTOTRADE_TIMEOUT*20)); + return(1); + } LP_tradecommand_log(argjson); - printf("%-4d (%-10u %10u) %12s id.%-20llu %5s/%-5s %12.8f -> %12.8f (%11.8f) | RT.%d %d n%d\n",(uint32_t)time(NULL) % 3600,Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,LP_RTcount,LP_swapscount,G.netid); - //LP_autoprices_update(method,Q.srccoin,dstr(Q.satoshis),Q.destcoin,dstr(Q.destsatoshis)); + qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); //jdouble(argjson,"price"); + //printf("%s\n",jprint(argjson,0)); + printf("%-4d (%-10u %10u) %12s id.%-20llu %5s/%-5s %12.8f -> %12.8f (%11.8f) | RT.%d %d n%d\n",(uint32_t)time(NULL) % 3600,Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),qprice,LP_RTcount,LP_swapscount,G.netid); retval = 1; aliceid = j64bits(argjson,"aliceid"); - qprice = jdouble(argjson,"price"); if ( strcmp(method,"reserved") == 0 ) { bestprice = LP_bob_competition(&counter,aliceid,qprice,1); //printf("%s lag %ld: aliceid.%llu price %.8f -> bestprice %.8f Alice max %.8f\n",jprint(argjson,0),Q.quotetime - (time(NULL)-20),(long long)aliceid,qprice,bestprice,LP_Alicemaxprice); - if ( 0 ) + if ( 1 ) { if ( LP_Alicemaxprice == 0. ) return(retval); @@ -1189,7 +1355,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, } else printf("got reserved response from destpubkey %s\n",bits256_str(str,Q.srchash)); } } - if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) + if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) // alice { if ( Qtrades == 0 ) { @@ -1205,9 +1371,19 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, else if ( strcmp(method,"connected") == 0 ) { bestprice = LP_bob_competition(&counter,aliceid,qprice,1000); - if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) + if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) // alice { - //printf("CONNECTED.(%s)\n",jprint(argjson,0)); + static uint64_t rqs[1024]; + for (i=0; i 0 ) Q.othercredits = LP_instantdex_proofcheck(Q.srccoin,Q.coinaddr,proof,num); if ( Qtrades == 0 ) @@ -1231,21 +1407,31 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, printf("{\"error\":\"GAME can only be alice coin\"}\n"); return(retval); } - if ( strcmp(method,"request") == 0 ) + if ( strcmp(method,"request") == 0 ) // bob { + //if ( LP_Alicemaxprice != 0. ) + // return(retval); bestprice = LP_bob_competition(&counter,aliceid,qprice,-1); - //if ( strcmp(Q.srccoin,"GRS") == 0 || strcmp(Q.destcoin,"GRS") == 0 ) - // printf("%s lag %ld: aliceid.%llu price %.8f -> bestprice %.8f\n",jprint(argjson,0),Q.quotetime - (time(NULL)-20),(long long)aliceid,qprice,bestprice); - if ( Qtrades == 0 ) + 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); } else if ( strcmp(method,"connect") == 0 ) { LP_bob_competition(&counter,aliceid,qprice,1000); - if ( bits256_cmp(G.LP_mypub25519,Q.srchash) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0 ) + if ( bits256_cmp(G.LP_mypub25519,Q.srchash) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0 ) // bob { - printf("CONNECT.(%s)\n",jprint(argjson,0)); + static uint64_t rqs[1024]; + for (i=0; i 0 ) Q.othercredits = LP_instantdex_proofcheck(Q.destcoin,Q.destaddr,proof,num); if ( Qtrades == 0 ) @@ -1258,9 +1444,9 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson, return(retval); } -char *LP_autobuy(void *ctx,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 *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) { - uint64_t desttxfee,txfee; 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[1000]; int32_t max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); + 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)); basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( gui == 0 ) @@ -1297,19 +1483,61 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel jaddnum(retjson,"wait",Alice_expiration-time(NULL)); return(jprint(retjson,1)); } else LP_alicequery_clear(); + if ( relcoin->etomic[0] != 0 ) + LP_address_utxo_reset(&num,LP_coinfind("ETOMIC")); + else + { + LP_address_utxo_reset(&num,relcoin); + if ( num <= 1 ) + { + if ( time(NULL) > relcoin->lastautosplit+300 ) + { + relcoin->lastautosplit = (uint32_t)time(NULL); + return(LP_autosplit(relcoin)); + } + return(clonestr("{\"error\":\"not enough utxo, please make more deposits\"}")); + } + } + LP_txfees(&txfee,&desttxfee,base,rel); + if ( txfee != 0 && txfee < 10000 ) + txfee = 10000; + if ( desttxfee != 0 && desttxfee < 10000 ) + desttxfee = 10000; + if ( fomoflag != 0 ) + { + uint64_t median,minutxo,maxutxo; + maxprice = 0.; // fomo -> price is 1. and needs to be set + LP_address_minmax(0,&median,&minutxo,&maxutxo,relcoin,relcoin->smartaddr); // limit to largest utxo + if ( maxutxo > 0 ) + { + relvolume = MIN(relvolume,dstr(maxutxo) - dstr(desttxfee)*3); + printf("maxutxo %.8f relvolume %.8f desttxfee %.8f\n",dstr(maxutxo),relvolume,dstr(desttxfee)); + maxprice = LP_fomoprice(base,rel,&relvolume); + printf("fomoprice %.8f relvolume %.8f\n",maxprice,relvolume); + } else printf("no utxo available\n"); + } if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 ) return(clonestr("{\"error\":\"invalid parameter\"}")); if ( strcmp("BTC",rel) == 0 ) maxprice *= 1.01; else maxprice *= 1.001; memset(pubkeys,0,sizeof(pubkeys)); - LP_txfees(&txfee,&desttxfee,base,rel); destsatoshis = SATOSHIDEN * relvolume + 2*desttxfee; - memset(&A,0,sizeof(A)); - LP_address_utxo_reset(relcoin); - if ( (autxo= LP_address_myutxopair(&A,0,utxos,max,relcoin,relcoin->smartaddr,txfee,dstr(destsatoshis),maxprice,desttxfee)) == 0 ) + autxo = 0; + for (i=0; ismartaddr,txfee,dstr(destsatoshis),maxprice,desttxfee)) != 0 ) + break; + destsatoshis *= 0.98; + if ( destsatoshis < desttxfee*LP_MINSIZE_TXFEEMULT ) + break; + } + if ( destsatoshis < desttxfee*LP_MINSIZE_TXFEEMULT || i == maxiters ) + { return(clonestr("{\"error\":\"cant find a deposit that is close enough in size. make another deposit that is just a bit larger than what you want to trade\"}")); - //printf("bestfit selected alice (%.8f %.8f) for %.8f sats %.8f\n",dstr(autxo->payment.value),dstr(autxo->fee.value),dstr(destsatoshis),dstr(autxo->swap_satoshis)); + } + printf("bestfit.[%d] selected alice (%.8f %.8f) for %.8f sats %.8f\n",i,dstr(autxo->payment.value),dstr(autxo->fee.value),dstr(destsatoshis),dstr(autxo->swap_satoshis)); if ( destsatoshis - desttxfee < autxo->swap_satoshis ) { destsatoshis -= desttxfee; @@ -1325,7 +1553,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel if ( 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 just a bit larger than what you want to trade\"}")); + 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\"}")); } bestsatoshis = 1.001 * LP_basesatoshis(dstr(destsatoshis),maxprice,txfee,desttxfee); memset(&B,0,sizeof(B)); @@ -1334,9 +1562,26 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel return(clonestr("{\"error\":\"cant set ordermatch quote\"}")); if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,G.LP_mypub25519,autxo->coinaddr) < 0 ) return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); + if ( relcoin->etomic[0] != 0 || basecoin->etomic[0] != 0 ) + { + struct iguana_info *coin; + if ( relcoin->etomic[0] != 0 ) + strcpy(Q.etomicdest,relcoin->smartaddr); + else if (basecoin->etomic[0] != 0 ) + { + strcpy(Q.etomicdest,basecoin->smartaddr); + printf("Q.etomicdest (%s)\n",Q.etomicdest); + } + if ( relcoin->etomic[0] != 0 ) + { + if ((coin= LP_coinfind("ETOMIC")) != 0 ) + strcpy(Q.destaddr,coin->smartaddr); + else return(clonestr("{\"error\":\"cant find ETOMIC\"}")); + } + } int32_t changed; - LP_mypriceset(&changed,autxo->coin,base,1. / maxprice); - LP_mypriceset(&changed,base,autxo->coin,0.); + LP_mypriceset(&changed,rel,base,1. / maxprice); + LP_mypriceset(&changed,base,rel,0.); return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); } diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index dc324666f..6a5b7c311 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -56,9 +56,64 @@ char *LP_peers() return(jprint(peersjson,1)); } +void LP_cmdchannel(struct LP_peerinfo *peer) +{ + char *hellostr = "{\"method\":\"hello\"}"; + char connectaddr[128],publicaddr[128],*retstr; int32_t pairsock=-1,pubsock,sentbytes=-2; uint16_t cmdport; +#ifdef LP_DONT_CMDCHANNEL + return; +#endif + if ( bits256_nonz(G.LP_mypub25519) == 0 ) //|| strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") == 0 ) + return; + if ( (cmdport= LP_psock_get(connectaddr,publicaddr,1,1,peer->ipaddr)) != 0 ) + { + if ( (retstr= _LP_psock_create(&pairsock,&pubsock,peer->ipaddr,cmdport,cmdport,1,1,G.LP_mypub25519)) != 0 ) + { + if ( nn_connect(pairsock,connectaddr) < 0 ) + printf("error connecting cmdchannel with %s\n",connectaddr); + else + { + peer->pairsock = pairsock; + sentbytes = nn_send(peer->pairsock,hellostr,(int32_t)strlen(hellostr)+1,0); + printf("cmdchannel %d created %s sent.%d\n",peer->pairsock,retstr,sentbytes); + } + free(retstr); + } + } else printf("error getting cmdchannel with %s\n",peer->ipaddr); +} + +void LP_cmdchannels() +{ + struct LP_peerinfo *peer,*tmp; + if ( IAMLP == 0 ) + { + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( peer->pairsock < 0 ) + LP_cmdchannel(peer); + } + } +} + +void LP_peer_pairsock(bits256 pubkey) +{ + struct LP_peerinfo *peer,*tmp; + if ( IAMLP == 0 ) + { + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( bits256_cmp(pubkey,peer->pubkey) == 0 ) + { + peer->pairsock = -1; + break; + } + } + } +} + struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,int32_t isLP,uint32_t sessionid,uint16_t netid) { - uint32_t ipbits; int32_t valid,pushsock,subsock,timeout; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0; + uint32_t ipbits; int32_t valid,pushsock,subsock,timeout; char checkip[64],pushaddr[128],subaddr[128]; struct LP_peerinfo *peer = 0; #ifdef LP_STRICTPEERS if ( strncmp("5.9.253",ipaddr,strlen("5.9.253")) != 0 ) return(0); @@ -79,6 +134,8 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char if ( (peer->isLP= isLP) != 0 ) LP_numactive_LP++; } + if ( IAMLP == 0 && peer->pairsock < 0 ) + LP_cmdchannel(peer); /*if ( numpeers > peer->numpeers ) peer->numpeers = numpeers; if ( numutxos > peer->numutxos ) @@ -86,10 +143,11 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char if ( peer->sessionid == 0 ) peer->sessionid = sessionid;*/ } - else if ( IAMLP != 0 || LP_numactive_LP < 3 ) + else if ( IAMLP != 0 || LP_numactive_LP < 10 ) { //printf("addpeer (%s:%u) pushport.%u subport.%u\n",ipaddr,port,pushport,subport); peer = calloc(1,sizeof(*peer)); + peer->pairsock = -1; if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) peer->sessionid = G.LP_sessionid; else peer->sessionid = sessionid; @@ -105,33 +163,27 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char if ( pushport != 0 && subport != 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 ) { nanomsg_transportname(0,pushaddr,peer->ipaddr,pushport); - //nanomsg_transportname2(0,pushaddr2,peer->ipaddr,pushport); valid = 0; if ( nn_connect(pushsock,pushaddr) >= 0 ) valid++; - //if ( nn_connect(pushsock,pushaddr2) >= 0 ) - // valid++; if ( valid > 0 ) { - timeout = 1; + //timeout = 10; + //nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_MAXTTL,&timeout,sizeof(timeout)); + timeout = 100; nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); - //maxsize = 2 * 1024 * 1024; - //nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDBUF,&maxsize,sizeof(maxsize)); printf("connected to push.(%s) pushsock.%d valid.%d | ",pushaddr,pushsock,valid); peer->connected = (uint32_t)time(NULL); peer->pushsock = pushsock; if ( (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 ) { - timeout = 1; + timeout = 100; nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); nanomsg_transportname(0,subaddr,peer->ipaddr,subport); - //nanomsg_transportname2(0,subaddr2,peer->ipaddr,subport); valid = 0; if ( nn_connect(subsock,subaddr) >= 0 ) valid++; - //if ( nn_connect(subsock,subaddr2) >= 0 ) - // valid++; if ( valid > 0 ) { peer->subsock = subsock; @@ -163,24 +215,8 @@ struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char printf("_LPaddpeer %s -> numpeers.%d mypubsock.%d other.(%d)\n",ipaddr,mypeer->numpeers,mypubsock,isLP); } else peer->numpeers = 1; // will become mypeer portable_mutex_unlock(&LP_peermutex); - /*if ( IAMLP != 0 && mypubsock >= 0 ) - { - //struct iguana_info *coin,*ctmp; char busaddr[64]; // - //memset(zero.bytes,0,sizeof(zero)); - //LP_send(mypubsock,msg,(int32_t)strlen(msg)+1,1); - //LP_reserved_msg(0,"","",zero,jprint(LP_peerjson(peer),1)); - if ( 0 ) - { - HASH_ITER(hh,LP_coins,coin,ctmp) - { - if ( coin->bussock >= 0 ) - { - nanomsg_transportname(0,busaddr,peer->ipaddr,coin->busport); - nn_connect(coin->bussock,busaddr); - } - } - } - }*/ + if ( IAMLP == 0 && peer->pairsock < 0 ) + LP_cmdchannel(peer); } else printf("%s invalid pushsock.%d or subsock.%d\n",peer->ipaddr,peer->pushsock,peer->subsock); } } else printf("LP_addpeer: checkip.(%s) vs (%s)\n",checkip,ipaddr); @@ -233,13 +269,18 @@ void LP_closepeers() return(bussock); }*/ -void LP_peer_recv(char *ipaddr,int32_t ismine) +void LP_peer_recv(char *ipaddr,int32_t ismine,struct LP_pubkey_info *pubp) { struct LP_peerinfo *peer; if ( (peer= LP_peerfind((uint32_t)calc_ipbits(ipaddr),RPC_port)) != 0 ) { peer->numrecv++; - //if ( ismine != 0 ) + if ( ismine != 0 && bits256_cmp(G.LP_mypub25519,pubp->pubkey) != 0 && (bits256_cmp(peer->pubkey,pubp->pubkey) != 0 || pubp->pairsock != peer->pairsock) ) + { + peer->pubkey = pubp->pubkey; + pubp->pairsock = peer->pairsock; + char str[65]; printf("set pubkey for %s <- %s, pairsock.%d\n",ipaddr,bits256_str(str,pubp->pubkey),pubp->pairsock); + } peer->recvtime = (uint32_t)time(NULL); } } diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c index ead40b27c..7cc4380ff 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -22,7 +22,7 @@ struct LP_portfoliotrade { double metric; char buycoin[65],sellcoin[65]; }; struct LP_autoprice_ref { - char refbase[65],refrel[65],base[65],rel[65],fundbid[16],fundask[16]; + char refbase[65],refrel[65],base[65],rel[65],fundbid[16],fundask[16],usdpeg; double buymargin,sellmargin,factor,offset,lastbid,lastask; cJSON *fundvalue; uint32_t count; @@ -95,6 +95,14 @@ 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); + } else +#endif +*/ if ( (array= LP_listunspent(symbol,coinaddr,zero,zero)) != 0 ) { if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) @@ -447,26 +455,48 @@ double LP_tickered_price(int32_t bidask,char *base,char *rel,double price,cJSON return(price); } +int32_t LP_autoref_clear(char *base,char *rel) +{ + int32_t i; + for (i=0; i SMALLVAL ) { - if ( strcmp(rel,"KMD") == 0 && kmd_btc > SMALLVAL ) - price = kmd_btc / price_btc; - else if ( strcmp(rel,"BCH") == 0 && bch_btc > SMALLVAL ) - price = bch_btc / price_btc; - else if ( strcmp(rel,"BTC") == 0 ) - price = 1. / price_btc; - else continue; + if ( LP_autorefs[i].usdpeg != 0 ) + { + if ( price_usd > SMALLVAL ) + price = 1. / price_usd; + else continue; + } + else + { + if ( strcmp(rel,"KMD") == 0 && kmd_btc > SMALLVAL ) + price = kmd_btc / price_btc; + else if ( strcmp(rel,"BCH") == 0 && bch_btc > SMALLVAL ) + price = bch_btc / price_btc; + else if ( strcmp(rel,"BTC") == 0 ) + price = 1. / price_btc; + else continue; + } if ( factor > 0. ) + { + //printf("USD %.8f KMDBTC %.8f pricebtc %.8f price %.8f -> factor %.8f %.8f\n",price_usd,kmd_btc,price_btc,price,factor,(price * factor) + offset); price = (price * factor) + offset; + } newprice = (price * (1. + buymargin)); if ( LP_autorefs[i].lastbid < SMALLVAL ) LP_autorefs[i].lastbid = newprice; @@ -581,7 +633,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) newprice = LP_autorefs[i].lastask; LP_mypriceset(&changed,base,rel,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); - } + } //else printf("null return from CMC\n"); } else { @@ -661,7 +713,7 @@ int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) refrel = jstr(argjson,"refrel"); fundvalue_bid = jstr(argjson,"fundvalue_bid"); fundvalue_ask = jstr(argjson,"fundvalue_ask"); - if ( fundvalue_bid != 0 || fundvalue_ask != 0 || fixedprice > SMALLVAL || (refbase != 0 && refrel != 0) ) + if ( fundvalue_bid != 0 || fundvalue_ask != 0 || fixedprice > SMALLVAL || (refbase != 0 && refrel != 0 && strlen(refbase) > 0 && strlen(refrel) > 0) ) { if ( fixedprice > SMALLVAL ) { @@ -702,8 +754,9 @@ int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) safecopy(LP_autorefs[num_LP_autorefs].fundbid,fundvalue_bid,sizeof(LP_autorefs[num_LP_autorefs].fundbid)); safecopy(LP_autorefs[num_LP_autorefs].fundask,fundvalue_ask,sizeof(LP_autorefs[num_LP_autorefs].fundask)); } - LP_autorefs[i].buymargin = buymargin; - LP_autorefs[i].sellmargin = sellmargin; + LP_autorefs[num_LP_autorefs].usdpeg = juint(argjson,"usdpeg"); + LP_autorefs[num_LP_autorefs].buymargin = buymargin; + LP_autorefs[num_LP_autorefs].sellmargin = sellmargin; LP_autorefs[num_LP_autorefs].factor = factor; LP_autorefs[num_LP_autorefs].offset = offset; safecopy(LP_autorefs[num_LP_autorefs].refbase,refbase,sizeof(LP_autorefs[num_LP_autorefs].refbase)); @@ -746,7 +799,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,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1,zero,1)) != 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 ) { if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) { @@ -840,10 +893,16 @@ void prices_loop(void *ctx) { char *retstr; cJSON *retjson,*array; char *buycoin,*sellcoin; struct iguana_info *buy,*sell; uint32_t requestid,quoteid; int32_t i,n,m; struct LP_portfoliotrade trades[256]; struct LP_priceinfo *btcpp; strcpy(prices_loop_stats.name,"prices_loop"); - prices_loop_stats.threshold = 191000.; + prices_loop_stats.threshold = 600000.; + printf("start prices_loop\n"); while ( LP_STOP_RECEIVED == 0 ) { - //printf("prices loop autoprices.%d autorefs.%d\n",LP_autoprices,num_LP_autorefs); + //printf("G.initializing.%d prices loop autoprices.%d autorefs.%d\n",G.initializing,LP_autoprices,num_LP_autorefs); + if ( G.initializing != 0 ) + { + sleep(30); + continue; + } LP_millistats_update(&prices_loop_stats); LP_tradebots_timeslice(ctx); if ( (btcpp= LP_priceinfofind("BTC")) == 0 ) diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c index cee20a5d2..f160561b4 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -304,6 +304,7 @@ struct LP_pubkey_info *LP_pubkeyadd(bits256 pubkey) { pubp = calloc(1,sizeof(*pubp)); pubp->pubkey = pubkey; + pubp->pairsock = -1; if ( bits256_cmp(G.LP_mypub25519,pubkey) == 0 ) { memcpy(pubp->rmd160,G.LP_myrmd160,sizeof(pubp->rmd160)); @@ -511,7 +512,7 @@ char *LP_myprices() int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) { - struct LP_priceinfo *basepp,*relpp; struct LP_pubkey_info *pubp; double minprice,maxprice; + struct LP_priceinfo *basepp=0,*relpp=0; struct LP_pubkey_info *pubp; double minprice,maxprice,margin,buymargin,sellmargin; *changedp = 0; //if ( strcmp("DEX",base) == 0 || strcmp("DEX",rel) == 0 ) // printf("%s/%s setprice %.8f\n",base,rel,price); @@ -520,6 +521,9 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) if ( price == 0. || fabs(basepp->myprices[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. ) { relpp->minprices[basepp->ind] = 0.; @@ -528,18 +532,20 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) 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; + //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) ) { - printf("%s/%s price %.8f less than maxprice %.8f, more than %.8f\n",base,rel,price,maxprice,1./maxprice); - 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 ) @@ -548,7 +554,7 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) }*/ basepp->myprices[relpp->ind] = price; // ask //printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); - //relpp->myprices[basepp->ind] = (1. / price); // bid + //relpp->myprices[basepp->ind] = (1. / price); // bid, but best to do one dir at a time if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 ) { pubp->timestamp = (uint32_t)time(NULL); @@ -558,7 +564,9 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) //pubp->matrix[relpp->ind][basepp->ind] = (1. / price); } return(0); - } else return(-1); + } + printf("base.%s rel.%s %p %p price %.8f error case\n",base!=0?base:"",rel!=0?rel:"",basepp,relpp,price); + return(-1); } double LP_price(char *base,char *rel) @@ -637,9 +645,14 @@ struct LP_priceinfo *LP_priceinfoadd(char *symbol) struct LP_priceinfo *pp; cJSON *retjson; if ( symbol == 0 ) return(0); + if ( (pp= LP_priceinfofind(symbol)) != 0 ) + { + printf("%s already there\n",symbol); + return(pp); + } if ( LP_numpriceinfos >= sizeof(LP_priceinfos)/sizeof(*LP_priceinfos) ) { - printf("cant add any more priceinfos\n"); + printf("cant add any more priceinfos than %d\n",LP_numpriceinfos); return(0); } pp = &LP_priceinfos[LP_numpriceinfos]; @@ -647,7 +660,7 @@ struct LP_priceinfo *LP_priceinfoadd(char *symbol) safecopy(pp->symbol,symbol,sizeof(pp->symbol)); pp->coinbits = stringbits(symbol); pp->ind = LP_numpriceinfos++; - LP_numpriceinfos++; + //LP_numpriceinfos++; if ( (retjson= LP_priceinfomatrix(0)) != 0 ) free_json(retjson); return(pp); @@ -743,9 +756,9 @@ cJSON *LP_orderbookjson(char *symbol,struct LP_orderbookentry *op) jaddstr(item,"address",op->coinaddr); jaddnum(item,"price",op->price); jaddnum(item,"numutxos",op->numutxos); - jaddnum(item,"avevolume",dstr(op->avesatoshis)*0.8); - jaddnum(item,"maxvolume",dstr(op->maxsatoshis)*0.8); - jaddnum(item,"depth",dstr(op->depth)*0.8); + jaddnum(item,"avevolume",dstr(op->avesatoshis)); + jaddnum(item,"maxvolume",dstr(op->maxsatoshis)); + jaddnum(item,"depth",dstr(op->depth)); jaddbits256(item,"pubkey",op->pubkey); jaddnum(item,"age",time(NULL)-op->timestamp); jaddnum(item,"zcredits",dstr(op->dynamictrust)); @@ -810,7 +823,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char * } if ( pubp->timestamp < oldest ) continue; - bitcoin_address(base,coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); + bitcoin_address(base,coinaddr,basecoin->taddr,basecoin->pubtype,pubp->pubsecp,33); avesatoshis = maxsatoshis = n = 0; ap = 0; if ( (price= LP_pubkey_price(&n,&avesatoshis,&maxsatoshis,pubp,baseid,relid)) > SMALLVAL ) //pubp->matrix[baseid][relid]) > SMALLVAL )//&& pubp->timestamps[baseid][relid] >= oldest ) @@ -853,7 +866,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) suppress_prefetch = 1; duration = LP_ORDERBOOK_DURATION; } - LP_pubkeys_query(); + //LP_pubkeys_query(); baseid = basepp->ind; relid = relpp->ind; now = (uint32_t)time(NULL); @@ -957,6 +970,43 @@ char *LP_orderbook(char *base,char *rel,int32_t duration) return(jprint(retjson,1)); } +double LP_fomoprice(char *base,char *rel,double *relvolumep) +{ + char *retstr; cJSON *retjson,*asks,*item; int32_t i,numasks; double maxvol=0.,relvolume,biggest,price,fomoprice = 0.; + relvolume = *relvolumep; + if ( (retstr= LP_orderbook(base,rel,0)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (asks= jarray(&numasks,retjson,"asks")) != 0 && numasks > 0 ) + { + for (i=0; i maxvol ) + { + maxvol = biggest; + fomoprice = price; + } + printf("fomoprice (%.8f) i.%d %.8f vol %.8f [max %.8f @ %.8f]\n",relvolume,i,price,biggest,maxvol,fomoprice); + } + } + free_json(retjson); + } + free(retstr); + } + if ( maxvol > 0. && fomoprice > 0. ) + { + if ( maxvol < relvolume ) + relvolume = maxvol * 0.98; + fomoprice /= 0.95; + } else fomoprice = 0.; + *relvolumep = relvolume; + return(fomoprice); +} + int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance) { double price = 0.; int64_t KMDvalue=0; @@ -1181,7 +1231,7 @@ double LP_CMCbtcprice(double *price_usdp,char *symbol) item = jitem(ticker,0); price_btc = jdouble(item,"price_btc"); *price_usdp = jdouble(item,"price_usd"); - //printf("%.8f item.(%s)\n",price_btc,jprint(item,0)); +//printf("%.8f item.(%s)\n",price_btc,jprint(item,0)); free_json(ticker); } free(retstr); diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c index 191c5fde1..6552cfbf0 100644 --- a/iguana/exchanges/LP_privkey.c +++ b/iguana/exchanges/LP_privkey.c @@ -251,10 +251,47 @@ int32_t LP_wifstr_valid(char *symbol,char *wifstr) return(0); } +char *LP_convaddress(char *symbol,char *address,char *dest) +{ + struct iguana_info *coin,*destcoin; cJSON *retjson; char destaddress[64],coinaddr2[64]; uint8_t addrtype,rmd160[20],rmd160b[20]; + if ( (coin= LP_coinfind(symbol)) == 0 || (destcoin= LP_coinfind(dest)) == 0 ) + return(clonestr("{\"error\":\"both coins must be present\"}")); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"coin",symbol); + jaddstr(retjson,"address",address); + jaddstr(retjson,"destcoin",dest); + bitcoin_addr2rmd160(symbol,coin->taddr,&addrtype,rmd160,address); + if ( addrtype == coin->pubtype ) + { + bitcoin_address(destcoin->symbol,destaddress,destcoin->taddr,destcoin->pubtype,rmd160,20); + bitcoin_addr2rmd160(destcoin->symbol,destcoin->taddr,&addrtype,rmd160b,destaddress); + bitcoin_address(coin->symbol,coinaddr2,coin->taddr,coin->pubtype,rmd160b,20); + } + else if ( addrtype == coin->p2shtype ) + { + bitcoin_address(destcoin->symbol,destaddress,destcoin->taddr,destcoin->p2shtype,rmd160,20); + bitcoin_addr2rmd160(symbol,coin->taddr,&addrtype,rmd160b,destaddress); + bitcoin_address(destcoin->symbol,coinaddr2,coin->taddr,coin->p2shtype,rmd160b,20); + } + else + { + jaddstr(retjson,"error","invalid base58 prefix"); + jaddnum(retjson,"invalid",addrtype); + } + if ( strcmp(address,coinaddr2) != 0 ) + { + jaddstr(retjson,"error","checkaddress mismatch"); + jaddstr(retjson,"checkaddress",coinaddr2); + } + jaddstr(retjson,"destaddress",destaddress); + return(jprint(retjson,1)); +} + bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguana_info *coin,char *passphrase,char *wifstr) { //static uint32_t counter; - bits256 privkey,userpub,zero,userpass,checkkey,tmpkey; char tmpstr[128]; cJSON *retjson; uint8_t tmptype; int32_t notarized; uint64_t nxtaddr; + 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; if ( (wifstr == 0 || wifstr[0] == 0) && LP_wifstr_valid(coin->symbol,passphrase) > 0 ) { wifstr = passphrase; @@ -262,12 +299,17 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan } if ( passphrase != 0 && passphrase[0] != 0 ) { - calc_NXTaddr(G.LP_NXTaddr,userpub.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); - conv_NXTpassword(privkey.bytes,pubkeyp->bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); - privkey.bytes[0] &= 248, privkey.bytes[31] &= 127, privkey.bytes[31] |= 64; - //vcalc_sha256(0,checkkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); - //printf("SHA256.(%s) ",bits256_str(pstr,checkkey)); - //printf("privkey.(%s)\n",bits256_str(pstr,privkey)); + if ( strlen(passphrase) == 66 && passphrase[0] == '0' && passphrase[1] == 'x' && is_hexstr(passphrase+2,0) == 64 ) + { + decode_hex(privkey.bytes,32,passphrase+2); + //printf("ETH style privkey.(%s)\n",passphrase); + } + else + { + calc_NXTaddr(G.LP_NXTaddr,userpub.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + conv_NXTpassword(privkey.bytes,pubkeyp->bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + privkey.bytes[0] &= 248, privkey.bytes[31] &= 127, privkey.bytes[31] |= 64; + } bitcoin_priv2wif(coin->symbol,coin->wiftaddr,tmpstr,privkey,coin->wiftype); bitcoin_wif2priv(coin->symbol,coin->wiftaddr,&tmptype,&checkkey,tmpstr); if ( bits256_cmp(privkey,checkkey) != 0 ) @@ -294,6 +336,39 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan RS_encode(G.LP_NXTaddr,nxtaddr); } bitcoin_priv2pub(ctx,coin->symbol,coin->pubkey33,coin->smartaddr,privkey,coin->taddr,coin->pubtype); +#ifndef NOTETOMIC + if ( coin->etomic[0] != 0 ) + { + uint8_t check64[64],checktype,checkrmd160[20],rmd160[20]; char checkaddr[64],checkaddr2[64]; + if ( LP_etomic_priv2pub(check64,privkey) == 0 ) + { + if ( memcmp(check64,coin->pubkey33+1,32) == 0 ) + { + if ( LP_etomic_priv2addr(checkaddr,privkey) == 0 && LP_etomic_pub2addr(checkaddr2,check64) == 0 && strcmp(checkaddr,checkaddr2) == 0 ) + { + //printf("addr is (%s)\n",checkaddr); + strcpy(coin->smartaddr,checkaddr); + decode_hex(checkrmd160,20,checkaddr+2); + bitcoin_addr2rmd160(coin->symbol,coin->taddr,&checktype,rmd160,checkaddr); + if ( memcmp(rmd160,checkrmd160,20) != 0 ) + printf("rmd160 doesnt match\n"); + } else printf("error getting addr (%s) != (%s)\n",checkaddr,checkaddr2); + } else printf("pubkey 64 mismatch\n"); + } else printf("error creating pubkey\n"); + } +#endif + OS_randombytes(tmpkey.bytes,sizeof(tmpkey)); + siglen = 0; + if ( bits256_nonz(privkey) == 0 || (siglen= bitcoin_sign(ctx,coin->symbol,sig,tmpkey,privkey,0)) <= 0 ) + { + printf("illegal privkey %s\n",bits256_str(str,privkey)); + exit(0); + } + if ( bits256_nonz(privkey) != 0 && bitcoin_verify(ctx,sig,siglen,tmpkey,coin->pubkey33,33) != 0 ) + { + printf("signature.[%d] for %s by %s didnt verify\n",siglen,bits256_str(str,tmpkey),bits256_str(str2,privkey)); + exit(0); + } if ( coin->counter == 0 ) { coin->counter++; @@ -317,7 +392,7 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan printf("userpass.(%s)\n",bits256_str(G.USERPASS,userpub)); } } - if ( coin->importedprivkey == 0 && coin->electrum == 0 && coin->userpass[0] != 0 && LP_getheight(¬arized,coin) > 0 ) + if ( strcmp(coin->smartaddr,"RPZVpjptzfZnFZZoLnuSbfLexjtkhe6uvn") != 0 && coin->importedprivkey == 0 && coin->electrum == 0 && coin->userpass[0] != 0 && LP_getheight(¬arized,coin) > 0 ) { memset(zero.bytes,0,sizeof(zero)); LP_listunspent_issue(coin->symbol,coin->smartaddr,0,zero,zero); @@ -417,6 +492,7 @@ int32_t LP_passphrase_init(char *passphrase,char *gui,uint16_t netid,char *seedn LP_priceinfos_clear(); G.USERPASS_COUNTER = counter; G.initializing = 0; + //LP_cmdchannels(); return(0); } @@ -460,7 +536,7 @@ int32_t JPG_encrypt(uint16_t ind,uint8_t encoded[JPG_ENCRYPTED_MAXSIZE],uint8_t int32_t i; for (i=0; i 0 && cipherlen <= JPG_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES ) { + //int32_t i; for (i=0; i 0 ) + { + //printf("datalen.%d -> len.%d max.%d\n",datalen,len,maxsize); + if ( len <= maxsize ) + { + memcpy(dest,encoded,len); + return(len); + } + } + return(-1); +} + // from https://github.com/owencm/C-Steganography-Framework #include "../../crypto777/jpeg/cdjpeg.h" // Common decls for compressing and decompressing jpegs diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c index 995964069..ca08c52ec 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -17,7 +17,6 @@ // LP_remember.c // marketmaker // - void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,int32_t scriptlen) { int32_t i; char scriptstr[513]; @@ -66,7 +65,25 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx fprintf(fp,",\"expiration\":%u",swap->I.expiration); fprintf(fp,",\"iambob\":%d",swap->I.iambob); fprintf(fp,",\"bobcoin\":\"%s\"",swap->I.bobstr); + if ( swap->I.bobtomic[0] != 0 ) + fprintf(fp,",\"bobtomic\":\"%s\"",swap->I.bobtomic); + if ( swap->I.etomicsrc[0] != 0 ) + fprintf(fp,",\"etomicsrc\":\"%s\"",swap->I.etomicsrc); + if (swap->bobdeposit.I.ethTxid[0] != 0) { + fprintf(fp,",\"bobDepositEthTx\":\"%s\"", swap->bobdeposit.I.ethTxid); + } + if (swap->bobpayment.I.ethTxid[0] != 0) { + fprintf(fp,",\"bobPaymentEthTx\":\"%s\"", swap->bobpayment.I.ethTxid); + } + if (swap->alicepayment.I.ethTxid[0] != 0) { + fprintf(fp,",\"alicePaymentEthTx\":\"%s\"", swap->alicepayment.I.ethTxid); + } + fprintf(fp,",\"alicecoin\":\"%s\"",swap->I.alicestr); + if ( swap->I.alicetomic[0] != 0 ) + fprintf(fp,",\"alicetomic\":\"%s\"",swap->I.alicetomic); + if ( swap->I.etomicdest[0] != 0 ) + fprintf(fp,",\"etomicdest\":\"%s\"",swap->I.etomicdest); fprintf(fp,",\"lock\":%u",locktime); fprintf(fp,",\"amount\":%.8f",dstr(rawtx->I.amount)); if ( bits256_nonz(triggertxid) != 0 ) @@ -120,6 +137,7 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx init_hexbytes_noT(secretBn256str,swap->I.secretBn256,32); fprintf(fp,",\"secretBn256\":\"%s\"",secretBn256str); } + for (i=0; i<2; i++) if ( bits256_nonz(swap->I.myprivs[i]) != 0 ) fprintf(fp,",\"myprivs%d\":\"%s\"",i,bits256_str(str,swap->I.myprivs[i])); @@ -220,6 +238,33 @@ void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx } else if ( rawtx == &swap->bobreclaim ) basilisk_dontforget(swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid); + if ( IPC_ENDPOINT >= 0 ) + { + char fname[512],*fstr,*outstr; long fsize; cJSON *reqjson; + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname); + if ( rawtx != 0 ) + sprintf(fname+strlen(fname),".%s",rawtx->name); + if ( (fstr= OS_filestr(&fsize,fname)) != 0 ) + { + if ( (reqjson= cJSON_Parse(fstr)) != 0 ) + { + if ( jobj(reqjson,"method") != 0 ) + jdelete(reqjson,"method"); + jaddstr(reqjson,"method","update"); + if ( jobj(reqjson,"update") != 0 ) + jdelete(reqjson,"update"); + if ( rawtx != 0 ) + jaddstr(reqjson,"update",rawtx->name); + else jaddstr(reqjson,"update","main"); + jaddnum(reqjson,"requestid",swap->I.req.requestid); + jaddnum(reqjson,"quoteid",swap->I.req.quoteid); + outstr = jprint(reqjson,1); + LP_queuecommand(0,outstr,IPC_ENDPOINT,-1,0); + free(outstr); + } + free(fstr); + } + } } bits256 basilisk_swap_privbob_extract(char *symbol,bits256 spendtxid,int32_t vini,int32_t revflag) @@ -256,7 +301,7 @@ bits256 basilisk_swap_privBn_extract(bits256 *bobrefundp,char *bobcoin,bits256 b bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t utxovout,char *aliceaddr,char *bobaddr,char *Adest,char *dest) { - bits256 spendtxid,txid; char destaddr[64],str[65]; int32_t i,n; struct iguana_info *coin; cJSON *array,*txobj; + bits256 spendtxid,txid; char destaddr[64],str[65]; int32_t i,n,j,numvins,numvouts; struct iguana_info *coin; cJSON *array,*txobj,*vins,*vin,*vouts; memset(&spendtxid,0,sizeof(spendtxid)); destaddr[0] = 0; if ( (coin= LP_coinfind(symbol)) == 0 ) @@ -271,11 +316,47 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in for (i=0; i %s\n",bits256_str(str,txid),destaddr); + if ( 0 && utxoind == BASILISK_BOBPAYMENT ) + printf("ALICE spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); sentflags[alicespent] = 1; sentflags[bobspent] = 0; txids[alicespent] = spendtxid; } else if ( bobaddr != 0 && (strcmp(destaddr,bobaddr) == 0 || strcmp(dest,destaddr) == 0) ) { - //printf("BOB spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); + if ( 0 && utxoind == BASILISK_BOBPAYMENT ) + printf("BOB spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); sentflags[bobspent] = 1; sentflags[alicespent] = 0; txids[bobspent] = spendtxid; } else { - printf("OTHER dest spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); + if ( 0 && utxoind == BASILISK_BOBPAYMENT ) + printf("OTHER dest spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); if ( iambob == 0 ) { sentflags[bobspent] = 1; @@ -327,7 +412,9 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in txids[alicespent] = spendtxid; } } - } //else printf("no spend of %s/v%d detected\n",bits256_str(str,txid),vout); + } + else if ( 0 && utxoind == BASILISK_BOBPAYMENT ) + printf("no spend of %s/v%d detected\n",bits256_str(str,txid),utxovout); } //else printf("utxoind.%d null txid\n",utxoind); return(spendtxid); } @@ -353,46 +440,95 @@ int32_t basilisk_isbobcoin(int32_t iambob,int32_t ind) } } -int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflags,bits256 paymentspent,bits256 Apaymentspent,bits256 depositspent) +int32_t basilisk_swap_isfinished(uint32_t requestid,uint32_t quoteid,uint32_t expiration,int32_t iambob,bits256 *txids,int32_t *sentflags,bits256 paymentspent,bits256 Apaymentspent,bits256 depositspent,uint32_t lockduration) { - int32_t i,n = 0; - for (i=0; i expiration - lockduration ) { - if ( bits256_nonz(txids[BASILISK_BOBDEPOSIT]) == 0 && sentflags[BASILISK_BOBDEPOSIT] == 0 ) - return(1); - else if ( bits256_nonz(txids[BASILISK_BOBPAYMENT]) == 0 || sentflags[BASILISK_BOBPAYMENT] == 0 ) + if ( bits256_nonz(paymentspent) != 0 ) + n++; + if ( bits256_nonz(Apaymentspent) != 0 ) + n++; + if ( bits256_nonz(depositspent) != 0 ) + n++; + for (i=0; i expiration ) { - if ( bits256_nonz(txids[BASILISK_ALICEPAYMENT]) == 0 ) + if ( bits256_nonz(txids[BASILISK_BOBDEPOSIT]) == 0 && sentflags[BASILISK_BOBDEPOSIT] == 0 ) return(1); - else if ( sentflags[BASILISK_BOBPAYMENT] != 0 && sentflags[BASILISK_BOBREFUND] != 0 ) + else if ( bits256_nonz(txids[BASILISK_BOBPAYMENT]) == 0 || sentflags[BASILISK_BOBPAYMENT] == 0 ) + { + if ( bits256_nonz(depositspent) != 0 ) + { + //if ( bits256_nonz(Apaymentspent) == 0 && sentflags[BASILISK_BOBREFUND] == 0 ) + // printf("used to be bob was too late in claiming bobrefund %u-%u\n",requestid,quoteid); + return(0); + } + } + //else if ( bits256_nonz(Apaymentspent) != 0 ) + // return(1); + else if ( bits256_nonz(Apaymentspent) != 0 && bits256_nonz(paymentspent) != 0 && bits256_nonz(depositspent) != 0 ) return(1); } - else + } + else + { + if ( sentflags[BASILISK_ALICESPEND] != 0 || sentflags[BASILISK_ALICERECLAIM] != 0 || sentflags[BASILISK_ALICECLAIM] != 0 ) + return(1); + else if ( now > expiration ) { - if ( sentflags[BASILISK_ALICERECLAIM] != 0 || sentflags[BASILISK_ALICESPEND] != 0 ) - return(1); - else if ( sentflags[BASILISK_BOBSPEND] != 0 ) // without ALICECLAIM this is loss due to inactivity - return(1); + if ( sentflags[BASILISK_ALICEPAYMENT] == 0 ) + { + if ( bits256_nonz(txids[BASILISK_ALICEPAYMENT]) == 0 ) + return(1); + else if ( sentflags[BASILISK_BOBREFUND] != 0 ) //sentflags[BASILISK_BOBPAYMENT] != 0 + return(1); + } + else + { + if ( sentflags[BASILISK_ALICESPEND] != 0 ) + return(1); + else if ( sentflags[BASILISK_ALICERECLAIM] != 0 ) + return(1); + else if ( sentflags[BASILISK_ALICECLAIM] != 0 ) //got deposit! happy alice + return(1); + } } } return(0); @@ -502,9 +638,17 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) jaddstr(item,"Agui",rswap->Agui); jaddstr(item,"gui",rswap->gui); jaddstr(item,"bob",rswap->src); + if ( rswap->bobtomic[0] != 0 ) + jaddstr(item,"bobtomic",rswap->bobtomic); + if ( rswap->etomicsrc[0] != 0 ) + jaddstr(item,"etomicsrc",rswap->etomicsrc); jaddnum(item,"srcamount",dstr(rswap->srcamount)); jaddnum(item,"bobtxfee",dstr(rswap->Btxfee)); jaddstr(item,"alice",rswap->dest); + if ( rswap->alicetomic[0] != 0 ) + jaddstr(item,"alicetomic",rswap->alicetomic); + if ( rswap->etomicdest[0] != 0 ) + jaddstr(item,"etomicdest",rswap->etomicdest); jaddnum(item,"destamount",dstr(rswap->destamount)); jaddnum(item,"alicetxfee",dstr(rswap->Atxfee)); jadd64bits(item,"aliceid",rswap->aliceid); @@ -539,7 +683,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t quoteid,int32_t forceflag) { - char fname[1024],*fstr,*secretstr,*srcstr,*deststr,*dest33,*txname; long fsize; cJSON *item,*txobj,*array; bits256 privkey; struct iguana_info *coin; uint32_t r,q; int32_t i,j,n; uint8_t other33[33]; + char fname[1024],*fstr,*secretstr,*srcstr,*deststr,*dest33,*txname; long fsize; cJSON *item,*txobj,*array; bits256 privkey; struct iguana_info *coin; uint32_t r,q; int32_t i,j,n; uint8_t other33[33]; uint32_t lockduration; memset(rswap,0,sizeof(*rswap)); rswap->requestid = requestid; rswap->quoteid = quoteid; @@ -552,6 +696,8 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t safecopy(rswap->Bgui,jstr(item,"Bgui"),sizeof(rswap->Bgui)); safecopy(rswap->Agui,jstr(item,"Agui"),sizeof(rswap->Agui)); safecopy(rswap->gui,jstr(item,"gui"),sizeof(rswap->gui)); + safecopy(rswap->bobtomic,jstr(item,"bobtomic"),sizeof(rswap->bobtomic)); + safecopy(rswap->alicetomic,jstr(item,"alicetomic"),sizeof(rswap->alicetomic)); rswap->tradeid = juint(item,"tradeid"); rswap->aliceid = j64bits(item,"aliceid"); if ( (secretstr= jstr(item,"secretAm")) != 0 && strlen(secretstr) == 40 ) @@ -637,9 +783,9 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t rswap->txids[BASILISK_MYFEE] = jbits256(item,"myfee"); rswap->txids[BASILISK_OTHERFEE] = jbits256(item,"otherfee"); free_json(item); - } + } else printf("couldnt parse.(%s)\n",fstr); free(fstr); - } + } // else printf("cant open.(%s)\n",fname); sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); if ( (fstr= OS_filestr(&fsize,fname)) != 0 ) { @@ -670,7 +816,8 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t } free_json(txobj); } - rswap->origfinishedflag = basilisk_swap_isfinished(rswap->iambob,rswap->txids,rswap->sentflags,rswap->paymentspent,rswap->Apaymentspent,rswap->depositspent); + lockduration = LP_atomic_locktime(rswap->bobcoin,rswap->alicecoin); + rswap->origfinishedflag = basilisk_swap_isfinished(requestid,quoteid,rswap->expiration,rswap->iambob,rswap->txids,rswap->sentflags,rswap->paymentspent,rswap->Apaymentspent,rswap->depositspent,lockduration); rswap->finishedflag = rswap->origfinishedflag; if ( forceflag != 0 ) rswap->finishedflag = rswap->origfinishedflag = 0; @@ -741,6 +888,35 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag) free_json(txobj); continue; } + + if (jstr(txobj,"etomicsrc") != 0) { + strcpy(rswap->etomicsrc,jstr(txobj,"etomicsrc")); + } + + if (jstr(txobj,"etomicdest") != 0) { + strcpy(rswap->etomicdest,jstr(txobj,"etomicdest")); + } + + if (jstr(txobj,"bobDepositEthTx") != 0) { + strcpy(rswap->bobDepositEthTx, jstr(txobj,"bobDepositEthTx")); + } + + if (jstr(txobj,"bobPaymentEthTx") != 0) { + strcpy(rswap->bobPaymentEthTx, jstr(txobj,"bobPaymentEthTx")); + } + + if (jstr(txobj,"alicePaymentEthTx") != 0) { + strcpy(rswap->alicePaymentEthTx, jstr(txobj,"alicePaymentEthTx")); + } + + if (jstr(txobj,"bobtomic") != 0) { + strcpy(rswap->bobtomic, jstr(txobj,"bobtomic")); + } + + if (jstr(txobj,"alicetomic") != 0) { + strcpy(rswap->alicetomic, jstr(txobj,"alicetomic")); + } + rswap->txids[i] = txid; if ( jstr(txobj,"Apayment") != 0 ) safecopy(rswap->alicepaymentaddr,jstr(txobj,"Apayment"),sizeof(rswap->alicepaymentaddr)); @@ -757,6 +933,7 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag) { rswap->Predeemlen >>= 1; decode_hex(rswap->Predeemscript,rswap->Predeemlen,rstr); + //printf("%p Predeemscript.(%s)\n",rswap->Predeemscript,rstr); } else if ( strcmp(txnames[i],"bobdeposit") == 0 && (rstr= jstr(txobj,"redeem")) != 0 && (rswap->Dredeemlen= is_hexstr(rstr,0)) > 0 ) { @@ -792,9 +969,9 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag) safecopy(rswap->alicecoin,symbol,sizeof(rswap->alicecoin)); if ( rswap->finishedflag == 0 ) { - if ( (sentobj= LP_gettx(symbol,txid,1)) == 0 ) + if ( (sentobj= LP_gettx("LP_remember",symbol,txid,1)) == 0 ) { - char str2[65]; printf("%s %s ready to broadcast\n",symbol,bits256_str(str2,txid)); + //char str2[65]; printf("%s %s ready to broadcast %s r%u q%u\n",symbol,bits256_str(str2,txid),txnames[i],rswap->requestid,rswap->quoteid); } else { @@ -812,6 +989,7 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag) //printf("%s %s %.8f\n",txnames[i],bits256_str(str,txid),dstr(value)); } } + free_json(txobj); } //else printf("no symbol\n"); free(fstr); @@ -887,10 +1065,22 @@ int32_t LP_spends_set(struct LP_swap_remember *rswap) return(numspent); } -cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid,int32_t forceflag,int32_t pendingonly) +cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid,int32_t forceflag,int32_t pendingonly) { static void *ctx; - struct LP_swap_remember rswap; int32_t i,j,flag,numspent,len,secretstart,redeemlen; char str[65],*srcAdest,*srcBdest,*destAdest,*destBdest,otheraddr[64]; cJSON *item,*txoutobj; bits256 rev,signedtxid,zero,deadtxid; uint32_t claimtime; struct iguana_info *bob=0,*alice=0; uint8_t redeemscript[1024],userdata[1024]; + struct LP_swap_remember rswap; int32_t i,j,flag,numspent,len,secretstart,redeemlen; char str[65],*srcAdest,*srcBdest,*destAdest,*destBdest,otheraddr[64],*fstr,fname[512],bobtomic[128],alicetomic[128],bobstr[65],alicestr[65]; cJSON *item,*txoutobj,*retjson; bits256 rev,revAm,signedtxid,zero,deadtxid; uint32_t claimtime,lockduration; struct iguana_info *bob=0,*alice=0; uint8_t redeemscript[1024],userdata[1024]; long fsize; + sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + if ( (fstr= OS_filestr(&fsize,fname)) != 0 ) + { + if ( (retjson= cJSON_Parse(fstr)) != 0 ) + { + free(fstr); + if ( pendingonly != 0 ) + free_json(retjson), retjson = 0; + return(retjson); + } + free(fstr); + } if ( ctx == 0 ) ctx = bitcoin_ctx(); if ( requestid == 0 || quoteid == 0 ) @@ -903,18 +1093,26 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti otheraddr[0] = 0; claimtime = (uint32_t)time(NULL) - 777; srcAdest = srcBdest = destAdest = destBdest = 0; - if ( rswap.bobcoin[0] == 0 || rswap.alicecoin[0] == 0 || strcmp(rswap.bobcoin,rswap.src) != 0 || strcmp(rswap.alicecoin,rswap.dest) != 0 ) + alice = LP_coinfind(rswap.alicecoin); + bob = LP_coinfind(rswap.bobcoin); + LP_etomicsymbol(bobstr,bobtomic,rswap.src); + LP_etomicsymbol(alicestr,alicetomic,rswap.dest); + lockduration = LP_atomic_locktime(rswap.bobcoin,rswap.alicecoin); + if ( rswap.bobcoin[0] == 0 || rswap.alicecoin[0] == 0 || strcmp(rswap.bobcoin,bobstr) != 0 || strcmp(rswap.alicecoin,alicestr) != 0 ) { //printf("legacy r%u-q%u DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",requestid,quoteid,rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); cJSON *retjson = cJSON_CreateObject(); jaddstr(retjson,"error","swap never started"); + jaddstr(retjson,"status","finished"); + jaddstr(retjson,"bob",rswap.bobcoin); + jaddstr(retjson,"src",rswap.src); + jaddstr(retjson,"alice",rswap.alicecoin); + jaddstr(retjson,"dest",rswap.dest); jaddnum(retjson,"requestid",requestid); jaddnum(retjson,"quoteid",quoteid); return(retjson); //return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}")); } - alice = LP_coinfind(rswap.alicecoin); - bob = LP_coinfind(rswap.bobcoin); rswap.Atxfee = LP_txfeecalc(alice,rswap.Atxfee,0); rswap.Btxfee = LP_txfeecalc(bob,rswap.Btxfee,0); if ( rswap.iambob == 0 ) @@ -929,6 +1127,21 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti printf("this isnt my swap! alice.(%s vs %s)\n",alice->smartaddr,rswap.Adestaddr); cJSON *retjson = cJSON_CreateObject(); jaddstr(retjson,"error","swap for different account"); + jaddstr(retjson,"alice",alice->symbol); + jaddstr(retjson,"aliceaddr",alice->smartaddr); + jaddstr(retjson,"dest",rswap.dest); + jaddnum(retjson,"requestid",requestid); + jaddnum(retjson,"quoteid",quoteid); + return(retjson); + } + if ( 0 && alice->electrum == 0 && alice->lastscanht < alice->longestchain+1 ) + { + printf("need to scan %s first\n",alice->symbol); + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","need to scan coin first"); + jaddstr(retjson,"coin",alice->symbol); + jaddnum(retjson,"scanned",alice->lastscanht); + jaddnum(retjson,"longest",alice->longestchain); jaddnum(retjson,"requestid",requestid); jaddnum(retjson,"quoteid",quoteid); return(retjson); @@ -953,6 +1166,21 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti printf("this isnt my swap! bob.(%s vs %s)\n",bob->smartaddr,rswap.destaddr); cJSON *retjson = cJSON_CreateObject(); jaddstr(retjson,"error","swap for different account"); + jaddstr(retjson,"bob",bob->symbol); + jaddstr(retjson,"bobaddr",bob->smartaddr); + jaddstr(retjson,"src",rswap.src); + jaddnum(retjson,"requestid",requestid); + jaddnum(retjson,"quoteid",quoteid); + return(retjson); + } + if ( 0 && bob->electrum == 0 && bob->lastscanht < bob->longestchain+1 ) + { + printf("need to scan %s first\n",bob->symbol); + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","need to scan coin first"); + jaddstr(retjson,"coin",bob->symbol); + jaddnum(retjson,"scanned",bob->lastscanht); + jaddnum(retjson,"longest",bob->longestchain); jaddnum(retjson,"requestid",requestid); jaddnum(retjson,"quoteid",quoteid); return(retjson); @@ -970,26 +1198,27 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti printf("Bob.%p is null or Alice.%p is null\n",bob,alice); return(cJSON_Parse("{\"error\":\"null bob or alice coin\"}")); } + if ( alice->inactive != 0 || bob->inactive != 0 ) + { + printf("Alice.%s inactive.%u or Bob.%s inactive.%u\n",rswap.alicecoin,alice->inactive,rswap.bobcoin,bob->inactive); + return(cJSON_Parse("{\"error\":\"inactive bob or alice coin\"}")); + } //printf("src.(Adest %s, Bdest %s), dest.(Adest %s, Bdest %s)\n",srcAdest,srcBdest,destAdest,destBdest); //printf("iambob.%d finishedflag.%d %s %.8f txfee, %s %.8f txfee\n",rswap.iambob,rswap.finishedflag,rswap.alicecoin,dstr(rswap.Atxfee),rswap.bobcoin,dstr(rswap.Btxfee)); //printf("privAm.(%s) %p/%p\n",bits256_str(str,rswap.privAm),Adest,AAdest); //printf("privBn.(%s) %p/%p\n",bits256_str(str,rswap.privBn),Bdest,ABdest); - if ( rswap.finishedflag == 0 && rswap.bobcoin[0] != 0 && rswap.alicecoin[0] != 0 ) + if ( fastflag == 0 && rswap.finishedflag == 0 && rswap.bobcoin[0] != 0 && rswap.alicecoin[0] != 0 ) { - //printf("ALICE.(%s) 1st refht %s <- %d, scan %d %d\n",rswap.Adestaddr,alice->symbol,alice->firstrefht,alice->firstscanht,alice->lastscanht); + portable_mutex_lock(&LP_swaplistmutex); + //printf("ALICE.(%s) 1st refht %s <- %d, scan %d %d\n",rswap.Adestaddr,alice->symbol,alice->firstrefht,alice->firstscanht,alice->lastscanht); //printf("BOB.(%s) 1st refht %s <- %d, scan %d %d\n",rswap.destaddr,bob->symbol,bob->firstrefht,bob->firstscanht,bob->lastscanht); - if ( alice->inactive != 0 || bob->inactive != 0 ) - { - printf("Alice.%s inactive.%u or Bob.%s inactive.%u\n",rswap.alicecoin,alice->inactive,rswap.bobcoin,bob->inactive); - return(cJSON_Parse("{\"error\":\"inactive bob or alice coin\"}")); - } LP_rswap_checktx(&rswap,rswap.alicecoin,BASILISK_ALICEPAYMENT); LP_rswap_checktx(&rswap,rswap.bobcoin,BASILISK_BOBPAYMENT); LP_rswap_checktx(&rswap,rswap.bobcoin,BASILISK_BOBDEPOSIT); rswap.paymentspent = basilisk_swap_spendupdate(rswap.iambob,rswap.bobcoin,rswap.bobpaymentaddr,rswap.sentflags,rswap.txids,BASILISK_BOBPAYMENT,BASILISK_ALICESPEND,BASILISK_BOBRECLAIM,0,srcAdest,srcBdest,rswap.Adestaddr,rswap.destaddr); rswap.Apaymentspent = basilisk_swap_spendupdate(rswap.iambob,rswap.alicecoin,rswap.alicepaymentaddr,rswap.sentflags,rswap.txids,BASILISK_ALICEPAYMENT,BASILISK_ALICERECLAIM,BASILISK_BOBSPEND,0,destAdest,destBdest,rswap.Adestaddr,rswap.destaddr); rswap.depositspent = basilisk_swap_spendupdate(rswap.iambob,rswap.bobcoin,rswap.bobdepositaddr,rswap.sentflags,rswap.txids,BASILISK_BOBDEPOSIT,BASILISK_ALICECLAIM,BASILISK_BOBREFUND,0,srcAdest,srcBdest,rswap.Adestaddr,rswap.destaddr); - rswap.finishedflag = basilisk_swap_isfinished(rswap.iambob,rswap.txids,rswap.sentflags,rswap.paymentspent,rswap.Apaymentspent,rswap.depositspent); + rswap.finishedflag = basilisk_swap_isfinished(requestid,quoteid,rswap.expiration,rswap.iambob,rswap.txids,rswap.sentflags,rswap.paymentspent,rswap.Apaymentspent,rswap.depositspent,lockduration); LP_spends_set(&rswap); if ( rswap.iambob == 0 ) { @@ -1012,30 +1241,46 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti memset(rev.bytes,0,sizeof(rev)); for (j=0; j<32; j++) rev.bytes[j] = rswap.privAm.bytes[31 - j]; - //revcalc_rmd160_sha256(secretAm,rev);//privAm); - //vcalc_sha256(0,secretAm256,rev.bytes,sizeof(rev)); + redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,rswap.plocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,rev,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); if ( rswap.Predeemlen != 0 ) - redeemlen = rswap.Predeemlen, memcpy(redeemscript,rswap.Predeemscript,rswap.Predeemlen); - else redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,rswap.plocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,rev,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); + { + if ( rswap.Predeemlen != redeemlen || memcmp(redeemscript,rswap.Predeemscript,redeemlen) != 0 ) + printf("Predeemscript error len %d vs %d, cmp.%d\n",rswap.Predeemlen,redeemlen,memcmp(redeemscript,rswap.Predeemscript,redeemlen)); + //else printf("Predeem matches\n"); + } else printf("%p Predeemscript missing\n",rswap.Predeemscript); len = basilisk_swapuserdata(userdata,rev,0,rswap.myprivs[0],redeemscript,redeemlen); + if ( 0 ) { - char privaddr[64]; uint8_t privpub33[33]; - bitcoin_pubkey33(ctx,privpub33,rswap.myprivs[0]); - bitcoin_address(rswap.bobcoin,privaddr,0,60,privpub33,33); - printf("alicespend len.%d redeemlen.%d priv0addr.(%s) priv0.(%s)\n",len,redeemlen,privaddr,bits256_str(str,rswap.myprivs[0])); + uint8_t secretAm[20]; + calc_rmd160_sha256(secretAm,rswap.privAm.bytes,sizeof(rswap.privAm)); + for (j=0; j<20; j++) + printf("%02x",secretAm[j]); + printf(" secretAm, privAm %s alicespend len.%d redeemlen.%d\n",bits256_str(str,rswap.privAm),len,redeemlen); + } + claimtime = LP_claimtime(bob,rswap.plocktime - 777); + if ( (rswap.txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"alicespend",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,1,claimtime,&rswap.values[BASILISK_ALICESPEND],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + { + //printf("alicespend.(%s)\n",rswap.txbytes[BASILISK_ALICESPEND]); +#ifndef NOTETOMIC + if ( rswap.bobtomic[0] != 0 ) + { + char *aliceSpendEthTxId = LP_etomicalice_spends_bob_payment(&rswap); + if (aliceSpendEthTxId != NULL) { + free(aliceSpendEthTxId); + } else { + printf("Alice spend ETH tx send failed!\n"); + } + } +#endif } - for (j=0; j<32; j++) - rev.bytes[j] = rswap.myprivs[0].bytes[31 - j]; - if ( (rswap.txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"alicespend",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_ALICESPEND],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) - printf("alicespend.(%s)\n",rswap.txbytes[BASILISK_ALICESPEND]); } LP_txbytes_update("alicespend",rswap.bobcoin,rswap.txbytes[BASILISK_ALICESPEND],&rswap.txids[BASILISK_ALICESPEND],&rswap.paymentspent,&rswap.sentflags[BASILISK_ALICESPEND]); } } } - if ( rswap.sentflags[BASILISK_ALICECLAIM] == 0 && rswap.sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(rswap.txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(rswap.depositspent) == 0 ) + if ( rswap.sentflags[BASILISK_ALICECLAIM] == 0 && (rswap.sentflags[BASILISK_BOBDEPOSIT] != 0 || bits256_nonz(rswap.txids[BASILISK_BOBDEPOSIT]) != 0) && bits256_nonz(rswap.depositspent) == 0 ) { - if ( time(NULL) > rswap.expiration+777 ) + if ( time(NULL) > rswap.dlocktime+777 ) { flag = 0; if ( bob->electrum == 0 ) @@ -1044,22 +1289,45 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti free_json(txoutobj), flag = 0; else flag = -1, rswap.depositspent = deadtxid; } - //if ( flag == 0 ) + if ( flag == 0 ) { if ( rswap.Dredeemlen != 0 ) redeemlen = rswap.Dredeemlen, memcpy(redeemscript,rswap.Dredeemscript,rswap.Dredeemlen); - else redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,rswap.dlocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,rswap.privAm,zero,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); + else + redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,rswap.dlocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,rswap.privAm,zero,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); + /*if ( rswap.Dredeemlen != 0 ) + { + if ( rswap.Dredeemlen != redeemlen || memcmp(redeemscript,rswap.Dredeemscript,redeemlen) != 0 ) + printf("Dredeemscript error len %d vs %d, cmp.%d\n",rswap.Dredeemlen,redeemlen,memcmp(redeemscript,rswap.Dredeemscript,redeemlen)); + } else printf("%p Dredeemscript missing\n",rswap.Dredeemscript);*/ if ( redeemlen > 0 ) { - len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[0],redeemscript,redeemlen); + memset(revAm.bytes,0,sizeof(revAm)); + for (i=0; i<32; i++) + revAm.bytes[i] = rswap.privAm.bytes[31-i]; + len = basilisk_swapuserdata(userdata,revAm,1,rswap.myprivs[0],redeemscript,redeemlen); + claimtime = LP_claimtime(bob,rswap.dlocktime); if ( (rswap.txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"aliceclaim",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,0,claimtime,&rswap.values[BASILISK_ALICECLAIM],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) - printf("claimtime.%u aliceclaim.(%s)\n",claimtime,rswap.txbytes[BASILISK_ALICECLAIM]); + { + //printf("dlocktime.%u claimtime.%u aliceclaim.(%s)\n",rswap.dlocktime,claimtime,rswap.txbytes[BASILISK_ALICECLAIM]); +#ifndef NOTETOMIC + if ( rswap.bobtomic[0] != 0 ) + { + char *aliceClaimsEthTxId = LP_etomicalice_claims_bob_deposit(&rswap); + if (aliceClaimsEthTxId != NULL) { + free(aliceClaimsEthTxId); + } else { + printf("Alice Bob deposit claim ETH tx failed!\n"); + } + } +#endif + } } LP_txbytes_update("aliceclaim",rswap.bobcoin,rswap.txbytes[BASILISK_ALICECLAIM],&rswap.txids[BASILISK_ALICECLAIM],&rswap.depositspent,&rswap.sentflags[BASILISK_ALICECLAIM]); } - } else printf("now %u before expiration %u\n",(uint32_t)time(NULL),rswap.expiration); + } //else printf("now %u before expiration %u\n",(uint32_t)time(NULL),rswap.expiration); } - if ( rswap.sentflags[BASILISK_ALICEPAYMENT] != 0 && bits256_nonz(rswap.Apaymentspent) == 0 && rswap.sentflags[BASILISK_ALICECLAIM] == 0 ) + if ( (rswap.sentflags[BASILISK_ALICEPAYMENT] != 0 || bits256_nonz(rswap.txids[BASILISK_ALICEPAYMENT]) != 0)&& bits256_nonz(rswap.Apaymentspent) == 0 && rswap.sentflags[BASILISK_ALICERECLAIM] == 0 ) { flag = 0; if ( alice->electrum == 0 ) @@ -1073,8 +1341,16 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti rswap.privBn = basilisk_swap_privBn_extract(&rswap.txids[BASILISK_BOBREFUND],rswap.bobcoin,rswap.txids[BASILISK_BOBDEPOSIT],rswap.privBn); if ( bits256_nonz(rswap.txids[BASILISK_ALICEPAYMENT]) != 0 && bits256_nonz(rswap.privAm) != 0 && bits256_nonz(rswap.privBn) != 0 ) { - if ( (rswap.txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration,&rswap.values[BASILISK_ALICERECLAIM],rswap.alicepaymentaddr,alice->zcash)) != 0 ) - printf("alicereclaim.(%s)\n",rswap.txbytes[BASILISK_ALICERECLAIM]); + if ( (rswap.txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration,&rswap.values[BASILISK_ALICERECLAIM],rswap.alicepaymentaddr,alice->zcash)) != 0 ) { + printf("alicereclaim.(%s)\n", rswap.txbytes[BASILISK_ALICERECLAIM]); +#ifndef NOTETOMIC + if ( rswap.alicetomic[0] != 0 ) + { + char *aliceReclaimEthTx = LP_etomicalice_reclaims_payment(&rswap); + free(aliceReclaimEthTx); + } +#endif + } } LP_txbytes_update("alicereclaim",rswap.alicecoin,rswap.txbytes[BASILISK_ALICERECLAIM],&rswap.txids[BASILISK_ALICERECLAIM],&rswap.Apaymentspent,&rswap.sentflags[BASILISK_ALICERECLAIM]); } @@ -1084,8 +1360,8 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti { if ( rswap.sentflags[BASILISK_BOBSPEND] == 0 && bits256_nonz(rswap.Apaymentspent) == 0 ) { - //printf("try to bobspend aspend.%s have privAm.%d\n",bits256_str(str,rswap.txids[BASILISK_ALICESPEND]),bits256_nonz(rswap.privAm)); - if ( bits256_nonz(rswap.txids[BASILISK_ALICESPEND]) != 0 || bits256_nonz(rswap.privAm) != 0 ) + //printf("try to bobspend aspend.%s have privAm.%d aspent.%d\n",bits256_str(str,rswap.txids[BASILISK_ALICESPEND]),bits256_nonz(rswap.privAm),rswap.sentflags[BASILISK_ALICESPEND]); + if ( rswap.sentflags[BASILISK_ALICESPEND] != 0 || bits256_nonz(rswap.paymentspent) != 0 || bits256_nonz(rswap.privAm) != 0 || bits256_nonz(rswap.depositspent) != 0 ) { flag = 0; if ( alice->electrum == 0 ) @@ -1094,23 +1370,41 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti free_json(txoutobj), flag = 0; else flag = -1, rswap.Apaymentspent = deadtxid; } + //printf("flag.%d apayment.%s\n",flag,bits256_str(str,rswap.paymentspent)); if ( flag == 0 ) { if ( bits256_nonz(rswap.privAm) == 0 ) { - rswap.privAm = basilisk_swap_privbob_extract(rswap.bobcoin,rswap.txids[BASILISK_ALICESPEND],0,1); - //printf("try to bobspend aspend.%s have privAm.%d\n",bits256_str(str,rswap.txids[BASILISK_ALICESPEND]),bits256_nonz(rswap.privAm)); + rswap.privAm = basilisk_swap_privbob_extract(rswap.bobcoin,rswap.paymentspent,0,1); + if ( bits256_nonz(rswap.privAm) == 0 && bits256_nonz(rswap.depositspent) != 0 ) + { + rswap.privAm = basilisk_swap_privbob_extract(rswap.bobcoin,rswap.depositspent,0,1); + //printf("try to bobspend aspend.%s have privAm.%d\n",bits256_str(str,rswap.depositspent),bits256_nonz(rswap.privAm)); + } } if ( bits256_nonz(rswap.privAm) != 0 && bits256_nonz(rswap.privBn) != 0 ) { if ( (rswap.txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration,&rswap.values[BASILISK_BOBSPEND],rswap.alicepaymentaddr,alice->zcash)) != 0 ) - printf("bobspend.(%s)\n",rswap.txbytes[BASILISK_BOBSPEND]); + { +#ifndef NOTETOMIC + if ( rswap.alicetomic[0] != 0 ) + { + char *bobSpendEthTx = LP_etomicbob_spends_alice_payment(&rswap); + if (bobSpendEthTx != NULL) { + free(bobSpendEthTx); + } else { + printf("Bob spends Alice payment ETH tx send failed!\n"); + } + } +#endif + //printf("bobspend.(%s)\n",rswap.txbytes[BASILISK_BOBSPEND]); + } } LP_txbytes_update("bobspend",rswap.alicecoin,rswap.txbytes[BASILISK_BOBSPEND],&rswap.txids[BASILISK_BOBSPEND],&rswap.Apaymentspent,&rswap.sentflags[BASILISK_BOBSPEND]); } } } - if ( rswap.sentflags[BASILISK_BOBRECLAIM] == 0 && rswap.sentflags[BASILISK_BOBPAYMENT] != 0 && bits256_nonz(rswap.txids[BASILISK_BOBPAYMENT]) != 0 && bits256_nonz(rswap.paymentspent) == 0 ) + if ( rswap.sentflags[BASILISK_BOBRECLAIM] == 0 && (rswap.sentflags[BASILISK_BOBPAYMENT] != 0 || bits256_nonz(rswap.txids[BASILISK_BOBPAYMENT]) != 0) && bits256_nonz(rswap.paymentspent) == 0 ) { flag = 0; if ( bob->electrum == 0 ) @@ -1119,28 +1413,43 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti free_json(txoutobj), flag = 0; else flag = -1, rswap.paymentspent = deadtxid; } - if ( time(NULL) > rswap.expiration+777 ) + if ( flag == 0 && time(NULL) > rswap.plocktime+777 ) { // bobreclaim redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,rswap.plocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,zero,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); if ( redeemlen > 0 ) { len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[1],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,claimtime,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + claimtime = LP_claimtime(bob,rswap.plocktime - 777); + if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobreclaim",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,claimtime,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) { - int32_t z; - for (z=0; z<20; z++) - printf("%02x",rswap.secretAm[z]); - printf(" secretAm, myprivs[1].(%s) bobreclaim.(%s)\n",bits256_str(str,rswap.myprivs[1]),rswap.txbytes[BASILISK_BOBRECLAIM]); +#ifndef NOTETOMIC + if ( rswap.bobtomic[0] != 0 ) + { + char *bobReclaimEthTx = LP_etomicbob_reclaims_payment(&rswap); + if (bobReclaimEthTx != NULL) { + free(bobReclaimEthTx); + } else { + printf("Bob reclaims payment ETH tx send failed!\n"); + } + } +#endif + //int32_t z; + //for (z=0; z<20; z++) + // printf("%02x",rswap.secretAm[z]); + //printf(" secretAm, myprivs[1].(%s) bobreclaim.(%s)\n",bits256_str(str,rswap.myprivs[1]),rswap.txbytes[BASILISK_BOBRECLAIM]); } } LP_txbytes_update("bobreclaim",rswap.bobcoin,rswap.txbytes[BASILISK_BOBRECLAIM],&rswap.txids[BASILISK_BOBRECLAIM],&rswap.paymentspent,&rswap.sentflags[BASILISK_BOBRECLAIM]); } else if ( flag == 0 ) - printf("bobpayment: now.%u < expiration %u\n",(uint32_t)time(NULL),rswap.expiration); + { + //printf("bobpayment: now.%u < expiration %u\n",(uint32_t)time(NULL),rswap.expiration); + } } - if ( rswap.sentflags[BASILISK_BOBREFUND] == 0 && rswap.sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(rswap.txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(rswap.depositspent) == 0 ) + if ( rswap.sentflags[BASILISK_BOBREFUND] == 0 && (rswap.sentflags[BASILISK_BOBDEPOSIT] != 0 || bits256_nonz(rswap.txids[BASILISK_BOBDEPOSIT]) != 0) && bits256_nonz(rswap.depositspent) == 0 ) { + //printf("bobdeposit.%d depositspent.%d paymentspent.%d\n",rswap.sentflags[BASILISK_BOBDEPOSIT],bits256_nonz(rswap.depositspent),bits256_nonz(rswap.paymentspent)); flag = 0; if ( bob->electrum == 0 ) { @@ -1148,17 +1457,38 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti free_json(txoutobj), flag = 0; else flag = -1, rswap.depositspent = deadtxid; } - if ( bits256_nonz(rswap.Apaymentspent) != 0 || time(NULL) > rswap.expiration+777 ) + //printf("lockduration.%d plocktime.%u lag.%d\n",lockduration,rswap.plocktime,(int32_t)(time(NULL) - (rswap.plocktime-lockduration+1800))); + if ( flag == 0 && ( + bits256_nonz(rswap.Apaymentspent) != 0 || + time(NULL) > rswap.dlocktime-777 || + (bits256_nonz(rswap.txids[BASILISK_ALICEPAYMENT]) == 0 && time(NULL) > rswap.plocktime-777) || + (bits256_nonz(rswap.txids[BASILISK_BOBPAYMENT]) != 0 && rswap.sentflags[BASILISK_BOBPAYMENT] == 0 && time(NULL) > rswap.plocktime-lockduration+1800) || // failed bobpayment + (bits256_nonz(rswap.txids[BASILISK_BOBPAYMENT]) == 0 && time(NULL) > rswap.dlocktime-3*lockduration/2) + ) ) { - printf("do the refund! paymentspent.%s now.%u vs expiration.%u\n",bits256_str(str,rswap.paymentspent),(uint32_t)time(NULL),rswap.expiration); + //printf("do the refund! paymentspent.%s now.%u vs expiration.%u\n",bits256_str(str,rswap.paymentspent),(uint32_t)time(NULL),rswap.expiration); //if ( txbytes[BASILISK_BOBREFUND] == 0 ) { revcalc_rmd160_sha256(rswap.secretBn,rswap.privBn); vcalc_sha256(0,rswap.secretBn256,rswap.privBn.bytes,sizeof(rswap.privBn)); redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,rswap.dlocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,rswap.privAm,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); len = basilisk_swapuserdata(userdata,rswap.privBn,0,rswap.myprivs[0],redeemscript,redeemlen); - if ( (rswap.txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_BOBREFUND],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) - printf("pubB1.(%s) bobrefund.(%s)\n",bits256_str(str,rswap.pubB1),rswap.txbytes[BASILISK_BOBREFUND]); + claimtime = LP_claimtime(bob,rswap.plocktime - 777); + if ( (rswap.txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,1,claimtime,&rswap.values[BASILISK_BOBREFUND],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) + { +#ifndef NOTETOMIC + if ( rswap.bobtomic[0] != 0 ) + { + char *bobRefundsEthTx = LP_etomicbob_refunds_deposit(&rswap); + if (bobRefundsEthTx != NULL) { + free(bobRefundsEthTx); + } else { + printf("Bob refunds deposit ETH tx send failed!\n"); + } + } +#endif + //printf("pubB1.(%s) bobrefund.(%s)\n",bits256_str(str,rswap.pubB1),rswap.txbytes[BASILISK_BOBREFUND]); + } } LP_txbytes_update("bobrefund",rswap.bobcoin,rswap.txbytes[BASILISK_BOBREFUND],&rswap.txids[BASILISK_BOBREFUND],&rswap.depositspent,&rswap.sentflags[BASILISK_BOBREFUND]); } @@ -1166,6 +1496,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti printf("bobrefund's time %u vs expiration %u\n",(uint32_t)time(NULL),rswap.expiration); } } + portable_mutex_unlock(&LP_swaplistmutex); } //printf("finish.%d iambob.%d REFUND %d %d %d %d\n",finishedflag,iambob,sentflags[BASILISK_BOBREFUND] == 0,sentflags[BASILISK_BOBDEPOSIT] != 0,bits256_nonz(txids[BASILISK_BOBDEPOSIT]) != 0,bits256_nonz(depositspent) == 0); if ( rswap.sentflags[BASILISK_ALICESPEND] != 0 || rswap.sentflags[BASILISK_BOBRECLAIM] != 0 ) @@ -1186,7 +1517,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti LP_totals_update(rswap.iambob,rswap.alicecoin,rswap.bobcoin,KMDtotals,BTCtotals,rswap.sentflags,rswap.values); if ( (numspent= LP_spends_set(&rswap)) == 3 ) rswap.finishedflag = 1; - else rswap.finishedflag = basilisk_swap_isfinished(rswap.iambob,rswap.txids,rswap.sentflags,rswap.paymentspent,rswap.Apaymentspent,rswap.depositspent); + else rswap.finishedflag = basilisk_swap_isfinished(requestid,quoteid,rswap.expiration,rswap.iambob,rswap.txids,rswap.sentflags,rswap.paymentspent,rswap.Apaymentspent,rswap.depositspent,lockduration); if ( rswap.origfinishedflag == 0 && rswap.finishedflag != 0 ) { char fname[1024],*itemstr; FILE *fp; @@ -1249,10 +1580,10 @@ void for_satinder() } else printf("error with satinder tx\n"); } -char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid,int32_t forceflag,int32_t pendingonly) +char *basilisk_swaplist(int32_t fastflag,uint32_t origrequestid,uint32_t origquoteid,int32_t forceflag,int32_t pendingonly) { uint64_t ridqids[4096],ridqid; char fname[512]; FILE *fp; cJSON *item,*retjson,*array,*totalsobj; uint32_t r,q,quoteid,requestid; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS],Btotal,Ktotal; int32_t i,j,count=0; - portable_mutex_lock(&LP_swaplistmutex); + //portable_mutex_lock(&LP_swaplistmutex); memset(ridqids,0,sizeof(ridqids)); memset(KMDtotals,0,sizeof(KMDtotals)); memset(BTCtotals,0,sizeof(BTCtotals)); @@ -1262,7 +1593,7 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid,int32_t forc if ( origrequestid != 0 && origquoteid != 0 ) { //printf("orig req.%u q.%u\n",origrequestid,origquoteid); - if ( (item= basilisk_remember(KMDtotals,BTCtotals,origrequestid,origquoteid,forceflag,0)) != 0 ) + if ( (item= basilisk_remember(fastflag,KMDtotals,BTCtotals,origrequestid,origquoteid,forceflag,0)) != 0 ) jaddi(array,item); //printf("got.(%s)\n",jprint(item,0)); } @@ -1304,7 +1635,7 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid,int32_t forc { if ( count < sizeof(ridqids)/sizeof(*ridqids) ) ridqids[count++] = ridqid; - if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,0,pendingonly)) != 0 ) + if ( (item= basilisk_remember(fastflag,KMDtotals,BTCtotals,requestid,quoteid,0,pendingonly)) != 0 ) jaddi(array,item); } } @@ -1333,16 +1664,16 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid,int32_t forc else if ( Ktotal < 0 && Btotal > 0 ) jaddnum(retjson,"avesell",(double)-Btotal/Ktotal); } - portable_mutex_unlock(&LP_swaplistmutex); + //portable_mutex_unlock(&LP_swaplistmutex); return(jprint(retjson,1)); } -char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid,int32_t forceflag) +char *basilisk_swapentry(int32_t fastflag,uint32_t requestid,uint32_t quoteid,int32_t forceflag) { cJSON *item; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS]; memset(KMDtotals,0,sizeof(KMDtotals)); memset(BTCtotals,0,sizeof(BTCtotals)); - if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,forceflag,0)) != 0 ) + if ( (item= basilisk_remember(fastflag,KMDtotals,BTCtotals,requestid,quoteid,forceflag,0)) != 0 ) return(jprint(item,1)); else return(clonestr("{\"error\":\"cant find requestid-quoteid\"}")); } @@ -1377,7 +1708,7 @@ char *LP_recent_swaps(int32_t limit) item = cJSON_CreateArray(); jaddinum(item,requestid); jaddinum(item,quoteid); - if ( (retstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) + if ( (retstr= basilisk_swapentry(1,requestid,quoteid,0)) != 0 ) { if ( (swapjson= cJSON_Parse(retstr)) != 0 ) { @@ -1441,7 +1772,7 @@ char *LP_recent_swaps(int32_t limit) jaddstr(item,"alice",LP_Alicequery.destcoin); jaddstr(item,"rel",LP_Alicequery.destcoin); jaddnum(item,"relvalue",dstr(LP_Alicequery.destsatoshis)); - jaddnum(item,"aliceid",LP_aliceid_calc(LP_Alicequery.desttxid,LP_Alicequery.destvout,LP_Alicequery.feetxid,LP_Alicequery.feevout)); + jadd64bits(item,"aliceid",LP_aliceid_calc(LP_Alicequery.desttxid,LP_Alicequery.destvout,LP_Alicequery.feetxid,LP_Alicequery.feevout)); jadd(retjson,"pending",item); } else Alice_expiration = 0; return(jprint(retjson,1)); @@ -1469,14 +1800,14 @@ uint64_t basilisk_swap_addarray(cJSON *item,char *refbase,char *refrel) return(ridqid); } -char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) +char *basilisk_swapentries(int32_t fastflag,char *refbase,char *refrel,int32_t limit) { uint64_t ridqids[1024],ridqid; char *liststr,*retstr2; cJSON *retjson,*array,*pending,*swapjson,*item,*retarray; int32_t i,j,n,count = 0; uint32_t requestid,quoteid; if ( limit <= 0 ) limit = 10; memset(ridqids,0,sizeof(ridqids)); retarray = cJSON_CreateArray(); - if ( (liststr= basilisk_swaplist(0,0,0,0)) != 0 ) + if ( (liststr= basilisk_swaplist(fastflag,0,0,0,0)) != 0 ) { //printf("swapentry.(%s)\n",liststr); if ( (retjson= cJSON_Parse(liststr)) != 0 ) @@ -1498,6 +1829,7 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) } } free_json(retjson); + retjson = 0; } free(liststr); } @@ -1516,10 +1848,10 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) for (j=0; j 0 ) - jaddi(retarray,pending); - else free_json(pending); - } else free_json(pending); + jaddi(retarray,jduplicate(pending)); + } } free_json(retjson); } diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 76a4f820d..b2b7da969 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -52,7 +52,7 @@ cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params) //printf("issue.(%s, %s, %s, %s, %s)\n",coin->symbol,coin->serverport,coin->userpass,method,params); if ( coin->electrum != 0 && (strcmp(method,"getblock") == 0 || strcmp(method,"paxprice") == 0 || strcmp(method,"getrawmempool") == 0) ) return(cJSON_Parse("{\"error\":\"illegal electrum call\"}")); - if ( coin->inactive == 0 || strcmp(method,"importprivkey") == 0 || strcmp(method,"validateaddress") == 0 || strcmp(method,"getrawtransaction") == 0 || strcmp(method,"getblock") == 0 || strcmp(method,"getinfo") == 0 ) + if ( coin->inactive == 0 || strcmp(method,"importprivkey") == 0 || strcmp(method,"validateaddress") == 0 || strcmp(method,"getrawtransaction") == 0 || strcmp(method,"getblock") == 0 || strcmp(method,"getinfo") == 0 || strcmp(method,"getblockchaininfo") == 0 ) { if ( coin->electrum == 0 ) { @@ -88,28 +88,44 @@ void LP_unspents_mark(char *symbol,cJSON *vins) int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin) { - cJSON *retjson; char *retstr,*method = "getinfo"; int32_t height; + cJSON *retjson; char *retstr; int32_t height; *notarizedp = 0; if ( coin == 0 ) return(-1); + if ( coin->getinfostr[0] == 0 ) + strcpy(coin->getinfostr,"getinfo"); height = coin->height; if ( coin->electrum == 0 && time(NULL) > coin->heighttime+60 && coin->userpass[0] != 0 ) { - if ( strcmp(coin->symbol,"BTC") == 0 ) - method = "getblockchaininfo"; - retstr = bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,method,"[]"); + retstr = bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,coin->getinfostr,"[]"); if ( retstr != 0 && retstr[0] != 0 ) { - retjson = cJSON_Parse(retstr); - coin->height = height = jint(retjson,"blocks"); - if ( (*notarizedp= jint(retjson,"notarized")) != 0 && *notarizedp != coin->notarized ) + if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - //printf("new notarized %s %d -> %d\n",coin->symbol,coin->notarized,*notarizedp); - coin->notarized = *notarizedp; - coin->notarizationtxid = jbits256(retjson,"notarizedtxid"); - coin->notarizedhash = jbits256(retjson,"notarizedhash"); + if ( jobj(retjson,"error") != 0 && strcmp("getinfo",coin->getinfostr) == 0 ) + { + strcpy(coin->getinfostr,"getblockchaininfo"); + free_json(retjson), retjson = 0; + free(retstr); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,coin->getinfostr,"[]")) != 0 ) + { + retjson = cJSON_Parse(retstr); + printf("getblockchaininfo autoissue.(%s)\n",retstr); + } + } + if ( retjson != 0 ) + { + coin->height = height = jint(retjson,"blocks"); + if ( (*notarizedp= jint(retjson,"notarized")) != 0 && *notarizedp != coin->notarized ) + { + //printf("new notarized %s %d -> %d\n",coin->symbol,coin->notarized,*notarizedp); + coin->notarized = *notarizedp; + coin->notarizationtxid = jbits256(retjson,"notarizedtxid"); + coin->notarizedhash = jbits256(retjson,"notarizedhash"); + } + free_json(retjson); + } } - free_json(retjson); if ( coin->height > 0 ) coin->heighttime = (uint32_t)time(NULL); free(retstr); @@ -134,6 +150,7 @@ uint64_t LP_RTsmartbalance(struct iguana_info *coin) item = jitem(array,i); value = LP_value_extract(item,1); valuesum += value; + //printf("%s -> %.8f\n",jprint(item,0),dstr(value)); } } free_json(array); @@ -163,10 +180,10 @@ cJSON *LP_paxprice(char *fiat) return(bitcoin_json(coin,"paxprice",buf)); } -cJSON *LP_gettx(char *symbol,bits256 txid,int32_t suppress_errors) +cJSON *LP_gettx(char *debug,char *symbol,bits256 txid,int32_t suppress_errors) { struct iguana_info *coin; char buf[512],str[65]; int32_t height; cJSON *retjson; - //printf("LP_gettx %s %s\n",symbol,bits256_str(str,txid)); + //printf("%s LP_gettx %s %s\n",debug,symbol,bits256_str(str,txid)); if ( symbol == 0 || symbol[0] == 0 ) return(cJSON_Parse("{\"error\":\"null symbol\"}")); coin = LP_coinfind(symbol); @@ -193,7 +210,7 @@ cJSON *LP_gettx(char *symbol,bits256 txid,int32_t suppress_errors) uint32_t LP_locktime(char *symbol,bits256 txid) { cJSON *txobj; uint32_t locktime = 0; - if ( (txobj= LP_gettx(symbol,txid,0)) != 0 ) + if ( (txobj= LP_gettx("LP_locktime",symbol,txid,0)) != 0 ) { locktime = juint(txobj,"locktime"); free_json(txobj); @@ -316,7 +333,7 @@ cJSON *LP_validateaddress(char *symbol,char *address) strcat(script,"88ac"); jaddstr(retjson,"scriptPubKey",script); } - bitcoin_address(symbol,coinaddr,coin->taddr,coin->pubtype,G.LP_myrmd160,20); + bitcoin_address(symbol,coinaddr,coin->taddr,coin->pubtype,G.LP_pubsecp,33); jadd(retjson,"ismine",strcmp(coinaddr,coin->smartaddr) == 0 ? cJSON_CreateTrue() : cJSON_CreateFalse()); jadd(retjson,"iswatchonly",cJSON_CreateTrue()); jadd(retjson,"isscript",addrtype == coin->p2shtype ? cJSON_CreateTrue() : cJSON_CreateFalse()); @@ -354,7 +371,7 @@ int32_t LP_address_iswatchonly(char *symbol,char *address) return(0); if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) { - if ( (obj= jobj(retjson,"iswatchonly")) != 0 && is_cJSON_True(obj) != 0 ) + if ( ((obj= jobj(retjson,"iswatchonly")) != 0 || (obj= jobj(retjson,"watchonly")) != 0) && is_cJSON_True(obj) != 0 ) { doneflag = 1; //printf("%s iswatchonly (%s)\n",address,jprint(retjson,0)); @@ -385,7 +402,7 @@ int32_t LP_address_isvalid(char *symbol,char *address) cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxid2) { - char buf[128],*retstr; struct LP_address *ap; cJSON *retjson; int32_t numconfs,usecache=1; struct iguana_info *coin; + char buf[128],*retstr; bits256 txid; struct LP_address *ap; cJSON *retjson,*txjson,*array,*item; int32_t i,n,numconfs,vout,usecache=1; struct iguana_info *coin; if ( symbol == 0 || symbol[0] == 0 ) return(cJSON_Parse("{\"error\":\"null symbol\"}")); coin = LP_coinfind(symbol); @@ -395,15 +412,18 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxi { if ( (ap= LP_addressfind(coin,coinaddr)) != 0 ) { - if ( ap->unspenttime == 0 ) + if ( ap->unspenttime == 0 || strcmp(coin->symbol,"DYN") == 0 ) usecache = 0; - else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+1 ) + else if ( time(NULL) > ap->unspenttime+3 ) usecache = 0; + //printf("%s %s usecache.%d iswatched.%d\n",coin->symbol,coinaddr,usecache,LP_address_iswatchonly(symbol,coinaddr)); if ( usecache != 0 && (retstr= LP_unspents_filestr(symbol,coinaddr)) != 0 ) { retjson = cJSON_Parse(retstr); free(retstr); - return(retjson); + if ( cJSON_GetArraySize(retjson) > 0 ) + return(retjson); + else free_json(retjson); } } //printf("%s %s usecache.%d iswatched.%d\n",coin->symbol,coinaddr,usecache,LP_address_iswatchonly(symbol,coinaddr)); @@ -413,11 +433,28 @@ cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxi numconfs = 0; else numconfs = 1; sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr); -//printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); retjson = bitcoin_json(coin,"listunspent",buf); - retstr = jprint(retjson,0); - LP_unspents_cache(coin->symbol,coinaddr,retstr,1); - free(retstr); +//printf("LP_listunspent.(%s %s) -> %s\n",symbol,coinaddr,jprint(retjson,0)); + if ( (n= cJSON_GetArraySize(retjson)) > 0 ) + { + array = cJSON_CreateArray(); + for (i=0; isymbol,coinaddr,retstr,1); + free(retstr); + } if ( ap != 0 ) ap->unspenttime = (uint32_t)time(NULL); return(retjson); @@ -452,11 +489,45 @@ cJSON *LP_listreceivedbyaddress(char *symbol,char *coinaddr) } } } + free_json(array); } return(cJSON_Parse("[]")); } else return(electrum_address_gethistory(symbol,coin->electrum,&retjson,coinaddr,zero)); } + +cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t count,int32_t skip) +{ + char buf[128],*addr; bits256 zero; cJSON *retjson,*array,*item; int32_t i,n; struct iguana_info *coin; + if ( symbol == 0 || symbol[0] == 0 ) + return(cJSON_Parse("{\"error\":\"null symbol\"}")); + coin = LP_coinfind(symbol); + if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) + return(cJSON_Parse("{\"error\":\"no coin\"}")); + memset(zero.bytes,0,sizeof(zero)); + if ( coin->electrum == 0 ) + { + if ( count == 0 ) + count = 10; + sprintf(buf,"[\"\", %d, %d, true]",count,skip); + retjson = cJSON_CreateArray(); + if ( (array= bitcoin_json(coin,"listtransactions",buf)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ielectrum,&retjson,coinaddr,zero)); +} + int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item) { int64_t satoshis = 0; @@ -523,7 +594,8 @@ int32_t LP_importaddress(char *symbol,char *address) return(-2); coin = LP_coinfind(symbol); if ( coin == 0 ) - return(-2); + return(-3); + //printf("import.(%s %s)\n",symbol,address); if ( coin->electrum != 0 ) { /*if ( (retjson= electrum_address_subscribe(symbol,coin->electrum,&retjson,address)) != 0 ) @@ -537,13 +609,15 @@ int32_t LP_importaddress(char *symbol,char *address) { if ( (validatejson= LP_validateaddress(symbol,address)) != 0 ) { + //printf("validated.(%s)\n",jprint(validatejson,0)); if ( (isvalid= is_cJSON_True(jobj(validatejson,"isvalid")) != 0) != 0 ) { - if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 ) + if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"watchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 ) doneflag = 1; } free_json(validatejson); } + //printf("%s (%s) isvalid.%d doneflag.%d\n",symbol,address,isvalid,doneflag); if ( isvalid == 0 ) return(-1); if ( doneflag != 0 ) @@ -573,13 +647,11 @@ cJSON *LP_importprivkey(char *symbol,char *wifstr,char *label,int32_t flag) ctx = bitcoin_ctx(); bitcoin_wif2addr(ctx,symbol,coin->wiftaddr,coin->taddr,coin->pubtype,address,wifstr); #ifdef LP_DONT_IMPORTPRIVKEY - bitcoin_wif2addr(ctx,symbol,coin->wiftaddr,coin->taddr,coin->pubtype,address,wifstr); if ( LP_importaddress(symbol,address) < 0 ) { printf("%s importaddress %s from %s failed, isvalid.%d\n",symbol,address,wifstr,bitcoin_validaddress(symbol,coin->taddr,coin->pubtype,coin->p2shtype,address)); return(cJSON_Parse("{\"error\":\"couldnt import\"}")); - } - else return(cJSON_Parse("{\"result\":\"success\"}")); + } else return(cJSON_Parse("{\"result\":\"success\"}")); #endif if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) { @@ -600,52 +672,102 @@ cJSON *LP_importprivkey(char *symbol,char *wifstr,char *label,int32_t flag) } else return(cJSON_Parse("{\"result\":\"success\"}")); } +cJSON *LP_bitcoinfees() +{ + char *retstr; cJSON *retjson = 0; + if ( (retstr= issue_curlt("https://bitcoinfees.earn.com/api/v1/fees/recommended",LP_HTTP_TIMEOUT)) != 0 ) + { + retjson = cJSON_Parse(retstr); + free(retstr); + } + return(retjson); +} + double _LP_getestimatedrate(struct iguana_info *coin) { - char buf[512],*retstr=0; int32_t numblocks; cJSON *errjson,*retjson; double rate = 0.00000020; + char buf[512],*retstr=0; int32_t numblocks,err=0; cJSON *errjson,*retjson; double rate = 0.00000005; if ( coin->rate < 0. || time(NULL) > coin->ratetime+30 ) { - numblocks = strcmp(coin->symbol,"BTC") == 0 ? 6 : 2; + if ( coin->estimatefeestr[0] == 0 ) + strcpy(coin->estimatefeestr,"estimatefee"); + numblocks = 3;//strcmp(coin->symbol,"BTC") == 0 ? 6 : 2; +again: if ( coin->electrum == 0 ) { sprintf(buf,"[%d]",numblocks); - retstr = LP_apicall(coin,"estimatefee",buf); + retstr = LP_apicall(coin,coin->estimatefeestr,buf); } else { - if ( (retjson= electrum_estimatefee(coin->symbol,coin->electrum,&retjson,numblocks)) != 0 ) + // {"fastestFee":70,"halfHourFee":70,"hourFee":10} + if ( strcmp(coin->symbol,"BTC") == 0 && (retjson= LP_bitcoinfees()) != 0 ) + { + int32_t fastest,half,hour,best=0; + fastest = jint(retjson,"fastestFee"); + half = jint(retjson,"halfHourFee"); + hour = jint(retjson,"hourFee"); + if ( hour*3 > half ) + best = hour*3; + else best = half; + if ( fastest < best ) + best = fastest; + retstr = calloc(1,16); + sprintf(retstr,"%0.8f",((double)best * 1024)/SATOSHIDEN); + //printf("LP_getestimatedrate (%s) -> %s\n",jprint(retjson,0),retstr); + free(retjson); + } + /*if ( (retjson= electrum_estimatefee(coin->symbol,coin->electrum,&retjson,numblocks)) != 0 ) + { retstr = jprint(retjson,1); + //free_json(retjson), retjson = 0; causes crash? + printf("estfee numblocks.%d (%s)\n",numblocks,retstr); + }*/ } if ( retstr != 0 ) { if ( retstr[0] == '{' && (errjson= cJSON_Parse(retstr)) != 0 ) { if ( jobj(errjson,"error") != 0 ) + { rate = 0.; + err++; + } + if ( strcmp(coin->estimatefeestr,"estimatesmartfee") == 0 && (rate= jdouble(errjson,"feerate")) != 0 ) + { + printf("extracted feerate %.8f from estimatesmartfee\n",rate); + rate /= 1024.; + } free_json(errjson); } else if ( retstr[0] != '-' ) - { rate = atof(retstr) / 1024.; - if ( rate < 0.00000020 ) - rate = 0.00000020; - rate *= 1.5; - if ( coin->electrum != 0 ) - rate *= 1.5; + if ( rate != 0. ) + { + //rate *= 1.25; + if ( rate < 0.00000005 ) + rate = 0.00000005; if ( fabs(rate - coin->rate) > SMALLVAL ) - printf("t%u estimated rate.(%s) (%s) -> %.8f %.8f\n",coin->ratetime,coin->symbol,retstr,rate,coin->rate); + printf("%u t%u estimated rate.(%s) (%s) -> %.8f %.8f\n",(uint32_t)time(NULL),coin->ratetime,coin->symbol,retstr,rate,coin->rate); coin->rate = rate; coin->ratetime = (uint32_t)time(NULL); + //printf("set rate %.8f t%u\n",rate,coin->ratetime); } free(retstr); + if ( err == 1 && coin->electrum == 0 && strcmp(coin->estimatefeestr,"estimatefee") == 0 ) + { + strcpy(coin->estimatefeestr,"estimatesmartfee"); + err = 2; + goto again; + } } else rate = coin->rate; } else rate = coin->rate; + coin->rate = rate; return(rate); } double LP_getestimatedrate(struct iguana_info *coin) { - double rate = 0.00000020; + double rate = 0.00000005; if ( coin == 0 ) return(rate); if ( (rate= _LP_getestimatedrate(coin)) <= 0. ) @@ -735,7 +857,7 @@ char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON * printf("incomplete signing %s (%s)\n",rawtx,jprint(vins,0)); if ( signedtx != 0 ) free(signedtx), signedtx = 0; - } else printf("basilisk_swap_bobtxspend %s -> %s\n",rawtx,bits256_str(str,*signedtxidp)); + } // else printf("basilisk_swap_bobtxspend %s -> %s\n",rawtx,bits256_str(str,*signedtxidp)); if ( signedtx == 0 ) { retjson = cJSON_CreateObject(); @@ -859,9 +981,9 @@ uint32_t LP_heighttime(char *symbol,int32_t height) { if ( (blockhashstr= LP_blockhashstr(symbol,height)) != 0 ) { - if ( (retjson= cJSON_Parse(blockhashstr)) != 0 ) + if ( (retjson= LP_getblockhashstr(symbol,blockhashstr)) != 0 ) { - //printf("height.(%s)\n",jprint(retjson,0)); + //printf("%s -> height.(%s)\n",blockhashstr,jprint(retjson,0)); timestamp = juint(retjson,"time"); free_json(retjson); } @@ -988,7 +1110,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(coin->symbol,txid,0)) != 0 ) + if ( (txobj= LP_gettx("LP_txhasnotarization",coin->symbol,txid,0)) != 0 ) { if ( (vins= jarray(&numvins,txobj,"vin")) != 0 ) { @@ -1000,7 +1122,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(coin->symbol,spenttxid,0)) != 0 ) + if ( (spentobj= LP_gettx("LP_txhasnotarization",coin->symbol,spenttxid,0)) != 0 ) { if ( (vouts= jarray(&numvouts,spentobj,"vout")) != 0 ) { diff --git a/iguana/exchanges/LP_scan.c b/iguana/exchanges/LP_scan.c index fdb3801cd..2e0c4d009 100644 --- a/iguana/exchanges/LP_scan.c +++ b/iguana/exchanges/LP_scan.c @@ -22,6 +22,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 ( (txs= jarray(&numtx,blockobj,"tx")) != 0 ) @@ -52,6 +53,7 @@ int32_t LP_blockinit(struct iguana_info *coin,int32_t height) } free_json(blockobj); } + portable_mutex_unlock(&LP_blockinit_mutex); if ( checkht == height ) return(0); else return(-1); @@ -446,7 +448,7 @@ int32_t LP_mempoolscan(char *symbol,bits256 searchtxid) int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration) { - struct iguana_info *coin; bits256 zero; cJSON *array,*item; uint32_t expiration,i,n; int32_t numconfirms = -1; + struct iguana_info *coin; bits256 zero; cJSON *array,*item; uint32_t expiration,i,n; int32_t num,numconfirms = -1; if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) { printf("LP_waitmempool missing coin.%p or inactive\n",coin); @@ -455,8 +457,8 @@ int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int expiration = (uint32_t)time(NULL) + duration; while ( LP_STOP_RECEIVED == 0 ) { - if ( LP_gettx_presence(symbol,txid) != 0 ) - numconfirms = 0; + if ( LP_gettx_presence(&num,symbol,txid,coinaddr) != 0 ) + numconfirms = num; else { if ( coin->electrum == 0 ) diff --git a/iguana/exchanges/LP_secp.c b/iguana/exchanges/LP_secp.c index 516e2be75..58fd45d85 100644 --- a/iguana/exchanges/LP_secp.c +++ b/iguana/exchanges/LP_secp.c @@ -86,7 +86,7 @@ bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even) int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag) { int32_t fCompressed = 1; - secp256k1_ecdsa_signature SIG; void *funcp; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; uint8_t *entropy; int32_t recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB; + secp256k1_ecdsa_signature SIG,SIGOUT; void *funcp; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; uint8_t *entropy; int32_t recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB; seed = rand256(0); extra_entropy = rand256(0); SECP_ENSURE_CTX @@ -94,12 +94,12 @@ int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 funcp = secp256k1_nonce_function_rfc6979; if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) { - //printf("bitcoin_sign illegal privkey\n"); + printf("bitcoin_sign illegal privkey\n"); return(-1); } if ( strcmp(symbol,"BCH") == 0 || strcmp(symbol,"BTG") == 0 ) { - char str[65]; printf("BCH/BTG deterministic signature %s\n",bits256_str(str,txhash2)); + //char str[65]; printf("BCH/BTG deterministic signature %s\n",bits256_str(str,txhash2)); funcp = 0; entropy = 0; } else entropy = extra_entropy.bytes; @@ -134,7 +134,8 @@ int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 { if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,funcp,entropy) != 0 ) { - if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) != 0 ) + secp256k1_ecdsa_signature_normalize(ctx,&SIGOUT,&SIG); + if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIGOUT) != 0 ) retval = (int32_t)siglen; } } @@ -191,3 +192,20 @@ int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uin } return(retval); } + +int32_t bitcoin_expandcompressed(void *ctx,uint8_t *bigpubkey,uint8_t *pub33) +{ + int32_t retval = -1; secp256k1_pubkey PUB; size_t plen = 65; + SECP_ENSURE_CTX + { + if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pub33,33) != 0 ) + { + secp256k1_ec_pubkey_serialize(ctx,bigpubkey,&plen,&PUB,SECP256K1_EC_UNCOMPRESSED); + retval = 0; + } + ENDSECP_ENSURE_CTX + } + return(retval); +} + + diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c index 00c92a8d8..329172271 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -41,13 +41,19 @@ struct basilisk_request *LP_requestinit(struct basilisk_request *rp,bits256 srch cJSON *LP_quotejson(struct LP_quoteinfo *qp) { - double price; cJSON *retjson = cJSON_CreateObject(); + double price; char etomic[64],activesymbol[65]; cJSON *retjson = cJSON_CreateObject(); if ( jobj(retjson,"gui") == 0 ) jaddstr(retjson,"gui",qp->gui[0] != 0 ? qp->gui : LP_gui); jadd64bits(retjson,"aliceid",qp->aliceid); jaddnum(retjson,"tradeid",qp->tradeid); jaddstr(retjson,"base",qp->srccoin); + if ( LP_etomicsymbol(activesymbol,etomic,qp->srccoin) != 0 ) + jaddstr(retjson,"bobtomic",etomic); + jaddstr(retjson,"etomicsrc",qp->etomicsrc); jaddstr(retjson,"rel",qp->destcoin); + if ( LP_etomicsymbol(activesymbol,etomic,qp->destcoin) != 0 ) + jaddstr(retjson,"alicetomic",etomic); + jaddstr(retjson,"etomicdest",qp->etomicdest); if ( qp->coinaddr[0] != 0 ) jaddstr(retjson,"address",qp->coinaddr); if ( qp->timestamp != 0 ) @@ -104,13 +110,31 @@ cJSON *LP_quotejson(struct LP_quoteinfo *qp) int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson) { - uint32_t rid,qid; + uint32_t rid,qid; char etomic[64],activesymbol[65],*etomicstr; memset(qp,0,sizeof(*qp)); safecopy(qp->gui,LP_gui,sizeof(qp->gui)); safecopy(qp->srccoin,jstr(argjson,"base"),sizeof(qp->srccoin)); + if ( LP_etomicsymbol(activesymbol,etomic,qp->srccoin) != 0 ) + { + if ( (etomicstr= jstr(argjson,"bobtomic")) == 0 || strcmp(etomicstr,etomic) != 0 ) + { + printf("etomic src mismatch (%s) vs (%s)\n",etomicstr!=0?etomicstr:"",etomic); + return(-1); + } + } 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)); + if ( LP_etomicsymbol(activesymbol,etomic,qp->destcoin) != 0 ) + { + if ( (etomicstr= jstr(argjson,"alicetomic")) == 0 || strcmp(etomicstr,etomic) != 0 ) + { + printf("etomic dest mismatch (%s) vs (%s)\n",etomicstr!=0?etomicstr:"",etomic); + return(-1); + } + } safecopy(qp->destaddr,jstr(argjson,"destaddr"),sizeof(qp->destaddr)); + safecopy(qp->etomicdest,jstr(argjson,"etomicdest"),sizeof(qp->etomicdest)); qp->aliceid = j64bits(argjson,"aliceid"); qp->tradeid = juint(argjson,"tradeid"); qp->timestamp = juint(argjson,"timestamp"); @@ -125,9 +149,12 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson) qp->feetxid = jbits256(argjson,"feetxid"); qp->destvout = jint(argjson,"destvout"); qp->desthash = jbits256(argjson,"desthash"); - qp->satoshis = j64bits(argjson,"satoshis"); - qp->destsatoshis = j64bits(argjson,"destsatoshis"); qp->txfee = j64bits(argjson,"txfee"); + if ( (qp->satoshis= j64bits(argjson,"satoshis")) > qp->txfee ) + { + //qp->price = (double)qp->destsatoshis / (qp->satoshis = qp->txfee); + } + qp->destsatoshis = j64bits(argjson,"destsatoshis"); qp->desttxfee = j64bits(argjson,"desttxfee"); qp->R.requestid = juint(argjson,"requestid"); qp->R.quoteid = juint(argjson,"quoteid"); @@ -395,9 +422,8 @@ int32_t LP_price_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,uint8_t *pub char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price) { - struct iguana_info *basecoin,*relcoin,*kmd; struct LP_address *ap; char pubsecpstr[67]; uint32_t numutxos,timestamp; uint64_t price64,balance,minsize,maxsize; bits256 zero; cJSON *reqjson; + struct iguana_info *basecoin,*relcoin,*kmd; struct LP_address *ap; char pubsecpstr[67]; uint32_t numutxos,timestamp; uint64_t price64,median,minsize,maxsize; bits256 zero; cJSON *reqjson; reqjson = cJSON_CreateObject(); - // LP_addsig if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 )//&& basecoin->electrum == 0 )//&& relcoin->electrum == 0 ) { memset(zero.bytes,0,sizeof(zero)); @@ -414,12 +440,12 @@ 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)); - if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,basecoin,basecoin->smartaddr)) != 0 ) + if ( (numutxos= LP_address_minmax(1,&median,&minsize,&maxsize,basecoin,basecoin->smartaddr)) != 0 ) { - //printf("send %s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); + //printf("send %s numutxos.%d median %.8f min %.8f max %.8f\n",base,numutxos,dstr(median),dstr(minsize),dstr(maxsize)); jaddstr(reqjson,"utxocoin",base); jaddnum(reqjson,"n",numutxos); - jaddnum(reqjson,"bal",dstr(balance)); + jaddnum(reqjson,"bal",dstr(median) * numutxos); jaddnum(reqjson,"min",dstr(minsize)); jaddnum(reqjson,"max",dstr(maxsize)); } @@ -431,7 +457,7 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re char *LP_postprice_recv(cJSON *argjson) { - bits256 pubkey; double price; char *base,*rel; + bits256 pubkey; double price; char *base,*rel,*argstr; //printf("PRICE POSTED.(%s)\n",jprint(argjson,0)); if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && (price= jdouble(argjson,"price")) > SMALLVAL ) { @@ -440,13 +466,21 @@ char *LP_postprice_recv(cJSON *argjson) { if ( LP_price_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,base,rel,j64bits(argjson,"price64")) == 0 ) { + if ( IPC_ENDPOINT >= 0 ) + { + if ( (argstr= jprint(argjson,0)) != 0 ) + { + LP_queuecommand(0,argstr,IPC_ENDPOINT,-1,0); + free(argstr); + } + } //printf("call pricefeed update\n"); LP_pricefeedupdate(pubkey,base,rel,price,jstr(argjson,"utxocoin"),jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN,jdouble(argjson,"credits")*SATOSHIDEN); return(clonestr("{\"result\":\"success\"}")); } else { - printf("sig failure\n"); + printf("sig failure.(%s)\n",jprint(argjson,0)); return(clonestr("{\"error\":\"sig failure\"}")); } } @@ -547,7 +581,7 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock) } else printf("no LPipaddr\n"); } jaddnum(reqjson,"session",G.LP_sessionid); - LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); + LP_reserved_msg(1,"","",zero,jprint(reqjson,1)); } char *LP_notify_recv(cJSON *argjson) @@ -561,7 +595,7 @@ char *LP_notify_recv(cJSON *argjson) if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) { //printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"ismine")); - LP_peer_recv(ipaddr,jint(argjson,"ismine")); + LP_peer_recv(ipaddr,jint(argjson,"ismine"),pubp); if ( IAMLP != 0 && G.LP_IAMLP == 0 && strcmp(ipaddr,LP_myipaddr) == 0 ) { if ( bits256_cmp(pub,G.LP_mypub25519) != 0 ) @@ -626,7 +660,7 @@ printf("LP_uitem_recv deprecated\n"); { //char str[65]; printf("uitem %s %s %s/v%d %.8f ht.%d\n",symbol,coinaddr,bits256_str(str,txid),vout,dstr(value),height); if ( strcmp(coin->smartaddr,coinaddr) != 0 ) - LP_address_utxoadd((uint32_t)time(NULL),"LP_uitem_recv",coin,coinaddr,txid,vout,value,height,-1); + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_uitem_recv",coin,coinaddr,txid,vout,value,height,-1); //else printf("ignore external uitem %s %s\n",symbol,coin->smartaddr); } return(clonestr("{\"result\":\"success\"}")); @@ -671,26 +705,13 @@ 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 ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 ) - { - memset(&zero,0,sizeof(zero)); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); - //if ( strcmp(method,"request") == 0 ) - if ( 0 ) - { - sleep(1); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); - sleep(1); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); - } - free(msg); - /*portable_mutex_lock(&LP_reservedmutex); - if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) - Reserved_msgs[1][num_Reserved_msgs[1]++] = msg; - if ( num_Reserved_msgs[0] < sizeof(Reserved_msgs[0])/sizeof(*Reserved_msgs[0])-2 ) - Reserved_msgs[0][num_Reserved_msgs[0]++] = msg2; - portable_mutex_unlock(&LP_reservedmutex);*/ - } //else LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->srchash,msg); + //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)); + free(msg); } diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c index c754e6bc2..54f2b193c 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -303,7 +303,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep else { //printf("external unspent has no gettxout\n"); - flag += LP_address_utxoadd((uint32_t)time(NULL),"electrum process",coin,coinaddr,txid,v,value,0,1); + flag += LP_address_utxoadd(0,(uint32_t)time(NULL),"electrum process",coin,coinaddr,txid,v,value,0,1); } } else @@ -348,7 +348,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep if ( tx->height > 0 ) { //printf("from electrum_process_array\n"); - flag += LP_address_utxoadd((uint32_t)time(NULL),"electrum process2",coin,coinaddr,txid,v,value,tx->height,-1); + flag += LP_address_utxoadd(0,(uint32_t)time(NULL),"electrum process2",coin,coinaddr,txid,v,value,tx->height,-1); } //printf("v.%d numvouts.%d %.8f (%s)\n",v,tx->numvouts,dstr(tx->outpoints[jint(item,"tx_pos")].value),jprint(item,0)); } //else printf("cant find tx\n"); @@ -525,10 +525,26 @@ cJSON *electrum_address_subscribe(char *symbol,struct electrum_info *ep,cJSON ** return(retjson); } +cJSON *electrum_scripthash_cmd(char *symbol,uint8_t taddr,struct electrum_info *ep,cJSON **retjsonp,char *cmd,char *coinaddr) +{ + uint8_t addrtype,rmd160[20]; char btcaddr[64],cmdbuf[128]; //char scripthash[51],rmdstr[41],; + bitcoin_addr2rmd160(symbol,taddr,&addrtype,rmd160,coinaddr); + bitcoin_address("BTC",btcaddr,0,addrtype,rmd160,20); + //init_hexbytes_noT(rmdstr,rmd160,20); + //sprintf(scripthash,"%s",rmdstr); + //sprintf(cmdbuf,"blockchain.scripthash.%s",cmd); + sprintf(cmdbuf,"blockchain.address.%s",cmd); + return(electrum_strarg(symbol,ep,retjsonp,cmdbuf,btcaddr,ELECTRUM_TIMEOUT)); +} + cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid) { char str[65]; struct LP_transaction *tx; cJSON *retjson,*txobj,*item; int32_t i,n,height; bits256 txid; struct iguana_info *coin = LP_coinfind(symbol); - retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_history",addr,ELECTRUM_TIMEOUT); + if ( coin == 0 ) + return(0); + if ( strcmp(symbol,"BCH") == 0 ) + retjson = electrum_scripthash_cmd(symbol,coin->taddr,ep,retjsonp,"get_history",addr); + else retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_history",addr,ELECTRUM_TIMEOUT); //printf("history.(%s)\n",jprint(retjson,0)); if ( retjson != 0 && (n= cJSON_GetArraySize(retjson)) > 0 ) { @@ -551,7 +567,7 @@ cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON * if ( tx->height > 0 && tx->height != height ) printf("update %s height.%d <- %d\n",bits256_str(str,txid),tx->height,height); tx->height = height; - LP_address_utxoadd((uint32_t)time(NULL),"electrum history",coin,addr,txid,0,0,height,-1); + LP_address_utxoadd(0,(uint32_t)time(NULL),"electrum history",coin,addr,txid,0,0,height,-1); } } } @@ -574,7 +590,11 @@ int32_t LP_txheight_check(struct iguana_info *coin,char *coinaddr,bits256 txid) cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid,bits256 reftxid2) { cJSON *retjson; struct iguana_info *coin = LP_coinfind(symbol); - retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_mempool",addr,ELECTRUM_TIMEOUT); + if ( coin == 0 ) + return(0); + if ( strcmp(symbol,"BCH") == 0 ) + retjson = electrum_scripthash_cmd(symbol,coin->taddr,ep,retjsonp,"get_mempool",addr); + else retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_mempool",addr,ELECTRUM_TIMEOUT); //printf("MEMPOOL.(%s)\n",jprint(retjson,0)); electrum_process_array(coin,ep,addr,retjson,1,reftxid,reftxid2); return(retjson); @@ -601,7 +621,10 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON } if ( usecache == 0 || electrumflag > 1 ) { - if ( (retjson= electrum_strarg(symbol,ep,retjsonp,"blockchain.address.listunspent",addr,ELECTRUM_TIMEOUT)) != 0 ) + if ( strcmp(symbol,"BCH") == 0 ) + retjson = electrum_scripthash_cmd(symbol,coin->taddr,ep,retjsonp,"listunspent",addr); + else retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.listunspent",addr,ELECTRUM_TIMEOUT); + if ( retjson != 0 ) { if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) { @@ -616,17 +639,17 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON retstr = jprint(retjson,0); LP_unspents_cache(coin->symbol,addr,retstr,1); free(retstr); - if ( ap != 0 ) - { - ap->unspenttime = (uint32_t)time(NULL); - ap->unspentheight = height; - } } else { free_json(retjson); retjson = 0; } + if ( ap != 0 ) + { + ap->unspenttime = (uint32_t)time(NULL); + ap->unspentheight = height; + } } } if ( retjson == 0 ) @@ -642,7 +665,9 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON cJSON *electrum_address_getbalance(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr) { - return(electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_balance",addr,ELECTRUM_TIMEOUT)); + if ( strcmp(symbol,"BCH") == 0 ) + return(electrum_scripthash_cmd(symbol,0,ep,retjsonp,"get_balance",addr)); + else return(electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_balance",addr,ELECTRUM_TIMEOUT)); } cJSON *electrum_addpeer(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *endpoint) { return(electrum_strarg(symbol,ep,retjsonp,"server.add_peer",endpoint,ELECTRUM_TIMEOUT)); } @@ -750,6 +775,8 @@ cJSON *electrum_transaction(int32_t *heightp,char *symbol,struct electrum_info * { cJSON *retjson,*array; bits256 zero; struct LP_transaction *tx=0; struct iguana_info *coin; coin = LP_coinfind(symbol); + if ( coin == 0 ) + return(0); *heightp = 0; if ( ep != 0 ) portable_mutex_lock(&ep->txmutex); diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index e62279232..be24f44ed 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -2491,7 +2491,7 @@ void basilisk_swaploop(void *_utxo) { uint8_t *data; uint32_t expiration,savestatebits=0,saveotherbits=0; uint32_t channel; int32_t iters,retval=0,j,datalen,maxlen; struct basilisk_swap *swap; struct LP_utxoinfo *utxo = _utxo; swap = utxo->swap; - fprintf(stderr,"start swap iambob.%d\n",swap->I.iambob); + //fprintf(stderr,"start swap iambob.%d\n",swap->I.iambob); maxlen = 1024*1024 + sizeof(*swap); data = malloc(maxlen); expiration = (uint32_t)time(NULL) + 300; diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c index 1bce64fde..21f6868a5 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -110,10 +110,14 @@ void LP_tradecommand_log(cJSON *argjson) } if ( logfp != 0 ) { - jsonstr = jprint(argjson,0); - fprintf(logfp,"%s\n",jsonstr); - free(jsonstr); - fflush(logfp); + if ( (jsonstr= jprint(argjson,0)) != 0 ) + { + if ( IPC_ENDPOINT >= 0 ) + LP_queuecommand(0,jsonstr,IPC_ENDPOINT,-1,0); + fprintf(logfp,"%s\n",jsonstr); + free(jsonstr); + fflush(logfp); + } } } @@ -471,7 +475,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) flag = 1; break; } - if ( counter++ < 10 ) + if ( counter++ < 1 ) printf("error after delayed match\n"); } } @@ -500,7 +504,7 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) satoshis = j64bits(lineobj,"satoshis"); if ( base == 0 || rel == 0 || satoshis == 0 ) { - printf("quoteparse_error.(%s)\n",jprint(lineobj,0)); + //printf("quoteparse_error.(%s)\n",jprint(lineobj,0)); LP_parse_errors++; return(-1); } @@ -674,7 +678,7 @@ char *LP_gettradestatus(uint64_t aliceid,uint32_t requestid,uint32_t quoteid) return(clonestr("{\"result\":\"success\"}")); } } - if ( (swapstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) + if ( (swapstr= basilisk_swapentry(1,requestid,quoteid,0)) != 0 ) { if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) { @@ -727,7 +731,7 @@ int32_t LP_stats_dispiter(cJSON *array,struct LP_swapstats *sp,uint32_t starttim cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel) { static int32_t rval; - cJSON *retjson,*array,*item,*reqjson; struct LP_pubkey_info *pubp,*ptmp; bits256 zero; uint32_t now; struct LP_swapstats *sp,*tmp; int32_t i,n,numtrades[LP_MAXPRICEINFOS]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; + cJSON *retjson,*array,*item; struct LP_pubkey_info *pubp,*ptmp; uint32_t now; struct LP_swapstats *sp,*tmp; int32_t i,n,numtrades[LP_MAXPRICEINFOS]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; if ( rval == 0 ) rval = (LP_rand() % 300) + 60; if ( starttime > endtime ) @@ -754,14 +758,14 @@ cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 else { LP_RTcount++; - if ( now > sp->lasttime+rval ) + /*if ( now > sp->lasttime+rval ) { reqjson = cJSON_CreateObject(); jaddstr(reqjson,"method","gettradestatus"); jadd64bits(reqjson,"aliceid",sp->aliceid); memset(zero.bytes,0,sizeof(zero)); LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); - } + }*/ } } HASH_ITER(hh,LP_swapstats,sp,tmp) diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c index 2c2ad8b90..fd6bffc64 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -34,23 +34,22 @@ e) BEFORE Bob broadcasts deposit, Alice broadcasts BTC denominated fee in cltv so if trade isnt done fee is reclaimed */ -//#define DISABLE_CHECKSIG // unsolved MITM (evil peer) - /* both fees are standard payments: OP_DUP OP_HASH160 FEE_RMD160 OP_EQUALVERIFY OP_CHECKSIG - Alice altpayment: OP_2 OP_2 OP_CHECKMULTISIG Bob deposit: OP_IF - OP_CLTV OP_DROP OP_CHECKSIG + OP_CLTV OP_DROP OP_CHECKSIG OP_ELSE OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF + Alice altpayment: OP_2 OP_2 OP_CHECKMULTISIG + Bob paytx: OP_IF - OP_CLTV OP_DROP OP_CHECKSIG + OP_CLTV OP_DROP OP_CHECKSIG OP_ELSE OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF @@ -63,6 +62,23 @@ pubN and pubM are the corresponding pubkeys for these chosen privkeys Alice timeout event is triggered if INSTANTDEX_LOCKTIME elapses from the start of a FSM instance. Bob timeout event is triggered after INSTANTDEX_LOCKTIME*2 + + Based on https://gist.github.com/markblundeberg/7a932c98179de2190049f5823907c016 and to enable bob to spend alicepayment when alice does a claim for bob deposit, the scripts are changed to the following: + + Bob deposit: + OP_IF + OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF + + Bob paytx: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF + */ /* @@ -91,7 +107,7 @@ depositspent.(f34e04ad74e290f63f3d0bccb7d0d50abfa54eea58de38816fdc596a19767add) alice.1 bob.0 */ - +#define TX_WAIT_TIMEOUT 1800 uint32_t LP_atomic_locktime(char *base,char *rel) { @@ -192,7 +208,7 @@ int32_t LP_pubkeys_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) data[datalen++] = swap->persistent_pubkey33[i]; for (i=0; ideck)/sizeof(swap->deck[0][0]); i++) datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->deck[i>>1][i&1]),&swap->deck[i>>1][i&1]); - printf("send >>>>>>>>> r.%u q.%u datalen.%d\n",swap->I.req.requestid,swap->I.req.quoteid,datalen); + //printf("send >>>>>>>>> r.%u q.%u datalen.%d\n",swap->I.req.requestid,swap->I.req.quoteid,datalen); return(datalen); } @@ -253,7 +269,7 @@ int32_t LP_pubkeys_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datal int32_t LP_choosei_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { - int32_t i,datalen; char str[65]; + int32_t i,datalen; //char str[65]; datalen = iguana_rwnum(1,data,sizeof(swap->I.choosei),&swap->I.choosei); if ( swap->I.iambob != 0 ) { @@ -261,7 +277,7 @@ int32_t LP_choosei_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) data[datalen++] = swap->I.pubB0.bytes[i]; for (i=0; i<32; i++) data[datalen++] = swap->I.pubB1.bytes[i]; - printf("SEND pubB0/1 %s\n",bits256_str(str,swap->I.pubB0)); + //printf("SEND pubB0/1 %s\n",bits256_str(str,swap->I.pubB0)); } else { @@ -269,7 +285,7 @@ int32_t LP_choosei_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) data[datalen++] = swap->I.pubA0.bytes[i]; for (i=0; i<32; i++) data[datalen++] = swap->I.pubA1.bytes[i]; - printf("SEND pubA0/1 %s\n",bits256_str(str,swap->I.pubA0)); + //printf("SEND pubA0/1 %s\n",bits256_str(str,swap->I.pubA0)); } return(datalen); } @@ -473,13 +489,14 @@ int32_t LP_waitfor(int32_t pairsock,struct basilisk_swap *swap,int32_t timeout,i { //printf("wait for got.%d\n",datalen); retval = (*verify)(swap,data,datalen); + swap->received = (uint32_t)time(NULL); nn_freemsg(data); //printf("retval.%d\n",retval); return(retval); } // else printf("error nn_recv\n"); } } - printf("waitfor timedout\n"); + printf("waitfor timedout aliceid.%llu requestid.%u quoteid.%u\n",(long long)swap->aliceid,swap->I.req.requestid,swap->I.req.quoteid); return(retval); } @@ -537,9 +554,10 @@ int32_t LP_sendwait(char *statename,int32_t timeout,int32_t pairsock,struct basi return(retval); } -void LP_swapsfp_update(struct basilisk_request *rp) +void LP_swapsfp_update(uint32_t requestid,uint32_t quoteid) { static FILE *swapsfp; + portable_mutex_lock(&LP_listmutex); if ( swapsfp == 0 ) { char fname[512]; @@ -551,10 +569,11 @@ void LP_swapsfp_update(struct basilisk_request *rp) } if ( swapsfp != 0 ) { - fwrite(&rp->requestid,1,sizeof(rp->requestid),swapsfp); - fwrite(&rp->quoteid,1,sizeof(rp->quoteid),swapsfp); + fwrite(&requestid,1,sizeof(requestid),swapsfp); + fwrite("eid,1,sizeof(quoteid),swapsfp); fflush(swapsfp); } + portable_mutex_unlock(&LP_listmutex); } struct basilisk_rawtx *LP_swapdata_rawtx(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx) @@ -570,7 +589,9 @@ struct basilisk_rawtx *LP_swapdata_rawtx(struct basilisk_swap *swap,uint8_t *dat int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys) { - bits256 otherhash,myhash,txid; int64_t txfee,val; int32_t i,offset=0,datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr,redeemaddr[64],checkaddr[64]; uint32_t quoteid,msgbits; struct iguana_info *coin; + bits256 otherhash,myhash,txid; int64_t txfee,val; int32_t i,offset=0,datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr,bobstr[65],alicestr[65],redeemaddr[64],checkaddr[64]; uint32_t quoteid,msgbits; struct iguana_info *coin; + LP_etomicsymbol(bobstr,swap->I.bobtomic,swap->I.bobstr); + LP_etomicsymbol(alicestr,swap->I.alicetomic,swap->I.alicestr); if ( (coin= LP_coinfind(rawtx->symbol)) == 0 ) { printf("LP_rawtx_spendscript couldnt find coin.(%s)\n",rawtx->symbol); @@ -580,6 +601,7 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba otherhash.bytes[i] = recvbuf[offset++]; for (i=0; i<32; i++) myhash.bytes[i] = recvbuf[offset++]; + offset += iguana_rwnum(0,&recvbuf[offset],sizeof(quoteid),"eid); offset += iguana_rwnum(0,&recvbuf[offset],sizeof(msgbits),&msgbits); datalen = recvbuf[offset++]; @@ -590,6 +612,11 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba return(-1); } rawtx->I.redeemlen = recvbuf[offset++]; +#ifndef NOTETOMIC + uint8arrayToHex(rawtx->I.ethTxid, &recvbuf[offset], 32); + printf("ETH txid received: %s\n", rawtx->I.ethTxid); +#endif + offset += 32; data = &recvbuf[offset]; if ( rawtx->I.redeemlen > 0 && rawtx->I.redeemlen < 0x100 ) { @@ -622,10 +649,12 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba printf("%s rawtx data compare error, len %d vs %d <<<<<<<<<< warning\n",rawtx->name,rawtx->I.datalen,datalen); return(-1); } - if ( recvlen != datalen+rawtx->I.redeemlen+75 ) + + + if ( recvlen != datalen+rawtx->I.redeemlen + 107 ) printf("RECVLEN %d != %d + %d\n",recvlen,datalen,rawtx->I.redeemlen); txid = bits256_calctxid(coin->symbol,data,datalen); - char str[65]; printf("rawtx.%s txid %s\n",rawtx->name,bits256_str(str,txid)); + //char str[65]; printf("rawtx.%s txid %s\n",rawtx->name,bits256_str(str,txid)); if ( bits256_cmp(txid,rawtx->I.actualtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) rawtx->I.actualtxid = txid; if ( (txobj= bitcoin_data2json(coin->symbol,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,height,&rawtx->I.signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),data,datalen,0,suppress_pubkeys,coin->zcash)) != 0 ) @@ -639,9 +668,9 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba txfee = LP_MIN_TXFEE; else { - if ( strcmp(coin->symbol,swap->I.bobstr) == 0 ) + if ( strcmp(coin->symbol,bobstr) == 0 ) txfee = swap->I.Btxfee; - else if ( strcmp(coin->symbol,swap->I.alicestr) == 0 ) + else if ( strcmp(coin->symbol,alicestr) == 0 ) txfee = swap->I.Atxfee; else txfee = LP_MIN_TXFEE; } @@ -659,9 +688,8 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba retval = 0; if ( rawtx == &swap->otherfee ) { - char str[65]; LP_swap_coinaddr(coin,rawtx->p2shaddr,0,data,datalen,0); - printf("got %s txid.%s (%s) -> %s\n",rawtx->name,bits256_str(str,rawtx->I.signedtxid),jprint(txobj,0),rawtx->p2shaddr); + //printf("got %s txid.%s (%s) -> %s\n",rawtx->name,bits256_str(str,rawtx->I.signedtxid),jprint(txobj,0),rawtx->p2shaddr); } else bitcoin_address(coin->symbol,rawtx->p2shaddr,coin->taddr,coin->p2shtype,rawtx->spendscript,hexlen); } } else printf("%s satoshis %.8f ERROR.(%s) txfees.[%.8f %.8f: %.8f] amount.%.8f -> %.8f\n",rawtx->name,dstr(j64bits(vout,"satoshis")),jprint(txobj,0),dstr(swap->I.Atxfee),dstr(swap->I.Btxfee),dstr(txfee),dstr(rawtx->I.amount),dstr(rawtx->I.amount)-dstr(txfee)); @@ -689,10 +717,36 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3 } if ( bits256_nonz(rawtx->I.actualtxid) != 0 && msgbits != 0 ) { +#ifndef NOTETOMIC + if ( swap->I.bobtomic[0] != 0 || swap->I.alicetomic[0] != 0 ) + { + char *ethTxId = sendEthTx(swap, rawtx); + if (ethTxId != NULL) { + strcpy(rawtx->I.ethTxid, ethTxId); + free(ethTxId); + } else { + printf("Error sending ETH tx\n"); + return(-1); + } + } +#endif sendlen = 0; sendbuf[sendlen++] = rawtx->I.datalen & 0xff; sendbuf[sendlen++] = (rawtx->I.datalen >> 8) & 0xff; sendbuf[sendlen++] = rawtx->I.redeemlen; + if ( rawtx->I.ethTxid[0] != 0 && strlen(rawtx->I.ethTxid) == 66 ) + { + uint8_t ethTxidBytes[32]; + // ETH txid always starts with 0x + decode_hex(ethTxidBytes, 32, rawtx->I.ethTxid + 2); + memcpy(&sendbuf[sendlen], ethTxidBytes, 32); + } + else + { + // fill with zero bytes to always have fixed message size + memset(&sendbuf[sendlen], 0, 32); + } + sendlen += 32; //int32_t z; for (z=0; zI.datalen; z++) printf("%02x",rawtx->txbytes[z]); printf(" >>>>>>> send.%d %s\n",rawtx->I.datalen,rawtx->name); //printf("datalen.%d redeemlen.%d\n",rawtx->I.datalen,rawtx->I.redeemlen); memcpy(&sendbuf[sendlen],rawtx->txbytes,rawtx->I.datalen), sendlen += rawtx->I.datalen; @@ -701,6 +755,7 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3 memcpy(&sendbuf[sendlen],rawtx->redeemscript,rawtx->I.redeemlen); sendlen += rawtx->I.redeemlen; } + basilisk_dontforget_update(swap,rawtx); //printf("sendlen.%d datalen.%d redeemlen.%d\n",sendlen,rawtx->datalen,rawtx->redeemlen); if ( suppress_swapsend == 0 ) @@ -726,99 +781,125 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3 return(0); } -int32_t LP_swapwait(struct basilisk_swap *swap,uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t sleeptime) +uint32_t LP_swapwait(uint32_t expiration,uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t sleeptime) { - char *retstr; cJSON *retjson=0; uint32_t expiration = (uint32_t)(time(NULL) + duration); - printf("wait %d:%d for SWAP.(r%u/q%u) to complete\n",duration,sleeptime,requestid,quoteid); - sleep(sleeptime/3); - //if ( sleeptime < divisor*60 ) - // sleeptime = divisor * 60; - while ( time(NULL) < expiration ) + char *retstr; uint32_t finished = 0; cJSON *retjson=0; + if ( sleeptime != 0 ) + { + printf("wait %d:%d for SWAP.(r%u/q%u) to complete\n",duration,sleeptime,requestid,quoteid); + sleep(sleeptime/3); + } + while ( expiration == 0 || time(NULL) < expiration ) { - if ( (retstr= basilisk_swapentry(requestid,quoteid,1)) != 0 ) + if ( (retstr= basilisk_swapentry(0,requestid,quoteid,1)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( jstr(retjson,"status") != 0 && strcmp(jstr(retjson,"status"),"finished") == 0 ) { - swap->I.finished = (uint32_t)time(NULL); + finished = (uint32_t)time(NULL); + free(retstr), retstr = 0; break; } - //else printf("NOT FINISHED.(%s)\n",jprint(retjson,0)); - free_json(retjson); - retjson = 0; + else if ( expiration != 0 && time(NULL) > expiration ) + printf("NOT FINISHED.(%s)\n",jprint(retjson,0)); + free_json(retjson), retjson = 0; } free(retstr); } - sleep(sleeptime); - //sleep(sleeptime/divisor); - //if ( divisor > 1 ) - // divisor--; + if ( sleeptime != 0 ) + sleep(sleeptime); + if ( duration < 0 ) + break; } if ( retjson != 0 ) { - printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>\nSWAP completed! %u-%u %s\n",requestid,quoteid,jprint(retjson,0)); free_json(retjson); - if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid,1)) != 0 ) + if ( (retstr= basilisk_swapentry(0,requestid,quoteid,1)) != 0 ) { - printf("second call.(%s)\n",retstr); + printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>\nSWAP completed! %u-%u %s\n",requestid,quoteid,retstr); free(retstr); } + return(finished); + } + else + { + if ( expiration != 0 && time(NULL) > expiration ) + printf("\nSWAP did not complete! %u-%u %s\n",requestid,quoteid,jprint(retjson,0)); + if ( duration > 0 ) + LP_pendswap_add(expiration,requestid,quoteid); return(0); - } else return(-1); + } } void LP_bobloop(void *_swap) { - uint8_t *data; int32_t maxlen,m,n; uint32_t expiration; struct basilisk_swap *swap = _swap; + uint8_t *data; char bobstr[65],alicestr[65]; int32_t maxlen,m,n,err=0; uint32_t expiration; struct basilisk_swap *swap = _swap; G.LP_pendingswaps++; - printf("start swap iambob\n"); + //printf("start swap iambob\n"); + LP_etomicsymbol(bobstr,swap->I.bobtomic,swap->I.bobstr); + LP_etomicsymbol(alicestr,swap->I.alicetomic,swap->I.alicestr); maxlen = 1024*1024 + sizeof(*swap); data = malloc(maxlen); expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; if ( swap != 0 ) { if ( LP_waitsend("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) - printf("error waitsend pubkeys\n"); + err = -2000, printf("error waitsend pubkeys\n"); else if ( LP_waitsend("choosei",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 ) - printf("error waitsend choosei\n"); + err = -2001, printf("error waitsend choosei\n"); else if ( LP_waitsend("mostprivs",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 ) - printf("error waitsend mostprivs\n"); + err = -2002, printf("error waitsend mostprivs\n"); else if ( basilisk_bobscripts_set(swap,1,1) < 0 ) - printf("error bobscripts deposit\n"); + 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); //printf("depositlen.%d\n",swap->bobdeposit.I.datalen); - LP_swapsfp_update(&swap->I.req); + //LP_swapsfp_update(&swap->I.req); LP_swap_critical = (uint32_t)time(NULL); - if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*10,LP_verify_otherfee) < 0 ) - printf("error waiting for alicefee\n"); - else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0) == 0 ) - printf("error sending bobdeposit\n"); - else if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_alicepayment) < 0 ) - printf("error waiting for alicepayment\n"); - else + LP_unavailableset(swap->bobdeposit.utxotxid,swap->bobdeposit.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash); + if ( LP_waitfor(swap->N.pair,swap,TX_WAIT_TIMEOUT,LP_verify_otherfee) < 0 ) + { + error = 1; + err = -2004, printf("error waiting for alicefee\n"); + } + if ( error == 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,TX_WAIT_TIMEOUT,LP_verify_alicepayment) < 0 ) + { + error = 1; + err = -2006, printf("error waiting for alicepayment\n"); + } + if (error == 0) { LP_swap_critical = (uint32_t)time(NULL); if ( basilisk_bobscripts_set(swap,0,1) < 0 ) - printf("error bobscripts payment\n"); + err = -2007, printf("error bobscripts payment\n"); else { - /*if ( strcmp(swap->I.alicestr,"BTC") == 0 ) - m = 0; - else*/ m = swap->I.aliceconfirms; - while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) // sync with alice + m = swap->I.aliceconfirms; + 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); LP_swap_critical = (uint32_t)time(NULL); - char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); + char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); sleep(10); } LP_swap_critical = (uint32_t)time(NULL); - if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 ) - printf("error sending bobpayment\n"); + if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 ) { + err = -2008, printf("error sending bobpayment\n"); + } //if ( LP_waitfor(swap->N.pair,swap,10,LP_verify_alicespend) < 0 ) // printf("error waiting for alicespend\n"); //swap->sentflag = 1; @@ -827,22 +908,28 @@ void LP_bobloop(void *_swap) basilisk_bobpayment_reclaim(swap,swap->I.callduration); if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; - LP_swap_endcritical = (uint32_t)time(NULL); - LP_swapwait(swap,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30); } } } } else printf("swap timed out\n"); - G.LP_pendingswaps--; + LP_swap_endcritical = (uint32_t)time(NULL); + if ( err < 0 ) + LP_failedmsg(swap->I.req.requestid,swap->I.req.quoteid,err); + 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); free(swap); free(data); + G.LP_pendingswaps--; } void LP_aliceloop(void *_swap) { - uint8_t *data; int32_t maxlen,n,m; uint32_t expiration; struct basilisk_swap *swap = _swap; + uint8_t *data; char bobstr[65],alicestr[65]; int32_t maxlen,n,m,err=0; uint32_t expiration; struct basilisk_swap *swap = _swap; G.LP_pendingswaps++; + LP_etomicsymbol(bobstr,swap->I.bobtomic,swap->I.bobstr); + LP_etomicsymbol(alicestr,swap->I.alicetomic,swap->I.alicestr); maxlen = 1024*1024 + sizeof(*swap); data = malloc(maxlen); expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; @@ -850,76 +937,70 @@ void LP_aliceloop(void *_swap) { 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 ) - printf("error LP_sendwait pubkeys\n"); + err = -1000, printf("error LP_sendwait pubkeys\n"); else if ( LP_sendwait("choosei",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 ) - printf("error LP_sendwait choosei\n"); + err = -1001, printf("error LP_sendwait choosei\n"); else if ( LP_sendwait("mostprivs",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 ) - printf("error LP_sendwait mostprivs\n"); + err = -1002, printf("error LP_sendwait mostprivs\n"); else if ( basilisk_alicetxs(swap->N.pair,swap,data,maxlen) != 0 ) - printf("basilisk_alicetxs error\n"); + err = -1003, printf("basilisk_alicetxs error\n"); else { - LP_swapsfp_update(&swap->I.req); + //LP_swapsfp_update(&swap->I.req); LP_swap_critical = (uint32_t)time(NULL); if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x80,data,maxlen,&swap->myfee,0x40,0) == 0 ) - printf("error sending alicefee\n"); - else if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobdeposit) < 0 ) - printf("error waiting for bobdeposit\n"); + err = -1004, printf("error sending alicefee\n"); + else if ( LP_waitfor(swap->N.pair,swap,TX_WAIT_TIMEOUT,LP_verify_bobdeposit) < 0 ) + err = -1005, printf("error waiting for bobdeposit\n"); else { - /*if ( strcmp(swap->I.bobstr,"BTC") == 0 ) - m = 0; - else*/ m = swap->I.bobconfirms; - while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,1)) < m ) + m = swap->I.bobconfirms; + LP_unavailableset(swap->alicepayment.utxotxid,swap->alicepayment.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash); + while ( (n= LP_numconfirms(bobstr,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,1)) < m ) { LP_swap_critical = (uint32_t)time(NULL); - char str[65];printf("%d wait for bobdeposit %s numconfs.%d %s %s\n",n,swap->bobdeposit.I.destaddr,m,swap->I.bobstr,bits256_str(str,swap->bobdeposit.I.signedtxid)); + 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); } if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0) == 0 ) - printf("error sending alicepayment\n"); + err = -1006, printf("error sending alicepayment\n"); else { - /*if ( strcmp(swap->I.alicestr,"BTC") == 0 ) - m = 0; - else*/ m = swap->I.aliceconfirms; - while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) + m = swap->I.aliceconfirms; + while ( (n= LP_numconfirms(alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) { LP_swap_critical = (uint32_t)time(NULL); - char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); + char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); sleep(10); } //swap->sentflag = 1; LP_swap_critical = (uint32_t)time(NULL); - if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobpayment) < 0 ) - printf("error waiting for bobpayment\n"); + if ( LP_waitfor(swap->N.pair,swap,TX_WAIT_TIMEOUT,LP_verify_bobpayment) < 0 ) + err = -1007, printf("error waiting for bobpayment\n"); else { LP_swap_endcritical = (uint32_t)time(NULL); - while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms ) + while ( (n= LP_numconfirms(bobstr,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms ) { - char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->I.bobstr,bits256_str(str,swap->bobpayment.I.signedtxid)); + 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); } - /*if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x20000,data,maxlen,&swap->alicespend,0x40000,0) == 0 ) - printf("error sending alicespend\n"); - while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicespend.I.destaddr,swap->alicespend.I.signedtxid,0,1)) < swap->I.aliceconfirms ) - { - char str[65];printf("%d wait for alicespend %s numconfs.%d %s %s\n",n,swap->alicespend.I.destaddr,swap->I.aliceconfirms,swap->I.bobstr,bits256_str(str,swap->alicespend.I.signedtxid)); - sleep(LP_SWAPSTEP_TIMEOUT); - }*/ if ( swap->N.pair >= 0 ) nn_close(swap->N.pair), swap->N.pair = -1; - LP_swap_endcritical = (uint32_t)time(NULL); - LP_swapwait(swap,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30); } } } } } - free(data); + LP_swap_endcritical = (uint32_t)time(NULL); + if ( err < 0 ) + LP_failedmsg(swap->I.req.requestid,swap->I.req.quoteid,err); + 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); free(swap); + free(data); G.LP_pendingswaps--; } @@ -933,15 +1014,7 @@ bits256 instantdex_derivekeypair(void *ctx,bits256 *newprivp,uint8_t pubkey[33], bits256 basilisk_revealkey(bits256 privkey,bits256 pubkey) { - bits256 reveal; -#ifdef DISABLE_CHECKSIG - vcalc_sha256(0,reveal.bytes,privkey.bytes,sizeof(privkey)); - //reveal = revcalc_sha256(privkey); - char str[65],str2[65]; printf("priv.(%s) -> reveal.(%s)\n",bits256_str(str,privkey),bits256_str(str2,reveal)); -#else - reveal = pubkey; -#endif - return(reveal); + return(pubkey); } int32_t instantdex_pubkeyargs(struct basilisk_swap *swap,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte) @@ -996,8 +1069,8 @@ int32_t instantdex_pubkeyargs(struct basilisk_swap *swap,int32_t numpubs,bits256 } n++; } - if ( n > 2 || m > 2 ) - printf("n.%d m.%d len.%d numpubs.%d\n",n,m,len,swap->I.numpubs); + //if ( n > 2 || m > 2 ) + // printf("n.%d m.%d len.%d numpubs.%d\n",n,m,len,swap->I.numpubs); return(n); } @@ -1007,7 +1080,7 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx * numconfirms = 0; #endif strcpy(rawtx->name,name); - printf("set coin.%s %s -> %s\n",coin->symbol,coin->smartaddr,name); + //printf("set coin.%s %s -> %s\n",coin->symbol,coin->smartaddr,name); strcpy(rawtx->symbol,coin->symbol); rawtx->I.numconfirms = numconfirms; if ( (rawtx->I.amount= satoshis) < LP_MIN_TXFEE ) @@ -1030,39 +1103,51 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx * if ( rawtx->I.vouttype <= 1 && rawtx->I.destaddr[0] != 0 ) { rawtx->I.spendlen = bitcoin_standardspend(rawtx->spendscript,0,rawtx->I.rmd160); - printf("%s spendlen.%d %s <- %.8f\n",name,rawtx->I.spendlen,rawtx->I.destaddr,dstr(rawtx->I.amount)); - } else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->I.vouttype,rawtx->I.destaddr); + //printf("%s spendlen.%d %s <- %.8f\n",name,rawtx->I.spendlen,rawtx->I.destaddr,dstr(rawtx->I.amount)); + } //else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->I.vouttype,rawtx->I.destaddr); } struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 pubkey25519,struct basilisk_swap *swap,int32_t optionduration,uint32_t statebits,struct LP_quoteinfo *qp,int32_t dynamictrust) { //FILE *fp; char fname[512]; - uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag=-2,x = -1; struct iguana_info *bobcoin,*alicecoin; + uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag=-2,x = -1; struct iguana_info *bobcoin,*alicecoin; char bobstr[65],alicestr[65]; + strcpy(swap->I.etomicsrc,qp->etomicsrc); + strcpy(swap->I.etomicdest,qp->etomicdest); strcpy(swap->I.bobstr,swap->I.req.src); strcpy(swap->I.alicestr,swap->I.req.dest); - if ( (alicecoin= LP_coinfind(swap->I.alicestr)) == 0 ) + LP_etomicsymbol(bobstr,swap->I.bobtomic,swap->I.bobstr); + LP_etomicsymbol(alicestr,swap->I.alicetomic,swap->I.alicestr); + if ( (alicecoin= LP_coinfind(alicestr)) == 0 ) { - printf("missing alicecoin src.%p dest.%p\n",LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); + printf("missing alicecoin src.%p dest.%p\n",LP_coinfind(alicestr),LP_coinfind(bobstr)); free(swap); return(0); } - if ( (bobcoin= LP_coinfind(swap->I.bobstr)) == 0 ) + if ( (bobcoin= LP_coinfind(bobstr)) == 0 ) { printf("missing bobcoin src.%p dest.%p\n",LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); free(swap); return(0); } + if ( alicecoin == 0 || bobcoin == 0 ) + { + printf("couldnt find ETOMIC\n"); + free(swap); + return(0); + } if ( (swap->I.Atxfee= qp->desttxfee) < 0 ) { printf("bitcoin_swapinit %s Atxfee %.8f rejected\n",swap->I.req.dest,dstr(swap->I.Atxfee)); + free(swap); return(0); } if ( (swap->I.Btxfee= qp->txfee) < 0 ) { printf("bitcoin_swapinit %s Btxfee %.8f rejected\n",swap->I.req.src,dstr(swap->I.Btxfee)); + free(swap); return(0); } - swap->I.putduration = swap->I.callduration = LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr); + swap->I.putduration = swap->I.callduration = LP_atomic_locktime(bobstr,alicestr); if ( optionduration < 0 ) swap->I.putduration -= optionduration; else if ( optionduration > 0 ) @@ -1070,11 +1155,13 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 if ( (swap->I.bobsatoshis= swap->I.req.srcamount) <= 0 ) { printf("bitcoin_swapinit %s bobsatoshis %.8f rejected\n",swap->I.req.src,dstr(swap->I.bobsatoshis)); + free(swap); return(0); } if ( (swap->I.alicesatoshis= swap->I.req.destamount) <= 0 ) { printf("bitcoin_swapinit %s alicesatoshis %.8f rejected\n",swap->I.req.dest,dstr(swap->I.alicesatoshis)); + free(swap); return(0); } if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE ) @@ -1110,14 +1197,15 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 if ( bits256_nonz(privkey) == 0 || (x= instantdex_pubkeyargs(swap,2 + INSTANTDEX_DECKSIZE,privkey,swap->I.orderhash,0x02+swap->I.iambob)) != 2 + INSTANTDEX_DECKSIZE ) { char str[65]; printf("couldnt generate privkeys %d %s\n",x,bits256_str(str,privkey)); + free(swap); return(0); } - if ( strcmp("BTC",swap->I.bobstr) == 0 ) + if ( strcmp("BTC",bobstr) == 0 ) { swap->I.bobconfirms = 1;//(1 + sqrt(dstr(swap->I.bobsatoshis) * .1)); swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS; } - else if ( strcmp("BTC",swap->I.alicestr) == 0 ) + else if ( strcmp("BTC",alicestr) == 0 ) { swap->I.aliceconfirms = 1;//(1 + sqrt(dstr(swap->I.alicesatoshis) * .1)); swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS; @@ -1127,10 +1215,6 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS; swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS; } - if ( bobcoin->isassetchain != 0 ) - swap->I.bobconfirms = 1; - if ( alicecoin->isassetchain != 0 ) - swap->I.aliceconfirms = 1; if ( bobcoin->userconfirms > 0 ) swap->I.bobconfirms = bobcoin->userconfirms; if ( alicecoin->userconfirms > 0 ) @@ -1143,9 +1227,28 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 swap->I.bobconfirms = swap->I.bobmaxconfirms; if ( swap->I.aliceconfirms > swap->I.alicemaxconfirms ) swap->I.aliceconfirms = swap->I.alicemaxconfirms; - swap->I.bobconfirms *= !swap->I.bobistrusted; - swap->I.aliceconfirms *= !swap->I.aliceistrusted; + if ( bobcoin->isassetchain != 0 ) { + if (strcmp(bobstr, "ETOMIC") != 0) { + swap->I.bobconfirms = BASILISK_DEFAULT_MAXCONFIRMS / 2; + } else { + swap->I.bobconfirms = 1; + } + } + if ( alicecoin->isassetchain != 0 ) { + if (strcmp(alicestr, "ETOMIC") != 0) { + swap->I.aliceconfirms = BASILISK_DEFAULT_MAXCONFIRMS / 2; + } else { + swap->I.aliceconfirms = 1; + } + } + if ( strcmp("BAY",swap->I.req.src) != 0 && strcmp("BAY",swap->I.req.dest) != 0 ) + { + swap->I.bobconfirms *= !swap->I.bobistrusted; + swap->I.aliceconfirms *= !swap->I.aliceistrusted; + } printf(">>>>>>>>>> jumblrflag.%d <<<<<<<<< r.%u q.%u, %.8f bobconfs.%d, %.8f aliceconfs.%d taddr.%d %d\n",jumblrflag,swap->I.req.requestid,swap->I.req.quoteid,dstr(swap->I.bobsatoshis),swap->I.bobconfirms,dstr(swap->I.alicesatoshis),swap->I.aliceconfirms,bobcoin->taddr,alicecoin->taddr); + if ( swap->I.etomicsrc[0] != 0 || swap->I.etomicdest[0] != 0 ) + printf("etomic src (%s %s) dest (%s %s)\n",swap->I.bobtomic,swap->I.etomicsrc,swap->I.alicetomic,swap->I.etomicdest); if ( swap->I.iambob != 0 ) { basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*bobcoin->txfee,0,0,jumblrflag); @@ -1181,9 +1284,9 @@ 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; - LP_mark_spent(swap->I.bobstr,qp->txid,qp->vout); - LP_mark_spent(swap->I.bobstr,qp->txid2,qp->vout2); - LP_mark_spent(swap->I.alicestr,qp->desttxid,qp->destvout); + LP_mark_spent(bobstr,qp->txid,qp->vout); + LP_mark_spent(bobstr,qp->txid2,qp->vout2); + LP_mark_spent(alicestr,qp->desttxid,qp->destvout); if ( swap->I.iambob != 0 ) swap->otherfee.utxotxid = qp->feetxid, swap->otherfee.utxovout = qp->feevout; else @@ -1191,23 +1294,26 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 swap->myfee.utxotxid = qp->feetxid, swap->myfee.utxovout = qp->feevout; LP_mark_spent(swap->I.alicestr,qp->feetxid,qp->feevout); } - char str[65],str2[65],str3[65]; printf("IAMBOB.%d %s %s %s [%s %s]\n",swap->I.iambob,bits256_str(str,qp->txid),bits256_str(str2,qp->txid2),bits256_str(str3,qp->feetxid),swap->I.bobstr,swap->I.alicestr); + //char str[65],str2[65],str3[65]; printf("IAMBOB.%d %s %s %s [%s %s]\n",swap->I.iambob,bits256_str(str,qp->txid),bits256_str(str2,qp->txid2),bits256_str(str3,qp->feetxid),bobstr,alicestr); return(swap); } struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp,int32_t dynamictrust) { + static void *ctx; struct basilisk_swap *swap; bits256 pubkey25519; uint8_t pubkey33[33]; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); swap = calloc(1,sizeof(*swap)); swap->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); swap->I.req.quoteid = rp->quoteid; - swap->ctx = bitcoin_ctx(); + swap->ctx = ctx; vcalc_sha256(0,swap->I.orderhash.bytes,(uint8_t *)rp,sizeof(*rp)); swap->I.req = *rp; G.LP_skipstatus[G.LP_numskips] = ((uint64_t)rp->requestid << 32) | rp->quoteid; if ( G.LP_numskips < sizeof(G.LP_skipstatus)/sizeof(*G.LP_skipstatus) ) G.LP_numskips++; - printf("LP_swapinit request.%u iambob.%d (%s/%s) quoteid.%u\n",rp->requestid,iambob,rp->src,rp->dest,rp->quoteid); + //printf("LP_swapinit request.%u iambob.%d (%s/%s) quoteid.%u\n",rp->requestid,iambob,rp->src,rp->dest,rp->quoteid); bitcoin_pubkey33(swap->ctx,pubkey33,privkey); pubkey25519 = curve25519(privkey,curve25519_basepoint9()); swap->persistent_pubkey = pubkey25519; diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c index 39526c2be..66380ba37 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -52,7 +52,7 @@ void LP_tradebot_pauseall() void LP_tradebot_updatestats(struct LP_tradebot *bot,struct LP_tradebot_trade *tp) { char *swapstr,*status; int32_t flag; cJSON *swapjson; - if ( (swapstr= basilisk_swapentry(tp->requestid,tp->quoteid,1)) != 0 ) + if ( (swapstr= basilisk_swapentry(0,tp->requestid,tp->quoteid,1)) != 0 ) { flag = 0; if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) @@ -338,7 +338,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) { if ( remaining < 0.001 ) break; - if ( (retstr= LP_autobuy(ctx,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining/i,0,0,G.gui,0,destpubkey,tradeid)) != 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 ) { if ( (retjson2= cJSON_Parse(retstr)) != 0 ) { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 5ea9509f2..c429b78c9 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -13,7 +13,6 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ - // // LP_transaction.c // marketmaker @@ -60,15 +59,42 @@ bits256 LP_pubkey(bits256 privkey) return(pubkey); } -int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid) +int32_t LP_gettx_presence(int32_t *numconfirmsp,char *symbol,bits256 expectedtxid,char *coinaddr) { - cJSON *txobj; bits256 txid; int32_t flag = 0; - if ( (txobj= LP_gettx(symbol,expectedtxid,0)) != 0 ) + cJSON *txobj,*retjson,*item; bits256 txid; struct iguana_info *coin; int32_t height=-1,i,n,flag = 0; + if ( numconfirmsp != 0 ) + *numconfirmsp = -1; + if ( (txobj= LP_gettx("LP_gettx_presence",symbol,expectedtxid,0)) != 0 ) { txid = jbits256(txobj,"txid"); if ( jobj(txobj,"error") == 0 && bits256_cmp(txid,expectedtxid) == 0 ) { - //char str[65]; printf("%s already in gettx (%s)\n",bits256_str(str,txid),jprint(txobj,0)); + if ( numconfirmsp != 0 ) + *numconfirmsp = 0; + if ( numconfirmsp != 0 && coinaddr != 0 && (coin= LP_coinfind(symbol)) != 0 && coin->electrum != 0 ) + { + //char str[65]; printf("%s %s already in gettx (%s)\n",coinaddr,bits256_str(str,txid),jprint(txobj,0)); + if ( (retjson= electrum_address_gethistory(symbol,coin->electrum,&retjson,coinaddr,expectedtxid)) != 0 ) + { + if ( (n= cJSON_GetArraySize(retjson)) > 0 ) + { + for (i=0; iheight ) + *numconfirmsp = (coin->height - height + 1); + break; + } + } + } + free_json(retjson); + //printf("got %s history height.%d vs coin.%d -> numconfirms.%d\n",coin->symbol,height,coin->height,*numconfirmsp); + } + } flag = 1; } free_json(txobj); @@ -93,8 +119,8 @@ bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxi } for (i=0; i<2; i++) { - //char str[65]; printf("LP_broadcast.%d (%s) %s i.%d sentflag.%d\n",i,symbol,bits256_str(str,expectedtxid),i,sentflag); - if ( sentflag == 0 && LP_gettx_presence(symbol,expectedtxid) != 0 ) + //char str[65]; printf("LP_broadcast.%d %s (%s) %s i.%d sentflag.%d %s\n",i,txname,symbol,bits256_str(str,expectedtxid),i,sentflag,txbytes); + if ( sentflag == 0 && LP_gettx_presence(0,symbol,expectedtxid,0) != 0 ) sentflag = 1; if ( sentflag == 0 && (retstr= LP_sendrawtransaction(symbol,txbytes)) != 0 ) { @@ -124,8 +150,7 @@ bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxi totalretries++; i--; } - } - else printf("broadcast error.(%s)\n",retstr); + } else printf("broadcast error.(%s)\n",retstr); } free_json(retjson); } @@ -444,7 +469,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype, if ( sig == 0 || siglen == 0 ) { memset(vp->signers[j].pubkey,0,sizeof(vp->signers[j].pubkey)); - printf("no sig.%p or siglen.%d zero\n",sig,siglen); + char str[65]; printf("no sig.%p or siglen.%d zero priv.(%s)\n",sig,siglen,bits256_str(str,vp->signers[j].privkey)); continue; } if ( bitcoin_verify(ctx,sig,siglen-1,sigtxid,vp->signers[j].pubkey,bitcoin_pubkeylen(vp->signers[j].pubkey)) < 0 ) @@ -744,7 +769,7 @@ void test_validate(struct iguana_info *coin,char *signedtx) char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t utxovout,char *destaddr,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp,uint64_t satoshis,char *changeaddr,char *vinaddr,int32_t suppress_pubkeys,int32_t zcash) { - char *rawtxbytes=0,*signedtx=0,str[65],tmpaddr[64],hexstr[999],wifstr[128],_destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *txobj,*vins,*obj,*vouts,*item,*privkeys; int32_t completed,spendlen,n,ignore_cltverr=1; struct vin_info V[8]; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; bits256 txid; uint64_t value=0,change = 0; struct iguana_msgtx msgtx; struct iguana_info *coin; + char *rawtxbytes=0,*signedtx=0,tmpaddr[64],hexstr[999],wifstr[128],_destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *txobj,*vins,*obj,*vouts,*item,*privkeys; int32_t completed,spendlen,n,ignore_cltverr=1; struct vin_info V[8]; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; bits256 txid; uint64_t value=0,change = 0; struct iguana_msgtx msgtx; struct iguana_info *coin; LP_mark_spent(symbol,utxotxid,utxovout); *destamountp = 0; memset(signedtxidp,0,sizeof(*signedtxidp)); @@ -756,10 +781,16 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch value = 0; if ( (coin= LP_coinfind(symbol)) != 0 ) { + if ( coin->etomic[0] != 0 ) + { + if ( (coin= LP_coinfind("ETOMIC")) == 0 ) + return(0); + symbol = coin->symbol; + } if ( txfee > 0 && txfee < coin->txfee ) txfee = coin->txfee; #ifndef BASILISK_DISABLESENDTX - if ( (txobj= LP_gettx(symbol,utxotxid,0)) != 0 ) + if ( (txobj= LP_gettx("basilisk_swap_bobtxspend",symbol,utxotxid,0)) != 0 ) { if ( (vouts= jarray(&n,txobj,"vout")) != 0 && utxovout < n ) { @@ -771,7 +802,7 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch } else printf("cant gettx\n"); if ( value == 0 ) { - printf("basilisk_swap_bobtxspend.%s %s utxo.(%s).v%d already spent or doesnt exist\n",name,symbol,bits256_str(str,utxotxid),utxovout); + //printf("basilisk_swap_bobtxspend.%s %s utxo.(%s).v%d already spent or doesnt exist\n",name,symbol,bits256_str(str,utxotxid),utxovout); return(0); } #endif @@ -790,7 +821,7 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch else if ( value == satoshis && (double)txfee/value < 0.25 ) { satoshis = value - txfee; - printf("txfee allocation from value %.8f identical to satoshis: %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(txfee)); + //printf("txfee allocation from value %.8f identical to satoshis: %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(txfee)); } else { @@ -800,7 +831,7 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch } if ( value > satoshis+txfee ) change = value - (satoshis + txfee); - printf("utxo %.8f, destamount %.8f change %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(change),dstr(txfee)); + //printf("utxo %.8f, destamount %.8f change %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(change),dstr(txfee)); } else if ( value > txfee ) satoshis = value - txfee; else @@ -904,7 +935,7 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch printf("incomplete signing suppress.%d %s (%s)\n",suppress_pubkeys,name,jprint(vins,0)); if ( signedtx != 0 ) free(signedtx), signedtx = 0; - } else printf("basilisk_swap_bobtxspend %s -> %s\n",name,bits256_str(str,*signedtxidp)); + } // else printf("basilisk_swap_bobtxspend %s -> %s\n",name,bits256_str(str,*signedtxidp)); free(rawtxbytes); } else printf("error making rawtx suppress.%d\n",suppress_pubkeys); free_json(privkeys); @@ -1001,7 +1032,7 @@ uint64_t _komodo_interestnew(uint64_t nValue,uint32_t nLockTime,uint32_t tiptime if ( tiptime > nLockTime && (minutes= (tiptime - nLockTime) / 60) >= 60 ) { //minutes.71582779 tiptime.1511292969 locktime.1511293505 - printf("minutes.%d tiptime.%u locktime.%u\n",minutes,tiptime,nLockTime); + //printf("minutes.%d tiptime.%u locktime.%u\n",minutes,tiptime,nLockTime); if ( minutes > 365 * 24 * 60 ) minutes = 365 * 24 * 60; minutes -= 59; @@ -1077,7 +1108,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ if ( up == 0 ) { value = LP_txvalue(0,coin->symbol,utxotxid,utxovout); - LP_address_utxoadd((uint32_t)time(NULL),"withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1); + LP_address_utxoadd(0,(uint32_t)time(NULL),"withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1); //printf("added after not finding\n"); } if ( (up= LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout)) != 0 ) @@ -1085,7 +1116,13 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ else { printf("couldnt add address_utxo after not finding\n"); - return(0); + 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"); + //return(0); } } if ( dustcombine >= 1 && min0 != 0 && min0->U.value < LP_DUSTCOMBINE_THRESHOLD && (coin->electrum == 0 || min0->SPV > 0) ) @@ -1175,7 +1212,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ vp->suppress_pubkeys = suppress_pubkeys; vp->ignore_cltverr = ignore_cltverr; jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr)); - LP_unavailableset(up->U.txid,up->U.vout,(uint32_t)time(NULL)+LP_RESERVETIME,G.LP_mypub25519); + LP_unavailableset(up->U.txid,up->U.vout,(uint32_t)time(NULL)+LP_RESERVETIME*2,G.LP_mypub25519); if ( remains <= 0 && i >= numpre-1 ) break; if ( numunspents < 0 || n >= LP_MAXVINS ) @@ -1188,10 +1225,10 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_ return(n); } -char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_info *coin,struct vin_info *V,int32_t max,bits256 privkey,cJSON *outputs,cJSON *vins,cJSON *privkeys,int64_t txfee,bits256 utxotxid,int32_t utxovout,uint32_t locktime) +char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_info *coin,struct vin_info *V,int32_t max,bits256 privkey,cJSON *outputs,cJSON *vins,cJSON *privkeys,int64_t txfee,bits256 utxotxid,int32_t utxovout,uint32_t locktime,char *opretstr,char *passphrase) { static void *ctx; - cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS*256]; struct LP_address *ap; + cJSON *txobj,*item; uint8_t addrtype,rmd160[20],data[8192+64],script[8192],spendscript[256]; char *coinaddr,*rawtxbytes,*scriptstr; bits256 txid; uint32_t crc32,timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t origspendlen=0,i,offset,len,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS*256]; struct LP_address *ap; if ( ctx == 0 ) ctx = bitcoin_ctx(); *numvinsp = 0; @@ -1211,6 +1248,9 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf else if ( coin->numutxos >= LP_MAXDESIRED_UTXOS ) dustcombine = 2; else dustcombine = 1; +#ifdef LP_DISABLE_DISTCOMBINE + dustcombine = 0; +#endif amount = txfee; for (i=0; i total %.8f\n",i,dstr(value),dstr(amount)); + //printf("vout.%d %.8f -> total %.8f\n",i,dstr(value),dstr(amount)); } else { @@ -1271,7 +1311,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf txobj = bitcoin_txcreate(coin->symbol,coin->isPoS,locktime,coin->txversion,timestamp); jdelete(txobj,"vin"); jadd(txobj,"vin",jduplicate(vins)); - printf("change %.8f = total %.8f - amount %.8f, adjust %.8f numvouts.%d\n",dstr(change),dstr(total),dstr(amount),dstr(adjust),numvouts); + //printf("change %.8f = total %.8f - amount %.8f, adjust %.8f numvouts.%d\n",dstr(change),dstr(total),dstr(amount),dstr(adjust),numvouts); for (i=0; isymbol,coin->taddr,&addrtype,rmd160,coinaddr); - if ( addrtype == coin->pubtype ) - spendlen = bitcoin_standardspend(spendscript,0,rmd160); - else spendlen = bitcoin_p2shspend(spendscript,0,rmd160); - if ( i == numvouts-1 && strcmp(coinaddr,coin->smartaddr) == 0 && change != 0 ) + if ( (scriptstr= jstr(item,"script")) != 0 ) { - printf("combine last vout %.8f with change %.8f\n",dstr(value+adjust),dstr(change)); - value += change; - change = 0; + spendlen = (int32_t)strlen(scriptstr) >> 1; + if ( spendlen < sizeof(script) ) + { + decode_hex(spendscript,spendlen,scriptstr); + //printf("i.%d using external script.(%s) %d\n",i,scriptstr,spendlen); + } + else + { + printf("custom script.%d too long %d\n",i,spendlen); + free_json(txobj); + return(0); + } + } + else + { + bitcoin_addr2rmd160(coin->symbol,coin->taddr,&addrtype,rmd160,coinaddr); + if ( addrtype == coin->pubtype ) + spendlen = bitcoin_standardspend(spendscript,0,rmd160); + else spendlen = bitcoin_p2shspend(spendscript,0,rmd160); + if ( i == numvouts-1 && strcmp(coinaddr,coin->smartaddr) == 0 && change != 0 ) + { + //printf("combine last vout %.8f with change %.8f\n",dstr(value+adjust),dstr(change)); + value += change; + change = 0; + } } txobj = bitcoin_txoutput(txobj,spendscript,spendlen,value + adjust); } @@ -1309,6 +1367,64 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf } if ( change != 0 ) txobj = bitcoin_txoutput(txobj,script,scriptlen,change); + if ( opretstr != 0 ) + { + spendlen = (int32_t)strlen(opretstr) >> 1; + if ( spendlen < sizeof(script)-60 ) + { + if ( passphrase != 0 && passphrase[0] != 0 ) + { + decode_hex(data,spendlen,opretstr); + offset = 2 + (spendlen >= 16); + origspendlen = spendlen; + crc32 = calc_crc32(0,data,spendlen); + spendlen = LP_opreturn_encrypt(&script[offset],(int32_t)sizeof(script)-offset,data,spendlen,passphrase,crc32&0xffff); + if ( spendlen < 0 ) + { + printf("error encrpting opreturn data\n"); + free_json(txobj); + return(0); + } + } else offset = crc32 = 0; + len = 0; + script[len++] = SCRIPT_OP_RETURN; + if ( spendlen < 76 ) + script[len++] = spendlen; + else if ( spendlen <= 0xff ) + { + script[len++] = 0x4c; + script[len++] = spendlen; + } + else if ( spendlen <= 0xffff ) + { + script[len++] = 0x4d; + script[len++] = (spendlen & 0xff); + script[len++] = ((spendlen >> 8) & 0xff); + } + if ( passphrase != 0 && passphrase[0] != 0 ) + { + if ( offset != len ) + { + printf("offset.%d vs len.%d, reencrypt\n",offset,len); + spendlen = LP_opreturn_encrypt(&script[len],(int32_t)sizeof(script)-len,data,origspendlen,passphrase,crc32&0xffff); + if ( spendlen < 0 ) + { + printf("error encrpting opreturn data\n"); + free_json(txobj); + return(0); + } + } //else printf("offset.%d already in right place\n",offset); + } else decode_hex(&script[len],spendlen,opretstr); + txobj = bitcoin_txoutput(txobj,script,len + spendlen,0); + //printf("OP_RETURN.[%d, %d] script.(%s)\n",len,spendlen,opretstr); + } + else + { + printf("custom script.%d too long %d\n",i,spendlen); + free_json(txobj); + return(0); + } + } if ( (rawtxbytes= bitcoin_json2hex(coin->symbol,coin->isPoS,&txid,txobj,V)) != 0 ) { } else printf("error making rawtx suppress.%d\n",suppress_pubkeys); @@ -1317,16 +1433,120 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf return(rawtxbytes); } +char *LP_opreturndecrypt(void *ctx,char *symbol,bits256 utxotxid,char *passphrase) +{ + cJSON *txjson,*vouts,*opret,*sobj,*retjson; uint16_t utxovout; char *opretstr,*hexstr; uint8_t *opretdata,*databuf,*decoded; uint16_t ind16; uint32_t crc32; int32_t i,len,numvouts,opretlen,datalen; struct iguana_info *coin; + if ( (coin= LP_coinfind(symbol)) == 0 ) + return(clonestr("{\"error\":\"cant find coin\"}")); + retjson = cJSON_CreateObject(); + utxovout = 0; + if ( (txjson= LP_gettx("LP_opreturn_decrypt",coin->symbol,utxotxid,1)) != 0 ) + { + if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts >= 1 ) + { + opret = jitem(vouts,numvouts - 1); + jaddstr(retjson,"coin",symbol); + jaddbits256(retjson,"opreturntxid",utxotxid); + if ( (sobj= jobj(opret,"scriptPubKey")) != 0 ) + { + if ( (opretstr= jstr(sobj,"hex")) != 0 ) + { + jaddstr(retjson,"opreturn",opretstr); + opretlen = (int32_t)strlen(opretstr) >> 1; + opretdata = malloc(opretlen); + decode_hex(opretdata,opretlen,opretstr); + databuf = &opretdata[2]; + datalen = 0; + if ( opretdata[0] != 0x6a ) + jaddstr(retjson,"error","not opreturn data"); + else if ( (datalen= opretdata[1]) < 76 ) + { + if ( &databuf[datalen] != &opretdata[opretlen] ) + databuf = 0, jaddstr(retjson,"error","mismatched short opretlen"); + } + else if ( opretdata[1] == 0x4c ) + { + datalen = opretdata[2]; + databuf++; + if ( &databuf[datalen] != &opretdata[opretlen] ) + databuf = 0, jaddstr(retjson,"error","mismatched opretlen"); + } + else if ( opretdata[1] == 0x4d ) + { + datalen = opretdata[3]; + datalen <<= 8; + datalen |= opretdata[2]; + databuf += 2; + if ( &databuf[datalen] != &opretdata[opretlen] ) + databuf = 0, jaddstr(retjson,"error","mismatched big opretlen"); + } + else databuf = 0, jaddstr(retjson,"error","unexpected opreturn data type"); + if ( databuf != 0 ) + { + decoded = calloc(1,opretlen+1); + if ( (len= LP_opreturn_decrypt(&ind16,decoded,databuf,datalen,passphrase)) < 0 ) + jaddstr(retjson,"error","decrypt error"); + else + { + crc32 = calc_crc32(0,decoded,len); + if ( (crc32 & 0xffff) == ind16 ) + { + jaddstr(retjson,"result","success"); + hexstr = malloc(len*2+1); + init_hexbytes_noT(hexstr,decoded,len); + jaddstr(retjson,"decrypted",hexstr); + for (i=0; isymbol,jprint(argjson,0)); + if ( coin->etomic[0] != 0 ) + { + if ( (coin= LP_coinfind("ETOMIC")) == 0 ) + return(clonestr("{\"error\":\"use LP_eth_withdraw for ETH or ERC20\"}")); + } if ( ctx == 0 ) ctx = bitcoin_ctx(); + broadcast = jint(argjson,"broadcast"); if ( (outputs= jarray(&numvouts,argjson,"outputs")) == 0 ) { - printf("no outputs in argjson (%s)\n",jprint(argjson,0)); - return(clonestr("{\"error\":\"no outputs specified\"}")); + if ( jstr(argjson,"opreturn") == 0 ) + { + printf("no outputs in argjson (%s)\n",jprint(argjson,0)); + return(clonestr("{\"error\":\"no outputs specified\"}")); + } + else + { + outputs = cJSON_CreateArray(); + item = cJSON_CreateObject(); + jaddnum(item,coin->smartaddr,0.0001); + jaddi(outputs,item); + numvouts = 1; + allocated_outputs = 1; + } } utxotxid = jbits256(argjson,"utxotxid"); utxovout = jint(argjson,"utxovout"); @@ -1349,17 +1569,12 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) V = malloc(maxV * sizeof(*V)); for (iter=0; iter<2; iter++) { - if ( (ap= LP_address_utxo_reset(coin)) == 0 ) - { - printf("LP_withdraw error utxo reset %s\n",coin->symbol); - free(V); - return(0); - } + LP_address_utxo_reset(&num,coin); privkeys = cJSON_CreateArray(); vins = cJSON_CreateArray(); memset(V,0,sizeof(*V) * maxV); numvins = 0; - if ( (rawtx= LP_createrawtransaction(&txobj,&numvins,coin,V,maxV,privkey,outputs,vins,privkeys,iter == 0 ? txfee : newtxfee,utxotxid,utxovout,locktime)) != 0 ) + if ( (rawtx= LP_createrawtransaction(&txobj,&numvins,coin,V,maxV,privkey,outputs,vins,privkeys,iter == 0 ? txfee : newtxfee,utxotxid,utxovout,locktime,jstr(argjson,"opreturn"),jstr(argjson,"passphrase"))) != 0 ) { completed = 0; memset(&msgtx,0,sizeof(msgtx)); @@ -1371,7 +1586,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) printf("incomplete signing withdraw (%s)\n",jprint(vins,0)); if ( signedtx != 0 ) free(signedtx), signedtx = 0; - } else printf("LP_withdraw.%s %s -> %s\n",coin->symbol,jprint(argjson,0),bits256_str(str,signedtxid)); + } if ( signedtx == 0 ) break; datalen = (int32_t)strlen(signedtx) / 2; @@ -1400,7 +1615,6 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) { if ( completed == 0 && (numvins= cJSON_GetArraySize(vins)) > 0 ) { - for (i=0; isymbol,signedtx)) != 0 ) + { + printf("LP_withdraw.%s %s -> %s (%s)\n",coin->symbol,jprint(argjson,0),bits256_str(str,signedtxid),signret); + free(signret); + } + } + free(signedtx); + } if ( txobj != 0 ) jadd(retjson,"tx",txobj); jaddbits256(retjson,"txid",signedtxid); jadd(retjson,"complete",completed!=0?jtrue():jfalse()); + if ( allocated_outputs != 0 ) + free_json(outputs); return(jprint(retjson,1)); } +char *LP_autosplit(struct iguana_info *coin) +{ + char *retstr; cJSON *argjson,*withdrawjson,*outputs,*item; int64_t total,balance,halfval; + if ( coin->etomic[0] == 0 ) + { + if ( coin->electrum != 0 ) + balance = LP_unspents_load(coin->symbol,coin->smartaddr); + else balance = LP_RTsmartbalance(coin); + //printf("%s balance %.8f\n",coin->symbol,dstr(balance)); + balance -= coin->txfee - 0.001; + if ( balance > coin->txfee ) + { + halfval = (balance / 100) * 45; + argjson = cJSON_CreateObject(); + outputs = cJSON_CreateArray(); + item = cJSON_CreateObject(); + jaddnum(item,coin->smartaddr,dstr(halfval)); + jaddi(outputs,item); + item = cJSON_CreateObject(); + jaddnum(item,coin->smartaddr,dstr(halfval)); + jaddi(outputs,item); + item = cJSON_CreateObject(); + jaddnum(item,coin->smartaddr,dstr(balance - 2*halfval)); + jaddi(outputs,item); + jadd(argjson,"outputs",outputs); + jaddnum(argjson,"broadcast",1); + jaddstr(argjson,"coin",coin->symbol); + //printf("autosplit.(%s)\n",jprint(argjson,0)); + retstr = LP_withdraw(coin,argjson); + free_json(argjson); + return(retstr); + } else return(clonestr("{\"error\":\"less than 0.0011 in balance\"}")); + } + return(clonestr("{\"error\":\"couldnt autosplit\"}")); +} + +#ifndef NOTETOMIC + +char *LP_eth_withdraw(struct iguana_info *coin,cJSON *argjson) +{ + cJSON *retjson = cJSON_CreateObject(); + char *dest_addr, *tx_id, privkey_str[70], amount_str[100]; + int64_t amount; + bits256 privkey; + + dest_addr = jstr(argjson, "to"); + amount = jdouble(argjson, "amount") * 100000000; + privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr); + uint8arrayToHex(privkey_str, privkey.bytes, 32); + satoshisToWei(amount_str, amount); + if (strcmp(coin->symbol, "ETH") == 0) { + tx_id = sendEth(dest_addr, amount_str, privkey_str, 0); + } else { + tx_id = sendErc20(coin->etomic, dest_addr, amount_str, privkey_str, 0); + } + jaddstr(retjson, "tx_id", tx_id); + 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; if ( (coin= LP_coinfind(rawtx->symbol)) == 0 ) return(-1); + if ( coin->etomic[0] != 0 ) + { + if ( (coin= LP_coinfind("ETOMIC")) == 0 ) + return(-1); + } if ( strcmp(coin->smartaddr,vinaddr) != 0 ) { printf("???????????????????????? basilisk_rawtx_gen mismatched %s %s vinaddr.%s != (%s)\n",rawtx->symbol,coin->symbol,vinaddr,coin->smartaddr); @@ -1455,49 +1753,13 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub rawtx->I.completed = 1; rawtx->I.signedtxid = jbits256(retjson,"txid"); retval = 0; - } else printf("rawtx withdraw error? (%s)\n",retstr); + } else printf("rawtx withdraw error? (%s)\n",jprint(argjson,0)); free_json(retjson); } free(retstr); } free_json(argjson); return(retval); -/*#ifdef old - int32_t retval=-1,iter; char *signedtx,*changeaddr = 0,_changeaddr[64]; struct iguana_info *coin; int64_t newtxfee=0,destamount; - char str2[65]; printf("%s rawtxgen.(%s/v%d)\n",rawtx->name,bits256_str(str2,rawtx->utxotxid),rawtx->utxovout); - if ( (coin= rawtx->coin) == 0 ) - return(-1); - //return(_basilisk_rawtx_gen(str,swapstarted,pubkey33,iambob,lockinputs,rawtx,locktime,script,scriptlen,txfee,minconf,delay,privkey)); - if ( changermd160 != 0 ) - { - changeaddr = _changeaddr; - bitcoin_address(changeaddr,coin->taddr,coin->pubtype,changermd160,20); - //printf("changeaddr.(%s) vs destaddr.(%s)\n",changeaddr,rawtx->I.destaddr); - } - if ( strcmp(str,"myfee") == 0 && strcmp(coin->symbol,"BTC") == 0 ) - txfee = LP_MIN_TXFEE; - for (iter=0; iter<2; iter++) - { - if ( (signedtx= basilisk_swap_bobtxspend(&rawtx->I.signedtxid,iter == 0 ? txfee : newtxfee,str,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,privkey,0,0,0,0,0,rawtx->utxotxid,rawtx->utxovout,rawtx->I.destaddr,pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,rawtx->I.suppress_pubkeys,coin->zcash)) != 0 ) - { - rawtx->I.datalen = (int32_t)strlen(signedtx) >> 1; - if ( rawtx->I.datalen <= sizeof(rawtx->txbytes) ) - { - decode_hex(rawtx->txbytes,rawtx->I.datalen,signedtx); - rawtx->I.completed = 1; - retval = 0; - } - free(signedtx); - if ( strcmp(coin->symbol,"BTC") != 0 ) - return(retval); - newtxfee = LP_txfeecalc(coin,0,rawtx->I.datalen); - printf("txfee %.8f -> newtxfee %.8f\n",dstr(txfee),dstr(newtxfee)); - } else break; - if ( strcmp(str,"myfee") == 0 ) - break; - } - return(retval); -#endif*/ } int32_t basilisk_rawtx_sign(char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,struct basilisk_swap *swap,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr,uint8_t *changermd160,char *vinaddr,int32_t zcash) @@ -1580,7 +1842,7 @@ int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vou { cJSON *retjson; coinaddr[0] = 0; - if ( (retjson= LP_gettx(symbol,txid,0)) != 0 ) + if ( (retjson= LP_gettx("LP_swap_getcoinaddr",symbol,txid,0)) != 0 ) { LP_txdestaddr(coinaddr,txid,vout,retjson); free_json(retjson); @@ -1591,8 +1853,10 @@ int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vou int32_t basilisk_swap_getsigscript(char *symbol,uint8_t *script,int32_t maxlen,bits256 txid,int32_t vini) { cJSON *retjson,*vins,*item,*skey; int32_t n,scriptlen = 0; char *hexstr; - if ( (retjson= LP_gettx(symbol,txid,0)) != 0 ) + //char str[65]; printf("getsigscript %s %s/v%d\n",symbol,bits256_str(str,txid),vini); + if ( bits256_nonz(txid) != 0 && (retjson= LP_gettx("basilisk_swap_getsigscript",symbol,txid,0)) != 0 ) { + //printf("gettx.(%s)\n",jprint(retjson,0)); if ( (vins= jarray(&n,retjson,"vin")) != 0 && vini < n ) { item = jitem(vins,vini); @@ -1600,7 +1864,7 @@ int32_t basilisk_swap_getsigscript(char *symbol,uint8_t *script,int32_t maxlen,b { scriptlen >>= 1; decode_hex(script,scriptlen,hexstr); - //char str[65]; printf("%s/v%d sigscript.(%s)\n",bits256_str(str,txid),vini,hexstr); + //char str[65]; printf("%s %s/v%d sigscript.(%s)\n",symbol,bits256_str(str,txid),vini,hexstr); } } free_json(retjson); @@ -1683,7 +1947,7 @@ bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t u for (i=0; i OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF*/ +int32_t LP_etomicsymbol(char *activesymbol,char *etomic,char *symbol) +{ + struct iguana_info *coin; + etomic[0] = activesymbol[0] = 0; + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + strcpy(etomic,coin->etomic); + if ( etomic[0] != 0 ) + strcpy(activesymbol,"ETOMIC"); + else strcpy(activesymbol,symbol); + } + return(etomic[0] != 0); +} + int32_t basilisk_bobpayment_reclaim(struct basilisk_swap *swap,int32_t delay) { static bits256 zero; - uint8_t userdata[512]; int32_t retval,i,len = 0; struct iguana_info *coin; - if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + uint8_t userdata[512]; char bobstr[65],bobtomic[128]; int32_t retval,len = 0; struct iguana_info *coin; + LP_etomicsymbol(bobstr,bobtomic,swap->I.bobstr); + if ( (coin= LP_coinfind(bobstr)) != 0 ) { //printf("basilisk_bobpayment_reclaim\n"); len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[1],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); @@ -1851,20 +2111,21 @@ int32_t basilisk_bobpayment_reclaim(struct basilisk_swap *swap,int32_t delay) swap->I.userdata_bobreclaimlen = len; if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->bobreclaim,&swap->bobpayment,swap->I.myprivs[1],0,userdata,len,1,swap->changermd160,swap->bobpayment.I.destaddr,coin->zcash)) == 0 ) { - for (i=0; ibobreclaim.I.datalen; i++) - printf("%02x",swap->bobreclaim.txbytes[i]); - printf(" <- bobreclaim\n"); + //for (i=0; ibobreclaim.I.datalen; i++) + // printf("%02x",swap->bobreclaim.txbytes[i]); + //printf(" <- bobreclaim\n"); //basilisk_txlog(swap,&swap->bobreclaim,delay); return(retval); } - } else printf("basilisk_bobpayment_reclaim cant find (%s)\n",swap->I.bobstr); + } else printf("basilisk_bobpayment_reclaim cant find (%s)\n",bobstr); return(-1); } int32_t basilisk_bobdeposit_refund(struct basilisk_swap *swap,int32_t delay) { - uint8_t userdata[512]; int32_t i,retval,len = 0; char str[65]; struct iguana_info *coin; - if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + uint8_t userdata[512]; int32_t i,retval,len = 0; char str[65],bobstr[65],bobtomic[128]; struct iguana_info *coin; + LP_etomicsymbol(bobstr,bobtomic,swap->I.bobstr); + if ( (coin= LP_coinfind(bobstr)) != 0 ) { len = basilisk_swapuserdata(userdata,swap->I.privBn,0,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); memcpy(swap->I.userdata_bobrefund,userdata,len); @@ -1877,7 +2138,7 @@ int32_t basilisk_bobdeposit_refund(struct basilisk_swap *swap,int32_t delay) //basilisk_txlog(swap,&swap->bobrefund,delay); return(retval); } - } else printf("basilisk_bobdeposit_refund cant find (%s)\n",swap->I.bobstr); + } else printf("basilisk_bobdeposit_refund cant find (%s)\n",bobstr); return(-1); } @@ -1903,8 +2164,9 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,int32_t genflag) { - int32_t j; char coinaddr[64],checkaddr[64]; struct iguana_info *coin; - if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + char coinaddr[64],checkaddr[64],bobstr[65],bobtomic[128]; struct iguana_info *coin; + LP_etomicsymbol(bobstr,bobtomic,swap->I.bobstr); + if ( (coin= LP_coinfind(bobstr)) != 0 ) { bitcoin_address(coin->symbol,coinaddr,coin->taddr,coin->pubtype,swap->changermd160,20); if ( genflag != 0 && swap->I.iambob == 0 ) @@ -1928,13 +2190,13 @@ int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,i } else { - for (j=0; jbobpayment.I.datalen; j++) + /*for (j=0; jbobpayment.I.datalen; j++) printf("%02x",swap->bobpayment.txbytes[j]); printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen); for (j=0; jbobpayment.I.redeemlen; j++) printf("%02x",swap->bobpayment.redeemscript[j]); printf(" <- redeem.%d\n",swap->bobpayment.I.redeemlen); - printf(" <- GENERATED BOB PAYMENT.%d destaddr.(%s)\n",swap->bobpayment.I.datalen,swap->bobpayment.I.destaddr); + printf(" <- GENERATED BOB PAYMENT.%d destaddr.(%s)\n",swap->bobpayment.I.datalen,swap->bobpayment.I.destaddr);*/ LP_swap_coinaddr(coin,checkaddr,0,swap->bobpayment.txbytes,swap->bobpayment.I.datalen,0); if ( strcmp(swap->bobpayment.I.destaddr,checkaddr) != 0 ) { @@ -1965,9 +2227,9 @@ int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,i } else { - for (j=0; jbobdeposit.I.datalen; j++) - printf("%02x",swap->bobdeposit.txbytes[j]); - printf(" <- GENERATED BOB DEPOSIT.%d (%s)\n",swap->bobdeposit.I.datalen,swap->bobdeposit.I.destaddr); + //for (j=0; jbobdeposit.I.datalen; j++) + // printf("%02x",swap->bobdeposit.txbytes[j]); + //printf(" <- GENERATED BOB DEPOSIT.%d (%s)\n",swap->bobdeposit.I.datalen,swap->bobdeposit.I.destaddr); LP_swap_coinaddr(coin,checkaddr,0,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen,0); if ( strcmp(swap->bobdeposit.I.destaddr,checkaddr) != 0 ) { @@ -1975,48 +2237,15 @@ int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,i return(-1); } LP_unspents_mark(coin->symbol,swap->bobdeposit.vins); - printf("bobscripts set completed\n"); + //printf("bobscripts set completed\n"); return(0); } } } - } else printf("bobscripts set cant find (%s)\n",swap->I.bobstr); + } else printf("bobscripts set cant find (%s)\n",bobstr); return(0); } -/* - -#ifdef old -int32_t basilisk_alicepayment_spend(struct basilisk_swap *swap,struct basilisk_rawtx *dest) -{ - int32_t i,retval; - printf("alicepayment_spend\n"); - swap->alicepayment.I.spendlen = basilisk_alicescript(swap->alicepayment.redeemscript,&swap->alicepayment.I.redeemlen,swap->alicepayment.spendscript,0,swap->alicepayment.I.destaddr,coin->p2shtype,swap->I.pubAm,swap->I.pubBn); - printf("alicepayment_spend len.%d\n",swap->alicepayment.I.spendlen); - if ( swap->I.iambob == 0 ) - { - memcpy(swap->I.userdata_alicereclaim,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen); - swap->I.userdata_alicereclaimlen = swap->alicepayment.I.spendlen; - } - else - { - memcpy(swap->I.userdata_bobspend,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen); - swap->I.userdata_bobspendlen = swap->alicepayment.I.spendlen; - } - if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1,swap->changermd160)) == 0 ) - { - for (i=0; iI.datalen; i++) - printf("%02x",dest->txbytes[i]); - printf(" <- msigspend\n\n"); - if ( dest == &swap->bobspend ) - swap->I.bobspent = 1; - //basilisk_txlog(swap,dest,0); // bobspend or alicereclaim - return(retval); - } - return(-1); -} -#endif*/ - void basilisk_alicepayment(struct basilisk_swap *swap,struct iguana_info *coin,struct basilisk_rawtx *alicepayment,bits256 pubAm,bits256 pubBn) { char coinaddr[64]; @@ -2028,8 +2257,9 @@ void basilisk_alicepayment(struct basilisk_swap *swap,struct iguana_info *coin,s int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { - char coinaddr[64]; int32_t i,retval = -1; struct iguana_info *coin; - if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) + char coinaddr[64],alicestr[65],alicetomic[128]; int32_t retval = -1; struct iguana_info *coin; + LP_etomicsymbol(alicestr,alicetomic,swap->I.alicestr); + if ( (coin= LP_coinfind(alicestr)) != 0 ) { if ( swap->alicepayment.I.datalen == 0 ) basilisk_alicepayment(swap,coin,&swap->alicepayment,swap->I.pubAm,swap->I.pubBn); @@ -2041,26 +2271,26 @@ int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *d //LP_importaddress(coin->symbol,swap->alicepayment.I.destaddr); strcpy(swap->alicepayment.p2shaddr,swap->alicepayment.I.destaddr); retval = 0; - for (i=0; ialicepayment.I.datalen; i++) - printf("%02x",swap->alicepayment.txbytes[i]); - printf(" ALICE PAYMENT created.(%s)\n",swap->alicepayment.I.destaddr); + //for (i=0; ialicepayment.I.datalen; i++) + // printf("%02x",swap->alicepayment.txbytes[i]); + //printf(" ALICE PAYMENT created.(%s)\n",swap->alicepayment.I.destaddr); LP_unspents_mark(coin->symbol,swap->alicepayment.vins); //LP_importaddress(coin->symbol,swap->alicepayment.I.destaddr); //basilisk_txlog(swap,&swap->alicepayment,-1); } if ( swap->myfee.I.datalen == 0 ) { - printf("%s generate fee %.8f from.%s\n",coin->symbol,dstr(strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee),coin->smartaddr); + //printf("%s generate fee %.8f from.%s\n",coin->symbol,dstr(strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee),coin->smartaddr); bitcoin_address(coin->symbol,coinaddr,coin->taddr,coin->pubtype,swap->changermd160,20); if ( basilisk_rawtx_gen(swap->ctx,"myfee",swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,swap->myfee.I.locktime,swap->myfee.spendscript,swap->myfee.I.spendlen,strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr) == 0 ) { - printf("rawtxsend %s %.8f\n",coin->symbol,dstr(strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee)); + //printf("rawtxsend %s %.8f\n",coin->symbol,dstr(strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee)); swap->I.statebits |= LP_swapdata_rawtxsend(pairsock,swap,0x80,data,maxlen,&swap->myfee,0x40,0); LP_unspents_mark(swap->I.iambob!=0?coin->symbol:coin->symbol,swap->myfee.vins); //basilisk_txlog(swap,&swap->myfee,-1); - for (i=0; imyfee.I.datalen; i++) - printf("%02x",swap->myfee.txbytes[i]); - printf(" <- fee state.%x\n",swap->I.statebits); + //int32_t i; for (i=0; imyfee.I.datalen; i++) + // printf("%02x",swap->myfee.txbytes[i]); + //printf(" <- fee state.%x\n",swap->I.statebits); swap->I.statebits |= 0x40; } else @@ -2071,29 +2301,40 @@ int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *d } if ( swap->alicepayment.I.datalen != 0 && swap->alicepayment.I.spendlen > 0 && swap->myfee.I.datalen != 0 && swap->myfee.I.spendlen > 0 ) { - printf("fee sent\n"); + //printf("fee sent\n"); return(0); } - } else printf("basilisk alicetx cant find (%s)\n",swap->I.alicestr); + } else printf("basilisk alicetx cant find (%s)\n",alicestr); return(-1); } int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { - int32_t diff; struct iguana_info *coin; - if ( (coin= LP_coinfind(swap->I.iambob != 0 ? swap->I.alicestr : swap->I.bobstr)) != 0 ) + int32_t diff; char bobstr[65],bobtomic[128],alicestr[65],alicetomic[128]; struct iguana_info *coin; + LP_etomicsymbol(bobstr,bobtomic,swap->I.bobstr); + LP_etomicsymbol(alicestr,alicetomic,swap->I.alicestr); + if ( (coin= LP_coinfind(swap->I.iambob != 0 ? alicestr : bobstr)) != 0 ) { if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->otherfee,0,data,datalen,0) == 0 ) { - printf("otherfee amount %.8f -> %s vs %s locktime %u vs %u\n",dstr(swap->otherfee.I.amount),swap->otherfee.p2shaddr,swap->otherfee.I.destaddr,swap->otherfee.I.locktime,swap->I.started+1); + //printf("otherfee amount %.8f -> %s vs %s locktime %u vs %u\n",dstr(swap->otherfee.I.amount),swap->otherfee.p2shaddr,swap->otherfee.I.destaddr,swap->otherfee.I.locktime,swap->I.started+1); if ( strcmp(swap->otherfee.I.destaddr,swap->otherfee.p2shaddr) == 0 ) { diff = swap->otherfee.I.locktime - (swap->I.started+1); if ( diff < 0 ) diff = -diff; if ( diff < LP_AUTOTRADE_TIMEOUT ) - printf("dexfee verified\n"); + { + //printf("dexfee verified\n"); + } else printf("locktime mismatch in otherfee, reject %u vs %u\n",swap->otherfee.I.locktime,swap->I.started+1); +#ifndef NOTETOMIC + if (swap->otherfee.I.ethTxid[0] != 0 && LP_etomic_is_empty_tx_id(swap->otherfee.I.ethTxid) == 0) { + if (LP_etomic_wait_for_confirmation(swap->otherfee.I.ethTxid) < 0 || LP_etomic_verify_alice_fee(swap) == 0) { + return(-1); + } + } +#endif return(0); } else printf("destaddress mismatch in other fee, reject (%s) vs (%s)\n",swap->otherfee.I.destaddr,swap->otherfee.p2shaddr); } @@ -2103,8 +2344,9 @@ int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t data int32_t LP_verify_alicespend(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { - struct iguana_info *coin; - if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) + struct iguana_info *coin; char alicestr[65],alicetomic[128]; + LP_etomicsymbol(alicestr,alicetomic,swap->I.alicestr); + if ( (coin= LP_coinfind(alicestr)) != 0 ) { if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->alicespend,0,data,datalen,0) == 0 ) { @@ -2115,22 +2357,23 @@ int32_t LP_verify_alicespend(struct basilisk_swap *swap,uint8_t *data,int32_t da return(0); } } - } else printf("verify alicespend cant find (%s)\n",swap->I.alicestr); + } else printf("verify alicespend cant find (%s)\n",alicestr); return(-1); } /* Bob deposit: OP_IF - OP_CLTV OP_DROP OP_CHECKSIG + OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY OP_CLTV OP_DROP OP_CHECKSIG OP_ELSE - OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG - OP_ENDIF*/ + OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF +*/ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { - static bits256 zero; - uint8_t userdata[512]; int32_t retval=-1,len = 0; struct iguana_info *coin; - if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + uint8_t userdata[512]; char bobstr[65],bobtomic[128]; int32_t i,retval=-1,len = 0; struct iguana_info *coin; bits256 revAm; + LP_etomicsymbol(bobstr,bobtomic,swap->I.bobstr); + if ( (coin= LP_coinfind(bobstr)) != 0 ) { if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->bobdeposit,0,data,datalen,0) == 0 ) { @@ -2139,7 +2382,10 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da if ( bits256_nonz(swap->bobdeposit.I.signedtxid) != 0 ) swap->depositunconf = 1; else swap->bobdeposit.I.signedtxid = swap->bobdeposit.I.actualtxid; - len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + memset(revAm.bytes,0,sizeof(revAm)); + for (i=0; i<32; i++) + revAm.bytes[i] = swap->I.privAm.bytes[31-i]; + len = basilisk_swapuserdata(userdata,revAm,1,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); swap->aliceclaim.utxotxid = swap->bobdeposit.I.signedtxid; memcpy(swap->I.userdata_aliceclaim,userdata,len); swap->I.userdata_aliceclaimlen = len; @@ -2159,25 +2405,33 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da retval = 0; if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobdeposit.I.destaddr,coin->zcash)) == 0 ) { - int32_t i; for (i=0; ibobdeposit.I.datalen; i++) + /*int32_t i; for (i=0; ibobdeposit.I.datalen; i++) printf("%02x",swap->bobdeposit.txbytes[i]); printf(" <- bobdeposit\n"); for (i=0; ialiceclaim.I.datalen; i++) printf("%02x",swap->aliceclaim.txbytes[i]); - printf(" <- aliceclaim\n"); + printf(" <- aliceclaim\n");*/ //basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration); +#ifndef NOTETOMIC + if (swap->bobdeposit.I.ethTxid[0] != 0 && LP_etomic_is_empty_tx_id(swap->bobdeposit.I.ethTxid) == 0) { + if (LP_etomic_wait_for_confirmation(swap->bobdeposit.I.ethTxid) < 0 || LP_etomic_verify_bob_deposit(swap, swap->bobdeposit.I.ethTxid) == 0) { + return(-1); + } + } +#endif return(LP_waitmempool(coin->symbol,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,60)); } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr); } - } else printf("verify bob depositcant find bob coin (%s)\n",swap->I.bobstr); + } else printf("verify bob depositcant find bob coin (%s)\n",bobstr); printf("error with bobdeposit\n"); return(retval); } int32_t LP_verify_alicepayment(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { - struct iguana_info *coin; - if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) + struct iguana_info *coin; char alicestr[65],alicetomic[128]; + LP_etomicsymbol(alicestr,alicetomic,swap->I.alicestr); + if ( (coin= LP_coinfind(alicestr)) != 0 ) { if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->alicepayment,0,data,datalen,0) == 0 ) { @@ -2188,20 +2442,37 @@ int32_t LP_verify_alicepayment(struct basilisk_swap *swap,uint8_t *data,int32_t if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 ) swap->aliceunconf = 1; basilisk_dontforget_update(swap,&swap->alicepayment); +#ifndef NOTETOMIC + if (swap->alicepayment.I.ethTxid[0] != 0 && LP_etomic_is_empty_tx_id(swap->alicepayment.I.ethTxid) == 0) { + if (LP_etomic_verify_alice_payment(swap, swap->alicepayment.I.ethTxid) == 0) { + return(-1); + } + } +#endif return(LP_waitmempool(coin->symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,60)); //printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr); //LP_importaddress(coin->symbol,swap->alicepayment.p2shaddr); return(0); } - } else printf("verify alicepayment couldnt find coin.(%s)\n",swap->I.alicestr); + } else printf("verify alicepayment couldnt find coin.(%s)\n",alicestr); printf("error validating alicepayment\n"); return(-1); } +/* + Bob paytx: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF +*/ + int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) { - uint8_t userdata[512]; int32_t i,retval=-1,len = 0; bits256 revAm; struct iguana_info *coin; - if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + uint8_t userdata[512]; char bobstr[65],bobtomic[128]; int32_t i,retval=-1,len = 0; bits256 revAm; struct iguana_info *coin; + LP_etomicsymbol(bobstr,bobtomic,swap->I.bobstr); + if ( (coin= LP_coinfind(bobstr)) != 0 ) { memset(revAm.bytes,0,sizeof(revAm)); if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->bobpayment,0,data,datalen,0) == 0 ) @@ -2210,6 +2481,7 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da swap->alicespend.utxotxid = swap->bobpayment.I.signedtxid = LP_broadcast_tx(swap->bobpayment.name,coin->symbol,swap->bobpayment.txbytes,swap->bobpayment.I.datalen); if ( bits256_nonz(swap->bobpayment.I.signedtxid) != 0 ) swap->paymentunconf = 1; + memset(revAm.bytes,0,sizeof(revAm)); for (i=0; i<32; i++) revAm.bytes[i] = swap->I.privAm.bytes[31-i]; len = basilisk_swapuserdata(userdata,revAm,0,swap->I.myprivs[0],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); @@ -2229,6 +2501,13 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da memcpy(swap->alicespend.I.pubkey33,swap->persistent_pubkey33,33); bitcoin_address(coin->symbol,swap->alicespend.I.destaddr,coin->taddr,coin->pubtype,swap->persistent_pubkey33,33); //char str[65],str2[65]; printf("bobpaid privAm.(%s) myprivs[0].(%s)\n",bits256_str(str,swap->I.privAm),bits256_str(str2,swap->I.myprivs[0])); +#ifndef NOTETOMIC + if (swap->bobpayment.I.ethTxid[0] != 0 && LP_etomic_is_empty_tx_id(swap->bobpayment.I.ethTxid) == 0) { + if (LP_etomic_wait_for_confirmation(swap->bobpayment.I.ethTxid) < 0 || LP_etomic_verify_bob_payment(swap, swap->bobpayment.I.ethTxid) == 0) { + return(-1); + } + } +#endif if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobpayment.I.destaddr,coin->zcash)) == 0 ) { /*for (i=0; ibobpayment.I.datalen; i++) @@ -2241,7 +2520,7 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da return(LP_waitmempool(coin->symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,60)); } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->alicespend.I.suppress_pubkeys,swap->bobpayment.I.destaddr); } - } else printf("verify bobpayment cant find (%s)\n",swap->I.bobstr); + } else printf("verify bobpayment cant find (%s)\n",bobstr); printf("error validating bobpayment\n"); return(-1); } diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c index 1bf47ebc2..ee2a8a336 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -27,6 +27,27 @@ struct LP_inuse_info } LP_inuse[1024]; int32_t LP_numinuse; +cJSON *LP_inuse_json() +{ + int32_t i; cJSON *item,*array; struct LP_inuse_info *lp; + array = cJSON_CreateArray(); + for (i=0; iexpiration != 0 ) + { + item = cJSON_CreateObject(); + jaddnum(item,"expiration",lp->expiration); + jaddbits256(item,"txid",lp->txid); + jaddnum(item,"vout",lp->vout); + if ( bits256_nonz(lp->otherpub) != 0 ) + jaddbits256(item,"otherpub",lp->otherpub); + jaddi(array,item); + } + } + return(array); +} + struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout) { int32_t i; @@ -103,7 +124,7 @@ struct LP_inuse_info *_LP_inuse_add(uint32_t expiration,bits256 otherpub,bits256 //if ( expiration > lp->expiration || expiration == 0 ) lp->expiration = expiration; } - char str[65]; printf("set inuse until %u lag.%d for %s/v%d\n",expiration,(int32_t)(expiration-(uint32_t)time(NULL)),bits256_str(str,txid),vout); + //char str[65]; printf("set inuse until %u lag.%d for %s/v%d\n",expiration,(int32_t)(expiration-(uint32_t)time(NULL)),bits256_str(str,txid),vout); return(lp); } else printf("_LP_inuse_add [%d] overflow\n",LP_numinuse); return(0); @@ -114,14 +135,16 @@ int32_t LP_reservation_check(bits256 txid,int32_t vout,bits256 pubkey) struct LP_inuse_info *lp; int32_t retval = -1; if ( bits256_nonz(pubkey) != 0 ) { + char str[65],str2[65]; portable_mutex_lock(&LP_inusemutex); if ( (lp= _LP_inuse_find(txid,vout)) != 0 ) { if ( bits256_cmp(lp->otherpub,pubkey) == 0 ) retval = 0; - } + else printf("otherpub.%s != %s\n",bits256_str(str,lp->otherpub),bits256_str(str2,pubkey)); + } else printf("couldnt find %s/v%d\n",bits256_str(str,txid),vout); portable_mutex_unlock(&LP_inusemutex); - } + } else printf("LP_reservation_check null pubkey\n"); return(retval); } @@ -260,30 +283,64 @@ struct LP_address *LP_address(struct iguana_info *coin,char *coinaddr) return(ap); } -int32_t LP_address_minmax(uint64_t *balancep,uint64_t *minp,uint64_t *maxp,struct iguana_info *coin,char *coinaddr) +int32_t LP_address_minmax(int32_t iambob,uint64_t *medianp,uint64_t *minp,uint64_t *maxp,struct iguana_info *coin,char *coinaddr) { - cJSON *array,*item; bits256 txid,zero; int64_t value; int32_t i,vout,height,n = 0; - *minp = *maxp = *balancep = 0; + cJSON *array,*item; bits256 txid,zero; int64_t max,max2,value; uint64_t *buf; int32_t i,m=0,vout,height,n = 0; + *minp = *maxp = *medianp = max = max2 = 0; memset(zero.bytes,0,sizeof(zero)); if ( (array= LP_listunspent(coin->symbol,coinaddr,zero,zero)) != 0 ) { //printf("address minmax.(%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { - for (i=0; i *maxp ) - *maxp = value; + if ( LP_allocated(txid,vout) != 0 ) + continue; + buf[m++] = value; + if ( value > max ) + { + max2 = max; + max = value; + } + else if ( value > max2 ) + max2 = value; if ( *minp == 0 || value < *minp ) *minp = value; - *balancep += value; } + if ( m > 1 ) + { + revsort64s(buf,m,sizeof(*buf)); + if ( iambob != 0 ) + { + if ( max == buf[0] && max2 == buf[1] ) + { + for (i=1; i= LP_DEPOSITSATOSHIS(buf[i]) ) + { + *maxp = buf[i]; + *medianp = buf[m/2]; + break; + } + } + } else printf("sort error? max %.8f != %.8f\n",dstr(max),dstr(buf[0])); + } + else + { + *maxp = buf[0]; + *medianp = buf[m/2]; + printf("alice addressmin max %s %.8f %.8f %.8f num.%d\n",coin->symbol,dstr(*minp),dstr(*maxp),dstr(*medianp),m); + } + } else *minp = *maxp = *medianp = 0; + free(buf); } free_json(array); } - return(n); + return(m/2); } int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct LP_address *ap,char *coinaddr) @@ -303,7 +360,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( LP_value_extract(txout,0) == 0 ) { - //printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); +//char str[65]; printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); free_json(txout); up->spendheight = 1; if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) @@ -314,7 +371,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a } else { - //printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); +//char str[65]; printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); up->spendheight = 1; if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) tx->outpoints[up->U.vout].spendheight = 1; @@ -381,9 +438,9 @@ void LP_mark_spent(char *symbol,bits256 txid,int32_t vout) } } -int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight) +int32_t LP_address_utxoadd(int32_t skipsearch,uint32_t timestamp,char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight) { - struct LP_address *ap; cJSON *txobj; struct LP_transaction *tx; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; //char str[65]; + struct LP_address *ap; char *hexstr; cJSON *txobj,*sobj; struct LP_transaction *tx; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; //char str[65]; if ( coin == 0 ) return(0); if ( spendheight > 0 ) // dont autocreate entries for spends we dont care about @@ -393,20 +450,23 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co if ( ap != 0 ) { flag = 0; - DL_FOREACH_SAFE(ap->utxos,up,tmp) + if ( skipsearch == 0 ) { - if ( vout == up->U.vout && bits256_cmp(up->U.txid,txid) == 0 ) + DL_FOREACH_SAFE(ap->utxos,up,tmp) { - flag = 1; - if ( height > 0 && up->U.height != height ) - up->U.height = height, flag |= 2; - if ( spendheight > 0 && up->spendheight != spendheight ) - up->spendheight = spendheight, flag |= 4; - if ( value != 0 && up->U.value == 0 && up->U.value != value ) - up->U.value = value, flag |= 8; - //up->timestamp = timestamp; - //char str[65]; printf("found >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); - break; + if ( vout == up->U.vout && bits256_cmp(up->U.txid,txid) == 0 ) + { + flag = 1; + if ( height > 0 && up->U.height != height ) + up->U.height = height, flag |= 2; + if ( spendheight > 0 && up->spendheight != spendheight ) + up->spendheight = spendheight, flag |= 4; + if ( value != 0 && up->U.value == 0 && up->U.value != value ) + up->U.value = value, flag |= 8; + //up->timestamp = timestamp; + //char str[65]; printf("found >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); + break; + } } } if ( flag == 0 && value != 0 ) @@ -417,7 +477,20 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co { //char str[65]; printf("prevent utxoadd since gettxout %s %s %s/v%d missing\n",coin->symbol,coinaddr,bits256_str(str,txid),vout); return(0); - } else free_json(txobj); + } + if ( (sobj= jobj(txobj,"scriptPubKey")) != 0 ) + { + if ( (hexstr= jstr(sobj,"hex")) != 0 ) + { + if ( strlen(hexstr) != 25*2 ) + { + //printf("skip non-standard utxo.(%s)\n",hexstr); + free_json(txobj); + return(0); + } + } + } + free_json(txobj); } up = calloc(1,sizeof(*up)); up->U.txid = txid; @@ -443,11 +516,13 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co return(retval); } -struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) +struct LP_address *LP_address_utxo_reset(int32_t *nump,struct iguana_info *coin) { - struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,m,vout,height; cJSON *array,*item,*txobj; bits256 zero; int64_t value; bits256 txid; uint32_t now; + struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,numconfs,m,vout,height; cJSON *array,*item,*txobj; bits256 zero; int64_t value; bits256 txid; uint32_t now; + *nump = 0; + if ( coin == 0 ) + return(0); LP_address(coin,coin->smartaddr); - //printf("call listunspent issue %s (%s)\n",coin->symbol,coin->smartaddr); memset(zero.bytes,0,sizeof(zero)); LP_listunspent_issue(coin->symbol,coin->smartaddr,2,zero,zero); if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) @@ -455,45 +530,63 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) printf("LP_address_utxo_reset: cant find address data\n"); return(0); } + if ( IAMLP != 0 && time(NULL) < coin->lastresetutxo+10 ) + return(ap); + coin->lastresetutxo = (uint32_t)time(NULL); + portable_mutex_lock(&coin->addressutxo_mutex); if ( (array= LP_listunspent(coin->symbol,coin->smartaddr,zero,zero)) != 0 ) { + portable_mutex_lock(&coin->addrmutex); + portable_mutex_lock(&LP_gcmutex); DL_FOREACH_SAFE(ap->utxos,up,tmp) { - portable_mutex_lock(&coin->addrmutex); DL_DELETE(ap->utxos,up); - portable_mutex_unlock(&coin->addrmutex); - portable_mutex_lock(&LP_gcmutex); up->spendheight = (int32_t)time(NULL); DL_APPEND(LP_garbage_collector2,up); - portable_mutex_unlock(&LP_gcmutex); } + portable_mutex_unlock(&coin->addrmutex); + portable_mutex_unlock(&LP_gcmutex); now = (uint32_t)time(NULL); if ( (n= cJSON_GetArraySize(array)) > 0 ) { char str[65]; + *nump = n; for (i=m=0; isymbol,coin->smartaddr,txid,vout)) == 0 ) + if ( bits256_nonz(txid) == 0 ) continue; - else free_json(txobj); - if ( LP_numconfirms(coin->symbol,coin->smartaddr,txid,vout,0) <= 0 ) - continue; - LP_address_utxoadd(now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1); + if ( 1 ) + { + if ( (txobj= LP_gettxout(coin->symbol,coin->smartaddr,txid,vout)) == 0 ) + { +//printf("skip null gettxout %s.v%d\n",bits256_str(str,txid),vout); + continue; + } + else free_json(txobj); + if ( (numconfs= LP_numconfirms(coin->symbol,coin->smartaddr,txid,vout,0)) <= 0 ) + { +//printf("skip numconfs.%d %s.v%d\n",numconfs,bits256_str(str,txid),vout); + continue; + } + } + LP_address_utxoadd(1,now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1); if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) - printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); + { +//printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); + } else { m++; //printf("%.8f ",dstr(value)); } } - //printf("added %d from listunspents\n",m); + printf("added %d of %d from %s listunspents\n",m,n,coin->symbol); } free_json(array); } + portable_mutex_unlock(&coin->addressutxo_mutex); return(ap); } @@ -545,9 +638,10 @@ cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrum } if ( up->spendheight <= 0 && up->U.value != 0 ) { - char str[65]; if ( LP_allocated(up->U.txid,up->U.vout) != 0 ) - printf("%s %s/v%d allocated\n",coin->symbol,bits256_str(str,up->U.txid),up->U.vout); + { + //printf("%s %s/v%d allocated\n",coin->symbol,bits256_str(str,up->U.txid),up->U.vout); + } else if ( coin->electrum == 0 || up->SPV > 0 ) { jaddi(array,LP_address_item(coin,up,electrumret)); @@ -583,20 +677,31 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr { cJSON *array,*retjson,*item; bits256 zero; int32_t i,n; uint64_t balance = 0; memset(zero.bytes,0,sizeof(zero)); + //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); + } else +#endif if ( coin->electrum == 0 ) { if ( (array= LP_listunspent(coin->symbol,coinaddr,zero,zero)) != 0 ) { + //printf("got address balance (%s)\n",jprint(array,0)); if ( (n= cJSON_GetArraySize(array)) > 0 ) { for (i=0; isymbol,coin->smartaddr); + //balance3 = LP_RTsmartbalance(coin); + //printf("balance %.8f vs balance2 %.8f vs balance3 %.8f\n",dstr(balance),dstr(balance2),dstr(balance3)); } else { @@ -728,7 +833,7 @@ int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array) if ( errs == 0 ) { //printf("from LP_unspents_array\n"); - LP_address_utxoadd((uint32_t)time(NULL),"LP_unspents_array",coin,coinaddr,txid,v,val,height,-1); + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_unspents_array",coin,coinaddr,txid,v,val,height,-1); count++; } } @@ -774,7 +879,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(coin->symbol,txid,0)) != 0 ) + if ( txobj != 0 || (txobj= LP_gettx("LP_transactioninit",coin->symbol,txid,0)) != 0 ) { if ( coin->electrum == 0 ) height = LP_txheight(coin,txid); @@ -792,7 +897,7 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest"); LP_destaddr(tx->outpoints[i].coinaddr,vout); //printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value)); - LP_address_utxoadd((uint32_t)time(NULL),"LP_transactioninit iter0",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_transactioninit iter0",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); } //printf("numvouts.%d\n",numvouts); } @@ -814,7 +919,7 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS tx->outpoints[spentvout].spendtxid = txid; tx->outpoints[spentvout].spendvini = i; tx->outpoints[spentvout].spendheight = height > 0 ? height : 1; - LP_address_utxoadd((uint32_t)time(NULL),"LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1); + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1); if ( 0 && strcmp(coin->symbol,"REVS") == 0 ) printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height); } @@ -831,12 +936,16 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS int32_t LP_txheight(struct iguana_info *coin,bits256 txid) { - bits256 blockhash; struct LP_transaction *tx; cJSON *blockobj,*retjson,*txobj; int32_t height = 0; + bits256 blockhash; struct LP_transaction *tx=0; cJSON *blockobj,*retjson,*txobj,*txobj2; int32_t height = 0; if ( coin == 0 ) return(-1); + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + height = tx->height; + if ( height > 0 ) + return(height); if ( coin->electrum == 0 ) { - if ( (txobj= LP_gettx(coin->symbol,txid,0)) != 0 ) + if ( (txobj= LP_gettx("LP_txheight",coin->symbol,txid,0)) != 0 ) { //*timestampp = juint(txobj,"locktime"); //*blocktimep = juint(txobj,"blocktime"); @@ -844,6 +953,17 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid) if ( bits256_nonz(blockhash) != 0 && (blockobj= LP_getblock(coin->symbol,blockhash)) != 0 ) { height = jint(blockobj,"height"); + if ( tx != 0 ) + tx->height = height; + else if ( 0 ) + { + txobj2 = LP_transactioninit(coin,txid,0,0); + txobj2 = LP_transactioninit(coin,txid,1,txobj2); + if ( txobj2 != 0 ) + free_json(txobj2); + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + tx->height = height; + } //char str[65]; //if ( strcmp(coin->symbol,"CHIPS") != 0 && strcmp(coin->symbol,"BTC") != 0 ) // printf("%s %s LP_txheight.%d\n",coin->symbol,bits256_str(str,txid),height); @@ -854,8 +974,8 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid) } else { - if ( (tx= LP_transactionfind(coin,txid)) != 0 ) - height = tx->height; + //if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + // height = tx->height; if ( height == 0 ) { if ( (retjson= electrum_transaction(&height,coin->symbol,coin->electrum,&retjson,txid,0)) != 0 ) @@ -886,7 +1006,7 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int } else if ( mempool != 0 && LP_mempoolscan(symbol,txid) >= 0 ) numconfirms = 0; - else if ( (txobj= LP_gettx(symbol,txid,1)) != 0 ) + else if ( (txobj= LP_gettx("LP_numconfirms",symbol,txid,1)) != 0 ) { numconfirms = jint(txobj,"confirmations"); free_json(txobj); @@ -904,6 +1024,18 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int numconfirms = 0; } } + /*if ( numconfirms == BASILISK_DEFAULT_MAXCONFIRMS ) + { + if ( coin->isassetchain != 0 || strcmp(coin->symbol,"KMD") == 0 ) + { + numconfirms--; + if ( coin->notarized >= coin->height-numconfirms ) + { + printf("%s notarized.%d current ht.%d - numconfirms.%d -> txheight.%d\n",coin->symbol,coin->notarized,coin->height,numconfirms,coin->height - numconfirms); + numconfirms = BASILISK_DEFAULT_MAXCONFIRMS; + } + } + }*/ return(numconfirms); } @@ -988,20 +1120,20 @@ uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout) } else if ( coin->electrum == 0 ) { - uint64_t value; + uint64_t value; char str[65]; if ( (txobj= LP_gettxout(coin->symbol,coinaddr,txid,vout)) != 0 ) { value = LP_value_extract(txobj,0);//SATOSHIDEN * (jdouble(txobj,"value") + jdouble(txobj,"interest")); if ( coinaddr != 0 ) LP_destaddr(coinaddr,txobj); - //printf("pruned node? LP_txvalue couldnt find %s tx %s, but gettxout %.8f\n",coin->symbol,bits256_str(str,txid),dstr(value)); + //printf("LP_txvalue %s tx %s/v%d value %.8f\n",coin->symbol,bits256_str(str,txid),vout,dstr(value)); if ( value != 0 ) { free_json(txobj); return(value); } } - //printf("pruned node? LP_txvalue couldnt find %s tx %s/v%d (%s)\n",coin->symbol,bits256_str(str,txid),vout,txobj!=0?jprint(txobj,0):""); + printf("pruned node? LP_txvalue couldnt find %s tx %s/v%d (%s)\n",coin->symbol,bits256_str(str,txid),vout,txobj!=0?jprint(txobj,0):""); if ( txobj != 0 ) free_json(txobj); } @@ -1015,7 +1147,7 @@ int64_t LP_outpoint_amount(char *symbol,bits256 txid,int32_t vout) return(amount); else { - if ( (txjson= LP_gettx(symbol,txid,1)) != 0 ) + if ( (txjson= LP_gettx("LP_outpoint_amount",symbol,txid,1)) != 0 ) { if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && vout < numvouts ) amount = LP_value_extract(jitem(vouts,vout),0); diff --git a/iguana/exchanges/auto_chipsbtc b/iguana/exchanges/auto_chipsbtc index 06c5282e9..35b9319e4 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.00002,\"maxprice\":0.0001,\"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.00006,\"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 c259a8cff..5a5794c86 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.04,\"maxprice\":0.1,\"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.15,\"maxprice\":0.4,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"KMD\",\"margin\":0.05,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}" diff --git a/iguana/exchanges/auto_usd b/iguana/exchanges/auto_usd new file mode 100644 index 000000000..3dfa13808 --- /dev/null +++ b/iguana/exchanges/auto_usd @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"OOT\",\"factor\":0.15,\"buymargin\":0.0001,\"sellmargin\":0.2,\"refbase\":\"komodo\",\"refrel\":\"coinmarketcap\",\"usdpeg\":1}" diff --git a/iguana/exchanges/autoprice b/iguana/exchanges/autoprice index 21369b468..52fc68df0 100755 --- a/iguana/exchanges/autoprice +++ b/iguana/exchanges/autoprice @@ -1,12 +1,55 @@ #!/bin/bash +margin=0.05 source userpass -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTC\",\"margin\":0.03}" -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BTC\",\"rel\":\"KMD\",\"margin\":0.03}" -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"HUSH\",\"margin\":0.01}" -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"HUSH\",\"rel\":\"KMD\",\"margin\":0.01}" -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"USD\",\"margin\":0.01}" -#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"USD\",\"rel\":\"KMD\",\"margin\":0.01}" -#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"JUMBLR\",\"margin\":0.01}" -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"JUMBLR\",\"rel\":\"KMD\",\"margin\":0.01}" -#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.0,\"refbase\":\"BTC\",\"refrel\":\"KMD\",\"factor\":0.00006667,\"margin\":-0.2}" -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"MNZ\",\"offset\":0.0,\"refbase\":\"KMD\",\"refrel\":\"BTC\",\"factor\":15000,\"margin\":-0.2}" + +# KMD/BTC must be first as other prices depend on it +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTC\",\"margin\":$margin,\"refbase\":\"komodo\",\"refrel\":\"coinmarketcap\"}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BTC\",\"rel\":\"KMD\",\"fixed\":0.00025,\"margin\":$margin}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTC\",\"fixed\":4000,\"margin\":$margin}" +curl --url "http://127.0.0.1:7783" --data "{\"minprice\":0.0003,\"maxprice\":0.001,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTC\",\"margin\":0.05,\"refbase\":\"komodo\",\"refrel\":\"coinmarketcap\"}" + +./auto_chipskmd +./auto_chipsbtc + +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"MNZ\",\"offset\":0.0,\"refbase\":\"KMD\",\"refrel\":\"BTC\",\"factor\":15000,\"margin\":-0.2}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"HUSH\",\"rel\":\"KMD\",\"margin\":$margin,\"refbase\":\"hush\",\"refrel\":\"coinmarketcap\"}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTCH\",\"offset\":0.0,\"refbase\":\"KMD\",\"refrel\":\"HUSH\",\"factor\":1.44,\"buymargin\":0.05,\"sellmargin\":0.05}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BTCH\",\"rel\":\"KMD\",\"offset\":0.0,\"refbase\":\"HUSH\",\"refrel\":\"KMD\",\"factor\":0.7,\"buymargin\":0.05,\"sellmargin\":0.05}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BEER\",\"rel\":\"PIZZA\",\"fixed\":0.0001,\"margin\":0.00001}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BEER\",\"rel\":\"ETOMIC\",\"fixed\":10,\"margin\":0.00001}" + +source crypto +source trackbtc + +#source jumblr +#source trackbtc + +source pangea +source trackbtc + +source bet +source trackbtc + +#source revs +#source trackbtc + +sharkholdings="{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"komodo\",\"balance\":120000}, {\"coin\":\"bitcoin-cash\",\"balance\":1200}, {\"coin\":\"bitcoin\",\"balance\":100}" +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\":600}, {\"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 }],\"divisor\":612529}" + +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}" +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}" + +curl --url "http://127.0.0.1:7783" --data "{\"base\":\"JUMBLR\",\"rel\":\"KMD\",\"margin\":$margin,\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RGhxXpXSSBTBm9EvNsXnTQczthMCxHX91t\",\"holdings\":[$dexholdings],\"divisor\":3333333}" + +curl --url "http://127.0.0.1:7783" --data "{\"base\":\"MGW\",\"rel\":\"KMD\",\"margin\":$margin,\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"holdings\":[$dexholdings],\"divisor\":13000000}" + +curl --url "http://127.0.0.1:7783" --data "{\"base\":\"REVS\",\"rel\":\"KMD\",\"margin\":$margin,\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"holdings\":[$dexholdings],\"divisor\":9000000}" diff --git a/iguana/exchanges/beertest b/iguana/exchanges/beertest new file mode 100755 index 000000000..61b600820 --- /dev/null +++ b/iguana/exchanges/beertest @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BEER\",\"rel\":\"KMD\",\"fixed\":1.28700,\"margin\":0.00001}" diff --git a/iguana/exchanges/bet b/iguana/exchanges/bet new file mode 100644 index 000000000..9f97c5b08 --- /dev/null +++ b/iguana/exchanges/bet @@ -0,0 +1,3 @@ +coin=BET +price=0.00075 +invprice=1333.33 diff --git a/iguana/exchanges/calcaddress b/iguana/exchanges/calcaddress new file mode 100755 index 000000000..76f1da5e1 --- /dev/null +++ b/iguana/exchanges/calcaddress @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"calcaddress\",\"passphrase\":\"default\"}" diff --git a/iguana/exchanges/client b/iguana/exchanges/client index 3b33a363a..8f5502a1d 100755 --- a/iguana/exchanges/client +++ b/iguana/exchanges/client @@ -3,8 +3,9 @@ source passphrase source coins ./stop git pull; +cp ../exchanges/updateprices .;./updateprices cd ..; ./m_mm; pkill -15 marketmaker; -./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & +stdbuf -oL $1 ./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & diff --git a/iguana/exchanges/client_static b/iguana/exchanges/client_static new file mode 100755 index 000000000..484c1cf57 --- /dev/null +++ b/iguana/exchanges/client_static @@ -0,0 +1,11 @@ +#!/bin/bash +source passphrase +source coins +pkill -15 marketmaker; +git pull; +cd ..; +make -f m_mm_StaticNanoMsg -j2 all; +rm -rf ./marketmaker +cp -av ../agents/marketmaker ./ +./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & + diff --git a/iguana/exchanges/coins b/iguana/exchanges/coins index b41a8b96f..750f2695f 100644 --- a/iguana/exchanges/coins +++ b/iguana/exchanges/coins @@ -1,3 +1,2 @@ -export coins="[{\"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\":\"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}, {\"coin\":\"BNB\",\"name\":\"binance-coin\",\"etomic\":\"0xB8c77482e45F1F44dE1745F52C74426C631bDD52\",\"rpcport\":80}, {\"coin\":\"DGD\",\"name\":\"digixdao\",\"etomic\":\"0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A\",\"rpcport\":80}, {\"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\":\"GNT\",\"name\":\"golem\",\"etomic\":\"0xa74476443119A942dE498590Fe1f2454d7D4aC0d\",\"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}]" -#{\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, diff --git a/iguana/exchanges/convaddress b/iguana/exchanges/convaddress new file mode 100755 index 000000000..fc2d1da2c --- /dev/null +++ b/iguana/exchanges/convaddress @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"convaddress\",\"coin\":\"BTC\",\"address\":\"1KPctPk4Zs4Qbe1x32A5bC1roAnmpvi9Fy\",\"destcoin\":\"KMD\"}" diff --git a/iguana/exchanges/crypto b/iguana/exchanges/crypto new file mode 100644 index 000000000..7cd57178c --- /dev/null +++ b/iguana/exchanges/crypto @@ -0,0 +1,3 @@ +coin=CRYPTO +price=0.002666666 +invprice=375 diff --git a/iguana/exchanges/dump b/iguana/exchanges/dump new file mode 100755 index 000000000..65f444120 --- /dev/null +++ b/iguana/exchanges/dump @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"KMD\",\"rel\":\"HODL\",\"dump\":40.00038}" diff --git a/iguana/exchanges/enable b/iguana/exchanges/enable index e5121918a..f682b9343 100755 --- a/iguana/exchanges/enable +++ b/iguana/exchanges/enable @@ -1,6 +1,7 @@ #!/bin/bash source userpass curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BEER\"}" +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\":\"PIZZA\"}" curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"REVS\"}" curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"KMD\"}" diff --git a/iguana/exchanges/etomicswap/CMakeLists.txt b/iguana/exchanges/etomicswap/CMakeLists.txt new file mode 100644 index 000000000..ace34d80f --- /dev/null +++ b/iguana/exchanges/etomicswap/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.5.1) +add_library(etomiclib-testnet etomiclib.cpp etomiccurl.c) +add_library(etomiclib-mainnet etomiclib.cpp etomiccurl.c) +target_compile_definitions(etomiclib-testnet PRIVATE ETOMIC_TESTNET) +add_executable(alice alice.c) +add_executable(bob bob.c) +if(WIN32) +add_definitions(-DNATIVE_WINDOWS) +add_definitions(-DIGUANA_LOG2PACKETSIZE=20) +add_definitions(-DIGUANA_MAXPACKETSIZE=1572864) +add_definitions(-D_CRT_SECURE_NO_WARNINGS) +add_definitions(-DNOMINMAX) +include_directories("${CMAKE_SOURCE_DIR}/includes") +endif() +include_directories("${CMAKE_SOURCE_DIR}/cpp-ethereum") +target_link_libraries(etomiclib-testnet PUBLIC curl libcrypto777 ethcore devcrypto devcore pthread) +target_link_libraries(etomiclib-mainnet PUBLIC curl libcrypto777 ethcore devcrypto devcore pthread) +target_link_libraries(alice PUBLIC etomiclib-testnet) +target_link_libraries(bob PUBLIC etomiclib-testnet) diff --git a/iguana/exchanges/etomicswap/alice.c b/iguana/exchanges/etomicswap/alice.c new file mode 100644 index 000000000..0b2508aac --- /dev/null +++ b/iguana/exchanges/etomicswap/alice.c @@ -0,0 +1,106 @@ +// +// Created by artem on 24.01.18. +// +#include +#include +#include +#include "etomiclib.h" +#include + +char* aliceContractAddress = "0xe1D4236C5774D35Dc47dcc2E5E0CcFc463A3289c"; +char* aliceAddress = "0x485d2cc2d13a9e12E4b53D606DB1c8adc884fB8a"; +char* bobAddress = "0xA7EF3f65714AE266414C9E58bB4bAa4E6FB82B41"; +char* tokenAddress = "0xc0eb7AeD740E1796992A08962c15661bDEB58003"; + +int main(int argc, char** argv) { + enum { INIT_ETH, INIT_ERC20, ALICE_CLAIMS, BOB_CLAIMS, ALICE_APPROVES_ERC20 }; + + if (argc < 2) { + return 1; + } + + int action = atoi(argv[1]); + char* result; + BasicTxData txData; + switch (action) + { + case INIT_ETH: + txData.amount = "1000000000000000000"; + txData.from = aliceAddress; + txData.to = aliceContractAddress; + txData.secretKey = getenv("ALICE_PK"); + + AliceSendsEthPaymentInput input = { + .dealId = argv[2], + .bobAddress = bobAddress, + .aliceHash = argv[3], + .bobHash = argv[4] + }; + + result = aliceSendsEthPayment(input, txData); + break; + case INIT_ERC20: + txData.amount = "0"; + txData.from = aliceAddress; + txData.to = aliceContractAddress; + txData.secretKey = getenv("ALICE_PK"); + + AliceSendsErc20PaymentInput input1 = { + .dealId = argv[2], + .bobAddress = bobAddress, + .aliceHash = argv[3], + .bobHash = argv[4], + .amount = "1000000000000000000", + .tokenAddress = tokenAddress + }; + + result = aliceSendsErc20Payment(input1, txData); + break; + case ALICE_CLAIMS: + txData.amount = "0"; + txData.from = aliceAddress; + txData.to = aliceContractAddress; + txData.secretKey = getenv("ALICE_PK"); + + AliceReclaimsAlicePaymentInput input2 = { + .dealId = argv[2], + .bobAddress = bobAddress, + .aliceHash = argv[3], + .bobSecret = argv[4], + .tokenAddress = argv[5], + .amount = "1000000000000000000" + }; + + result = aliceReclaimsAlicePayment(input2, txData); + break; + case BOB_CLAIMS: + txData.amount = "0"; + txData.from = bobAddress; + txData.to = aliceContractAddress; + txData.secretKey = getenv("BOB_PK"); + + BobSpendsAlicePaymentInput input3 = { + .dealId = argv[2], + .aliceAddress = aliceAddress, + .aliceSecret = argv[3], + .bobHash = argv[4], + .tokenAddress = argv[5], + .amount = "1000000000000000000" + }; + + result = bobSpendsAlicePayment(input3, txData); + break; + case ALICE_APPROVES_ERC20: + result = approveErc20( + "1000000000000000000", + "0x485d2cc2d13a9e12E4b53D606DB1c8adc884fB8a", + getenv("ALICE_PK") + ); + break; + default: + return 1; + } + printf("%s\n", result); + free(result); + return 0; +} diff --git a/iguana/exchanges/etomicswap/bob.c b/iguana/exchanges/etomicswap/bob.c new file mode 100644 index 000000000..6b3f28261 --- /dev/null +++ b/iguana/exchanges/etomicswap/bob.c @@ -0,0 +1,363 @@ +// +// Created by artem on 24.01.18. +// +#include +#include +#include +#include +#include +#include "etomiclib.h" +#include "etomiccurl.h" + +char* bobContractAddress = "0x9387Fd3a016bB0205e4e131Dde886B9d2BC000A2"; +char* aliceAddress = "0x485d2cc2d13a9e12E4b53D606DB1c8adc884fB8a"; +char* bobAddress = "0xbAB36286672fbdc7B250804bf6D14Be0dF69fa29"; +char* tokenAddress = "0xc0eb7AeD740E1796992A08962c15661bDEB58003"; + +void *erc20ApproveThread(ApproveErc20Input *input) { + char *result = approveErc20(*input); + free(result); +} + +int main(int argc, char** argv) +{ + enum { + BOB_ETH_DEPOSIT, + BOB_ERC20_DEPOSIT, + BOB_CLAIMS_DEPOSIT, + ALICE_CLAIMS_DEPOSIT, + BOB_ETH_PAYMENT, + BOB_ERC20_PAYMENT, + BOB_CLAIMS_PAYMENT, + ALICE_CLAIMS_PAYMENT, + BOB_APPROVES_ERC20, + BOB_ETH_BALANCE, + BOB_ERC20_BALANCE, + TX_RECEIPT, + TX_DATA + }; + if (argc < 2) { + return 1; + } + int action = atoi(argv[1]); + BasicTxData txData; + char* result; + switch (action) + { + case BOB_ETH_DEPOSIT: + strcpy(txData.amount, "1000000000000000000"); + strcpy(txData.from, bobAddress); + strcpy(txData.to, bobContractAddress); + strcpy(txData.secretKey, getenv("BOB_PK")); + + BobSendsEthDepositInput input; + + strcpy(input.aliceAddress, aliceAddress); + strcpy(input.depositId, argv[2]); + strcpy(input.bobHash, argv[3]); + + result = bobSendsEthDeposit(input, txData); + if (result != NULL) { + printf("%s\n", result); + free(result); + } else { + printf("Tx send result was NULL\n"); + } + break; + case BOB_ERC20_DEPOSIT: + strcpy(txData.amount, "0"); + strcpy(txData.from, bobAddress); + strcpy(txData.to, bobContractAddress); + strcpy(txData.secretKey, getenv("BOB_PK")); + + BobSendsErc20DepositInput input1 = { + .amount = "1000000000000000000" + }; + + strcpy(input1.depositId, argv[2]); + strcpy(input1.aliceAddress, aliceAddress); + strcpy(input1.bobHash, argv[3]); + strcpy(input1.tokenAddress, tokenAddress); + + result = bobSendsErc20Deposit(input1, txData); + if (result != NULL) { + printf("%s\n", result); + free(result); + } else { + printf("Tx send result was NULL\n"); + } + free(result); + break; + case BOB_CLAIMS_DEPOSIT: + strcpy(txData.amount, "0"); + strcpy(txData.from, bobAddress); + strcpy(txData.to, bobContractAddress); + strcpy(txData.secretKey, getenv("BOB_PK")); + + BobRefundsDepositInput input2; + strcpy(input2.depositId, argv[2]); + strcpy(input2.amount, "1000000000000000000"); + strcpy(input2.aliceAddress, aliceAddress); + strcpy(input2.tokenAddress, argv[3]); + strcpy(input2.bobSecret, argv[5]); + + result = bobRefundsDeposit(input2, txData); + if (result != NULL) { + printf("%s\n", result); + free(result); + } else { + printf("Tx send result was NULL\n"); + } + free(result); + break; + case ALICE_CLAIMS_DEPOSIT: + strcpy(txData.amount, "0"); + strcpy(txData.from, aliceAddress); + strcpy(txData.to, bobContractAddress); + strcpy(txData.secretKey, getenv("ALICE_PK")); + + AliceClaimsBobDepositInput input3; + strcpy(input3.depositId, argv[2]); + strcpy(input3.amount, "1000000000000000000"); + strcpy(input3.bobAddress, bobAddress); + strcpy(input3.tokenAddress, argv[3]); + strcpy(input3.bobHash, argv[5]); + + result = aliceClaimsBobDeposit(input3, txData); + if (result != NULL) { + printf("%s\n", result); + free(result); + } else { + printf("Tx send result was NULL\n"); + } + free(result); + break; + case BOB_ETH_PAYMENT: + strcpy(txData.amount, "1000000000000000000"); + strcpy(txData.from, bobAddress); + strcpy(txData.to, bobContractAddress); + strcpy(txData.secretKey, getenv("BOB_PK")); + + BobSendsEthPaymentInput input4; + strcpy(input4.paymentId, argv[2]); + strcpy(input4.aliceHash, argv[3]); + strcpy(input4.aliceAddress, aliceAddress); + + result = bobSendsEthPayment(input4, txData); + if (result != NULL) { + printf("%s\n", result); + free(result); + } else { + printf("Tx send result was NULL\n"); + } + free(result); + break; + case BOB_ERC20_PAYMENT: + strcpy(txData.amount, "0"); + strcpy(txData.from, bobAddress); + strcpy(txData.to, bobContractAddress); + strcpy(txData.secretKey, getenv("BOB_PK")); + + BobSendsErc20PaymentInput input5; + + strcpy(input5.paymentId, argv[2]); + strcpy(input5.amount, "1000000000000000000"); + strcpy(input5.tokenAddress, tokenAddress); + strcpy(input5.aliceAddress, aliceAddress); + strcpy(input5.aliceHash, argv[3]); + + result = bobSendsErc20Payment(input5, txData); + if (result != NULL) { + printf("%s\n", result); + free(result); + } else { + printf("Tx send result was NULL\n"); + } + free(result); + break; + case BOB_CLAIMS_PAYMENT: + strcpy(txData.amount, "0"); + strcpy(txData.from, bobAddress); + strcpy(txData.to, bobContractAddress); + strcpy(txData.secretKey, getenv("BOB_PK")); + + BobReclaimsBobPaymentInput input6; + + strcpy(input6.paymentId, argv[2]); + strcpy(input6.aliceAddress, aliceAddress); + strcpy(input6.amount, "1000000000000000000"); + strcpy(input6.tokenAddress, argv[3]); + strcpy(input6.aliceHash, argv[5]); + + result = bobReclaimsBobPayment(input6, txData); + if (result != NULL) { + printf("%s\n", result); + free(result); + } else { + printf("Tx send result was NULL\n"); + } + free(result); + break; + case ALICE_CLAIMS_PAYMENT: + strcpy(txData.amount, "0"); + strcpy(txData.from, aliceAddress); + strcpy(txData.to, bobContractAddress); + strcpy(txData.secretKey, getenv("ALICE_PK")); + + AliceSpendsBobPaymentInput input7; + + strcpy(input7.paymentId, argv[2]); + strcpy(input7.bobAddress, bobAddress); + strcpy(input7.amount, "1000000000000000000"); + strcpy(input7.tokenAddress, argv[3]); + strcpy(input7.aliceSecret, argv[5]); + + result = aliceSpendsBobPayment(input7, txData); + if (result != NULL) { + printf("%s\n", result); + free(result); + } else { + printf("Tx send result was NULL\n"); + } + break; + case BOB_APPROVES_ERC20: + printf("approving erc20\n"); + ApproveErc20Input input8; + strcpy(input8.amount, "0"); + strcpy(input8.spender, bobContractAddress); + strcpy(input8.owner, bobAddress); + strcpy(input8.tokenAddress, tokenAddress); + strcpy(input8.secret, getenv("BOB_PK")); + ApproveErc20Input input123; + strcpy(input123.amount, "100"); + strcpy(input123.spender, bobContractAddress); + strcpy(input123.owner, bobAddress); + strcpy(input123.tokenAddress, tokenAddress); + strcpy(input123.secret, getenv("BOB_PK")); + pthread_t t1, t2; + pthread_create(&t1, NULL, erc20ApproveThread, &input8); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_join(t1, NULL); + pthread_join(t2, NULL); + /*result = approveErc20(input8); + if (result != NULL) { + printf("%s\n", result); + free(result); + } else { + printf("Tx send result was NULL\n"); + } + result = approveErc20(&input8); + if (result != NULL) { + printf("%s\n", result); + free(result); + } else { + printf("Tx send result was NULL\n"); + } + */ + break; + case BOB_ETH_BALANCE: + printf("%" PRIu64 "\n", getEthBalance(bobAddress)); + break; + case BOB_ERC20_BALANCE: + printf("%" PRIu64 "\n", getErc20BalanceSatoshi(bobAddress, tokenAddress)); + break; + case TX_RECEIPT: + printf("getTxReceipt\n"); + EthTxReceipt txReceipt; + txReceipt = getEthTxReceipt("0xc337b9cfe76aaa9022d9399a9e4ecdc1b7044d65ef74e8911a4b47874bee60c6"); + printf("blockNumber: %" PRIu64 "\n", txReceipt.blockNumber); + printf("blockHash: %s\n", txReceipt.blockHash); + printf("status: %s\n", txReceipt.status); + printf("confirmations: %" PRIu64 "\n", txReceipt.confirmations); + break; + case TX_DATA: + printf("getTxData\n"); + EthTxData ethTxData; + ethTxData = getEthTxData("0xc337b9cfe76aaa9022d9399a9e4ecdc1b7044d65ef74e8911a4b47874bee60c6"); + printf("from : %s\n", ethTxData.from); + printf("to: %s\n", ethTxData.to); + printf("value: %s\n", ethTxData.valueHex); + printf("input: %s\n", ethTxData.input); + printf("exists: %d\n", ethTxData.exists); + break; + default: + return 1; + } + char *pubkey = getPubKeyFromPriv(getenv("BOB_PK")); + printf("pubkey: %s\n", pubkey); + free(pubkey); + + char *address = pubKey2Addr("03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06"); + printf("address: %s\n", address); + free(address); + + uint64_t satoshis = 100000000; + char weiBuffer[100]; + satoshisToWei(weiBuffer, satoshis); + printf("wei: %s\n", weiBuffer); + + uint8_t decimals = getErc20Decimals(tokenAddress); + printf("decimals: %d\n", decimals); + + uint64_t tokenAllowance = getErc20Allowance(bobAddress, bobContractAddress, tokenAddress); + printf("allowance: %" PRIu64 "\n", tokenAllowance); + + char *sendEthTx = sendEth(bobAddress, "100000000000000", getenv("BOB_PK"), 0); + printf("sent ETH: %s\n", sendEthTx); + free(sendEthTx); + + char *sendErc20Tx = sendErc20(tokenAddress, bobAddress, "100000000000000", getenv("BOB_PK"), 0); + printf("sent Erc20: %s\n", sendErc20Tx); + free(sendErc20Tx); + + uint64_t gasPrice = getGasPriceFromStation(); + printf("gasPrice: %" PRIu64 "\n", gasPrice); + return 0; +} diff --git a/iguana/exchanges/etomicswap/etomiccurl.c b/iguana/exchanges/etomicswap/etomiccurl.c new file mode 100644 index 000000000..e7f1296ee --- /dev/null +++ b/iguana/exchanges/etomicswap/etomiccurl.c @@ -0,0 +1,344 @@ +#include "etomiccurl.h" +#include + +static char *ethRpcUrl = ETOMIC_URL; +pthread_mutex_t sendTxMutex = PTHREAD_MUTEX_INITIALIZER; + +struct string { + char *ptr; + size_t len; +}; + +void init_eth_string(struct string *s) { + s->len = 0; + s->ptr = malloc(s->len+1); + if (s->ptr == NULL) { + fprintf(stderr, "malloc() failed\n"); + exit(EXIT_FAILURE); + } + s->ptr[0] = '\0'; +} + +size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s) +{ + size_t new_len = s->len + size*nmemb; + s->ptr = realloc(s->ptr, new_len+1); + if (s->ptr == NULL) { + fprintf(stderr, "realloc() failed\n"); + exit(EXIT_FAILURE); + } + memcpy(s->ptr+s->len, ptr, size*nmemb); + s->ptr[new_len] = '\0'; + s->len = new_len; + + return size*nmemb; +} + +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"); + return NULL; + } + cJSON *tmp = cJSON_GetObjectItem(json, "result"); + cJSON *error = cJSON_GetObjectItem(json, "error"); + cJSON *result = NULL; + if (!is_cJSON_Null(tmp)) { + result = cJSON_Duplicate(tmp, 1); + } else if (error != NULL && !is_cJSON_Null(error)) { + char *errorString = cJSON_PrintUnformatted(error); + printf("Got ETH rpc error: %s\n", errorString); + free(errorString); + } + cJSON_Delete(json); + return result; +} + +char* sendRequest(char* request) +{ + CURL *curl; + CURLcode res; + struct curl_slist *headers = NULL; + curl = curl_easy_init(); + if (curl) { + struct string s; + init_eth_string(&s); + + headers = curl_slist_append(headers, "Accept: application/json"); + headers = curl_slist_append(headers, "Content-Type: application/json"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + 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_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)); + } + + /* always cleanup */ + curl_easy_cleanup(curl); + return s.ptr; + } else { + return NULL; + } +} + +cJSON *sendRpcRequest(char *method, cJSON *params) +{ + char* string; + cJSON *request = cJSON_CreateObject(); + cJSON_AddStringToObject(request, "jsonrpc", "2.0"); + cJSON_AddStringToObject(request, "method", method); + cJSON_AddItemToObject(request, "params", cJSON_Duplicate(params, 1)); + cJSON_AddNumberToObject(request, "id", 1); + string = cJSON_PrintUnformatted(request); + char* requestResult = sendRequest(string); + free(string); + cJSON_Delete(request); + cJSON *result = parseEthRpcResponse(requestResult); + free(requestResult); + return result; +} + +char* sendRawTxWaitConfirm(char* rawTx) +{ + cJSON *params = cJSON_CreateArray(); + cJSON_AddItemToArray(params, cJSON_CreateString(rawTx)); + cJSON *resultJson = sendRpcRequest("eth_sendRawTransaction", params); + cJSON_Delete(params); + char *txId = NULL; + if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) { + char* tmp = resultJson->valuestring; + txId = (char *) malloc(strlen(tmp) + 1); + strcpy(txId, tmp); + } + /* + if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) { + char* tmp = resultJson->valuestring; + if (waitForConfirmation(tmp) > 0) { + txId = (char *) malloc(strlen(tmp) + 1); + strcpy(txId, tmp); + } + } + */ + cJSON_Delete(resultJson); + pthread_mutex_unlock(&sendTxMutex); + return txId; +} + +char* sendRawTx(char* rawTx) +{ + cJSON *params = cJSON_CreateArray(); + cJSON_AddItemToArray(params, cJSON_CreateString(rawTx)); + cJSON *resultJson = sendRpcRequest("eth_sendRawTransaction", params); + cJSON_Delete(params); + char *txId = NULL; + if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) { + char* tmp = resultJson->valuestring; + txId = (char *) malloc(strlen(tmp) + 1); + strcpy(txId, tmp); + } + cJSON_Delete(resultJson); + pthread_mutex_unlock(&sendTxMutex); + return txId; +} + +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! + if (pthread_mutex_lock(&sendTxMutex) != 0) { + printf("Nonce mutex lock failed\n"); + }; + cJSON *params = cJSON_CreateArray(); + cJSON_AddItemToArray(params, cJSON_CreateString(address)); + // cJSON_AddItemToArray(params, cJSON_CreateString("pending")); + int64_t nonce = -1; + cJSON *nonceJson = sendRpcRequest("parity_nextNonce", params); + cJSON_Delete(params); + if (nonceJson != NULL && is_cJSON_String(nonceJson) && nonceJson != NULL) { + nonce = (int64_t) strtol(nonceJson->valuestring, NULL, 0); + } + cJSON_Delete(nonceJson); + printf("Got ETH nonce %d\n", (int)nonce); + return nonce; +} + +char* getEthBalanceRequest(char* address) +{ + cJSON *params = cJSON_CreateArray(); + cJSON_AddItemToArray(params, cJSON_CreateString(address)); + cJSON_AddItemToArray(params, cJSON_CreateString("latest")); + cJSON *balanceJson = sendRpcRequest("eth_getBalance", params); + cJSON_Delete(params); + char *balance = NULL; + if (balanceJson != NULL && is_cJSON_String(balanceJson) && balanceJson->valuestring != NULL) { + balance = (char *) malloc(strlen(balanceJson->valuestring) + 1); + strcpy(balance, balanceJson->valuestring); + } + cJSON_Delete(balanceJson); + return balance; +} + +char* ethCall(char* to, const char* data) +{ + cJSON *params = cJSON_CreateArray(); + cJSON *txObject = cJSON_CreateObject(); + cJSON_AddStringToObject(txObject, "to", to); + cJSON_AddStringToObject(txObject, "data", data); + cJSON_AddItemToArray(params, txObject); + cJSON_AddItemToArray(params, cJSON_CreateString("latest")); + cJSON *resultJson = sendRpcRequest("eth_call", params); + cJSON_Delete(params); + char* result = NULL; + if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) { + result = (char *) malloc(strlen(resultJson->valuestring) + 1); + strcpy(result, resultJson->valuestring); + } + cJSON_Delete(resultJson); + return result; +} + +EthTxReceipt getEthTxReceipt(char *txId) +{ + EthTxReceipt result; + memset(&result, 0, sizeof(result)); + cJSON *params = cJSON_CreateArray(); + cJSON_AddItemToArray(params, cJSON_CreateString(txId)); + cJSON *receiptJson = sendRpcRequest("eth_getTransactionReceipt", params); + cJSON_Delete(params); + if (receiptJson == NULL || is_cJSON_Null(cJSON_GetObjectItem(receiptJson, "blockHash")) || is_cJSON_Null(cJSON_GetObjectItem(receiptJson, "blockNumber"))) { + printf("ETH tx %s is not confirmed yet or does not exist at all\n", txId); + strcpy(result.blockHash, "0x0000000000000000000000000000000000000000000000000000000000000000"); + result.blockNumber = 0; + } else { + uint64_t currentBlockNumber = getEthBlockNumber(); + strcpy(result.blockHash, cJSON_GetObjectItem(receiptJson, "blockHash")->valuestring); + strcpy(result.status, cJSON_GetObjectItem(receiptJson, "status")->valuestring); + result.blockNumber = (uint64_t) strtol(cJSON_GetObjectItem(receiptJson, "blockNumber")->valuestring, NULL, 0); + if (currentBlockNumber >= result.blockNumber) { + result.confirmations = currentBlockNumber - result.blockNumber + 1; + } + } + cJSON_Delete(receiptJson); + return result; +} + +uint64_t getEthBlockNumber() +{ + uint64_t result = 0; + cJSON *params = cJSON_CreateArray(); + cJSON *blockNumberJson = sendRpcRequest("eth_blockNumber", params); + cJSON_Delete(params); + if (blockNumberJson != NULL && is_cJSON_String(blockNumberJson) && blockNumberJson->valuestring != NULL) { + result = (uint64_t) strtol(blockNumberJson->valuestring, NULL, 0); + } + cJSON_Delete(blockNumberJson); + return result; +} + +EthTxData getEthTxData(char *txId) +{ + EthTxData result; + memset(&result, 0, sizeof(result)); + cJSON *params = cJSON_CreateArray(); + cJSON_AddItemToArray(params, cJSON_CreateString(txId)); + cJSON *dataJson = sendRpcRequest("eth_getTransactionByHash", params); + cJSON_Delete(params); + if (dataJson == NULL) { + result.exists = 0; + printf("ETH tx %s get data error or txId does not exist\n", txId); + } else { + result.exists = 1; + strcpy(result.from, cJSON_GetObjectItem(dataJson, "from")->valuestring); + strcpy(result.to, cJSON_GetObjectItem(dataJson, "to")->valuestring); + strcpy(result.input, cJSON_GetObjectItem(dataJson, "input")->valuestring); + strcpy(result.valueHex, cJSON_GetObjectItem(dataJson, "value")->valuestring); + } + free(dataJson); + return result; +} + +uint64_t getGasPriceFromStation() +{ + CURL *curl; + CURLcode res; + struct curl_slist *headers = NULL; + curl = curl_easy_init(); + if (curl) { + struct string s; + init_eth_string(&s); + + headers = curl_slist_append(headers, "Accept: application/json"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); + 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); + /* Check for errors */ + if (res != CURLE_OK) { + fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); + return DEFAULT_GAS_PRICE; + } + + /* always cleanup */ + curl_easy_cleanup(curl); + cJSON *resultJson = cJSON_Parse(s.ptr); + uint64_t result = DEFAULT_GAS_PRICE; + free(s.ptr); + if (resultJson == NULL) { + return result; + } + + if (is_cJSON_Number(cJSON_GetObjectItem(resultJson, "average"))) { +#ifdef ETOMIC_TESTNET + result = (uint64_t)(cJSON_GetObjectItem(resultJson, "average")->valuedouble / 10) + 10; +#else + result = (uint64_t)(cJSON_GetObjectItem(resultJson, "average")->valuedouble / 10) + 1; +#endif + } + cJSON_Delete(resultJson); + return result; + } else { + return DEFAULT_GAS_PRICE; + } +} + +int32_t waitForConfirmation(char *txId) +{ + EthTxReceipt receipt; + EthTxData txData; + uint8_t retries = 0; + do { + receipt = getEthTxReceipt(txId); + if (receipt.confirmations < 1) { + txData = getEthTxData(txId); + if (txData.exists == 0) { + retries++; + if (retries >= 30) { + printf("Have not found ETH tx %s after 10 checks, aborting\n", txId); + return (-1); + } + } + } else { + break; + } + printf("waiting for ETH txId to be confirmed: %s\n", txId); + sleep(15); + } while (1); + + if (strcmp(receipt.status, "0x1") != 0) { + printf("ETH txid %s receipt status failed\n", txId); + return(-1); + } + + return((int32_t)receipt.confirmations); +} diff --git a/iguana/exchanges/etomicswap/etomiccurl.h b/iguana/exchanges/etomicswap/etomiccurl.h new file mode 100644 index 000000000..c0433bc75 --- /dev/null +++ b/iguana/exchanges/etomicswap/etomiccurl.h @@ -0,0 +1,54 @@ +#ifndef ETOMIC_CURL_HEADER +#define ETOMIC_CURL_HEADER + +#include +#include +#ifdef _WIN32 +#include "../../../OSlibs/win/pthread.h" +#endif + +#ifdef __cplusplus +extern "C"{ +#endif + +#ifdef ETOMIC_TESTNET +#define ETOMIC_URL "http://195.201.0.6:8545" +#define DEFAULT_GAS_PRICE 100 +#else +#define ETOMIC_URL "http://195.201.0.6:8555" +#define DEFAULT_GAS_PRICE 4 +#endif + +typedef struct +{ + uint64_t blockNumber; + uint64_t confirmations; + char blockHash[75]; + char status[10]; +} EthTxReceipt; + +typedef struct +{ + char from[50]; + char to[50]; + char input[1000]; + char valueHex[70]; + uint8_t exists; +} EthTxData; + +char* sendRawTx(char* rawTx); +char* sendRawTxWaitConfirm(char* rawTx); +char* ethCall(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(); +int32_t waitForConfirmation(char *txId); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/iguana/exchanges/etomicswap/etomiclib.cpp b/iguana/exchanges/etomicswap/etomiclib.cpp new file mode 100644 index 000000000..204848477 --- /dev/null +++ b/iguana/exchanges/etomicswap/etomiclib.cpp @@ -0,0 +1,656 @@ +// +// Created by artem on 24.01.18. +// +#include "etomiclib.h" +#include "etomiccurl.h" +#include +#include +#include +#include +#include + +using namespace dev; +using namespace dev::eth; + +char *stringStreamToChar(std::stringstream& ss) +{ + const std::string tmp = ss.str(); + auto result = (char*)malloc(strlen(tmp.c_str()) + 1); + strcpy(result, tmp.c_str()); + return result; +} + +TransactionSkeleton txDataToSkeleton(BasicTxData txData) +{ + TransactionSkeleton tx; + tx.from = jsToAddress(txData.from); + tx.to = jsToAddress(txData.to); + tx.value = jsToU256(txData.amount); + tx.gas = 200000; + tx.gasPrice = getGasPriceFromStation() * 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); + ss << rlpStream.out(); + return stringStreamToChar(ss); +} + +char *approveErc20(ApproveErc20Input input) +{ + TransactionSkeleton tx; + tx.from = jsToAddress(input.owner); + tx.to = jsToAddress(input.tokenAddress); + tx.value = 0; + tx.gas = 300000; + tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9); + tx.nonce = getNonce(input.owner); + std::stringstream ss; + ss << "0x095ea7b3" + << "000000000000000000000000" + << toHex(jsToAddress(input.spender)) + << toHex(toBigEndian(jsToU256(input.amount))); + tx.data = jsToBytes(ss.str()); + char* rawTx = signTx(tx, input.secret); + char* result = sendRawTxWaitConfirm(rawTx); + free(rawTx); + return result; +} + +std::stringstream aliceSendsEthPaymentData(AliceSendsEthPaymentInput input) +{ + std::stringstream ss; + ss << "0x47c7b6e2" + << toHex(jsToBytes(input.dealId)) + << "000000000000000000000000" + << toHex(jsToAddress(input.bobAddress)) + << toHex(jsToBytes(input.aliceHash)) + << "000000000000000000000000" + << toHex(jsToBytes(input.bobHash)) + << "000000000000000000000000"; + return ss; +} + +char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData) +{ + TransactionSkeleton tx = txDataToSkeleton(txData); + std::stringstream ss = aliceSendsEthPaymentData(input); + tx.data = jsToBytes(ss.str()); + char *rawTx = signTx(tx, txData.secretKey); + char *result = sendRawTxWaitConfirm(rawTx); + free(rawTx); + return result; +} + +uint8_t verifyAliceEthPaymentData(AliceSendsEthPaymentInput input, char *data) +{ + std::stringstream ss = aliceSendsEthPaymentData(input); + if (strcmp(ss.str().c_str(), data) != 0) { + printf("Alice ETH payment data %s does not match expected %s\n", data, ss.str().c_str()); + return 0; + } + return 1; +} + +std::stringstream aliceSendsErc20PaymentData(AliceSendsErc20PaymentInput input) +{ + uint8_t decimals = getErc20Decimals(input.tokenAddress); + u256 amount = jsToU256(input.amount); + if (decimals < 18) { + amount /= boost::multiprecision::pow(u256(10), 18 - decimals); + } + std::stringstream ss; + ss << "0x184db3bf" + << toHex(jsToBytes(input.dealId)) + << toHex(toBigEndian(amount)) + << "000000000000000000000000" + << toHex(jsToAddress(input.bobAddress)) + << toHex(jsToBytes(input.aliceHash)) + << "000000000000000000000000" + << toHex(jsToBytes(input.bobHash)) + << "000000000000000000000000" + << "000000000000000000000000" + << toHex(jsToAddress(input.tokenAddress)); + return ss; +} + +char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txData) +{ + TransactionSkeleton tx = txDataToSkeleton(txData); + std::stringstream ss = aliceSendsErc20PaymentData(input); + tx.data = jsToBytes(ss.str()); + char* rawTx = signTx(tx, txData.secretKey); + char* result = sendRawTxWaitConfirm(rawTx); + free(rawTx); + return result; +} + +uint8_t verifyAliceErc20PaymentData(AliceSendsErc20PaymentInput input, char *data) +{ + std::stringstream ss = aliceSendsErc20PaymentData(input); + if (strcmp(ss.str().c_str(), data) != 0) { + printf("Alice ERC20 payment data %s is not equal to expected %s\n", data, ss.str().c_str()); + return 0; + } + return 1; +} + +char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxData txData) +{ + TransactionSkeleton tx = txDataToSkeleton(txData); + std::stringstream ss; + u256 amount = jsToU256(input.amount); + dev::Address tokenAddress = jsToAddress(input.tokenAddress); + if (tokenAddress != ZeroAddress) { + uint8_t decimals = getErc20Decimals(input.tokenAddress); + if (decimals < 18) { + amount /= boost::multiprecision::pow(u256(10), 18 - decimals); + } + } + ss << "0x8b9a167a" + << toHex(jsToBytes(input.dealId)) + << toHex(toBigEndian(amount)) + << "000000000000000000000000" + << toHex(tokenAddress) + << "000000000000000000000000" + << toHex(jsToAddress(input.bobAddress)) + << toHex(jsToBytes(input.aliceHash)) + << "000000000000000000000000" + << "00000000000000000000000000000000000000000000000000000000000000c0" + << "0000000000000000000000000000000000000000000000000000000000000020" + << toHex(jsToBytes(input.bobSecret)); + tx.data = jsToBytes(ss.str()); + char* rawTx = signTx(tx, txData.secretKey); + char* result = sendRawTxWaitConfirm(rawTx); + free(rawTx); + return result; +} + +char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData) +{ + TransactionSkeleton tx = txDataToSkeleton(txData); + std::stringstream ss; + u256 amount = jsToU256(input.amount); + dev::Address tokenAddress = jsToAddress(input.tokenAddress); + if (tokenAddress != ZeroAddress) { + uint8_t decimals = getErc20Decimals(input.tokenAddress); + if (decimals < 18) { + amount /= boost::multiprecision::pow(u256(10), 18 - decimals); + } + } + ss << "0x392ec66b" + << toHex(jsToBytes(input.dealId)) + << toHex(toBigEndian(amount)) + << "000000000000000000000000" + << toHex(tokenAddress) + << "000000000000000000000000" + << toHex(jsToAddress(input.aliceAddress)) + << toHex(jsToBytes(input.bobHash)) + << "000000000000000000000000" + << "00000000000000000000000000000000000000000000000000000000000000c0" + << "0000000000000000000000000000000000000000000000000000000000000020" + << toHex(jsToBytes(input.aliceSecret)); + tx.data = jsToBytes(ss.str()); + char* rawTx = signTx(tx, txData.secretKey); + char* result = sendRawTxWaitConfirm(rawTx); + free(rawTx); + return result; +} + +std::stringstream bobSendsEthDepositData(BobSendsEthDepositInput input) +{ + u256 lockTime = input.lockTime; + std::stringstream ss; + ss << "0xdd23795f" + << toHex(jsToBytes(input.depositId)) + << "000000000000000000000000" + << toHex(jsToAddress(input.aliceAddress)) + << toHex(jsToBytes(input.bobHash)) + << "000000000000000000000000" + << toHex(toBigEndian(lockTime)); + return ss; +} + +char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData) +{ + TransactionSkeleton tx = txDataToSkeleton(txData); + std::stringstream ss = bobSendsEthDepositData(input); + tx.data = jsToBytes(ss.str()); + char* rawTx = signTx(tx, txData.secretKey); + char* result = sendRawTx(rawTx); + free(rawTx); + return result; +} + +uint8_t verifyBobEthDepositData(BobSendsEthDepositInput input, char *data) +{ + std::stringstream ss = bobSendsEthDepositData(input); + if (strcmp(ss.str().c_str(), data) != 0) { + printf("Bob deposit data %s != expected %s\n", data, ss.str().c_str()); + return 0; + } + return 1; +} + +std::stringstream bobSendsErc20DepositData(BobSendsErc20DepositInput input) +{ + uint8_t decimals = getErc20Decimals(input.tokenAddress); + u256 amount = jsToU256(input.amount); + u256 lockTime = input.lockTime; + if (decimals < 18) { + amount /= boost::multiprecision::pow(u256(10), 18 - decimals); + } + std::stringstream ss; + ss << "0x5d567259" + << toHex(jsToBytes(input.depositId)) + << toHex(toBigEndian(amount)) + << "000000000000000000000000" + << toHex(jsToAddress(input.aliceAddress)) + << toHex(jsToBytes(input.bobHash)) + << "000000000000000000000000" + << "000000000000000000000000" + << toHex(jsToAddress(input.tokenAddress)) + << toHex(toBigEndian(lockTime)); + return ss; +} + +char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData) +{ + TransactionSkeleton tx = txDataToSkeleton(txData); + std::stringstream ss = bobSendsErc20DepositData(input); + tx.data = jsToBytes(ss.str()); + char* rawTx = signTx(tx, txData.secretKey); + char* result = sendRawTxWaitConfirm(rawTx); + free(rawTx); + return result; +} + +uint8_t verifyBobErc20DepositData(BobSendsErc20DepositInput input, char *data) +{ + std::stringstream ss = bobSendsErc20DepositData(input); + if (strcmp(ss.str().c_str(), data) != 0) { + printf("Bob deposit data %s != expected %s\n", data, ss.str().c_str()); + return 0; + } + return 1; +} + +char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData) +{ + TransactionSkeleton tx = txDataToSkeleton(txData); + std::stringstream ss; + u256 amount = jsToU256(input.amount); + dev::Address tokenAddress = jsToAddress(input.tokenAddress); + if (tokenAddress != ZeroAddress) { + uint8_t decimals = getErc20Decimals(input.tokenAddress); + if (decimals < 18) { + amount /= boost::multiprecision::pow(u256(10), 18 - decimals); + } + } + ss << "0x1f7a72f7" + << toHex(jsToBytes(input.depositId)) + << toHex(toBigEndian(amount)) + << toHex(jsToBytes(input.bobSecret)) + << "000000000000000000000000" + << toHex(jsToAddress(input.aliceAddress)) + << "000000000000000000000000" + << toHex(tokenAddress); + tx.data = jsToBytes(ss.str()); + char* rawTx = signTx(tx, txData.secretKey); + char* result = sendRawTxWaitConfirm(rawTx); + free(rawTx); + return result; +} + +char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData) +{ + TransactionSkeleton tx = txDataToSkeleton(txData); + std::stringstream ss; + u256 amount = jsToU256(input.amount); + dev::Address tokenAddress = jsToAddress(input.tokenAddress); + if (tokenAddress != ZeroAddress) { + uint8_t decimals = getErc20Decimals(input.tokenAddress); + if (decimals < 18) { + amount /= boost::multiprecision::pow(u256(10), 18 - decimals); + } + } + ss << "0x4b915a68" + << toHex(jsToBytes(input.depositId)) + << toHex(toBigEndian(amount)) + << "000000000000000000000000" + << toHex(jsToAddress(input.bobAddress)) + << "000000000000000000000000" + << toHex(tokenAddress) + << toHex(jsToBytes(input.bobHash)) + << "000000000000000000000000"; + tx.data = jsToBytes(ss.str()); + char* rawTx = signTx(tx, txData.secretKey); + char* result = sendRawTxWaitConfirm(rawTx); + free(rawTx); + return result; +} + +std::stringstream bobSendsEthPaymentData(BobSendsEthPaymentInput input) +{ + u256 lockTime = input.lockTime; + std::stringstream ss; + ss << "0x5ab30d95" + << toHex(jsToBytes(input.paymentId)) + << "000000000000000000000000" + << toHex(jsToAddress(input.aliceAddress)) + << toHex(jsToBytes(input.aliceHash)) + << "000000000000000000000000" + << toHex(toBigEndian(lockTime)); + return ss; +} + +char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData) +{ + TransactionSkeleton tx = txDataToSkeleton(txData); + std::stringstream ss = bobSendsEthPaymentData(input); + tx.data = jsToBytes(ss.str()); + char* rawTx = signTx(tx, txData.secretKey); + char* result = sendRawTxWaitConfirm(rawTx); + free(rawTx); + return result; +} + +uint8_t verifyBobEthPaymentData(BobSendsEthPaymentInput input, char *data) +{ + std::stringstream ss = bobSendsEthPaymentData(input); + if (strcmp(ss.str().c_str(), data) != 0) { + printf("Bob payment data %s != expected %s\n", data, ss.str().c_str()); + return 0; + } + return 1; +} + +std::stringstream bobSendsErc20PaymentData(BobSendsErc20PaymentInput input) +{ + uint8_t decimals = getErc20Decimals(input.tokenAddress); + u256 amount = jsToU256(input.amount); + u256 lockTime = input.lockTime; + if (decimals < 18) { + amount /= boost::multiprecision::pow(u256(10), 18 - decimals); + } + std::stringstream ss; + ss << "0xb8a15b1d" + << toHex(jsToBytes(input.paymentId)) + << toHex(toBigEndian(amount)) + << "000000000000000000000000" + << toHex(jsToAddress(input.aliceAddress)) + << toHex(jsToBytes(input.aliceHash)) + << "000000000000000000000000" + << "000000000000000000000000" + << toHex(jsToAddress(input.tokenAddress)) + << toHex(toBigEndian(lockTime)); + return ss; +} + +char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData) +{ + TransactionSkeleton tx = txDataToSkeleton(txData); + std::stringstream ss = bobSendsErc20PaymentData(input); + tx.data = jsToBytes(ss.str()); + char* rawTx = signTx(tx, txData.secretKey); + char* result = sendRawTxWaitConfirm(rawTx); + free(rawTx); + return result; +} + +uint8_t verifyBobErc20PaymentData(BobSendsErc20PaymentInput input, char *data) +{ + std::stringstream ss = bobSendsErc20PaymentData(input); + if (strcmp(ss.str().c_str(), data) != 0) { + printf("Bob payment data %s != expected %s\n", data, ss.str().c_str()); + return 0; + } + return 1; +} + +char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData) +{ + TransactionSkeleton tx = txDataToSkeleton(txData); + std::stringstream ss; + u256 amount = jsToU256(input.amount); + dev::Address tokenAddress = jsToAddress(input.tokenAddress); + if (tokenAddress != ZeroAddress) { + uint8_t decimals = getErc20Decimals(input.tokenAddress); + if (decimals < 18) { + amount /= boost::multiprecision::pow(u256(10), 18 - decimals); + } + } + ss << "0xe45ef4ad" + << toHex(jsToBytes(input.paymentId)) + << toHex(toBigEndian(amount)) + << "000000000000000000000000" + << toHex(jsToAddress(input.aliceAddress)) + << "000000000000000000000000" + << toHex(tokenAddress) + << toHex(jsToBytes(input.aliceHash)) + << "000000000000000000000000"; + tx.data = jsToBytes(ss.str()); + char* rawTx = signTx(tx, txData.secretKey); + char* result = sendRawTxWaitConfirm(rawTx); + free(rawTx); + return result; +} + +char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData) +{ + TransactionSkeleton tx = txDataToSkeleton(txData); + std::stringstream ss; + u256 amount = jsToU256(input.amount); + dev::Address tokenAddress = jsToAddress(input.tokenAddress); + if (tokenAddress != ZeroAddress) { + uint8_t decimals = getErc20Decimals(input.tokenAddress); + if (decimals < 18) { + amount /= boost::multiprecision::pow(u256(10), 18 - decimals); + } + } + ss << "0x113ee583" + << toHex(jsToBytes(input.paymentId)) + << toHex(toBigEndian(amount)) + << toHex(jsToBytes(input.aliceSecret)) + << "000000000000000000000000" + << toHex(jsToAddress(input.bobAddress)) + << "000000000000000000000000" + << toHex(tokenAddress); + tx.data = jsToBytes(ss.str()); + char* rawTx = signTx(tx, txData.secretKey); + char* result = sendRawTxWaitConfirm(rawTx); + free(rawTx); + return result; +} + +char* privKey2Addr(char* privKey) +{ + Secret& secretKey = *(new Secret(privKey)); + std::stringstream& ss = *(new std::stringstream); + ss << "0x" << toAddress(secretKey); + return stringStreamToChar(ss); +}; + +char* pubKey2Addr(char* pubKey) +{ + Public& publicKey = *(new Public(pubKey)); + std::stringstream& ss = *(new std::stringstream); + ss << "0x" << toAddress(publicKey); + return stringStreamToChar(ss); +}; + +char* getPubKeyFromPriv(char* privKey) +{ + Public publicKey = toPublic(*(new Secret(privKey))); + std::stringstream& ss = *(new std::stringstream); + ss << "0x" << publicKey; + return stringStreamToChar(ss); +} + +uint64_t getEthBalance(char* address) +{ + char* hexBalance = getEthBalanceRequest(address); + // convert wei to satoshi + u256 balance = jsToU256(hexBalance) / boost::multiprecision::pow(u256(10), 10); + free(hexBalance); + return static_cast(balance); +} + +uint64_t getErc20BalanceSatoshi(char *address, char *tokenAddress) +{ + 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); + } + balance /= boost::multiprecision::pow(u256(10), 10); + free(hexBalance); + return static_cast(balance); +} + +char *getErc20BalanceHexWei(char *address, char *tokenAddress) +{ + std::stringstream ss; + ss << "0x70a08231" + << "000000000000000000000000" + << toHex(jsToAddress(address)); + char *hexBalance = ethCall(tokenAddress, ss.str().c_str()); + return hexBalance; +} + +uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress) +{ + std::stringstream ss; + ss << "0xdd62ed3e" + << "000000000000000000000000" + << toHex(jsToAddress(owner)) + << "000000000000000000000000" + << toHex(jsToAddress(spender)); + char* hexAllowance = ethCall(tokenAddress, ss.str().c_str()); + uint8_t decimals = getErc20Decimals(tokenAddress); + u256 allowance = jsToU256(hexAllowance); + if (decimals < 18) { + allowance *= boost::multiprecision::pow(u256(10), 18 - decimals); + } + // convert wei to satoshi + allowance /= boost::multiprecision::pow(u256(10), 10); + free(hexAllowance); + return static_cast(allowance); +} + +uint8_t getErc20Decimals(char *tokenAddress) +{ + char* hexDecimals = ethCall(tokenAddress, "0x313ce567"); + auto decimals = (uint8_t) strtol(hexDecimals, NULL, 0); + free(hexDecimals); + return decimals; +} + +void uint8arrayToHex(char *dest, uint8_t *input, int len) +{ + strcpy(dest, "0x"); + for (int i = 0; i < len; i++) + { + sprintf(dest + (i + 1) * 2, "%02x", input[i]); + } + dest[(len + 1) * 2] = '\0'; +} + +void satoshisToWei(char *dest, uint64_t input) +{ + sprintf(dest, "%" PRIu64, input); + strcat(dest, "0000000000"); +} + +uint64_t weiToSatoshi(char *wei) +{ + u256 satoshi = jsToU256(wei) / boost::multiprecision::pow(u256(10), 10); + return static_cast(satoshi); +} + +char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm) +{ + 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); + + char *rawTx = signTx(tx, privKey); + if (waitConfirm == 0) { + result = sendRawTx(rawTx); + } else { + result = sendRawTxWaitConfirm(rawTx); + } + free(rawTx); + return result; +} + +std::stringstream getErc20TransferData(char *tokenAddress, char *to, char *amount) +{ + u256 amountWei = jsToU256(amount); + uint8_t decimals = getErc20Decimals(tokenAddress); + if (decimals < 18) { + amountWei /= boost::multiprecision::pow(u256(10), 18 - decimals); + } + // convert wei to satoshi + std::stringstream ss; + ss << "0xa9059cbb" + << "000000000000000000000000" + << toHex(jsToAddress(to)) + << toHex(toBigEndian(amountWei)); + return ss; +} + +char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8_t waitConfirm) +{ + TransactionSkeleton tx; + char *from = privKey2Addr(privKey), *result; + 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); + free(from); + + std::stringstream ss = getErc20TransferData(tokenAddress, to, amount); + tx.data = jsToBytes(ss.str()); + + char *rawTx = signTx(tx, privKey); + if (waitConfirm == 0) { + result = sendRawTx(rawTx); + } else { + result = sendRawTxWaitConfirm(rawTx); + } + free(rawTx); + return result; +} + +uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data) +{ + std::stringstream ss = getErc20TransferData(tokenAddress, to, amount); + 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; +} diff --git a/iguana/exchanges/etomicswap/etomiclib.h b/iguana/exchanges/etomicswap/etomiclib.h new file mode 100644 index 000000000..c7b846ddb --- /dev/null +++ b/iguana/exchanges/etomicswap/etomiclib.h @@ -0,0 +1,187 @@ +// +// Created by artem on 24.01.18. +// +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef ETOMIC_TESTNET +#define ETOMIC_ALICECONTRACT "0xe1d4236c5774d35dc47dcc2e5e0ccfc463a3289c" +#define ETOMIC_BOBCONTRACT "0x2a8e4f9ae69c86e277602c6802085febc4bd5986" +#else +#define ETOMIC_ALICECONTRACT "0x9bc5418ceded51db08467fc4b62f32c5d9ebda55" +#define ETOMIC_BOBCONTRACT "0xfef736cfa3b884669a4e0efd6a081250cce228e7" +#endif + +#define EMPTY_ETH_TX_ID "0x0000000000000000000000000000000000000000000000000000000000000000" + +typedef struct { + char from[65]; + char to[65]; + char amount[100]; + char secretKey[70]; +} BasicTxData; + +typedef struct { + char dealId[70]; + char bobAddress[65]; + char aliceHash[65]; + char bobHash[65]; +} AliceSendsEthPaymentInput; + +typedef struct { + char dealId[70]; + char amount[100]; + char tokenAddress[65]; + char bobAddress[65]; + char aliceHash[65]; + char bobHash[65]; +} AliceSendsErc20PaymentInput; + +typedef struct { + char dealId[70]; + char amount[100]; + char tokenAddress[65]; + char bobAddress[65]; + char aliceHash[65]; + char bobSecret[70]; +} AliceReclaimsAlicePaymentInput; + +typedef struct { + char dealId[70]; + char amount[100]; + char tokenAddress[65]; + char aliceAddress[65]; + char aliceSecret[70]; + char bobHash[65]; +} BobSpendsAlicePaymentInput; + +typedef struct { + char depositId[70]; + char aliceAddress[65]; + char bobHash[65]; + uint64_t lockTime; +} BobSendsEthDepositInput; + +typedef struct { + char depositId[70]; + char amount[100]; + char tokenAddress[65]; + char aliceAddress[65]; + char bobHash[65]; + uint64_t lockTime; +} BobSendsErc20DepositInput; + +typedef struct { + char depositId[70]; + char amount[100]; + char tokenAddress[65]; + char aliceAddress[65]; + char bobSecret[70]; +} BobRefundsDepositInput; + +typedef struct { + char depositId[70]; + char amount[100]; + char tokenAddress[65]; + char bobAddress[65]; + char bobHash[65]; +} AliceClaimsBobDepositInput; + +typedef struct { + char paymentId[70]; + char aliceAddress[65]; + char aliceHash[65]; + uint64_t lockTime; +} BobSendsEthPaymentInput; + +typedef struct { + char paymentId[70]; + char amount[100]; + char tokenAddress[65]; + char aliceAddress[65]; + char aliceHash[65]; + uint64_t lockTime; +} BobSendsErc20PaymentInput; + +typedef struct { + char paymentId[70]; + char amount[100]; + char tokenAddress[65]; + char aliceAddress[65]; + char aliceHash[65]; +} BobReclaimsBobPaymentInput; + +typedef struct { + char paymentId[70]; + char amount[100]; + char tokenAddress[65]; + char aliceSecret[70]; + char bobAddress[65]; +} AliceSpendsBobPaymentInput; + +typedef struct { + char tokenAddress[65]; + char owner[65]; + char spender[65]; + char amount[100]; + char secret[70]; +} ApproveErc20Input; + +char *approveErc20(ApproveErc20Input input); + +char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData); +uint8_t verifyAliceEthPaymentData(AliceSendsEthPaymentInput input, char *data); + +char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txData); +uint8_t verifyAliceErc20PaymentData(AliceSendsErc20PaymentInput input, char *data); + +char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxData txData); +char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData); + +char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData); +uint8_t verifyBobEthDepositData(BobSendsEthDepositInput input, char *data); + +char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData); +uint8_t verifyBobErc20DepositData(BobSendsErc20DepositInput input, char *data); + +char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData); +char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData); + +char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData); +uint8_t verifyBobEthPaymentData(BobSendsEthPaymentInput input, char *data); + +char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData); +uint8_t verifyBobErc20PaymentData(BobSendsErc20PaymentInput input, char *data); + +char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData); +char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData); + +char* privKey2Addr(char* privKey); +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]); +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); + +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); + +uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data); +// Your prototype or Definition +#ifdef __cplusplus +} +#endif diff --git a/iguana/exchanges/fomo b/iguana/exchanges/fomo new file mode 100755 index 000000000..4621b7edd --- /dev/null +++ b/iguana/exchanges/fomo @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"buy\",\"base\":\"KMD\",\"rel\":\"HODL\",\"fomo\":40.00038}" diff --git a/iguana/exchanges/fundLP b/iguana/exchanges/fundLP new file mode 100755 index 000000000..9dcf3eab8 --- /dev/null +++ b/iguana/exchanges/fundLP @@ -0,0 +1,2 @@ +fiat/$1 sendmany \"\" "{\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2}" 0 + diff --git a/iguana/exchanges/getendpoint b/iguana/exchanges/getendpoint new file mode 100755 index 000000000..230b3a837 --- /dev/null +++ b/iguana/exchanges/getendpoint @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getendpoint\"}" diff --git a/iguana/exchanges/install b/iguana/exchanges/install index 6f5c28723..ce8994885 100755 --- a/iguana/exchanges/install +++ b/iguana/exchanges/install @@ -1,5 +1,5 @@ #!/bin/bash -cp install get_supernet trackbtc auto_chipskmd auto_chipsbtc pendingswaps fundvalue balances dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js trust trusted setconfirms balance listunspent electrum snapshot_balance snapshot_loop secretaddresses dividends snapshot goals goal portfolio autoprice deletemessages getmessages debug buy sell bestfit orderbook client run_osx client_osx run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices help inv setprice status ../dexscripts +cp install updateprices get_supernet trackbtc auto_chipskmd auto_chipsbtc pendingswaps fundvalue balances dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js trust trusted setconfirms balance listunspent electrum snapshot_balance snapshot_loop secretaddresses dividends snapshot goals goal portfolio autoprice deletemessages getmessages debug buy sell bestfit orderbook client run_osx client_osx client_static run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices help inv setprice status ../dexscripts cp coins.json .. cd ../dexscripts #cp ../exchanges/passphrase ../exchanges/userpass . diff --git a/iguana/exchanges/inuse b/iguana/exchanges/inuse new file mode 100755 index 000000000..005d91040 --- /dev/null +++ b/iguana/exchanges/inuse @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"inuse\"}" diff --git a/iguana/exchanges/jumblr b/iguana/exchanges/jumblr index 501a99333..98b9a70f3 100755 --- a/iguana/exchanges/jumblr +++ b/iguana/exchanges/jumblr @@ -1,4 +1,3 @@ -#!/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\":\"RGhxXpXSSBTBm9EvNsXnTQczthMCxHX91t\",\"divisor\":1000000}" +coin=JUMBLR +price=0.002 +invprice=500 diff --git a/iguana/exchanges/listtransactions b/iguana/exchanges/listtransactions new file mode 100755 index 000000000..513a1647f --- /dev/null +++ b/iguana/exchanges/listtransactions @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"listtransactions\",\"coin\":\"CHIPS\",\"address\":\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\"}" diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index db8bc57b7..234565e32 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -28,6 +28,7 @@ void PNACL_message(char *arg,...) #include #include +// #include "lib.h" #ifndef NATIVE_WINDOWS #include "OS_portable.h" #else @@ -57,7 +58,8 @@ void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveas #include "../../crypto777/nanosrc/pipeline.h" #include "../../crypto777/nanosrc/reqrep.h" #include "../../crypto777/nanosrc/tcp.h" - #include "../../crypto777/nanosrc/pair.h" + #include "../../crypto777/nanosrc/pair.h" + #include "../../crypto777/nanosrc/ws.h" #else #include "/usr/local/include/nanomsg/nn.h" #include "/usr/local/include/nanomsg/bus.h" @@ -65,9 +67,13 @@ void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveas #include "/usr/local/include/nanomsg/pipeline.h" #include "/usr/local/include/nanomsg/reqrep.h" #include "/usr/local/include/nanomsg/tcp.h" - #include "/usr/local/include/nanomsg/pair.h" + #include "/usr/local/include/nanomsg/pair.h" + #include "/usr/local/include/nanomsg/ws.h" #endif #endif +#ifndef NN_WS_MSG_TYPE +#define NN_WS_MSG_TYPE 1 +#endif #include "LP_nativeDEX.c" @@ -111,31 +117,96 @@ void LP_main(void *ptr) } } +int32_t ensure_writable(char *dirname) +{ + char fname[512],str[65],str2[65]; bits256 r,check; FILE *fp; + OS_randombytes(r.bytes,sizeof(r)); + sprintf(fname,"%s/checkval",dirname), OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) == 0 ) + { + printf("FATAL ERROR cant create %s\n",fname); + fprintf(stderr,"FATAL ERROR cant create %s\n",fname); + return(-1); + } + else if ( fwrite(r.bytes,1,sizeof(r),fp) != sizeof(r) ) + { + printf("FATAL ERROR error writing %s\n",fname); + fprintf(stderr,"FATAL ERROR writing %s\n",fname); + return(-1); + } + else + { + fclose(fp); + if ( (fp= fopen(fname,"rb")) == 0 ) + { + printf("FATAL ERROR cant open %s\n",fname); + fprintf(stderr,"FATAL ERROR cant open %s\n",fname); + return(-1); + } + else if ( fread(check.bytes,1,sizeof(check),fp) != sizeof(check) ) + { + printf("FATAL ERROR error reading %s\n",fname); + fprintf(stderr,"FATAL ERROR reading %s\n",fname); + return(-1); + } + else if ( memcmp(check.bytes,r.bytes,sizeof(r)) != 0 ) + { + printf("FATAL ERROR error comparint %s %s vs %s\n",fname,bits256_str(str,r),bits256_str(str2,check)); + fprintf(stderr,"FATAL ERROR error comparint %s %s vs %s\n",fname,bits256_str(str,r),bits256_str(str2,check)); + return(-1); + } + fclose(fp); + } + return(0); +} + int main(int argc, const char * argv[]) { - char dirname[512],*passphrase; double incr; cJSON *retjson; + char dirname[512]; double incr; cJSON *retjson; OS_init(); if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 ) { - uint8_t addrtype,rmd160[20],rmd160b[20]; char coinaddr[64],coinaddr2[64]; - bitcoin_addr2rmd160("BTC",0,&addrtype,rmd160,(char *)argv[1]); - if ( addrtype == 0 ) + bits256 privkey,checkkey; uint8_t tmptype; char kmdwif[64],str[65],str2[65],*retstr; + if ( LP_wifstr_valid("BTC",(char *)argv[1]) > 0 ) { - bitcoin_address("KMD",coinaddr,0,60,rmd160,20); - bitcoin_addr2rmd160("KMD",0,&addrtype,rmd160b,coinaddr); - bitcoin_address("BTC",coinaddr2,0,0,rmd160b,20); + bitcoin_wif2priv("BTC",0,&tmptype,&privkey,(char *)argv[1]); + bitcoin_priv2wif("KMD",0,kmdwif,privkey,188); + bitcoin_wif2priv("KMD",0,&tmptype,&checkkey,kmdwif); + if ( bits256_cmp(privkey,checkkey) == 0 ) + printf("BTC %s -> KMD %s: privkey %s\n",argv[1],kmdwif,bits256_str(str,privkey)); + else printf("ERROR BTC %s %s != KMD %s %s\n",argv[1],bits256_str(str,privkey),kmdwif,bits256_str(str2,checkkey)); } - else if ( addrtype == 60 ) + else { - bitcoin_address("BTC",coinaddr,0,0,rmd160,20); - bitcoin_addr2rmd160("BTC",0,&addrtype,rmd160b,coinaddr); - bitcoin_address("KMD",coinaddr2,0,60,rmd160b,20); + if ( (retstr= LP_convaddress("BTC",(char *)argv[1],"KMD")) != 0 ) + printf("%s\n",retstr); } - printf("(%s) -> %s -> %s\n",(char *)argv[1],coinaddr,coinaddr2); - if ( strcmp((char *)argv[1],coinaddr2) != 0 ) - printf("ERROR\n"); exit(0); } + else if ( argv[1] != 0 && strcmp(argv[1],"events") == 0 ) + { + int32_t len,bufsize = 1000000; void *ptr; char *buf; + if ( (IPC_ENDPOINT= nn_socket(AF_SP,NN_PAIR)) >= 0 ) + { + if ( nn_connect(IPC_ENDPOINT,"ws://127.0.0.1:5555") >= 0 ) + { + buf = calloc(1,bufsize); + while ( 1 ) + { + if ( (len= nn_recv(IPC_ENDPOINT,&ptr,NN_MSG,0)) > 0 ) + { + if ( len < bufsize ) + { + memcpy(buf,ptr,len); + buf[len] = 0; + printf("%s\n",(char *)buf); + } + nn_freemsg(ptr); + } + } + } else printf("nn_connect error to IPC_ENDPOINT\n"); + } else printf("error opening IPC_ENDPOINT\n"); + } else if ( argv[1] != 0 && strcmp(argv[1],"hush") == 0 ) { uint32_t timestamp; char str[65],wifstr[128]; bits256 privkey; int32_t i; @@ -190,10 +261,91 @@ int main(int argc, const char * argv[]) printf("done vanitygen.(%s) done %u elapsed %d\n",argv[2],(uint32_t)time(NULL),(uint32_t)time(NULL) - timestamp); exit(0); } + else if ( argv[1] != 0 && strcmp(argv[1],"airdropH") == 0 && argv[2] != 0 ) + { + FILE *fp; double val,total = 0.; uint8_t checktype,addrtype,rmd160[21],checkrmd160[21]; char *floatstr,*addrstr,buf[256],checkaddr[64],coinaddr[64],manystrs[64][128],cmd[64*128]; int32_t n,i,num; char *flag; + if ( (fp= fopen(argv[2],"rb")) != 0 ) + { + num = 0; + while ( fgets(buf,sizeof(buf),fp) > 0 ) + { + if ( (n= (int32_t)strlen(buf)) > 0 ) + buf[--n] = 0; + flag = 0; + for (i=0; i (%s).%d -> (%s) %.8f?\n",addrstr,addrtype,coinaddr,checktype,checkaddr,atof(floatstr)); + } + else + { + val = atof(floatstr); + sprintf(manystrs[num++],"\\\"%s\\\":%0.8f",coinaddr,val); + if ( num >= sizeof(manystrs)/sizeof(*manystrs) ) + { + sprintf(cmd,"fiat/btch sendmany \\\"\\\" \"{"); + for (i=0; i 0 ) + { + sprintf(cmd,"fiat/btch sendmany \\\"\\\" \"{"); + for (i=0; i= 0 ) @@ -329,11 +330,12 @@ cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) } extern void *bitcoin_ctx(); +extern int32_t IPC_ENDPOINT; char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr,char *filetype,uint16_t port) { static void *ctx; - cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; char *myipaddr="127.0.0.1",symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr=0,*filestr,*token = 0; int32_t i,j,n,num=0; + cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; char symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr=0,*filestr,*token = 0; int32_t i,j,n,num=0; uint32_t queueid; if ( ctx == 0 ) ctx = bitcoin_ctx(); for (i=0; i 0 ) { - if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 ) + //buf = jprint(argjson,0); + //LP_queuecommand(&retstr,buf,-1,1); + //free(buf); + //while ( retstr == 0 ) + // usleep(10000); + if ( (retstr= stats_JSON(ctx,"127.0.0.1",-1,argjson,remoteaddr,port)) != 0 ) { if ( (retitem= cJSON_Parse(retstr)) != 0 ) jaddi(retarray,retitem); @@ -531,6 +538,11 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po } } else retstr = clonestr("{\"error\":\"invalid remote method\"}"); #else + //buf = jprint(argjson,0); + //LP_queuecommand(&retstr,buf,-1,1); + //free(buf); + //while ( retstr == 0 ) + // usleep(10000); if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 ) { if ( (retitem= cJSON_Parse(retstr)) != 0 ) @@ -545,7 +557,7 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po } else { - cJSON *arg; + cJSON *arg; char *buf; if ( jstr(argjson,"agent") != 0 && strcmp(jstr(argjson,"agent"),"bitcoinrpc") != 0 && jobj(argjson,"params") != 0 ) { arg = jobj(argjson,"params"); @@ -557,10 +569,22 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po jaddstr(arg,"userpass",userpass); #ifdef FROM_MARKETMAKER if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(arg) > 0 ) - retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port); - else retstr = clonestr("{\"error\":\"invalid remote method\"}"); + { + if ( IPC_ENDPOINT >= 0 && (queueid= juint(arg,"queueid")) > 0 ) + { + buf = jprint(arg,0); + LP_queuecommand(&retstr,buf,IPC_ENDPOINT,1,queueid); + free(buf); + retstr = clonestr("{\"result\":\"success\",\"status\":\"queued\"}"); + } else retstr = stats_JSON(ctx,"127.0.0.1",-1,arg,remoteaddr,port); + } else retstr = clonestr("{\"error\":\"invalid remote method\"}"); #else - retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port); + if ( IPC_ENDPOINT >= 0 && (queueid= juint(arg,"queueid")) > 0 ) + { + buf = jprint(arg,0); + LP_queuecommand(&retstr,buf,IPC_ENDPOINT,1,queueid); + free(buf); + } else retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port); #endif } free_json(argjson); @@ -568,6 +592,7 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po free_json(json); if ( tmpjson != 0 ) free(tmpjson); +//printf("stats_JSON rpc return.(%s)\n",retstr); return(retstr); } free_json(argjson); @@ -778,7 +803,7 @@ extern int32_t IAMLP,LP_STOP_RECEIVED; void stats_rpcloop(void *args) { - uint16_t port; int32_t retval,sock=-1,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req,*req2,*rtmp; + uint16_t port; int32_t retval,sock=-1,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req; if ( (port= *(uint16_t *)args) == 0 ) port = 7779; printf("Start stats_rpcloop.%u\n",port); @@ -834,14 +859,13 @@ void stats_rpcloop(void *args) req->ipbits = ipbits; req->port = port; LP_rpc_processreq(req); -continue; - // this leads to cant open file errors + continue; + // this might lead to "cant open file errors" if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) { printf("error launching rpc handler on port %d, retval.%d\n",port,retval); - closesocket(sock); - sock = -1; - portable_mutex_lock(&LP_gcmutex); + LP_rpc_processreq(req); + /*portable_mutex_lock(&LP_gcmutex); DL_FOREACH_SAFE(LP_garbage_collector,req2,rtmp) { DL_DELETE(LP_garbage_collector,req2); @@ -852,7 +876,7 @@ continue; { printf("error2 launching rpc handler on port %d, retval.%d\n",port,retval); LP_rpc_processreq(req); - } + }*/ } } printf("i got killed\n"); diff --git a/iguana/exchanges/supernet b/iguana/exchanges/supernet index 25e6af7e4..343ca9241 100755 --- a/iguana/exchanges/supernet +++ b/iguana/exchanges/supernet @@ -15,6 +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\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}" +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\":600}, {\"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 }],\"divisor\":612529}" -#curl --url "http://5.9.253.196:7782" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}" diff --git a/iguana/exchanges/timelock b/iguana/exchanges/timelock new file mode 100755 index 000000000..a3fc3b688 --- /dev/null +++ b/iguana/exchanges/timelock @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"timelock\",\"coin\":\"KMD\",\"duration\":1000,\"amount\":1}" diff --git a/iguana/exchanges/to_etomic b/iguana/exchanges/to_etomic new file mode 100755 index 000000000..b2f74ec70 --- /dev/null +++ b/iguana/exchanges/to_etomic @@ -0,0 +1,4 @@ +rm /usr/bin/g++ +ln /usr/bin/g++-7 /usr/bin/g++ +rm /usr/bin/gcc +ln /usr/bin/gcc-7 /usr/bin/gcc diff --git a/iguana/exchanges/to_zcash b/iguana/exchanges/to_zcash new file mode 100755 index 000000000..c294ea474 --- /dev/null +++ b/iguana/exchanges/to_zcash @@ -0,0 +1,4 @@ +rm /usr/bin/g++ +ln /usr/bin/g++-5 /usr/bin/g++ +rm /usr/bin/gcc +ln /usr/bin/gcc-5 /usr/bin/gcc diff --git a/iguana/exchanges/unlockedspend b/iguana/exchanges/unlockedspend new file mode 100755 index 000000000..f6f40c191 --- /dev/null +++ b/iguana/exchanges/unlockedspend @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"unlockedspend\",\"coin\":\"KMD\",\"txid\":\"e858e382a816b4cab22e3fd3e29901c7ef497cd1fdad7683314cc9187eca34fd\"}" diff --git a/iguana/exchanges/updateprices b/iguana/exchanges/updateprices new file mode 100755 index 000000000..89d44e948 --- /dev/null +++ b/iguana/exchanges/updateprices @@ -0,0 +1,7 @@ +cp ../exchanges/auto_* . +cp ../exchanges/prices/autoprice . +cp ../exchanges/prices/crypto . +cp ../exchanges/prices/jumblr . +cp ../exchanges/prices/pangea . +cp ../exchanges/prices/bet . +cp ../exchanges/prices/revs . diff --git a/iguana/iguana777.c b/iguana/iguana777.c index d998b4b81..9bfb1764b 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -48,6 +48,7 @@ struct iguana_info *iguana_coinadd(char *symbol,char *name,cJSON *argjson,int32_ { myinfo->allcoins_being_added = 1; coin = mycalloc('C',1,sizeof(*coin)); + strcpy(coin->getinfostr,"getinfo"); coin->blockspacesize = IGUANA_MAXPACKETSIZE + 8192; coin->blockspace = calloc(1,coin->blockspacesize); if ( virtcoin != 0 || ((privatechain= jstr(argjson,"geckochain")) != 0 && privatechain[0] != 0) ) @@ -1216,12 +1217,15 @@ int32_t iguana_launchcoin(struct supernet_info *myinfo,char *symbol,cJSON *json, return(0); } +void iguana_optableinit(); + void iguana_coins(void *arg) { struct iguana_info **coins,*coin; char *jsonstr,*symbol; cJSON *array,*item,*json; int32_t i,n,maxpeers,maphash,initialheight,minconfirms,maxrequests,maxbundles; int64_t maxrecvcache; uint64_t services; struct vin_info V; struct supernet_info *myinfo; myinfo = SuperNET_MYINFO(0); + iguana_optableinit(); memset(&V,0,sizeof(V)); if ( (jsonstr= arg) != 0 && (json= cJSON_Parse(jsonstr)) != 0 ) { diff --git a/iguana/iguana777.h b/iguana/iguana777.h index eb058e620..3e643bdaf 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -159,7 +159,7 @@ struct supernet_info struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; int32_t numexchanges; struct iguana_waccount *wallet; struct iguana_info *allcoins; int32_t allcoins_being_added,allcoins_numvirts; - portable_mutex_t bu_mutex,allcoins_mutex,gecko_mutex,basilisk_mutex,DEX_mutex,DEX_reqmutex,DEX_swapmutex,smart_mutex; + portable_mutex_t bu_mutex,allcoins_mutex,gecko_mutex,basilisk_mutex,DEX_mutex,DEX_reqmutex,DEX_swapmutex,smart_mutex,MoM_mutex; struct queueitem *DEX_quotes; cJSON *Cunspents,*Cspends; struct basilisk_swap *swaps[256]; int32_t numswaps; struct basilisk_message *messagetable; portable_mutex_t messagemutex; queue_t msgQ,p2pQ; @@ -167,7 +167,7 @@ struct supernet_info uint8_t *pingbuf; struct basilisk_request DEXaccept; FILE *dexfp; - struct dpow_info DPOWS[128]; int32_t numdpows,dpowsock,dexsock,pubsock,repsock,subsock,reqsock; + struct dpow_info DPOWS[1024]; int32_t numdpows,dpowsock,dexsock,pubsock,repsock,subsock,reqsock; struct delayedPoW_info dPoW; struct basilisk_spend *spends; int32_t numspends; char bindaddr[64]; diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index 3c65b069c..38f10addf 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -137,7 +137,7 @@ void iguana_blockcopy(uint8_t zcash,uint8_t auxpow,struct iguana_info *coin,stru } } -bits256 iguana_merkle(bits256 *tree,int32_t txn_count) +/*bits256 iguana_merkle(bits256 *tree,int32_t txn_count) { int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; if ( txn_count == 1 ) @@ -158,7 +158,7 @@ bits256 iguana_merkle(bits256 *tree,int32_t txn_count) txn_count >>= 1; } return(tree[n]); -} +}*/ struct iguana_block *iguana_prevblock(struct iguana_info *coin,struct iguana_block *block,int32_t PoSflag) { diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index bb3c92135..473b46953 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -68,6 +68,7 @@ void iguana_initcoin(struct iguana_info *coin,cJSON *argjson) portable_mutex_init(&coin->RTmutex); portable_mutex_init(&coin->kmdmutex); portable_mutex_init(&coin->peers_mutex); + portable_mutex_init(&coin->MoM_mutex); portable_mutex_init(&coin->blocks_mutex); portable_mutex_init(&coin->special_mutex); portable_mutex_init(&coin->allcoins_mutex); diff --git a/iguana/iguana_interpreter.c b/iguana/iguana_interpreter.c index d979752f6..75d559d57 100755 --- a/iguana/iguana_interpreter.c +++ b/iguana/iguana_interpreter.c @@ -881,7 +881,7 @@ int32_t iguana_checksequenceverify(struct iguana_info *coin,int64_t nLockTime,ui return(0); } -void iguana_optableinit(struct iguana_info *coin) +void iguana_optableinit() { int32_t i,extralen; uint8_t stackitems,flags; char *opname; struct bitcoin_opcode *op; if ( OPTABLE == 0 ) @@ -912,7 +912,7 @@ void iguana_optableinit(struct iguana_info *coin) int32_t iguana_expandscript(struct iguana_info *coin,char *asmstr,int32_t maxlen,uint8_t *script,int32_t scriptlen) { int32_t len,n,j,i = 0; uint8_t opcode; uint32_t val,extraflag; - iguana_optableinit(coin); + iguana_optableinit(); asmstr[0] = len = 0; while ( i < scriptlen ) { @@ -1001,7 +1001,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip struct iguana_stackdata args[MAX_PUBKEYS_PER_MULTISIG]; uint8_t databuf[MAX_SCRIPT_ELEMENT_SIZE]; char *asmstr,*str,*hexstr; cJSON *item; int32_t c,numops,dlen,plen,numvars,numused,numargs=0,i,j,k,n=0,len,datalen,errs=0; int64_t val; - iguana_optableinit(coin); + iguana_optableinit(); if ( (asmstr= jstr(interpreter,"interpreter")) == 0 || asmstr[0] == 0 ) return(0); if ( (numvars= juint(interpreter,"numvars")) > 0 ) diff --git a/iguana/iguana_notary.c b/iguana/iguana_notary.c index b4a1cdef1..73a6a167a 100755 --- a/iguana/iguana_notary.c +++ b/iguana/iguana_notary.c @@ -24,7 +24,7 @@ int32_t dpow_datahandler(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint8_t nn_senderind,uint32_t channel,uint32_t height,uint8_t *data,int32_t datalen); uint64_t dpow_maskmin(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp); -int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr); +int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr,char *srccoin); #include "dpow/dpow_network.c" #include "dpow/dpow_rpc.c" @@ -58,100 +58,25 @@ void dpow_checkpointset(struct supernet_info *myinfo,struct dpow_checkpoint *che checkpoint->blockhash.height = height; } -int32_t dpow_txhasnotarization(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid) -{ - cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[35]; bits256 spenttxid; uint64_t notarymask; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0; - if ( (txobj= dpow_gettransaction(myinfo,coin,txid)) != 0 ) - { - if ( (vins= jarray(&numvins,txobj,"vin")) != 0 ) - { - if ( numvins >= DPOW_MIN_ASSETCHAIN_SIGS ) - { - notarymask = numnotaries = 0; - for (i=0; i>= 1; - decode_hex(script,len,hexstr); - if ( script[0] == 33 && script[34] == 0xac ) - { - for (j=0; j 0 ) - { - if ( numnotaries >= DPOW_MIN_ASSETCHAIN_SIGS ) - hasnotarization = 1; - printf("numnotaries.%d %s hasnotarization.%d\n",numnotaries,coin->symbol,hasnotarization); - } - } - } - free_json(txobj); - } - return(hasnotarization); -} - -int32_t dpow_hasnotarization(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *blockjson) -{ - int32_t i,n,hasnotarization = 0; bits256 txid; cJSON *txarray; - if ( (txarray= jarray(&n,blockjson,"tx")) != 0 ) - { - for (i=0; ilast,height,hash,timestamp,blocktime); checkpoint = dp->srcfifo[dp->srcconfirms]; if ( strcmp("BTC",dp->dest) == 0 ) { freq = DPOW_CHECKPOINTFREQ; - minsigs = DPOW_MINSIGS; + minsigs = Notaries_BTCminsigs; //DPOW_MINSIGS; } else { - minsigs = DPOW_MIN_ASSETCHAIN_SIGS; + minsigs = Notaries_minsigs; //DPOW_MIN_ASSETCHAIN_SIGS; if ( strcmp("CHIPS",dp->symbol) == 0 ) freq = 100; else freq = 1; } dpow_fifoupdate(myinfo,dp->srcfifo,dp->last); - if ( strcmp(dp->dest,"KMD") == 0 ) + if ( strcmp(dp->dest,"KMD") == 0 || strcmp(dp->dest,"CHAIN") == 0 ) { //if ( dp->SRCREALTIME == 0 ) // return; @@ -162,15 +87,16 @@ void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t he { if ( (blockjson= dpow_getblock(myinfo,coin,hash)) != 0 ) { - if ( dpow_hasnotarization(myinfo,coin,blockjson) <= 0 ) + height = jint(blockjson,"height"); + if ( dpow_hasnotarization(&signedmask,¬ht,myinfo,coin,blockjson,height) <= 0 ) { - height = jint(blockjson,"height"); blocktime = juint(blockjson,"time"); free_json(blockjson); if ( height > 0 && blocktime > 0 ) { dpow_checkpointset(myinfo,&dp->last,height,hash,timestamp,blocktime); - //printf("dynamic set %s/%s %s <- height.%d\n",dp->symbol,dp->dest,bits256_str(str,hash),height); + if ( (0) && strcmp("CHIPS",dp->symbol) == 0 ) + printf("dynamic set %s/%s %s <- height.%d\n",dp->symbol,dp->dest,bits256_str(str,hash),height); checkpoint = dp->last; } else return; if ( bits256_nonz(dp->activehash) != 0 && bits256_cmp(dp->activehash,checkpoint.blockhash.hash) == 0 ) @@ -183,7 +109,8 @@ void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t he printf("lastnotarized.(%s) is current checkpoint, skip\n",bits256_str(str,dp->lastnotarized)); return; } - //printf("checkpoint.(%s) is not active and not lastnotarized\n",bits256_str(str,checkpoint.blockhash.hash)); + if ( (0) && strcmp("CHIPS",dp->symbol) == 0 ) + printf("checkpoint.(%s) is not active and not lastnotarized\n",bits256_str(str,checkpoint.blockhash.hash)); } else return; } else return; } else return; @@ -191,21 +118,37 @@ void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t he } if ( bits256_nonz(checkpoint.blockhash.hash) != 0 && (checkpoint.blockhash.height % freq) == 0 ) { - //printf("%s/%s src ht.%d dest.%u nonz.%d %s minsigs.%d\n",dp->symbol,dp->dest,checkpoint.blockhash.height,dp->destupdated,bits256_nonz(checkpoint.blockhash.hash),bits256_str(str,dp->last.blockhash.hash),minsigs); + if ( (0) && strcmp("CHIPS",dp->symbol) == 0 ) + printf("%s/%s src ht.%d dest.%u nonz.%d %s minsigs.%d\n",dp->symbol,dp->dest,checkpoint.blockhash.height,dp->destupdated,bits256_nonz(checkpoint.blockhash.hash),bits256_str(str,dp->last.blockhash.hash),minsigs); dpow_heightfind(myinfo,dp,checkpoint.blockhash.height + 1000); - ptrs = calloc(1,sizeof(void *)*5 + sizeof(struct dpow_checkpoint)); + ptrs = calloc(1,sizeof(void *)*5 + sizeof(struct dpow_checkpoint) + sizeof(pthread_t)); ptrs[0] = (void *)myinfo; ptrs[1] = (void *)dp; ptrs[2] = (void *)(uint64_t)minsigs; - if ( strcmp(dp->dest,"KMD") == 0 ) - ptrs[3] = (void *)(DPOW_DURATION * 60); // essentially try forever for assetchains - else ptrs[3] = (void *)DPOW_DURATION; + if ( strcmp(dp->dest,"KMD") != 0 ) + ptrs[3] = (void *)DPOW_DURATION; + else ptrs[3] = (void *)(DPOW_DURATION * 60); // essentially try forever for assetchains ptrs[4] = 0; memcpy(&ptrs[5],&checkpoint,sizeof(checkpoint)); dp->activehash = checkpoint.blockhash.hash; - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_statemachinestart,(void *)ptrs) != 0 ) + ht = checkpoint.blockhash.height; + if ( OS_thread_create((void *)((uint64_t)&ptrs[5] + sizeof(struct dpow_checkpoint)),NULL,(void *)dpow_statemachinestart,(void *)ptrs) != 0 ) { } + if ( ht > 500 ) + { + if ( (0) && strcmp("CHIPS",dp->symbol) == 0 ) + printf("ht.%d maxblocks.%d\n",ht,dp->maxblocks); + for (i=ht-500; i>ht-10000&&i>100; i--) + { + if ( (i % 100) != 0 && (bp= dp->blocks[i]) != 0 && bp->state == 0xffffffff ) + { + dp->blocks[i] = 0; + Numallocated--; + free(bp); + } + } + } } } @@ -251,7 +194,7 @@ void dpow_destupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t h dpow_fifoupdate(myinfo,dp->destfifo,dp->destchaintip); if ( strcmp(dp->dest,"BTC") == 0 ) { - printf("%s destupdate ht.%d\n",dp->dest,height); + //printf("%s destupdate ht.%d\n",dp->dest,height); dpow_destconfirm(myinfo,dp,&dp->destfifo[DPOW_BTCCONFIRMS]); } else dpow_destconfirm(myinfo,dp,&dp->destfifo[DPOW_KOMODOCONFIRMS*2]); // todo: change to notarized KMD depth @@ -259,22 +202,22 @@ void dpow_destupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t h void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp) { - int32_t height,num; uint32_t blocktime; bits256 blockhash; struct iguana_info *src,*dest; - //fprintf(stderr,"dp.%p dPoWupdate (%s -> %s)\n",dp,dp!=0?dp->symbol:"",dp!=0?dp->dest:""); + int32_t height,num; uint32_t blocktime; bits256 blockhash,merkleroot; struct iguana_info *src,*dest; //if ( strcmp(dp->symbol,"KMD") == 0 ) { num = dpow_nanomsg_update(myinfo); - //fprintf(stderr,"%d ",num); + //fprintf(stderr,"nano.%d ",num); } src = iguana_coinfind(dp->symbol); dest = iguana_coinfind(dp->dest); if ( src != 0 && dest != 0 ) { + //fprintf(stderr,"dp.%p dPoWupdate (%s -> %s)\n",dp,dp!=0?dp->symbol:"",dp!=0?dp->dest:""); dp->numdesttx = sizeof(dp->desttx)/sizeof(*dp->desttx); - if ( (height= dpow_getchaintip(myinfo,&blockhash,&blocktime,dp->desttx,&dp->numdesttx,dest)) != dp->destchaintip.blockhash.height && height >= 0 ) + if ( (height= dpow_getchaintip(myinfo,&merkleroot,&blockhash,&blocktime,dp->desttx,&dp->numdesttx,dest)) != dp->destchaintip.blockhash.height && height >= 0 ) { char str[65]; - if ( strcmp(dp->symbol,"KMD") == 0 )//|| height != dp->destchaintip.blockhash.height+1 ) + if ( (0) && strcmp(dp->symbol,"KMD") == 0 )//|| height != dp->destchaintip.blockhash.height+1 ) printf("[%s].%d %s %s height.%d vs last.%d\n",dp->symbol,dp->SRCHEIGHT,dp->dest,bits256_str(str,blockhash),height,dp->destchaintip.blockhash.height); if ( height <= dp->destchaintip.blockhash.height ) { @@ -284,13 +227,13 @@ void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp) } else dpow_destupdate(myinfo,dp,height,blockhash,(uint32_t)time(NULL),blocktime); } // else printf("error getchaintip for %s\n",dp->dest); dp->numsrctx = sizeof(dp->srctx)/sizeof(*dp->srctx); - if ( strcmp(dp->dest,"KMD") == 0 && dp->SRCHEIGHT < src->longestchain ) + if ( (strcmp(dp->dest,"KMD") == 0 || strcmp(dp->dest,"CHAIN") == 0) && dp->SRCHEIGHT < src->longestchain ) { //fprintf(stderr,"[I "); dp->SRCHEIGHT = dpow_issuer_iteration(dp,src,dp->SRCHEIGHT,&dp->SRCREALTIME); //fprintf(stderr," %d] ",dp->SRCHEIGHT); } - if ( (height= dpow_getchaintip(myinfo,&blockhash,&blocktime,dp->srctx,&dp->numsrctx,src)) != dp->last.blockhash.height && height >= 0 ) + if ( (height= dpow_getchaintip(myinfo,&merkleroot,&blockhash,&blocktime,dp->srctx,&dp->numsrctx,src)) != dp->last.blockhash.height && height >= 0 ) { //char str[65]; printf("[%s].%d %s %s height.%d vs last.%d\n",dp->dest,dp->SRCHEIGHT,dp->symbol,bits256_str(str,blockhash),height,dp->last.blockhash.height); if ( dp->lastheight == 0 ) @@ -334,9 +277,9 @@ void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp) void dpow_addresses() { int32_t i; char coinaddr[64]; uint8_t pubkey[33]; - for (i=0; iDPOWS[myinfo->numdpows]; + char *retstr,srcaddr[64],destaddr[64]; struct iguana_info *src,*destcoin; cJSON *ismine; int32_t i,srcvalid,destvalid; struct dpow_info *dp = &myinfo->DPOWS[myinfo->numdpows]; destvalid = srcvalid = 0; if ( myinfo->NOTARY.RELAYID < 0 ) { @@ -367,21 +310,22 @@ TWO_STRINGS(iguana,dpow,symbol,pubkey) return(clonestr("{\"error\":\"need 33 byte pubkey\"}")); if ( symbol == 0 || symbol[0] == 0 ) symbol = "KMD"; + if ( dest == 0 || dest[0] == 0 ) + { + if ( strcmp(symbol,"KMD") == 0 ) + dest = "BTC"; + else dest = "KMD"; + } //if ( myinfo->numdpows == 1 ) // komodo_assetcoins(-1); if ( iguana_coinfind(symbol) == 0 ) return(clonestr("{\"error\":\"cant dPoW an inactive coin\"}")); if ( strcmp(symbol,"KMD") == 0 && iguana_coinfind("BTC") == 0 ) return(clonestr("{\"error\":\"cant dPoW KMD without BTC\"}")); - else if ( myinfo->numdpows == 0 && strcmp(symbol,"KMD") != 0 && iguana_coinfind("KMD") == 0 ) - return(clonestr("{\"error\":\"cant dPoW without KMD\"}")); + else if ( iguana_coinfind(dest) == 0 ) + return(clonestr("{\"error\":\"cant dPoW without KMD (dest)\"}")); if ( myinfo->numdpows > 1 ) { - if ( strcmp(symbol,"KMD") == 0 || iguana_coinfind("BTC") == 0 ) - { - dp->symbol[0] = 0; - return(clonestr("{\"error\":\"cant dPoW KMD or BTC again\"}")); - } for (i=1; inumdpows; i++) if ( strcmp(symbol,myinfo->DPOWS[i].symbol) == 0 ) { @@ -397,14 +341,14 @@ TWO_STRINGS(iguana,dpow,symbol,pubkey) } else { - strcpy(dp->dest,"KMD"); + strcpy(dp->dest,dest); dp->srcconfirms = DPOW_THIRDPARTY_CONFIRMS; } if ( dp->srcconfirms > DPOW_FIFOSIZE ) dp->srcconfirms = DPOW_FIFOSIZE; src = iguana_coinfind(dp->symbol); - dest = iguana_coinfind(dp->dest); - if ( src == 0 || dest == 0 ) + destcoin = iguana_coinfind(dp->dest); + if ( src == 0 || destcoin == 0 ) { dp->symbol[0] = 0; return(clonestr("{\"error\":\"source coin or dest coin not there\"}")); @@ -422,8 +366,8 @@ TWO_STRINGS(iguana,dpow,symbol,pubkey) free(retstr); retstr = 0; } - bitcoin_address(destaddr,dest->chain->pubtype,dp->minerkey33,33); - if ( (retstr= dpow_validateaddress(myinfo,dest,destaddr)) != 0 ) + bitcoin_address(destaddr,destcoin->chain->pubtype,dp->minerkey33,33); + if ( (retstr= dpow_validateaddress(myinfo,destcoin,destaddr)) != 0 ) { json = cJSON_Parse(retstr); if ( (ismine= jobj(json,"ismine")) != 0 && is_cJSON_True(ismine) != 0 ) @@ -556,9 +500,11 @@ STRING_ARG(iguana,addnotary,ipaddr) return(clonestr("{\"result\":\"notary node added\"}")); } -char NOTARY_CURRENCIES[][16] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", - "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", - "REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "BOTS", "MGW", "COQUI", "WLC", "KV", "CEAL", "MESH", "MNZ", "CHIPS", "MSHARK", "AXO", "ETOMIC", "BTCH" }; // "LTC", +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" +}; + +// "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", void _iguana_notarystats(char *fname,int32_t totals[64],int32_t dispflag) { @@ -611,7 +557,7 @@ void _iguana_notarystats(char *fname,int32_t totals[64],int32_t dispflag) if ( dispflag != 0 ) { printf("after %s\n",fname); - for (i=0; i<64; i++) + for (i=0; i maxheight ) + break; + blockhash = dpow_getblockhash(myinfo,coin,ht); + if ( (blockjson= dpow_getblock(myinfo,coin,blockhash)) != 0 ) + { + if ( dpow_hasnotarization(&signedmask,¬ht,myinfo,coin,blockjson,ht) > 0 ) + { + for (j=0; j<64; j++) + if ( ((1LL << j) & signedmask) != 0 ) + masksums[j]++; + } + free_json(blockjson); + } + } + array = cJSON_CreateArray(); + for (i=0; izblock.RO.txn_count; i++) tree[i] = txarray[i].txid; - merkle_root = iguana_merkle(tree,origtxdata->zblock.RO.txn_count); + merkle_root = iguana_merkle(coin->symbol,tree,origtxdata->zblock.RO.txn_count); if ( bits256_cmp(merkle_root,origtxdata->zblock.RO.merkle_root) != 0 ) { char str[65],str2[65]; diff --git a/iguana/iguana_tx.c b/iguana/iguana_tx.c index ac6346fc8..22c12a5a6 100755 --- a/iguana/iguana_tx.c +++ b/iguana/iguana_tx.c @@ -346,7 +346,7 @@ int32_t iguana_peerblockrequest(struct supernet_info *myinfo,struct iguana_info } if ( i == block->RO.txn_count ) { - merkle_root = iguana_merkle(tree,block->RO.txn_count); + merkle_root = iguana_merkle(coin->symbol,tree,block->RO.txn_count); if ( bits256_cmp(merkle_root,block->RO.merkle_root) == 0 ) { if ( addr != 0 && addr->lastsent != block->height ) diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index e125aea2a..acf956890 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -1342,7 +1342,7 @@ ZERO_ARGS(bitcoinrpc,walletlock) TWOSTRINGS_AND_INT(bitcoinrpc,walletpassphrase,password,permanentfile,timeout) { - char *retstr; + char *retstr,*tmpstr; cJSON *retjson; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); if ( timeout <= 0 ) @@ -1368,9 +1368,22 @@ TWOSTRINGS_AND_INT(bitcoinrpc,walletpassphrase,password,permanentfile,timeout) bitcoin_address(coin->changeaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); if ( coin->FULLNODE < 0 ) { - char wifstr[64]; - bitcoin_priv2wif(wifstr,myinfo->persistent_priv,coin->chain->wiftype); - jumblr_importprivkey(myinfo,coin,wifstr); + char wifstr[64]; int32_t destvalid = 0; cJSON *ismine; + if ( (tmpstr= dpow_validateaddress(myinfo,coin,coin->changeaddr)) != 0 ) + { + retjson = cJSON_Parse(tmpstr); + if ( (ismine= jobj(json,"ismine")) != 0 && is_cJSON_True(ismine) != 0 ) + destvalid = 1; + else destvalid = 0; + free(tmpstr); + free(retjson); + tmpstr = 0; + } + if ( destvalid == 0 ) + { + bitcoin_priv2wif(wifstr,myinfo->persistent_priv,coin->chain->wiftype); + jumblr_importprivkey(myinfo,coin,wifstr); + } } } if ( bits256_nonz(myinfo->persistent_priv) != 0 ) diff --git a/iguana/keccak.c b/iguana/keccak.c new file mode 100644 index 000000000..86ce1387d --- /dev/null +++ b/iguana/keccak.c @@ -0,0 +1,1837 @@ +/* $Id: keccak.c 259 2011-07-19 22:11:27Z tp $ */ +/* + * Keccak implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#include +#include + +#include "sph_keccak.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#include + +/* + * Parameters: + * + * SPH_KECCAK_64 use a 64-bit type + * SPH_KECCAK_UNROLL number of loops to unroll (0/undef for full unroll) + * SPH_KECCAK_INTERLEAVE use bit-interleaving (32-bit type only) + * SPH_KECCAK_NOCOPY do not copy the state into local variables + * + * If there is no usable 64-bit type, the code automatically switches + * back to the 32-bit implementation. + * + * Some tests on an Intel Core2 Q6600 (both 64-bit and 32-bit, 32 kB L1 + * code cache), a PowerPC (G3, 32 kB L1 code cache), an ARM920T core + * (16 kB L1 code cache), and a small MIPS-compatible CPU (Broadcom BCM3302, + * 8 kB L1 code cache), seem to show that the following are optimal: + * + * -- x86, 64-bit: use the 64-bit implementation, unroll 8 rounds, + * do not copy the state; unrolling 2, 6 or all rounds also provides + * near-optimal performance. + * -- x86, 32-bit: use the 32-bit implementation, unroll 6 rounds, + * interleave, do not copy the state. Unrolling 1, 2, 4 or 8 rounds + * also provides near-optimal performance. + * -- PowerPC: use the 64-bit implementation, unroll 8 rounds, + * copy the state. Unrolling 4 or 6 rounds is near-optimal. + * -- ARM: use the 64-bit implementation, unroll 2 or 4 rounds, + * copy the state. + * -- MIPS: use the 64-bit implementation, unroll 2 rounds, copy + * the state. Unrolling only 1 round is also near-optimal. + * + * Also, interleaving does not always yield actual improvements when + * using a 32-bit implementation; in particular when the architecture + * does not offer a native rotation opcode (interleaving replaces one + * 64-bit rotation with two 32-bit rotations, which is a gain only if + * there is a native 32-bit rotation opcode and not a native 64-bit + * rotation opcode; also, interleaving implies a small overhead when + * processing input words). + * + * To sum up: + * -- when possible, use the 64-bit code + * -- exception: on 32-bit x86, use 32-bit code + * -- when using 32-bit code, use interleaving + * -- copy the state, except on x86 + * -- unroll 8 rounds on "big" machine, 2 rounds on "small" machines + */ + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_KECCAK +#define SPH_SMALL_FOOTPRINT_KECCAK 1 +#endif + +/* + * By default, we select the 64-bit implementation if a 64-bit type + * is available, unless a 32-bit x86 is detected. + */ +#if !defined SPH_KECCAK_64 && SPH_64 \ + && !(defined __i386__ || SPH_I386_GCC || SPH_I386_MSVC) +#define SPH_KECCAK_64 1 +#endif + +/* + * If using a 32-bit implementation, we prefer to interleave. + */ +#if !SPH_KECCAK_64 && !defined SPH_KECCAK_INTERLEAVE +#define SPH_KECCAK_INTERLEAVE 1 +#endif + +/* + * Unroll 8 rounds on big systems, 2 rounds on small systems. + */ +#ifndef SPH_KECCAK_UNROLL +#if SPH_SMALL_FOOTPRINT_KECCAK +#define SPH_KECCAK_UNROLL 2 +#else +#define SPH_KECCAK_UNROLL 8 +#endif +#endif + +/* + * We do not want to copy the state to local variables on x86 (32-bit + * and 64-bit alike). + */ +#ifndef SPH_KECCAK_NOCOPY +#if defined __i386__ || defined __x86_64 || SPH_I386_MSVC || SPH_I386_GCC +#define SPH_KECCAK_NOCOPY 1 +#else +#define SPH_KECCAK_NOCOPY 0 +#endif +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +#if SPH_KECCAK_64 + +static const sph_u64 RC[] = { + SPH_C64(0x0000000000000001), SPH_C64(0x0000000000008082), + SPH_C64(0x800000000000808A), SPH_C64(0x8000000080008000), + SPH_C64(0x000000000000808B), SPH_C64(0x0000000080000001), + SPH_C64(0x8000000080008081), SPH_C64(0x8000000000008009), + SPH_C64(0x000000000000008A), SPH_C64(0x0000000000000088), + SPH_C64(0x0000000080008009), SPH_C64(0x000000008000000A), + SPH_C64(0x000000008000808B), SPH_C64(0x800000000000008B), + SPH_C64(0x8000000000008089), SPH_C64(0x8000000000008003), + SPH_C64(0x8000000000008002), SPH_C64(0x8000000000000080), + SPH_C64(0x000000000000800A), SPH_C64(0x800000008000000A), + SPH_C64(0x8000000080008081), SPH_C64(0x8000000000008080), + SPH_C64(0x0000000080000001), SPH_C64(0x8000000080008008) +}; + +#if SPH_KECCAK_NOCOPY + +#define a00 (kc->u.wide[ 0]) +#define a10 (kc->u.wide[ 1]) +#define a20 (kc->u.wide[ 2]) +#define a30 (kc->u.wide[ 3]) +#define a40 (kc->u.wide[ 4]) +#define a01 (kc->u.wide[ 5]) +#define a11 (kc->u.wide[ 6]) +#define a21 (kc->u.wide[ 7]) +#define a31 (kc->u.wide[ 8]) +#define a41 (kc->u.wide[ 9]) +#define a02 (kc->u.wide[10]) +#define a12 (kc->u.wide[11]) +#define a22 (kc->u.wide[12]) +#define a32 (kc->u.wide[13]) +#define a42 (kc->u.wide[14]) +#define a03 (kc->u.wide[15]) +#define a13 (kc->u.wide[16]) +#define a23 (kc->u.wide[17]) +#define a33 (kc->u.wide[18]) +#define a43 (kc->u.wide[19]) +#define a04 (kc->u.wide[20]) +#define a14 (kc->u.wide[21]) +#define a24 (kc->u.wide[22]) +#define a34 (kc->u.wide[23]) +#define a44 (kc->u.wide[24]) + +#define DECL_STATE +#define READ_STATE(sc) +#define WRITE_STATE(sc) + +#define INPUT_BUF(size) do { \ + size_t j; \ + for (j = 0; j < (size); j += 8) { \ + kc->u.wide[j >> 3] ^= sph_dec64le_aligned(buf + j); \ + } \ + } while (0) + +#define INPUT_BUF144 INPUT_BUF(144) +#define INPUT_BUF136 INPUT_BUF(136) +#define INPUT_BUF104 INPUT_BUF(104) +#define INPUT_BUF72 INPUT_BUF(72) + +#else + +#define DECL_STATE \ + sph_u64 a00, a01, a02, a03, a04; \ + sph_u64 a10, a11, a12, a13, a14; \ + sph_u64 a20, a21, a22, a23, a24; \ + sph_u64 a30, a31, a32, a33, a34; \ + sph_u64 a40, a41, a42, a43, a44; + +#define READ_STATE(state) do { \ + a00 = (state)->u.wide[ 0]; \ + a10 = (state)->u.wide[ 1]; \ + a20 = (state)->u.wide[ 2]; \ + a30 = (state)->u.wide[ 3]; \ + a40 = (state)->u.wide[ 4]; \ + a01 = (state)->u.wide[ 5]; \ + a11 = (state)->u.wide[ 6]; \ + a21 = (state)->u.wide[ 7]; \ + a31 = (state)->u.wide[ 8]; \ + a41 = (state)->u.wide[ 9]; \ + a02 = (state)->u.wide[10]; \ + a12 = (state)->u.wide[11]; \ + a22 = (state)->u.wide[12]; \ + a32 = (state)->u.wide[13]; \ + a42 = (state)->u.wide[14]; \ + a03 = (state)->u.wide[15]; \ + a13 = (state)->u.wide[16]; \ + a23 = (state)->u.wide[17]; \ + a33 = (state)->u.wide[18]; \ + a43 = (state)->u.wide[19]; \ + a04 = (state)->u.wide[20]; \ + a14 = (state)->u.wide[21]; \ + a24 = (state)->u.wide[22]; \ + a34 = (state)->u.wide[23]; \ + a44 = (state)->u.wide[24]; \ + } while (0) + +#define WRITE_STATE(state) do { \ + (state)->u.wide[ 0] = a00; \ + (state)->u.wide[ 1] = a10; \ + (state)->u.wide[ 2] = a20; \ + (state)->u.wide[ 3] = a30; \ + (state)->u.wide[ 4] = a40; \ + (state)->u.wide[ 5] = a01; \ + (state)->u.wide[ 6] = a11; \ + (state)->u.wide[ 7] = a21; \ + (state)->u.wide[ 8] = a31; \ + (state)->u.wide[ 9] = a41; \ + (state)->u.wide[10] = a02; \ + (state)->u.wide[11] = a12; \ + (state)->u.wide[12] = a22; \ + (state)->u.wide[13] = a32; \ + (state)->u.wide[14] = a42; \ + (state)->u.wide[15] = a03; \ + (state)->u.wide[16] = a13; \ + (state)->u.wide[17] = a23; \ + (state)->u.wide[18] = a33; \ + (state)->u.wide[19] = a43; \ + (state)->u.wide[20] = a04; \ + (state)->u.wide[21] = a14; \ + (state)->u.wide[22] = a24; \ + (state)->u.wide[23] = a34; \ + (state)->u.wide[24] = a44; \ + } while (0) + +#define INPUT_BUF144 do { \ + a00 ^= sph_dec64le_aligned(buf + 0); \ + a10 ^= sph_dec64le_aligned(buf + 8); \ + a20 ^= sph_dec64le_aligned(buf + 16); \ + a30 ^= sph_dec64le_aligned(buf + 24); \ + a40 ^= sph_dec64le_aligned(buf + 32); \ + a01 ^= sph_dec64le_aligned(buf + 40); \ + a11 ^= sph_dec64le_aligned(buf + 48); \ + a21 ^= sph_dec64le_aligned(buf + 56); \ + a31 ^= sph_dec64le_aligned(buf + 64); \ + a41 ^= sph_dec64le_aligned(buf + 72); \ + a02 ^= sph_dec64le_aligned(buf + 80); \ + a12 ^= sph_dec64le_aligned(buf + 88); \ + a22 ^= sph_dec64le_aligned(buf + 96); \ + a32 ^= sph_dec64le_aligned(buf + 104); \ + a42 ^= sph_dec64le_aligned(buf + 112); \ + a03 ^= sph_dec64le_aligned(buf + 120); \ + a13 ^= sph_dec64le_aligned(buf + 128); \ + a23 ^= sph_dec64le_aligned(buf + 136); \ + } while (0) + +#define INPUT_BUF136 do { \ + a00 ^= sph_dec64le_aligned(buf + 0); \ + a10 ^= sph_dec64le_aligned(buf + 8); \ + a20 ^= sph_dec64le_aligned(buf + 16); \ + a30 ^= sph_dec64le_aligned(buf + 24); \ + a40 ^= sph_dec64le_aligned(buf + 32); \ + a01 ^= sph_dec64le_aligned(buf + 40); \ + a11 ^= sph_dec64le_aligned(buf + 48); \ + a21 ^= sph_dec64le_aligned(buf + 56); \ + a31 ^= sph_dec64le_aligned(buf + 64); \ + a41 ^= sph_dec64le_aligned(buf + 72); \ + a02 ^= sph_dec64le_aligned(buf + 80); \ + a12 ^= sph_dec64le_aligned(buf + 88); \ + a22 ^= sph_dec64le_aligned(buf + 96); \ + a32 ^= sph_dec64le_aligned(buf + 104); \ + a42 ^= sph_dec64le_aligned(buf + 112); \ + a03 ^= sph_dec64le_aligned(buf + 120); \ + a13 ^= sph_dec64le_aligned(buf + 128); \ + } while (0) + +#define INPUT_BUF104 do { \ + a00 ^= sph_dec64le_aligned(buf + 0); \ + a10 ^= sph_dec64le_aligned(buf + 8); \ + a20 ^= sph_dec64le_aligned(buf + 16); \ + a30 ^= sph_dec64le_aligned(buf + 24); \ + a40 ^= sph_dec64le_aligned(buf + 32); \ + a01 ^= sph_dec64le_aligned(buf + 40); \ + a11 ^= sph_dec64le_aligned(buf + 48); \ + a21 ^= sph_dec64le_aligned(buf + 56); \ + a31 ^= sph_dec64le_aligned(buf + 64); \ + a41 ^= sph_dec64le_aligned(buf + 72); \ + a02 ^= sph_dec64le_aligned(buf + 80); \ + a12 ^= sph_dec64le_aligned(buf + 88); \ + a22 ^= sph_dec64le_aligned(buf + 96); \ + } while (0) + +#define INPUT_BUF72 do { \ + a00 ^= sph_dec64le_aligned(buf + 0); \ + a10 ^= sph_dec64le_aligned(buf + 8); \ + a20 ^= sph_dec64le_aligned(buf + 16); \ + a30 ^= sph_dec64le_aligned(buf + 24); \ + a40 ^= sph_dec64le_aligned(buf + 32); \ + a01 ^= sph_dec64le_aligned(buf + 40); \ + a11 ^= sph_dec64le_aligned(buf + 48); \ + a21 ^= sph_dec64le_aligned(buf + 56); \ + a31 ^= sph_dec64le_aligned(buf + 64); \ + } while (0) + +#define INPUT_BUF(lim) do { \ + a00 ^= sph_dec64le_aligned(buf + 0); \ + a10 ^= sph_dec64le_aligned(buf + 8); \ + a20 ^= sph_dec64le_aligned(buf + 16); \ + a30 ^= sph_dec64le_aligned(buf + 24); \ + a40 ^= sph_dec64le_aligned(buf + 32); \ + a01 ^= sph_dec64le_aligned(buf + 40); \ + a11 ^= sph_dec64le_aligned(buf + 48); \ + a21 ^= sph_dec64le_aligned(buf + 56); \ + a31 ^= sph_dec64le_aligned(buf + 64); \ + if ((lim) == 72) \ + break; \ + a41 ^= sph_dec64le_aligned(buf + 72); \ + a02 ^= sph_dec64le_aligned(buf + 80); \ + a12 ^= sph_dec64le_aligned(buf + 88); \ + a22 ^= sph_dec64le_aligned(buf + 96); \ + if ((lim) == 104) \ + break; \ + a32 ^= sph_dec64le_aligned(buf + 104); \ + a42 ^= sph_dec64le_aligned(buf + 112); \ + a03 ^= sph_dec64le_aligned(buf + 120); \ + a13 ^= sph_dec64le_aligned(buf + 128); \ + if ((lim) == 136) \ + break; \ + a23 ^= sph_dec64le_aligned(buf + 136); \ + } while (0) + +#endif + +#define DECL64(x) sph_u64 x +#define MOV64(d, s) (d = s) +#define XOR64(d, a, b) (d = a ^ b) +#define AND64(d, a, b) (d = a & b) +#define OR64(d, a, b) (d = a | b) +#define NOT64(d, s) (d = SPH_T64(~s)) +#define ROL64(d, v, n) (d = SPH_ROTL64(v, n)) +#define XOR64_IOTA XOR64 + +#else + +static const struct { + sph_u32 high, low; +} RC[] = { +#if SPH_KECCAK_INTERLEAVE + { SPH_C32(0x00000000), SPH_C32(0x00000001) }, + { SPH_C32(0x00000089), SPH_C32(0x00000000) }, + { SPH_C32(0x8000008B), SPH_C32(0x00000000) }, + { SPH_C32(0x80008080), SPH_C32(0x00000000) }, + { SPH_C32(0x0000008B), SPH_C32(0x00000001) }, + { SPH_C32(0x00008000), SPH_C32(0x00000001) }, + { SPH_C32(0x80008088), SPH_C32(0x00000001) }, + { SPH_C32(0x80000082), SPH_C32(0x00000001) }, + { SPH_C32(0x0000000B), SPH_C32(0x00000000) }, + { SPH_C32(0x0000000A), SPH_C32(0x00000000) }, + { SPH_C32(0x00008082), SPH_C32(0x00000001) }, + { SPH_C32(0x00008003), SPH_C32(0x00000000) }, + { SPH_C32(0x0000808B), SPH_C32(0x00000001) }, + { SPH_C32(0x8000000B), SPH_C32(0x00000001) }, + { SPH_C32(0x8000008A), SPH_C32(0x00000001) }, + { SPH_C32(0x80000081), SPH_C32(0x00000001) }, + { SPH_C32(0x80000081), SPH_C32(0x00000000) }, + { SPH_C32(0x80000008), SPH_C32(0x00000000) }, + { SPH_C32(0x00000083), SPH_C32(0x00000000) }, + { SPH_C32(0x80008003), SPH_C32(0x00000000) }, + { SPH_C32(0x80008088), SPH_C32(0x00000001) }, + { SPH_C32(0x80000088), SPH_C32(0x00000000) }, + { SPH_C32(0x00008000), SPH_C32(0x00000001) }, + { SPH_C32(0x80008082), SPH_C32(0x00000000) } +#else + { SPH_C32(0x00000000), SPH_C32(0x00000001) }, + { SPH_C32(0x00000000), SPH_C32(0x00008082) }, + { SPH_C32(0x80000000), SPH_C32(0x0000808A) }, + { SPH_C32(0x80000000), SPH_C32(0x80008000) }, + { SPH_C32(0x00000000), SPH_C32(0x0000808B) }, + { SPH_C32(0x00000000), SPH_C32(0x80000001) }, + { SPH_C32(0x80000000), SPH_C32(0x80008081) }, + { SPH_C32(0x80000000), SPH_C32(0x00008009) }, + { SPH_C32(0x00000000), SPH_C32(0x0000008A) }, + { SPH_C32(0x00000000), SPH_C32(0x00000088) }, + { SPH_C32(0x00000000), SPH_C32(0x80008009) }, + { SPH_C32(0x00000000), SPH_C32(0x8000000A) }, + { SPH_C32(0x00000000), SPH_C32(0x8000808B) }, + { SPH_C32(0x80000000), SPH_C32(0x0000008B) }, + { SPH_C32(0x80000000), SPH_C32(0x00008089) }, + { SPH_C32(0x80000000), SPH_C32(0x00008003) }, + { SPH_C32(0x80000000), SPH_C32(0x00008002) }, + { SPH_C32(0x80000000), SPH_C32(0x00000080) }, + { SPH_C32(0x00000000), SPH_C32(0x0000800A) }, + { SPH_C32(0x80000000), SPH_C32(0x8000000A) }, + { SPH_C32(0x80000000), SPH_C32(0x80008081) }, + { SPH_C32(0x80000000), SPH_C32(0x00008080) }, + { SPH_C32(0x00000000), SPH_C32(0x80000001) }, + { SPH_C32(0x80000000), SPH_C32(0x80008008) } +#endif +}; + +#if SPH_KECCAK_INTERLEAVE + +#define INTERLEAVE(xl, xh) do { \ + sph_u32 l, h, t; \ + l = (xl); h = (xh); \ + t = (l ^ (l >> 1)) & SPH_C32(0x22222222); l ^= t ^ (t << 1); \ + t = (h ^ (h >> 1)) & SPH_C32(0x22222222); h ^= t ^ (t << 1); \ + t = (l ^ (l >> 2)) & SPH_C32(0x0C0C0C0C); l ^= t ^ (t << 2); \ + t = (h ^ (h >> 2)) & SPH_C32(0x0C0C0C0C); h ^= t ^ (t << 2); \ + t = (l ^ (l >> 4)) & SPH_C32(0x00F000F0); l ^= t ^ (t << 4); \ + t = (h ^ (h >> 4)) & SPH_C32(0x00F000F0); h ^= t ^ (t << 4); \ + t = (l ^ (l >> 8)) & SPH_C32(0x0000FF00); l ^= t ^ (t << 8); \ + t = (h ^ (h >> 8)) & SPH_C32(0x0000FF00); h ^= t ^ (t << 8); \ + t = (l ^ SPH_T32(h << 16)) & SPH_C32(0xFFFF0000); \ + l ^= t; h ^= t >> 16; \ + (xl) = l; (xh) = h; \ + } while (0) + +#define UNINTERLEAVE(xl, xh) do { \ + sph_u32 l, h, t; \ + l = (xl); h = (xh); \ + t = (l ^ SPH_T32(h << 16)) & SPH_C32(0xFFFF0000); \ + l ^= t; h ^= t >> 16; \ + t = (l ^ (l >> 8)) & SPH_C32(0x0000FF00); l ^= t ^ (t << 8); \ + t = (h ^ (h >> 8)) & SPH_C32(0x0000FF00); h ^= t ^ (t << 8); \ + t = (l ^ (l >> 4)) & SPH_C32(0x00F000F0); l ^= t ^ (t << 4); \ + t = (h ^ (h >> 4)) & SPH_C32(0x00F000F0); h ^= t ^ (t << 4); \ + t = (l ^ (l >> 2)) & SPH_C32(0x0C0C0C0C); l ^= t ^ (t << 2); \ + t = (h ^ (h >> 2)) & SPH_C32(0x0C0C0C0C); h ^= t ^ (t << 2); \ + t = (l ^ (l >> 1)) & SPH_C32(0x22222222); l ^= t ^ (t << 1); \ + t = (h ^ (h >> 1)) & SPH_C32(0x22222222); h ^= t ^ (t << 1); \ + (xl) = l; (xh) = h; \ + } while (0) + +#else + +#define INTERLEAVE(l, h) +#define UNINTERLEAVE(l, h) + +#endif + +#if SPH_KECCAK_NOCOPY + +#define a00l (kc->u.narrow[2 * 0 + 0]) +#define a00h (kc->u.narrow[2 * 0 + 1]) +#define a10l (kc->u.narrow[2 * 1 + 0]) +#define a10h (kc->u.narrow[2 * 1 + 1]) +#define a20l (kc->u.narrow[2 * 2 + 0]) +#define a20h (kc->u.narrow[2 * 2 + 1]) +#define a30l (kc->u.narrow[2 * 3 + 0]) +#define a30h (kc->u.narrow[2 * 3 + 1]) +#define a40l (kc->u.narrow[2 * 4 + 0]) +#define a40h (kc->u.narrow[2 * 4 + 1]) +#define a01l (kc->u.narrow[2 * 5 + 0]) +#define a01h (kc->u.narrow[2 * 5 + 1]) +#define a11l (kc->u.narrow[2 * 6 + 0]) +#define a11h (kc->u.narrow[2 * 6 + 1]) +#define a21l (kc->u.narrow[2 * 7 + 0]) +#define a21h (kc->u.narrow[2 * 7 + 1]) +#define a31l (kc->u.narrow[2 * 8 + 0]) +#define a31h (kc->u.narrow[2 * 8 + 1]) +#define a41l (kc->u.narrow[2 * 9 + 0]) +#define a41h (kc->u.narrow[2 * 9 + 1]) +#define a02l (kc->u.narrow[2 * 10 + 0]) +#define a02h (kc->u.narrow[2 * 10 + 1]) +#define a12l (kc->u.narrow[2 * 11 + 0]) +#define a12h (kc->u.narrow[2 * 11 + 1]) +#define a22l (kc->u.narrow[2 * 12 + 0]) +#define a22h (kc->u.narrow[2 * 12 + 1]) +#define a32l (kc->u.narrow[2 * 13 + 0]) +#define a32h (kc->u.narrow[2 * 13 + 1]) +#define a42l (kc->u.narrow[2 * 14 + 0]) +#define a42h (kc->u.narrow[2 * 14 + 1]) +#define a03l (kc->u.narrow[2 * 15 + 0]) +#define a03h (kc->u.narrow[2 * 15 + 1]) +#define a13l (kc->u.narrow[2 * 16 + 0]) +#define a13h (kc->u.narrow[2 * 16 + 1]) +#define a23l (kc->u.narrow[2 * 17 + 0]) +#define a23h (kc->u.narrow[2 * 17 + 1]) +#define a33l (kc->u.narrow[2 * 18 + 0]) +#define a33h (kc->u.narrow[2 * 18 + 1]) +#define a43l (kc->u.narrow[2 * 19 + 0]) +#define a43h (kc->u.narrow[2 * 19 + 1]) +#define a04l (kc->u.narrow[2 * 20 + 0]) +#define a04h (kc->u.narrow[2 * 20 + 1]) +#define a14l (kc->u.narrow[2 * 21 + 0]) +#define a14h (kc->u.narrow[2 * 21 + 1]) +#define a24l (kc->u.narrow[2 * 22 + 0]) +#define a24h (kc->u.narrow[2 * 22 + 1]) +#define a34l (kc->u.narrow[2 * 23 + 0]) +#define a34h (kc->u.narrow[2 * 23 + 1]) +#define a44l (kc->u.narrow[2 * 24 + 0]) +#define a44h (kc->u.narrow[2 * 24 + 1]) + +#define DECL_STATE +#define READ_STATE(state) +#define WRITE_STATE(state) + +#define INPUT_BUF(size) do { \ + size_t j; \ + for (j = 0; j < (size); j += 8) { \ + sph_u32 tl, th; \ + tl = sph_dec32le_aligned(buf + j + 0); \ + th = sph_dec32le_aligned(buf + j + 4); \ + INTERLEAVE(tl, th); \ + kc->u.narrow[(j >> 2) + 0] ^= tl; \ + kc->u.narrow[(j >> 2) + 1] ^= th; \ + } \ + } while (0) + +#define INPUT_BUF144 INPUT_BUF(144) +#define INPUT_BUF136 INPUT_BUF(136) +#define INPUT_BUF104 INPUT_BUF(104) +#define INPUT_BUF72 INPUT_BUF(72) + +#else + +#define DECL_STATE \ + sph_u32 a00l, a00h, a01l, a01h, a02l, a02h, a03l, a03h, a04l, a04h; \ + sph_u32 a10l, a10h, a11l, a11h, a12l, a12h, a13l, a13h, a14l, a14h; \ + sph_u32 a20l, a20h, a21l, a21h, a22l, a22h, a23l, a23h, a24l, a24h; \ + sph_u32 a30l, a30h, a31l, a31h, a32l, a32h, a33l, a33h, a34l, a34h; \ + sph_u32 a40l, a40h, a41l, a41h, a42l, a42h, a43l, a43h, a44l, a44h; + +#define READ_STATE(state) do { \ + a00l = (state)->u.narrow[2 * 0 + 0]; \ + a00h = (state)->u.narrow[2 * 0 + 1]; \ + a10l = (state)->u.narrow[2 * 1 + 0]; \ + a10h = (state)->u.narrow[2 * 1 + 1]; \ + a20l = (state)->u.narrow[2 * 2 + 0]; \ + a20h = (state)->u.narrow[2 * 2 + 1]; \ + a30l = (state)->u.narrow[2 * 3 + 0]; \ + a30h = (state)->u.narrow[2 * 3 + 1]; \ + a40l = (state)->u.narrow[2 * 4 + 0]; \ + a40h = (state)->u.narrow[2 * 4 + 1]; \ + a01l = (state)->u.narrow[2 * 5 + 0]; \ + a01h = (state)->u.narrow[2 * 5 + 1]; \ + a11l = (state)->u.narrow[2 * 6 + 0]; \ + a11h = (state)->u.narrow[2 * 6 + 1]; \ + a21l = (state)->u.narrow[2 * 7 + 0]; \ + a21h = (state)->u.narrow[2 * 7 + 1]; \ + a31l = (state)->u.narrow[2 * 8 + 0]; \ + a31h = (state)->u.narrow[2 * 8 + 1]; \ + a41l = (state)->u.narrow[2 * 9 + 0]; \ + a41h = (state)->u.narrow[2 * 9 + 1]; \ + a02l = (state)->u.narrow[2 * 10 + 0]; \ + a02h = (state)->u.narrow[2 * 10 + 1]; \ + a12l = (state)->u.narrow[2 * 11 + 0]; \ + a12h = (state)->u.narrow[2 * 11 + 1]; \ + a22l = (state)->u.narrow[2 * 12 + 0]; \ + a22h = (state)->u.narrow[2 * 12 + 1]; \ + a32l = (state)->u.narrow[2 * 13 + 0]; \ + a32h = (state)->u.narrow[2 * 13 + 1]; \ + a42l = (state)->u.narrow[2 * 14 + 0]; \ + a42h = (state)->u.narrow[2 * 14 + 1]; \ + a03l = (state)->u.narrow[2 * 15 + 0]; \ + a03h = (state)->u.narrow[2 * 15 + 1]; \ + a13l = (state)->u.narrow[2 * 16 + 0]; \ + a13h = (state)->u.narrow[2 * 16 + 1]; \ + a23l = (state)->u.narrow[2 * 17 + 0]; \ + a23h = (state)->u.narrow[2 * 17 + 1]; \ + a33l = (state)->u.narrow[2 * 18 + 0]; \ + a33h = (state)->u.narrow[2 * 18 + 1]; \ + a43l = (state)->u.narrow[2 * 19 + 0]; \ + a43h = (state)->u.narrow[2 * 19 + 1]; \ + a04l = (state)->u.narrow[2 * 20 + 0]; \ + a04h = (state)->u.narrow[2 * 20 + 1]; \ + a14l = (state)->u.narrow[2 * 21 + 0]; \ + a14h = (state)->u.narrow[2 * 21 + 1]; \ + a24l = (state)->u.narrow[2 * 22 + 0]; \ + a24h = (state)->u.narrow[2 * 22 + 1]; \ + a34l = (state)->u.narrow[2 * 23 + 0]; \ + a34h = (state)->u.narrow[2 * 23 + 1]; \ + a44l = (state)->u.narrow[2 * 24 + 0]; \ + a44h = (state)->u.narrow[2 * 24 + 1]; \ + } while (0) + +#define WRITE_STATE(state) do { \ + (state)->u.narrow[2 * 0 + 0] = a00l; \ + (state)->u.narrow[2 * 0 + 1] = a00h; \ + (state)->u.narrow[2 * 1 + 0] = a10l; \ + (state)->u.narrow[2 * 1 + 1] = a10h; \ + (state)->u.narrow[2 * 2 + 0] = a20l; \ + (state)->u.narrow[2 * 2 + 1] = a20h; \ + (state)->u.narrow[2 * 3 + 0] = a30l; \ + (state)->u.narrow[2 * 3 + 1] = a30h; \ + (state)->u.narrow[2 * 4 + 0] = a40l; \ + (state)->u.narrow[2 * 4 + 1] = a40h; \ + (state)->u.narrow[2 * 5 + 0] = a01l; \ + (state)->u.narrow[2 * 5 + 1] = a01h; \ + (state)->u.narrow[2 * 6 + 0] = a11l; \ + (state)->u.narrow[2 * 6 + 1] = a11h; \ + (state)->u.narrow[2 * 7 + 0] = a21l; \ + (state)->u.narrow[2 * 7 + 1] = a21h; \ + (state)->u.narrow[2 * 8 + 0] = a31l; \ + (state)->u.narrow[2 * 8 + 1] = a31h; \ + (state)->u.narrow[2 * 9 + 0] = a41l; \ + (state)->u.narrow[2 * 9 + 1] = a41h; \ + (state)->u.narrow[2 * 10 + 0] = a02l; \ + (state)->u.narrow[2 * 10 + 1] = a02h; \ + (state)->u.narrow[2 * 11 + 0] = a12l; \ + (state)->u.narrow[2 * 11 + 1] = a12h; \ + (state)->u.narrow[2 * 12 + 0] = a22l; \ + (state)->u.narrow[2 * 12 + 1] = a22h; \ + (state)->u.narrow[2 * 13 + 0] = a32l; \ + (state)->u.narrow[2 * 13 + 1] = a32h; \ + (state)->u.narrow[2 * 14 + 0] = a42l; \ + (state)->u.narrow[2 * 14 + 1] = a42h; \ + (state)->u.narrow[2 * 15 + 0] = a03l; \ + (state)->u.narrow[2 * 15 + 1] = a03h; \ + (state)->u.narrow[2 * 16 + 0] = a13l; \ + (state)->u.narrow[2 * 16 + 1] = a13h; \ + (state)->u.narrow[2 * 17 + 0] = a23l; \ + (state)->u.narrow[2 * 17 + 1] = a23h; \ + (state)->u.narrow[2 * 18 + 0] = a33l; \ + (state)->u.narrow[2 * 18 + 1] = a33h; \ + (state)->u.narrow[2 * 19 + 0] = a43l; \ + (state)->u.narrow[2 * 19 + 1] = a43h; \ + (state)->u.narrow[2 * 20 + 0] = a04l; \ + (state)->u.narrow[2 * 20 + 1] = a04h; \ + (state)->u.narrow[2 * 21 + 0] = a14l; \ + (state)->u.narrow[2 * 21 + 1] = a14h; \ + (state)->u.narrow[2 * 22 + 0] = a24l; \ + (state)->u.narrow[2 * 22 + 1] = a24h; \ + (state)->u.narrow[2 * 23 + 0] = a34l; \ + (state)->u.narrow[2 * 23 + 1] = a34h; \ + (state)->u.narrow[2 * 24 + 0] = a44l; \ + (state)->u.narrow[2 * 24 + 1] = a44h; \ + } while (0) + +#define READ64(d, off) do { \ + sph_u32 tl, th; \ + tl = sph_dec32le_aligned(buf + (off)); \ + th = sph_dec32le_aligned(buf + (off) + 4); \ + INTERLEAVE(tl, th); \ + d ## l ^= tl; \ + d ## h ^= th; \ + } while (0) + +#define INPUT_BUF144 do { \ + READ64(a00, 0); \ + READ64(a10, 8); \ + READ64(a20, 16); \ + READ64(a30, 24); \ + READ64(a40, 32); \ + READ64(a01, 40); \ + READ64(a11, 48); \ + READ64(a21, 56); \ + READ64(a31, 64); \ + READ64(a41, 72); \ + READ64(a02, 80); \ + READ64(a12, 88); \ + READ64(a22, 96); \ + READ64(a32, 104); \ + READ64(a42, 112); \ + READ64(a03, 120); \ + READ64(a13, 128); \ + READ64(a23, 136); \ + } while (0) + +#define INPUT_BUF136 do { \ + READ64(a00, 0); \ + READ64(a10, 8); \ + READ64(a20, 16); \ + READ64(a30, 24); \ + READ64(a40, 32); \ + READ64(a01, 40); \ + READ64(a11, 48); \ + READ64(a21, 56); \ + READ64(a31, 64); \ + READ64(a41, 72); \ + READ64(a02, 80); \ + READ64(a12, 88); \ + READ64(a22, 96); \ + READ64(a32, 104); \ + READ64(a42, 112); \ + READ64(a03, 120); \ + READ64(a13, 128); \ + } while (0) + +#define INPUT_BUF104 do { \ + READ64(a00, 0); \ + READ64(a10, 8); \ + READ64(a20, 16); \ + READ64(a30, 24); \ + READ64(a40, 32); \ + READ64(a01, 40); \ + READ64(a11, 48); \ + READ64(a21, 56); \ + READ64(a31, 64); \ + READ64(a41, 72); \ + READ64(a02, 80); \ + READ64(a12, 88); \ + READ64(a22, 96); \ + } while (0) + +#define INPUT_BUF72 do { \ + READ64(a00, 0); \ + READ64(a10, 8); \ + READ64(a20, 16); \ + READ64(a30, 24); \ + READ64(a40, 32); \ + READ64(a01, 40); \ + READ64(a11, 48); \ + READ64(a21, 56); \ + READ64(a31, 64); \ + } while (0) + +#define INPUT_BUF(lim) do { \ + READ64(a00, 0); \ + READ64(a10, 8); \ + READ64(a20, 16); \ + READ64(a30, 24); \ + READ64(a40, 32); \ + READ64(a01, 40); \ + READ64(a11, 48); \ + READ64(a21, 56); \ + READ64(a31, 64); \ + if ((lim) == 72) \ + break; \ + READ64(a41, 72); \ + READ64(a02, 80); \ + READ64(a12, 88); \ + READ64(a22, 96); \ + if ((lim) == 104) \ + break; \ + READ64(a32, 104); \ + READ64(a42, 112); \ + READ64(a03, 120); \ + READ64(a13, 128); \ + if ((lim) == 136) \ + break; \ + READ64(a23, 136); \ + } while (0) + +#endif + +#define DECL64(x) sph_u64 x ## l, x ## h +#define MOV64(d, s) (d ## l = s ## l, d ## h = s ## h) +#define XOR64(d, a, b) (d ## l = a ## l ^ b ## l, d ## h = a ## h ^ b ## h) +#define AND64(d, a, b) (d ## l = a ## l & b ## l, d ## h = a ## h & b ## h) +#define OR64(d, a, b) (d ## l = a ## l | b ## l, d ## h = a ## h | b ## h) +#define NOT64(d, s) (d ## l = SPH_T32(~s ## l), d ## h = SPH_T32(~s ## h)) +#define ROL64(d, v, n) ROL64_ ## n(d, v) + +#if SPH_KECCAK_INTERLEAVE + +#define ROL64_odd1(d, v) do { \ + sph_u32 tmp; \ + tmp = v ## l; \ + d ## l = SPH_T32(v ## h << 1) | (v ## h >> 31); \ + d ## h = tmp; \ + } while (0) + +#define ROL64_odd63(d, v) do { \ + sph_u32 tmp; \ + tmp = SPH_T32(v ## l << 31) | (v ## l >> 1); \ + d ## l = v ## h; \ + d ## h = tmp; \ + } while (0) + +#define ROL64_odd(d, v, n) do { \ + sph_u32 tmp; \ + tmp = SPH_T32(v ## l << (n - 1)) | (v ## l >> (33 - n)); \ + d ## l = SPH_T32(v ## h << n) | (v ## h >> (32 - n)); \ + d ## h = tmp; \ + } while (0) + +#define ROL64_even(d, v, n) do { \ + d ## l = SPH_T32(v ## l << n) | (v ## l >> (32 - n)); \ + d ## h = SPH_T32(v ## h << n) | (v ## h >> (32 - n)); \ + } while (0) + +#define ROL64_0(d, v) +#define ROL64_1(d, v) ROL64_odd1(d, v) +#define ROL64_2(d, v) ROL64_even(d, v, 1) +#define ROL64_3(d, v) ROL64_odd( d, v, 2) +#define ROL64_4(d, v) ROL64_even(d, v, 2) +#define ROL64_5(d, v) ROL64_odd( d, v, 3) +#define ROL64_6(d, v) ROL64_even(d, v, 3) +#define ROL64_7(d, v) ROL64_odd( d, v, 4) +#define ROL64_8(d, v) ROL64_even(d, v, 4) +#define ROL64_9(d, v) ROL64_odd( d, v, 5) +#define ROL64_10(d, v) ROL64_even(d, v, 5) +#define ROL64_11(d, v) ROL64_odd( d, v, 6) +#define ROL64_12(d, v) ROL64_even(d, v, 6) +#define ROL64_13(d, v) ROL64_odd( d, v, 7) +#define ROL64_14(d, v) ROL64_even(d, v, 7) +#define ROL64_15(d, v) ROL64_odd( d, v, 8) +#define ROL64_16(d, v) ROL64_even(d, v, 8) +#define ROL64_17(d, v) ROL64_odd( d, v, 9) +#define ROL64_18(d, v) ROL64_even(d, v, 9) +#define ROL64_19(d, v) ROL64_odd( d, v, 10) +#define ROL64_20(d, v) ROL64_even(d, v, 10) +#define ROL64_21(d, v) ROL64_odd( d, v, 11) +#define ROL64_22(d, v) ROL64_even(d, v, 11) +#define ROL64_23(d, v) ROL64_odd( d, v, 12) +#define ROL64_24(d, v) ROL64_even(d, v, 12) +#define ROL64_25(d, v) ROL64_odd( d, v, 13) +#define ROL64_26(d, v) ROL64_even(d, v, 13) +#define ROL64_27(d, v) ROL64_odd( d, v, 14) +#define ROL64_28(d, v) ROL64_even(d, v, 14) +#define ROL64_29(d, v) ROL64_odd( d, v, 15) +#define ROL64_30(d, v) ROL64_even(d, v, 15) +#define ROL64_31(d, v) ROL64_odd( d, v, 16) +#define ROL64_32(d, v) ROL64_even(d, v, 16) +#define ROL64_33(d, v) ROL64_odd( d, v, 17) +#define ROL64_34(d, v) ROL64_even(d, v, 17) +#define ROL64_35(d, v) ROL64_odd( d, v, 18) +#define ROL64_36(d, v) ROL64_even(d, v, 18) +#define ROL64_37(d, v) ROL64_odd( d, v, 19) +#define ROL64_38(d, v) ROL64_even(d, v, 19) +#define ROL64_39(d, v) ROL64_odd( d, v, 20) +#define ROL64_40(d, v) ROL64_even(d, v, 20) +#define ROL64_41(d, v) ROL64_odd( d, v, 21) +#define ROL64_42(d, v) ROL64_even(d, v, 21) +#define ROL64_43(d, v) ROL64_odd( d, v, 22) +#define ROL64_44(d, v) ROL64_even(d, v, 22) +#define ROL64_45(d, v) ROL64_odd( d, v, 23) +#define ROL64_46(d, v) ROL64_even(d, v, 23) +#define ROL64_47(d, v) ROL64_odd( d, v, 24) +#define ROL64_48(d, v) ROL64_even(d, v, 24) +#define ROL64_49(d, v) ROL64_odd( d, v, 25) +#define ROL64_50(d, v) ROL64_even(d, v, 25) +#define ROL64_51(d, v) ROL64_odd( d, v, 26) +#define ROL64_52(d, v) ROL64_even(d, v, 26) +#define ROL64_53(d, v) ROL64_odd( d, v, 27) +#define ROL64_54(d, v) ROL64_even(d, v, 27) +#define ROL64_55(d, v) ROL64_odd( d, v, 28) +#define ROL64_56(d, v) ROL64_even(d, v, 28) +#define ROL64_57(d, v) ROL64_odd( d, v, 29) +#define ROL64_58(d, v) ROL64_even(d, v, 29) +#define ROL64_59(d, v) ROL64_odd( d, v, 30) +#define ROL64_60(d, v) ROL64_even(d, v, 30) +#define ROL64_61(d, v) ROL64_odd( d, v, 31) +#define ROL64_62(d, v) ROL64_even(d, v, 31) +#define ROL64_63(d, v) ROL64_odd63(d, v) + +#else + +#define ROL64_small(d, v, n) do { \ + sph_u32 tmp; \ + tmp = SPH_T32(v ## l << n) | (v ## h >> (32 - n)); \ + d ## h = SPH_T32(v ## h << n) | (v ## l >> (32 - n)); \ + d ## l = tmp; \ + } while (0) + +#define ROL64_0(d, v) 0 +#define ROL64_1(d, v) ROL64_small(d, v, 1) +#define ROL64_2(d, v) ROL64_small(d, v, 2) +#define ROL64_3(d, v) ROL64_small(d, v, 3) +#define ROL64_4(d, v) ROL64_small(d, v, 4) +#define ROL64_5(d, v) ROL64_small(d, v, 5) +#define ROL64_6(d, v) ROL64_small(d, v, 6) +#define ROL64_7(d, v) ROL64_small(d, v, 7) +#define ROL64_8(d, v) ROL64_small(d, v, 8) +#define ROL64_9(d, v) ROL64_small(d, v, 9) +#define ROL64_10(d, v) ROL64_small(d, v, 10) +#define ROL64_11(d, v) ROL64_small(d, v, 11) +#define ROL64_12(d, v) ROL64_small(d, v, 12) +#define ROL64_13(d, v) ROL64_small(d, v, 13) +#define ROL64_14(d, v) ROL64_small(d, v, 14) +#define ROL64_15(d, v) ROL64_small(d, v, 15) +#define ROL64_16(d, v) ROL64_small(d, v, 16) +#define ROL64_17(d, v) ROL64_small(d, v, 17) +#define ROL64_18(d, v) ROL64_small(d, v, 18) +#define ROL64_19(d, v) ROL64_small(d, v, 19) +#define ROL64_20(d, v) ROL64_small(d, v, 20) +#define ROL64_21(d, v) ROL64_small(d, v, 21) +#define ROL64_22(d, v) ROL64_small(d, v, 22) +#define ROL64_23(d, v) ROL64_small(d, v, 23) +#define ROL64_24(d, v) ROL64_small(d, v, 24) +#define ROL64_25(d, v) ROL64_small(d, v, 25) +#define ROL64_26(d, v) ROL64_small(d, v, 26) +#define ROL64_27(d, v) ROL64_small(d, v, 27) +#define ROL64_28(d, v) ROL64_small(d, v, 28) +#define ROL64_29(d, v) ROL64_small(d, v, 29) +#define ROL64_30(d, v) ROL64_small(d, v, 30) +#define ROL64_31(d, v) ROL64_small(d, v, 31) + +#define ROL64_32(d, v) do { \ + sph_u32 tmp; \ + tmp = v ## l; \ + d ## l = v ## h; \ + d ## h = tmp; \ + } while (0) + +#define ROL64_big(d, v, n) do { \ + sph_u32 trl, trh; \ + ROL64_small(tr, v, n); \ + d ## h = trl; \ + d ## l = trh; \ + } while (0) + +#define ROL64_33(d, v) ROL64_big(d, v, 1) +#define ROL64_34(d, v) ROL64_big(d, v, 2) +#define ROL64_35(d, v) ROL64_big(d, v, 3) +#define ROL64_36(d, v) ROL64_big(d, v, 4) +#define ROL64_37(d, v) ROL64_big(d, v, 5) +#define ROL64_38(d, v) ROL64_big(d, v, 6) +#define ROL64_39(d, v) ROL64_big(d, v, 7) +#define ROL64_40(d, v) ROL64_big(d, v, 8) +#define ROL64_41(d, v) ROL64_big(d, v, 9) +#define ROL64_42(d, v) ROL64_big(d, v, 10) +#define ROL64_43(d, v) ROL64_big(d, v, 11) +#define ROL64_44(d, v) ROL64_big(d, v, 12) +#define ROL64_45(d, v) ROL64_big(d, v, 13) +#define ROL64_46(d, v) ROL64_big(d, v, 14) +#define ROL64_47(d, v) ROL64_big(d, v, 15) +#define ROL64_48(d, v) ROL64_big(d, v, 16) +#define ROL64_49(d, v) ROL64_big(d, v, 17) +#define ROL64_50(d, v) ROL64_big(d, v, 18) +#define ROL64_51(d, v) ROL64_big(d, v, 19) +#define ROL64_52(d, v) ROL64_big(d, v, 20) +#define ROL64_53(d, v) ROL64_big(d, v, 21) +#define ROL64_54(d, v) ROL64_big(d, v, 22) +#define ROL64_55(d, v) ROL64_big(d, v, 23) +#define ROL64_56(d, v) ROL64_big(d, v, 24) +#define ROL64_57(d, v) ROL64_big(d, v, 25) +#define ROL64_58(d, v) ROL64_big(d, v, 26) +#define ROL64_59(d, v) ROL64_big(d, v, 27) +#define ROL64_60(d, v) ROL64_big(d, v, 28) +#define ROL64_61(d, v) ROL64_big(d, v, 29) +#define ROL64_62(d, v) ROL64_big(d, v, 30) +#define ROL64_63(d, v) ROL64_big(d, v, 31) + +#endif + +#define XOR64_IOTA(d, s, k) \ + (d ## l = s ## l ^ k.low, d ## h = s ## h ^ k.high) + +#endif + +#define TH_ELT(t, c0, c1, c2, c3, c4, d0, d1, d2, d3, d4) do { \ + DECL64(tt0); \ + DECL64(tt1); \ + DECL64(tt2); \ + DECL64(tt3); \ + XOR64(tt0, d0, d1); \ + XOR64(tt1, d2, d3); \ + XOR64(tt0, tt0, d4); \ + XOR64(tt0, tt0, tt1); \ + ROL64(tt0, tt0, 1); \ + XOR64(tt2, c0, c1); \ + XOR64(tt3, c2, c3); \ + XOR64(tt0, tt0, c4); \ + XOR64(tt2, tt2, tt3); \ + XOR64(t, tt0, tt2); \ + } while (0) + +#define THETA(b00, b01, b02, b03, b04, b10, b11, b12, b13, b14, \ + b20, b21, b22, b23, b24, b30, b31, b32, b33, b34, \ + b40, b41, b42, b43, b44) \ + do { \ + DECL64(t0); \ + DECL64(t1); \ + DECL64(t2); \ + DECL64(t3); \ + DECL64(t4); \ + TH_ELT(t0, b40, b41, b42, b43, b44, b10, b11, b12, b13, b14); \ + TH_ELT(t1, b00, b01, b02, b03, b04, b20, b21, b22, b23, b24); \ + TH_ELT(t2, b10, b11, b12, b13, b14, b30, b31, b32, b33, b34); \ + TH_ELT(t3, b20, b21, b22, b23, b24, b40, b41, b42, b43, b44); \ + TH_ELT(t4, b30, b31, b32, b33, b34, b00, b01, b02, b03, b04); \ + XOR64(b00, b00, t0); \ + XOR64(b01, b01, t0); \ + XOR64(b02, b02, t0); \ + XOR64(b03, b03, t0); \ + XOR64(b04, b04, t0); \ + XOR64(b10, b10, t1); \ + XOR64(b11, b11, t1); \ + XOR64(b12, b12, t1); \ + XOR64(b13, b13, t1); \ + XOR64(b14, b14, t1); \ + XOR64(b20, b20, t2); \ + XOR64(b21, b21, t2); \ + XOR64(b22, b22, t2); \ + XOR64(b23, b23, t2); \ + XOR64(b24, b24, t2); \ + XOR64(b30, b30, t3); \ + XOR64(b31, b31, t3); \ + XOR64(b32, b32, t3); \ + XOR64(b33, b33, t3); \ + XOR64(b34, b34, t3); \ + XOR64(b40, b40, t4); \ + XOR64(b41, b41, t4); \ + XOR64(b42, b42, t4); \ + XOR64(b43, b43, t4); \ + XOR64(b44, b44, t4); \ + } while (0) + +#define RHO(b00, b01, b02, b03, b04, b10, b11, b12, b13, b14, \ + b20, b21, b22, b23, b24, b30, b31, b32, b33, b34, \ + b40, b41, b42, b43, b44) \ + do { \ + /* ROL64(b00, b00, 0); */ \ + ROL64(b01, b01, 36); \ + ROL64(b02, b02, 3); \ + ROL64(b03, b03, 41); \ + ROL64(b04, b04, 18); \ + ROL64(b10, b10, 1); \ + ROL64(b11, b11, 44); \ + ROL64(b12, b12, 10); \ + ROL64(b13, b13, 45); \ + ROL64(b14, b14, 2); \ + ROL64(b20, b20, 62); \ + ROL64(b21, b21, 6); \ + ROL64(b22, b22, 43); \ + ROL64(b23, b23, 15); \ + ROL64(b24, b24, 61); \ + ROL64(b30, b30, 28); \ + ROL64(b31, b31, 55); \ + ROL64(b32, b32, 25); \ + ROL64(b33, b33, 21); \ + ROL64(b34, b34, 56); \ + ROL64(b40, b40, 27); \ + ROL64(b41, b41, 20); \ + ROL64(b42, b42, 39); \ + ROL64(b43, b43, 8); \ + ROL64(b44, b44, 14); \ + } while (0) + +/* + * The KHI macro integrates the "lane complement" optimization. On input, + * some words are complemented: + * a00 a01 a02 a04 a13 a20 a21 a22 a30 a33 a34 a43 + * On output, the following words are complemented: + * a04 a10 a20 a22 a23 a31 + * + * The (implicit) permutation and the theta expansion will bring back + * the input mask for the next round. + */ + +#define KHI_XO(d, a, b, c) do { \ + DECL64(kt); \ + OR64(kt, b, c); \ + XOR64(d, a, kt); \ + } while (0) + +#define KHI_XA(d, a, b, c) do { \ + DECL64(kt); \ + AND64(kt, b, c); \ + XOR64(d, a, kt); \ + } while (0) + +#define KHI(b00, b01, b02, b03, b04, b10, b11, b12, b13, b14, \ + b20, b21, b22, b23, b24, b30, b31, b32, b33, b34, \ + b40, b41, b42, b43, b44) \ + do { \ + DECL64(c0); \ + DECL64(c1); \ + DECL64(c2); \ + DECL64(c3); \ + DECL64(c4); \ + DECL64(bnn); \ + NOT64(bnn, b20); \ + KHI_XO(c0, b00, b10, b20); \ + KHI_XO(c1, b10, bnn, b30); \ + KHI_XA(c2, b20, b30, b40); \ + KHI_XO(c3, b30, b40, b00); \ + KHI_XA(c4, b40, b00, b10); \ + MOV64(b00, c0); \ + MOV64(b10, c1); \ + MOV64(b20, c2); \ + MOV64(b30, c3); \ + MOV64(b40, c4); \ + NOT64(bnn, b41); \ + KHI_XO(c0, b01, b11, b21); \ + KHI_XA(c1, b11, b21, b31); \ + KHI_XO(c2, b21, b31, bnn); \ + KHI_XO(c3, b31, b41, b01); \ + KHI_XA(c4, b41, b01, b11); \ + MOV64(b01, c0); \ + MOV64(b11, c1); \ + MOV64(b21, c2); \ + MOV64(b31, c3); \ + MOV64(b41, c4); \ + NOT64(bnn, b32); \ + KHI_XO(c0, b02, b12, b22); \ + KHI_XA(c1, b12, b22, b32); \ + KHI_XA(c2, b22, bnn, b42); \ + KHI_XO(c3, bnn, b42, b02); \ + KHI_XA(c4, b42, b02, b12); \ + MOV64(b02, c0); \ + MOV64(b12, c1); \ + MOV64(b22, c2); \ + MOV64(b32, c3); \ + MOV64(b42, c4); \ + NOT64(bnn, b33); \ + KHI_XA(c0, b03, b13, b23); \ + KHI_XO(c1, b13, b23, b33); \ + KHI_XO(c2, b23, bnn, b43); \ + KHI_XA(c3, bnn, b43, b03); \ + KHI_XO(c4, b43, b03, b13); \ + MOV64(b03, c0); \ + MOV64(b13, c1); \ + MOV64(b23, c2); \ + MOV64(b33, c3); \ + MOV64(b43, c4); \ + NOT64(bnn, b14); \ + KHI_XA(c0, b04, bnn, b24); \ + KHI_XO(c1, bnn, b24, b34); \ + KHI_XA(c2, b24, b34, b44); \ + KHI_XO(c3, b34, b44, b04); \ + KHI_XA(c4, b44, b04, b14); \ + MOV64(b04, c0); \ + MOV64(b14, c1); \ + MOV64(b24, c2); \ + MOV64(b34, c3); \ + MOV64(b44, c4); \ + } while (0) + +#define IOTA(r) XOR64_IOTA(a00, a00, r) + +#define P0 a00, a01, a02, a03, a04, a10, a11, a12, a13, a14, a20, a21, \ + a22, a23, a24, a30, a31, a32, a33, a34, a40, a41, a42, a43, a44 +#define P1 a00, a30, a10, a40, a20, a11, a41, a21, a01, a31, a22, a02, \ + a32, a12, a42, a33, a13, a43, a23, a03, a44, a24, a04, a34, a14 +#define P2 a00, a33, a11, a44, a22, a41, a24, a02, a30, a13, a32, a10, \ + a43, a21, a04, a23, a01, a34, a12, a40, a14, a42, a20, a03, a31 +#define P3 a00, a23, a41, a14, a32, a24, a42, a10, a33, a01, a43, a11, \ + a34, a02, a20, a12, a30, a03, a21, a44, a31, a04, a22, a40, a13 +#define P4 a00, a12, a24, a31, a43, a42, a04, a11, a23, a30, a34, a41, \ + a03, a10, a22, a21, a33, a40, a02, a14, a13, a20, a32, a44, a01 +#define P5 a00, a21, a42, a13, a34, a04, a20, a41, a12, a33, a03, a24, \ + a40, a11, a32, a02, a23, a44, a10, a31, a01, a22, a43, a14, a30 +#define P6 a00, a02, a04, a01, a03, a20, a22, a24, a21, a23, a40, a42, \ + a44, a41, a43, a10, a12, a14, a11, a13, a30, a32, a34, a31, a33 +#define P7 a00, a10, a20, a30, a40, a22, a32, a42, a02, a12, a44, a04, \ + a14, a24, a34, a11, a21, a31, a41, a01, a33, a43, a03, a13, a23 +#define P8 a00, a11, a22, a33, a44, a32, a43, a04, a10, a21, a14, a20, \ + a31, a42, a03, a41, a02, a13, a24, a30, a23, a34, a40, a01, a12 +#define P9 a00, a41, a32, a23, a14, a43, a34, a20, a11, a02, a31, a22, \ + a13, a04, a40, a24, a10, a01, a42, a33, a12, a03, a44, a30, a21 +#define P10 a00, a24, a43, a12, a31, a34, a03, a22, a41, a10, a13, a32, \ + a01, a20, a44, a42, a11, a30, a04, a23, a21, a40, a14, a33, a02 +#define P11 a00, a42, a34, a21, a13, a03, a40, a32, a24, a11, a01, a43, \ + a30, a22, a14, a04, a41, a33, a20, a12, a02, a44, a31, a23, a10 +#define P12 a00, a04, a03, a02, a01, a40, a44, a43, a42, a41, a30, a34, \ + a33, a32, a31, a20, a24, a23, a22, a21, a10, a14, a13, a12, a11 +#define P13 a00, a20, a40, a10, a30, a44, a14, a34, a04, a24, a33, a03, \ + a23, a43, a13, a22, a42, a12, a32, a02, a11, a31, a01, a21, a41 +#define P14 a00, a22, a44, a11, a33, a14, a31, a03, a20, a42, a23, a40, \ + a12, a34, a01, a32, a04, a21, a43, a10, a41, a13, a30, a02, a24 +#define P15 a00, a32, a14, a41, a23, a31, a13, a40, a22, a04, a12, a44, \ + a21, a03, a30, a43, a20, a02, a34, a11, a24, a01, a33, a10, a42 +#define P16 a00, a43, a31, a24, a12, a13, a01, a44, a32, a20, a21, a14, \ + a02, a40, a33, a34, a22, a10, a03, a41, a42, a30, a23, a11, a04 +#define P17 a00, a34, a13, a42, a21, a01, a30, a14, a43, a22, a02, a31, \ + a10, a44, a23, a03, a32, a11, a40, a24, a04, a33, a12, a41, a20 +#define P18 a00, a03, a01, a04, a02, a30, a33, a31, a34, a32, a10, a13, \ + a11, a14, a12, a40, a43, a41, a44, a42, a20, a23, a21, a24, a22 +#define P19 a00, a40, a30, a20, a10, a33, a23, a13, a03, a43, a11, a01, \ + a41, a31, a21, a44, a34, a24, a14, a04, a22, a12, a02, a42, a32 +#define P20 a00, a44, a33, a22, a11, a23, a12, a01, a40, a34, a41, a30, \ + a24, a13, a02, a14, a03, a42, a31, a20, a32, a21, a10, a04, a43 +#define P21 a00, a14, a23, a32, a41, a12, a21, a30, a44, a03, a24, a33, \ + a42, a01, a10, a31, a40, a04, a13, a22, a43, a02, a11, a20, a34 +#define P22 a00, a31, a12, a43, a24, a21, a02, a33, a14, a40, a42, a23, \ + a04, a30, a11, a13, a44, a20, a01, a32, a34, a10, a41, a22, a03 +#define P23 a00, a13, a21, a34, a42, a02, a10, a23, a31, a44, a04, a12, \ + a20, a33, a41, a01, a14, a22, a30, a43, a03, a11, a24, a32, a40 + +#define P1_TO_P0 do { \ + DECL64(t); \ + MOV64(t, a01); \ + MOV64(a01, a30); \ + MOV64(a30, a33); \ + MOV64(a33, a23); \ + MOV64(a23, a12); \ + MOV64(a12, a21); \ + MOV64(a21, a02); \ + MOV64(a02, a10); \ + MOV64(a10, a11); \ + MOV64(a11, a41); \ + MOV64(a41, a24); \ + MOV64(a24, a42); \ + MOV64(a42, a04); \ + MOV64(a04, a20); \ + MOV64(a20, a22); \ + MOV64(a22, a32); \ + MOV64(a32, a43); \ + MOV64(a43, a34); \ + MOV64(a34, a03); \ + MOV64(a03, a40); \ + MOV64(a40, a44); \ + MOV64(a44, a14); \ + MOV64(a14, a31); \ + MOV64(a31, a13); \ + MOV64(a13, t); \ + } while (0) + +#define P2_TO_P0 do { \ + DECL64(t); \ + MOV64(t, a01); \ + MOV64(a01, a33); \ + MOV64(a33, a12); \ + MOV64(a12, a02); \ + MOV64(a02, a11); \ + MOV64(a11, a24); \ + MOV64(a24, a04); \ + MOV64(a04, a22); \ + MOV64(a22, a43); \ + MOV64(a43, a03); \ + MOV64(a03, a44); \ + MOV64(a44, a31); \ + MOV64(a31, t); \ + MOV64(t, a10); \ + MOV64(a10, a41); \ + MOV64(a41, a42); \ + MOV64(a42, a20); \ + MOV64(a20, a32); \ + MOV64(a32, a34); \ + MOV64(a34, a40); \ + MOV64(a40, a14); \ + MOV64(a14, a13); \ + MOV64(a13, a30); \ + MOV64(a30, a23); \ + MOV64(a23, a21); \ + MOV64(a21, t); \ + } while (0) + +#define P4_TO_P0 do { \ + DECL64(t); \ + MOV64(t, a01); \ + MOV64(a01, a12); \ + MOV64(a12, a11); \ + MOV64(a11, a04); \ + MOV64(a04, a43); \ + MOV64(a43, a44); \ + MOV64(a44, t); \ + MOV64(t, a02); \ + MOV64(a02, a24); \ + MOV64(a24, a22); \ + MOV64(a22, a03); \ + MOV64(a03, a31); \ + MOV64(a31, a33); \ + MOV64(a33, t); \ + MOV64(t, a10); \ + MOV64(a10, a42); \ + MOV64(a42, a32); \ + MOV64(a32, a40); \ + MOV64(a40, a13); \ + MOV64(a13, a23); \ + MOV64(a23, t); \ + MOV64(t, a14); \ + MOV64(a14, a30); \ + MOV64(a30, a21); \ + MOV64(a21, a41); \ + MOV64(a41, a20); \ + MOV64(a20, a34); \ + MOV64(a34, t); \ + } while (0) + +#define P6_TO_P0 do { \ + DECL64(t); \ + MOV64(t, a01); \ + MOV64(a01, a02); \ + MOV64(a02, a04); \ + MOV64(a04, a03); \ + MOV64(a03, t); \ + MOV64(t, a10); \ + MOV64(a10, a20); \ + MOV64(a20, a40); \ + MOV64(a40, a30); \ + MOV64(a30, t); \ + MOV64(t, a11); \ + MOV64(a11, a22); \ + MOV64(a22, a44); \ + MOV64(a44, a33); \ + MOV64(a33, t); \ + MOV64(t, a12); \ + MOV64(a12, a24); \ + MOV64(a24, a43); \ + MOV64(a43, a31); \ + MOV64(a31, t); \ + MOV64(t, a13); \ + MOV64(a13, a21); \ + MOV64(a21, a42); \ + MOV64(a42, a34); \ + MOV64(a34, t); \ + MOV64(t, a14); \ + MOV64(a14, a23); \ + MOV64(a23, a41); \ + MOV64(a41, a32); \ + MOV64(a32, t); \ + } while (0) + +#define P8_TO_P0 do { \ + DECL64(t); \ + MOV64(t, a01); \ + MOV64(a01, a11); \ + MOV64(a11, a43); \ + MOV64(a43, t); \ + MOV64(t, a02); \ + MOV64(a02, a22); \ + MOV64(a22, a31); \ + MOV64(a31, t); \ + MOV64(t, a03); \ + MOV64(a03, a33); \ + MOV64(a33, a24); \ + MOV64(a24, t); \ + MOV64(t, a04); \ + MOV64(a04, a44); \ + MOV64(a44, a12); \ + MOV64(a12, t); \ + MOV64(t, a10); \ + MOV64(a10, a32); \ + MOV64(a32, a13); \ + MOV64(a13, t); \ + MOV64(t, a14); \ + MOV64(a14, a21); \ + MOV64(a21, a20); \ + MOV64(a20, t); \ + MOV64(t, a23); \ + MOV64(a23, a42); \ + MOV64(a42, a40); \ + MOV64(a40, t); \ + MOV64(t, a30); \ + MOV64(a30, a41); \ + MOV64(a41, a34); \ + MOV64(a34, t); \ + } while (0) + +#define P12_TO_P0 do { \ + DECL64(t); \ + MOV64(t, a01); \ + MOV64(a01, a04); \ + MOV64(a04, t); \ + MOV64(t, a02); \ + MOV64(a02, a03); \ + MOV64(a03, t); \ + MOV64(t, a10); \ + MOV64(a10, a40); \ + MOV64(a40, t); \ + MOV64(t, a11); \ + MOV64(a11, a44); \ + MOV64(a44, t); \ + MOV64(t, a12); \ + MOV64(a12, a43); \ + MOV64(a43, t); \ + MOV64(t, a13); \ + MOV64(a13, a42); \ + MOV64(a42, t); \ + MOV64(t, a14); \ + MOV64(a14, a41); \ + MOV64(a41, t); \ + MOV64(t, a20); \ + MOV64(a20, a30); \ + MOV64(a30, t); \ + MOV64(t, a21); \ + MOV64(a21, a34); \ + MOV64(a34, t); \ + MOV64(t, a22); \ + MOV64(a22, a33); \ + MOV64(a33, t); \ + MOV64(t, a23); \ + MOV64(a23, a32); \ + MOV64(a32, t); \ + MOV64(t, a24); \ + MOV64(a24, a31); \ + MOV64(a31, t); \ + } while (0) + +#define LPAR ( +#define RPAR ) + +#define KF_ELT(r, s, k) do { \ + THETA LPAR P ## r RPAR; \ + RHO LPAR P ## r RPAR; \ + KHI LPAR P ## s RPAR; \ + IOTA(k); \ + } while (0) + +#define DO(x) x + +#define KECCAK_F_1600 DO(KECCAK_F_1600_) + +#if SPH_KECCAK_UNROLL == 1 + +#define KECCAK_F_1600_ do { \ + int j; \ + for (j = 0; j < 24; j ++) { \ + KF_ELT( 0, 1, RC[j + 0]); \ + P1_TO_P0; \ + } \ + } while (0) + +#elif SPH_KECCAK_UNROLL == 2 + +#define KECCAK_F_1600_ do { \ + int j; \ + for (j = 0; j < 24; j += 2) { \ + KF_ELT( 0, 1, RC[j + 0]); \ + KF_ELT( 1, 2, RC[j + 1]); \ + P2_TO_P0; \ + } \ + } while (0) + +#elif SPH_KECCAK_UNROLL == 4 + +#define KECCAK_F_1600_ do { \ + int j; \ + for (j = 0; j < 24; j += 4) { \ + KF_ELT( 0, 1, RC[j + 0]); \ + KF_ELT( 1, 2, RC[j + 1]); \ + KF_ELT( 2, 3, RC[j + 2]); \ + KF_ELT( 3, 4, RC[j + 3]); \ + P4_TO_P0; \ + } \ + } while (0) + +#elif SPH_KECCAK_UNROLL == 6 + +#define KECCAK_F_1600_ do { \ + int j; \ + for (j = 0; j < 24; j += 6) { \ + KF_ELT( 0, 1, RC[j + 0]); \ + KF_ELT( 1, 2, RC[j + 1]); \ + KF_ELT( 2, 3, RC[j + 2]); \ + KF_ELT( 3, 4, RC[j + 3]); \ + KF_ELT( 4, 5, RC[j + 4]); \ + KF_ELT( 5, 6, RC[j + 5]); \ + P6_TO_P0; \ + } \ + } while (0) + +#elif SPH_KECCAK_UNROLL == 8 + +#define KECCAK_F_1600_ do { \ + int j; \ + for (j = 0; j < 24; j += 8) { \ + KF_ELT( 0, 1, RC[j + 0]); \ + KF_ELT( 1, 2, RC[j + 1]); \ + KF_ELT( 2, 3, RC[j + 2]); \ + KF_ELT( 3, 4, RC[j + 3]); \ + KF_ELT( 4, 5, RC[j + 4]); \ + KF_ELT( 5, 6, RC[j + 5]); \ + KF_ELT( 6, 7, RC[j + 6]); \ + KF_ELT( 7, 8, RC[j + 7]); \ + P8_TO_P0; \ + } \ + } while (0) + +#elif SPH_KECCAK_UNROLL == 12 + +#define KECCAK_F_1600_ do { \ + int j; \ + for (j = 0; j < 24; j += 12) { \ + KF_ELT( 0, 1, RC[j + 0]); \ + KF_ELT( 1, 2, RC[j + 1]); \ + KF_ELT( 2, 3, RC[j + 2]); \ + KF_ELT( 3, 4, RC[j + 3]); \ + KF_ELT( 4, 5, RC[j + 4]); \ + KF_ELT( 5, 6, RC[j + 5]); \ + KF_ELT( 6, 7, RC[j + 6]); \ + KF_ELT( 7, 8, RC[j + 7]); \ + KF_ELT( 8, 9, RC[j + 8]); \ + KF_ELT( 9, 10, RC[j + 9]); \ + KF_ELT(10, 11, RC[j + 10]); \ + KF_ELT(11, 12, RC[j + 11]); \ + P12_TO_P0; \ + } \ + } while (0) + +#elif SPH_KECCAK_UNROLL == 0 + +#define KECCAK_F_1600_ do { \ + KF_ELT( 0, 1, RC[ 0]); \ + KF_ELT( 1, 2, RC[ 1]); \ + KF_ELT( 2, 3, RC[ 2]); \ + KF_ELT( 3, 4, RC[ 3]); \ + KF_ELT( 4, 5, RC[ 4]); \ + KF_ELT( 5, 6, RC[ 5]); \ + KF_ELT( 6, 7, RC[ 6]); \ + KF_ELT( 7, 8, RC[ 7]); \ + KF_ELT( 8, 9, RC[ 8]); \ + KF_ELT( 9, 10, RC[ 9]); \ + KF_ELT(10, 11, RC[10]); \ + KF_ELT(11, 12, RC[11]); \ + KF_ELT(12, 13, RC[12]); \ + KF_ELT(13, 14, RC[13]); \ + KF_ELT(14, 15, RC[14]); \ + KF_ELT(15, 16, RC[15]); \ + KF_ELT(16, 17, RC[16]); \ + KF_ELT(17, 18, RC[17]); \ + KF_ELT(18, 19, RC[18]); \ + KF_ELT(19, 20, RC[19]); \ + KF_ELT(20, 21, RC[20]); \ + KF_ELT(21, 22, RC[21]); \ + KF_ELT(22, 23, RC[22]); \ + KF_ELT(23, 0, RC[23]); \ + } while (0) + +#else + +#error Unimplemented unroll count for Keccak. + +#endif + +static void +keccak_init(void *kcv, unsigned out_size) +{ + sph_keccak_context* kc = (sph_keccak_context*)kcv; + int i; + +#if SPH_KECCAK_64 + for (i = 0; i < 25; i ++) + kc->u.wide[i] = 0; + /* + * Initialization for the "lane complement". + */ + kc->u.wide[ 1] = SPH_C64(0xFFFFFFFFFFFFFFFF); + kc->u.wide[ 2] = SPH_C64(0xFFFFFFFFFFFFFFFF); + kc->u.wide[ 8] = SPH_C64(0xFFFFFFFFFFFFFFFF); + kc->u.wide[12] = SPH_C64(0xFFFFFFFFFFFFFFFF); + kc->u.wide[17] = SPH_C64(0xFFFFFFFFFFFFFFFF); + kc->u.wide[20] = SPH_C64(0xFFFFFFFFFFFFFFFF); +#else + + for (i = 0; i < 50; i ++) + kc->u.narrow[i] = 0; + /* + * Initialization for the "lane complement". + * Note: since we set to all-one full 64-bit words, + * interleaving (if applicable) is a no-op. + */ + kc->u.narrow[ 2] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[ 3] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[ 4] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[ 5] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[16] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[17] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[24] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[25] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[34] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[35] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[40] = SPH_C32(0xFFFFFFFF); + kc->u.narrow[41] = SPH_C32(0xFFFFFFFF); +#endif + kc->ptr = 0; + kc->lim = 200 - (out_size >> 2); +} + +static void +keccak_core(void *kcv, const void *data, size_t len, size_t lim) +{ + + sph_keccak_context* kc = (sph_keccak_context*)kcv; + unsigned char *buf; + size_t ptr; + DECL_STATE + + buf = kc->buf; + ptr = kc->ptr; + + if (len < (lim - ptr)) { + memcpy(buf + ptr, data, len); + kc->ptr = ptr + len; + return; + } + + READ_STATE(kc); + while (len > 0) { + size_t clen; + + clen = (lim - ptr); + if (clen > len) + clen = len; + memcpy(buf + ptr, data, clen); + ptr += clen; + data = (const unsigned char *)data + clen; + len -= clen; + if (ptr == lim) { + INPUT_BUF(lim); + KECCAK_F_1600; + ptr = 0; + } + } + WRITE_STATE(kc); + kc->ptr = ptr; +} + +#if SPH_KECCAK_64 + +#define DEFCLOSE(d, lim) \ + static void keccak_close ## d( \ + void *kcv, unsigned ub, unsigned n, void *dst) \ + { \ + sph_keccak_context* kc = (sph_keccak_context*)kcv; \ + unsigned eb; \ + union { \ + unsigned char tmp[lim + 1]; \ + sph_u64 dummy; /* for alignment */ \ + } u; \ + size_t j; \ + \ + eb = (0x100 | (ub & 0xFF)) >> (8 - n); \ + if (kc->ptr == (lim - 1)) { \ + if (n == 7) { \ + u.tmp[0] = eb; \ + memset(u.tmp + 1, 0, lim - 1); \ + u.tmp[lim] = 0x80; \ + j = 1 + lim; \ + } else { \ + u.tmp[0] = eb | 0x80; \ + j = 1; \ + } \ + } else { \ + j = lim - kc->ptr; \ + u.tmp[0] = eb; \ + memset(u.tmp + 1, 0, j - 2); \ + u.tmp[j - 1] = 0x80; \ + } \ + keccak_core(kc, u.tmp, j, lim); \ + /* Finalize the "lane complement" */ \ + kc->u.wide[ 1] = ~kc->u.wide[ 1]; \ + kc->u.wide[ 2] = ~kc->u.wide[ 2]; \ + kc->u.wide[ 8] = ~kc->u.wide[ 8]; \ + kc->u.wide[12] = ~kc->u.wide[12]; \ + kc->u.wide[17] = ~kc->u.wide[17]; \ + kc->u.wide[20] = ~kc->u.wide[20]; \ + for (j = 0; j < d; j += 8) \ + sph_enc64le_aligned(u.tmp + j, kc->u.wide[j >> 3]); \ + memcpy(dst, u.tmp, d); \ + keccak_init(kc, (unsigned)d << 3); \ + } \ + +#else + +#define DEFCLOSE(d, lim) \ + static void keccak_close ## d( \ + sph_keccak_context *kc, unsigned ub, unsigned n, void *dst) \ + { \ + unsigned eb; \ + union { \ + unsigned char tmp[lim + 1]; \ + sph_u64 dummy; /* for alignment */ \ + } u; \ + size_t j; \ + \ + eb = (0x100 | (ub & 0xFF)) >> (8 - n); \ + if (kc->ptr == (lim - 1)) { \ + if (n == 7) { \ + u.tmp[0] = eb; \ + memset(u.tmp + 1, 0, lim - 1); \ + u.tmp[lim] = 0x80; \ + j = 1 + lim; \ + } else { \ + u.tmp[0] = eb | 0x80; \ + j = 1; \ + } \ + } else { \ + j = lim - kc->ptr; \ + u.tmp[0] = eb; \ + memset(u.tmp + 1, 0, j - 2); \ + u.tmp[j - 1] = 0x80; \ + } \ + keccak_core(kc, u.tmp, j, lim); \ + /* Finalize the "lane complement" */ \ + kc->u.narrow[ 2] = ~kc->u.narrow[ 2]; \ + kc->u.narrow[ 3] = ~kc->u.narrow[ 3]; \ + kc->u.narrow[ 4] = ~kc->u.narrow[ 4]; \ + kc->u.narrow[ 5] = ~kc->u.narrow[ 5]; \ + kc->u.narrow[16] = ~kc->u.narrow[16]; \ + kc->u.narrow[17] = ~kc->u.narrow[17]; \ + kc->u.narrow[24] = ~kc->u.narrow[24]; \ + kc->u.narrow[25] = ~kc->u.narrow[25]; \ + kc->u.narrow[34] = ~kc->u.narrow[34]; \ + kc->u.narrow[35] = ~kc->u.narrow[35]; \ + kc->u.narrow[40] = ~kc->u.narrow[40]; \ + kc->u.narrow[41] = ~kc->u.narrow[41]; \ + /* un-interleave */ \ + for (j = 0; j < 50; j += 2) \ + UNINTERLEAVE(kc->u.narrow[j], kc->u.narrow[j + 1]); \ + for (j = 0; j < d; j += 4) \ + sph_enc32le_aligned(u.tmp + j, kc->u.narrow[j >> 2]); \ + memcpy(dst, u.tmp, d); \ + keccak_init(kc, (unsigned)d << 3); \ + } \ + +#endif + +DEFCLOSE(28, 144) +DEFCLOSE(32, 136) +DEFCLOSE(48, 104) +DEFCLOSE(64, 72) + +/* see sph_keccak.h */ +void +sph_keccak224_init(void *cc) +{ + keccak_init(cc, 224); +} + +/* see sph_keccak.h */ +void +sph_keccak224(void *cc, const void *data, size_t len) +{ + keccak_core(cc, data, len, 144); +} + +/* see sph_keccak.h */ +void +sph_keccak224_close(void *cc, void *dst) +{ + sph_keccak224_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + keccak_close28(cc, ub, n, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak256_init(void *cc) +{ + keccak_init(cc, 256); +} + +/* see sph_keccak.h */ +void +sph_keccak256(void *cc, const void *data, size_t len) +{ + keccak_core(cc, data, len, 136); +} + +/* see sph_keccak.h */ +void +sph_keccak256_close(void *cc, void *dst) +{ + sph_keccak256_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + keccak_close32(cc, ub, n, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak384_init(void *cc) +{ + keccak_init(cc, 384); +} + +/* see sph_keccak.h */ +void +sph_keccak384(void *cc, const void *data, size_t len) +{ + keccak_core(cc, data, len, 104); +} + +/* see sph_keccak.h */ +void +sph_keccak384_close(void *cc, void *dst) +{ + sph_keccak384_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + keccak_close48(cc, ub, n, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak512_init(void *cc) +{ + keccak_init(cc, 512); +} + +/* see sph_keccak.h */ +void +sph_keccak512(void *cc, const void *data, size_t len) +{ + keccak_core(cc, data, len, 72); +} + +/* see sph_keccak.h */ +void +sph_keccak512_close(void *cc, void *dst) +{ + sph_keccak512_addbits_and_close(cc, 0, 0, dst); +} + +/* see sph_keccak.h */ +void +sph_keccak512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + keccak_close64(cc, ub, n, dst); +} + +void HashKeccak(uint8_t *hash,void *data,size_t len) +{ + sph_keccak256_context ctx_keccak; + sph_keccak256_init(&ctx_keccak); + sph_keccak256(&ctx_keccak,data,len); + sph_keccak256_close(&ctx_keccak,(void *)hash); +} + +#ifdef __cplusplus +} +#endif diff --git a/iguana/kmd_lookup.h b/iguana/kmd_lookup.h index 05cb91ad4..6beb536eb 100755 --- a/iguana/kmd_lookup.h +++ b/iguana/kmd_lookup.h @@ -354,7 +354,7 @@ int32_t kmd_height(struct iguana_info *coin) { char params[64],*curlstr; cJSON *curljson; int32_t height = 0; strcpy(params,"[]"); - if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getinfo",params)) != 0 ) + if ( (curlstr= bitcoind_getinfo(coin->symbol,coin->chain->serverport,coin->chain->userpass,coin->getinfostr)) != 0 ) { if ( (curljson= cJSON_Parse(curlstr)) != 0 ) { diff --git a/iguana/m_LP_StaticNanoMsg b/iguana/m_LP_StaticNanoMsg index f121efc88..d2d295351 100755 --- a/iguana/m_LP_StaticNanoMsg +++ b/iguana/m_LP_StaticNanoMsg @@ -2,11 +2,12 @@ #./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery rm -f ../agents/iguana *.o git pull +./build_static_nanomsg.sh cd secp256k1; ./m_unix; cd .. cd ../crypto777; make -f m_LP_StaticNanoMsg all; make -f m_LP_StaticNanoMsg clean; cd ../iguana -clang -g -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 -DUSE_STATIC_NANOMSG *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c -clang -g -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 -DUSE_STATIC_NANOMSG main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c +clang -g -DNOTETOMIC -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 -DUSE_STATIC_NANOMSG *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +clang -g -DNOTETOMIC -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 -DUSE_STATIC_NANOMSG main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a ../OSlibs/linux/$(uname -m)/libnanomsg-static.a -lcurl -lssl -lcrypto -lpthread -lz -lm -lanl -lrt -lnsl diff --git a/iguana/m_mm b/iguana/m_mm index 5a227a69a..39df45ee7 100755 --- a/iguana/m_mm +++ b/iguana/m_mm @@ -1,3 +1,14 @@ +#!/bin/bash cd secp256k1; ./m_unix; cd .. cd ../crypto777; ./m_LP; cd ../iguana -gcc -g -o marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c mini-gmp.c groestl.c segwit_addr.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm + +nanomsg_lib="-lnanomsg" + +# Build static libnanomsg on macOS +if [[ "$OSTYPE" == "darwin"* ]]; then + ./build_static_nanomsg.sh + nanomsg_lib="../OSlibs/osx/$(uname -m)/libnanomsg-static.a" +fi + +rm marketmaker +gcc -g -o marketmaker -DNOTETOMIC -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c mini-gmp.c keccak.c groestl.c segwit_addr.c secp256k1.o ../agents/libcrypto777.a $nanomsg_lib -lcurl -lpthread -lm diff --git a/iguana/m_mm_StaticNanoMsg b/iguana/m_mm_StaticNanoMsg index 2c224b764..c5068eeb8 100755 --- a/iguana/m_mm_StaticNanoMsg +++ b/iguana/m_mm_StaticNanoMsg @@ -19,7 +19,7 @@ all: +$(MAKE) -C secp256k1 -f m_unix_Makefile all +$(MAKE) -C ../crypto777 -f m_LP_StaticNanoMsg all +$(MAKE) -C ../crypto777 -f m_LP_StaticNanoMsg clean - $(CC) -o ../agents/marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c mini-gmp.c groestl.c segwit_addr.c secp256k1.o ../agents/libcrypto777.a ../OSlibs/linux/$(shell uname -m)/libnanomsg-static.a -lcurl -lpthread -lm -lanl + $(CC) -DNOTETOMIC -o ../agents/marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c mini-gmp.c keccak.c groestl.c segwit_addr.c secp256k1.o ../agents/libcrypto777.a ../OSlibs/linux/$(shell uname -m)/libnanomsg-static.a -lcurl -lpthread -lm -lanl @echo "===========================" @echo " marketmaker -> `pwd`/../agents/marketmaker" @echo "===========================" diff --git a/iguana/m_notary b/iguana/m_notary index 0d4d9a9c4..9eff95e6b 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 +./m_notary_run $1 diff --git a/iguana/m_notary_run b/iguana/m_notary_run index b3b789b32..abad7b7e0 100755 --- a/iguana/m_notary_run +++ b/iguana/m_notary_run @@ -8,7 +8,7 @@ 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 -../agents/iguana notary & #> iguana.log 2> error.log & +stdbuf -oL $1 ../agents/iguana notary & #> iguana.log 2> error.log & myip=`curl -s4 checkip.amazonaws.com` source pubkey.txt @@ -29,7 +29,6 @@ coins/dex_7776 coins/bet_7776 coins/bots_7776 coins/hodl_7776 -coins/shark_7776 coins/mshark_7776 coins/jumblr_7776 coins/crypto_7776 @@ -44,6 +43,10 @@ coins/mnz_7776 coins/axo_7776 coins/etomic_7776 coins/btch_7776 +coins/vote2018_7776 +coins/ninja_7776 +coins/oot_7776 + #curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"passthru\",\"method\":\"paxfiats\",\"timeout\":900000}" #curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"$myip\"}" diff --git a/iguana/m_notary_testnet b/iguana/m_notary_testnet new file mode 100755 index 000000000..483d523f3 --- /dev/null +++ b/iguana/m_notary_testnet @@ -0,0 +1,31 @@ +#!/bin/bash +pkill -15 iguana +rm -f ../agents/iguana *.o +git pull +cd secp256k1; ./m_unix; cd .. +cd ../crypto777; ./m_LP; cd ../iguana +clang -g -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +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 +wget -qO testnet https://raw.githubusercontent.com/KomodoPlatform/vote2018/master/testnet/testnet.json +../agents/iguana testnet & #> iguana.log 2> error.log & +myip=`curl -s4 checkip.amazonaws.com` +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\":\"145.239.204.33\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"167.114.116.173\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"167.99.16.61\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"172.104.107.94\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"208.79.81.98\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"139.99.148.62\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"172.104.244.83\"}" +coins/btc_7776 +coins/kmd_7776 +./wp_7776 +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"BEER.conf\",\"path\":\"${HOME#"/"}/.komodo/BEER\",\"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\":\"BEER\",\"name\":\"BEER\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"9fecbb6e\",\"p2p\":8922,\"rpc\":8923,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"PIZZA.conf\",\"path\":\"${HOME#"/"}/.komodo/PIZZA\",\"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\":\"PIZZA\",\"name\":\"PIZZA\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"adbe523c\",\"p2p\":11607,\"rpc\":11608,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KMD\",\"pubkey\":\"$pubkey\"}" +curl --url "http://127.0.0.1:7776" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"BEER\",\"pubkey\":\"$pubkey\"}" +curl --url "http://127.0.0.1:7776" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"PIZZA\",\"pubkey\":\"$pubkey\"}" diff --git a/iguana/m_splitfund b/iguana/m_splitfund index 75f4b0cfd..66528aae5 100755 --- a/iguana/m_splitfund +++ b/iguana/m_splitfund @@ -3,60 +3,29 @@ set -x curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BTC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KMD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KMD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"REVS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SUPERNET\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DEX\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PANGEA\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JUMBLR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BET\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CRYPTO\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HODL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MSHARK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BOTS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MGW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MVP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"COQUI\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"WLC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KV\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CEAL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MESH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MNZ\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"AXO\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BTCH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ETOMIC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" - -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"USD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"EUR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" - -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JPY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"GBP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"AUD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CAD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CHF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NZD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CNY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RUB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MXN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BRL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"INR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HKD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"TRY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ZAR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PLN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NOK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SEK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DKK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CZK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HUF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ILS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KRW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MYR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PHP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RON\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SGD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"THB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BGN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"IDR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" -#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HRK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"REVS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SUPERNET\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DEX\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PANGEA\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JUMBLR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BET\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CRYPTO\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HODL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MSHARK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BOTS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MGW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"COQUI\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"WLC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KV\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CEAL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MESH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MNZ\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"AXO\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BTCH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ETOMIC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"VOTE2018\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CHIPS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NINJA\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"OOT\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":50}" diff --git a/iguana/m_unix b/iguana/m_unix index 8517b1135..762bcbd58 100755 --- a/iguana/m_unix +++ b/iguana/m_unix @@ -9,4 +9,4 @@ cd secp256k1; ./m_unix; cd .. cd ../crypto777; ./m_unix; cd ../iguana gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c -gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lpthread -lm -lnanomsg +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lpthread -lm -lnanomsg -lcurl diff --git a/iguana/main.c b/iguana/main.c index 0528393ed..0bb573287 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -2157,9 +2157,11 @@ void komodo_REVS_merge(char *str,char *str2) getchar(); } +int32_t komodo_initjson(char *fname); + void iguana_main(void *arg) { - int32_t usessl = 0,ismainnet = 1, do_OStests = 0; struct supernet_info *myinfo; + int32_t usessl = 0,ismainnet = 1, do_OStests = 0; struct supernet_info *myinfo; char *elected = "elected"; if ( (IGUANA_BIGENDIAN= iguana_isbigendian()) > 0 ) printf("BIGENDIAN\n"); else if ( IGUANA_BIGENDIAN == 0 ) @@ -2192,7 +2194,6 @@ void iguana_main(void *arg) iguana_Qinit(); libgfshare_init(myinfo,myinfo->logs,myinfo->exps); myinfo->dpowsock = myinfo->dexsock = myinfo->pubsock = myinfo->subsock = myinfo->reqsock = myinfo->repsock = -1; - dex_init(myinfo); myinfo->psockport = 30000; if ( arg != 0 ) { @@ -2206,18 +2207,31 @@ void iguana_main(void *arg) iguana_notarystats(totals,1); exit(0); } - else if ( strcmp((char *)arg,"notary") == 0 ) + else if ( strncmp((char *)arg,"-port=",6) == 0 ) + { + myinfo->rpcport = atoi(&((char *)arg)[6]); + printf("OVERRIDE IGUANA port <- %u\n",myinfo->rpcport); + } + else if ( strcmp((char *)arg,"notary") == 0 ) // must be second to last { myinfo->rpcport = IGUANA_NOTARYPORT; myinfo->IAMNOTARY = 1; myinfo->DEXEXPLORER = 0;//1; disable as SPV is used now } - else if ( strncmp((char *)arg,"-port=",6) == 0 ) + else { - myinfo->rpcport = atoi(&((char *)arg)[6]); - printf("OVERRIDE IGUANA port <- %u\n",myinfo->rpcport); + myinfo->rpcport = IGUANA_NOTARYPORT; + myinfo->IAMNOTARY = 1; + myinfo->DEXEXPLORER = 0;//1; disable as SPV is used now + elected = (char *)arg; } } + if ( komodo_initjson(elected) < 0 ) + { + printf("didnt find any elected notaries JSON in (%s)\n",elected); + exit(-1); + } + dex_init(myinfo); #ifdef IGUANA_OSTESTS do_OStests = 1; #endif @@ -2231,6 +2245,7 @@ void iguana_main(void *arg) strcpy(myinfo->rpcsymbol,"BTCD"); iguana_urlinit(myinfo,ismainnet,usessl); portable_mutex_init(&myinfo->pending_mutex); + portable_mutex_init(&myinfo->MoM_mutex); portable_mutex_init(&myinfo->dpowmutex); portable_mutex_init(&myinfo->notarymutex); portable_mutex_init(&myinfo->psockmutex); diff --git a/iguana/mini-gmp.c b/iguana/mini-gmp.c index f39c66f69..99cb68222 100644 --- a/iguana/mini-gmp.c +++ b/iguana/mini-gmp.c @@ -4402,6 +4402,7 @@ int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr) p++; if ( *p != '\0' ) { + int32_t zeroval(); printf("bitcoin_base58decode error: p %02x != 0x00\n",*p); mpz_clear(bn), mpz_clear(bn58); return(-1); diff --git a/iguana/notarizations b/iguana/notarizations new file mode 100755 index 000000000..a1a8fd0ed --- /dev/null +++ b/iguana/notarizations @@ -0,0 +1,2 @@ + curl --url "http://127.0.0.1:7776" --data "{\"pubkey\":\"$pubkey\",\"agent\":\"dpow\",\"method\":\"notarizations\",\"symbol\":\"PIZZA\",\"height\":5000,\"numblocks\":1000}" + diff --git a/iguana/orderbooks.h b/iguana/orderbooks.h index ae7be5277..9b9ea91de 100755 --- a/iguana/orderbooks.h +++ b/iguana/orderbooks.h @@ -3236,7 +3236,7 @@ void prices777_RTupdate(double cryptovols[2][8][2],double RTmetals[4],double *RT int32_t prices777_getmatrix(double *basevals,double *btcusdp,double *btcdbtcp,double Hmatrix[32][32],double *RTprices,char *contracts[],int32_t num,uint32_t timestamp) { - int32_t i,j,c; char name[16]; double btcusd,btcdbtc; + int32_t i,j,c; char name[65]; double btcusd,btcdbtc; memcpy(Hmatrix,BUNDLE.data.ecbmatrix,sizeof(BUNDLE.data.ecbmatrix)); prices777_calcmatrix(Hmatrix); /*for (i=0; i<32; i++) @@ -3411,7 +3411,7 @@ void prices777_sim(uint32_t now,int32_t numiters) void prices777_getlist(char *retbuf) { - int32_t i,j; struct prices777 *prices; char pair[16],*jsonstr; cJSON *json,*array,*item; + int32_t i,j; struct prices777 *prices; char pair[130],*jsonstr; cJSON *json,*array,*item; json = cJSON_CreateObject(); array = cJSON_CreateArray(); for (i=0; idata[0], 64); + secp256k1_ge_from_storage(ge, &s); + } else { + /* Otherwise, fall back to 32-byte big endian for X and Y. */ + secp256k1_fe x, y; + secp256k1_fe_set_b32(&x, pubkey->data); + secp256k1_fe_set_b32(&y, pubkey->data + 32); + secp256k1_ge_set_xy(ge, &x, &y); + } + ARG_CHECK(!secp256k1_fe_is_zero(&ge->x)); + return 1; +} + +void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { + if (sizeof(secp256k1_ge_storage) == 64) { + secp256k1_ge_storage s; + secp256k1_ge_to_storage(&s, ge); + memcpy(&pubkey->data[0], &s, 64); + } else { + VERIFY_CHECK(!secp256k1_ge_is_infinity(ge)); + secp256k1_fe_normalize_var(&ge->x); + secp256k1_fe_normalize_var(&ge->y); + secp256k1_fe_get_b32(pubkey->data, &ge->x); + secp256k1_fe_get_b32(pubkey->data + 32, &ge->y); + } +} + +#ifndef EXTERNAL_SECP256 + secp256k1_context* secp256k1_context_create(unsigned int flags) { secp256k1_context* ret = (secp256k1_context*)checked_malloc(&default_error_callback, sizeof(secp256k1_context)); ret->illegal_callback = default_illegal_callback; @@ -137,39 +172,6 @@ void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(co ctx->error_callback.data = data; } -static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) { - if (sizeof(secp256k1_ge_storage) == 64) { - /* When the secp256k1_ge_storage type is exactly 64 byte, use its - * representation inside secp256k1_pubkey, as conversion is very fast. - * Note that secp256k1_pubkey_save must use the same representation. */ - secp256k1_ge_storage s; - memcpy(&s, &pubkey->data[0], 64); - secp256k1_ge_from_storage(ge, &s); - } else { - /* Otherwise, fall back to 32-byte big endian for X and Y. */ - secp256k1_fe x, y; - secp256k1_fe_set_b32(&x, pubkey->data); - secp256k1_fe_set_b32(&y, pubkey->data + 32); - secp256k1_ge_set_xy(ge, &x, &y); - } - ARG_CHECK(!secp256k1_fe_is_zero(&ge->x)); - return 1; -} - -static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { - if (sizeof(secp256k1_ge_storage) == 64) { - secp256k1_ge_storage s; - secp256k1_ge_to_storage(&s, ge); - memcpy(&pubkey->data[0], &s, 64); - } else { - VERIFY_CHECK(!secp256k1_ge_is_infinity(ge)); - secp256k1_fe_normalize_var(&ge->x); - secp256k1_fe_normalize_var(&ge->y); - secp256k1_fe_get_b32(pubkey->data, &ge->x); - secp256k1_fe_get_b32(pubkey->data + 32, &ge->y); - } -} - int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) { secp256k1_ge Q; @@ -577,14 +579,16 @@ int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey * # include "modules/ecdh/main_impl.h" #endif -#ifdef ENABLE_MODULE_SCHNORR -# include "modules/schnorr/main_impl.h" -#endif - #ifdef ENABLE_MODULE_RECOVERY # include "modules/recovery/main_impl.h" #endif +#endif + +#ifdef ENABLE_MODULE_SCHNORR +# include "modules/schnorr/main_impl.h" +#endif + #ifdef ENABLE_MODULE_RANGEPROOF # include "modules/rangeproof/main_impl.h" #endif diff --git a/iguana/sph_keccak.h b/iguana/sph_keccak.h new file mode 100644 index 000000000..bdafdb88d --- /dev/null +++ b/iguana/sph_keccak.h @@ -0,0 +1,293 @@ +/* $Id: sph_keccak.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * Keccak interface. This is the interface for Keccak with the + * recommended parameters for SHA-3, with output lengths 224, 256, + * 384 and 512 bits. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_keccak.h + * @author Thomas Pornin + */ + +#ifndef SPH_KECCAK_H__ +#define SPH_KECCAK_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for Keccak-224. + */ +#define SPH_SIZE_keccak224 224 + +/** + * Output size (in bits) for Keccak-256. + */ +#define SPH_SIZE_keccak256 256 + +/** + * Output size (in bits) for Keccak-384. + */ +#define SPH_SIZE_keccak384 384 + +/** + * Output size (in bits) for Keccak-512. + */ +#define SPH_SIZE_keccak512 512 + +/** + * This structure is a context for Keccak computations: it contains the + * intermediate values and some data from the last entered block. Once a + * Keccak computation has been performed, the context can be reused for + * another computation. + * + * The contents of this structure are private. A running Keccak computation + * can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[144]; /* first field, for alignment */ + size_t ptr, lim; + union { +#if SPH_64 + sph_u64 wide[25]; +#endif + sph_u32 narrow[50]; + } u; +#endif +} sph_keccak_context; + +/** + * Type for a Keccak-224 context (identical to the common context). + */ +typedef sph_keccak_context sph_keccak224_context; + +/** + * Type for a Keccak-256 context (identical to the common context). + */ +typedef sph_keccak_context sph_keccak256_context; + +/** + * Type for a Keccak-384 context (identical to the common context). + */ +typedef sph_keccak_context sph_keccak384_context; + +/** + * Type for a Keccak-512 context (identical to the common context). + */ +typedef sph_keccak_context sph_keccak512_context; + +/** + * Initialize a Keccak-224 context. This process performs no memory allocation. + * + * @param cc the Keccak-224 context (pointer to a + * sph_keccak224_context) + */ +void sph_keccak224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Keccak-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_keccak224(void *cc, const void *data, size_t len); + +/** + * Terminate the current Keccak-224 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (28 bytes). The context is automatically + * reinitialized. + * + * @param cc the Keccak-224 context + * @param dst the destination buffer + */ +void sph_keccak224_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (28 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Keccak-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_keccak224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Keccak-256 context. This process performs no memory allocation. + * + * @param cc the Keccak-256 context (pointer to a + * sph_keccak256_context) + */ +void sph_keccak256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Keccak-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_keccak256(void *cc, const void *data, size_t len); + +/** + * Terminate the current Keccak-256 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the Keccak-256 context + * @param dst the destination buffer + */ +void sph_keccak256_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (32 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Keccak-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_keccak256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Keccak-384 context. This process performs no memory allocation. + * + * @param cc the Keccak-384 context (pointer to a + * sph_keccak384_context) + */ +void sph_keccak384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Keccak-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_keccak384(void *cc, const void *data, size_t len); + +/** + * Terminate the current Keccak-384 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (48 bytes). The context is automatically + * reinitialized. + * + * @param cc the Keccak-384 context + * @param dst the destination buffer + */ +void sph_keccak384_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (48 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Keccak-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_keccak384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Keccak-512 context. This process performs no memory allocation. + * + * @param cc the Keccak-512 context (pointer to a + * sph_keccak512_context) + */ +void sph_keccak512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Keccak-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_keccak512(void *cc, const void *data, size_t len); + +/** + * Terminate the current Keccak-512 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (64 bytes). The context is automatically + * reinitialized. + * + * @param cc the Keccak-512 context + * @param dst the destination buffer + */ +void sph_keccak512_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (64 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Keccak-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_keccak512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index 48d39e417..97044e029 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -20,6 +20,7 @@ emit compiler error if recursively being included #define _IGUANA_APIDEC_H_ STRING_ARG(dpow,pending,fiat); +STRING_AND_TWOINTS(dpow,notarizations,symbol,height,numblocks); ZERO_ARGS(dpow,notarychains); STRING_ARG(dpow,active,maskhex); TWOINTS_AND_ARRAY(dpow,ratify,minsigs,timestamp,ratified); @@ -173,7 +174,7 @@ STRING_AND_INT(iguana,snapshot,symbol,height); INT_ARRAY_STRING(iguana,dividends,height,vals,symbol); THREE_STRINGS(iguana,passthru,asset,function,hex); STRING_ARG(iguana,initfastfind,activecoin); -TWO_STRINGS(iguana,dpow,symbol,pubkey); +THREE_STRINGS(iguana,dpow,symbol,dest,pubkey); STRING_ARG(iguana,peers,activecoin); STRING_AND_INT(iguana,maxpeers,activecoin,max); STRING_ARG(iguana,getconnectioncount,activecoin); diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index ceb086e22..5fe9bed5c 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -416,7 +416,7 @@ int32_t iguana_bundlefname(struct iguana_info *coin,struct iguana_bundle *bp,cha int32_t iguana_bundleremove(struct iguana_info *coin,int32_t hdrsi,int32_t tmpfiles); int32_t iguana_voutsfname(struct iguana_info *coin,int32_t roflag,char *fname,int32_t slotid); int32_t iguana_vinsfname(struct iguana_info *coin,int32_t roflag,char *fname,int32_t slotid); -bits256 iguana_merkle(bits256 *tree,int32_t txn_count); +bits256 iguana_merkle(char *symbol,bits256 *tree,int32_t txn_count); int32_t iguana_bundleready(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t requiredflag); int32_t iguana_blast(struct iguana_info *coin,struct iguana_peer *addr); int32_t iguana_validated(struct iguana_info *coin); diff --git a/includes/iguana_structs.h b/includes/iguana_structs.h index e9fd52383..feaf910e7 100755 --- a/includes/iguana_structs.h +++ b/includes/iguana_structs.h @@ -511,7 +511,7 @@ struct iguana_info struct OS_memspace TXMEM,MEM,MEMB[IGUANA_MAXBUNDLESIZE]; queue_t acceptQ,hdrsQ,blocksQ,priorityQ,possibleQ,cacheQ,recvQ,msgrequestQ,jsonQ,finishedQ; double parsemillis,avetime; uint32_t Launched[8],Terminated[8]; - portable_mutex_t peers_mutex,blocks_mutex,special_mutex,RTmutex,allcoins_mutex; + portable_mutex_t peers_mutex,blocks_mutex,special_mutex,RTmutex,allcoins_mutex,MoM_mutex; char changeaddr[64]; struct iguana_bundle *bundles[IGUANA_MAXBUNDLES],*current,*lastpending; struct OS_memspace RTrawmem,RTmem,RThashmem; // struct iguana_ramchain RTramchain; @@ -528,7 +528,7 @@ struct iguana_info #ifdef DEPRECATED_HHUTXO struct iguana_hhaccount *accountstable; #endif - char lastdispstr[2048]; + char lastdispstr[2048],getinfostr[64]; double txidfind_totalmillis,txidfind_num,spendtxid_totalmillis,spendtxid_num; struct iguana_monitorinfo monitoring[256]; int32_t notarychain,didaddresses; diff --git a/marketmaker.vcxproj b/marketmaker.vcxproj index fbe023dc8..b3d9f07fa 100644 --- a/marketmaker.vcxproj +++ b/marketmaker.vcxproj @@ -86,7 +86,7 @@ Level2 Disabled - _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_DEBUG;_CONSOLE;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_DEBUG;_CONSOLE;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;NOTETOMIC;%(PreprocessorDefinitions) 8Bytes .\iguana;%(AdditionalIncludeDirectories) @@ -103,7 +103,7 @@ Level3 Disabled - _DEBUG;_CONSOLE;NATIVE_WINDOWS;WIN32;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;NATIVE_WINDOWS;WIN32;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;NOTETOMIC;%(PreprocessorDefinitions) 8Bytes @@ -121,7 +121,7 @@ MaxSpeed true true - _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;NOTETOMIC;%(PreprocessorDefinitions) 8Bytes @@ -141,7 +141,7 @@ MaxSpeed true true - WIN64;_WIN64;_CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + WIN64;_WIN64;_CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;NOTETOMIC;%(PreprocessorDefinitions) 8Bytes MultiThreaded @@ -249,6 +249,7 @@ + @@ -257,4 +258,4 @@ - \ No newline at end of file + diff --git a/marketmaker.vcxproj.filters b/marketmaker.vcxproj.filters index 36d2bdfe0..dd2b563f0 100644 --- a/marketmaker.vcxproj.filters +++ b/marketmaker.vcxproj.filters @@ -296,8 +296,11 @@ Source Files + + Source Files + - \ No newline at end of file + diff --git a/marketmaker_build_32_64.cmd b/marketmaker_build_32_64.cmd index 730081702..faf016457 100644 --- a/marketmaker_build_32_64.cmd +++ b/marketmaker_build_32_64.cmd @@ -72,10 +72,14 @@ IF "%host%"=="VM-81" ( mkdir package_content\win64 copy /y Release\marketmaker.exe package_content\win32 copy /y x64\Release\marketmaker.exe package_content\win64 + copy /y x64\Release\libcurl.dll package_content\win64 + copy /y x64\Release\nanomsg.dll package_content\win64 echo Marketmaker_%LP_MAJOR_VERSION%.%LP_MINOR_VERSION%_%LP_BUILD_NUMBER%%GIT_COMMIT% > package_content\version.txt cd package_content "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z win32\marketmaker.exe "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z win64\marketmaker.exe + "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z win64\libcurl.dll + "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z win64\nanomsg.dll "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z version.txt cd .. rd package_content /s /q diff --git a/marketmaker_build_cpp-ethereum.cmd b/marketmaker_build_cpp-ethereum.cmd new file mode 100644 index 000000000..589d2924b --- /dev/null +++ b/marketmaker_build_cpp-ethereum.cmd @@ -0,0 +1,15 @@ +@echo off +rem Sample script to build cpp-ethereum libs by Decker (don't fully tested yet) +rem Make sure cpp-ethereum is empty, before run. + +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 +mkdir build_win64_release +cd build_win64_release +cmake .. -G "Visual Studio 14 2015 Win64" +cmake --build . --config Release +rem cmake --build . \ No newline at end of file diff --git a/marketmaker_build_depends.cmd b/marketmaker_build_depends.cmd new file mode 100644 index 000000000..a09e0ea04 --- /dev/null +++ b/marketmaker_build_depends.cmd @@ -0,0 +1,89 @@ +@echo off +rem [ Decker] Automatically download and build depends script for marketmaker. +rem +rem 1. Requires installed CMake for Windows (!) +rem 2. Currently build only 64-bit release versions of .lib and .dll +rem 3. Libraries available: pthreads, nanomsg, curl + +@REM Check for Visual Studio +call set "VSPATH=" +if defined VS140COMNTOOLS ( if not defined VSPATH ( + call set "VSPATH=%%VS140COMNTOOLS%%" +) ) + +@REM check if we already have the tools in the environment +if exist "%VCINSTALLDIR%" ( + goto compile +) + +if not defined VSPATH ( + echo You need Microsoft Visual Studio 15 installed + pause + exit +) + +@REM set up the environment +if exist "%VSPATH%..\..\vc\vcvarsall.bat" ( + call "%%VSPATH%%..\..\vc\vcvarsall.bat" amd64 + goto compile +) + +echo Unable to set up the environment +pause +exit + +:compile +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 +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 ../../.. +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 + +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 ../../.. +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 new file mode 100644 index 000000000..ed76db72c --- /dev/null +++ b/marketmaker_build_etomic.cmd @@ -0,0 +1,56 @@ +@echo off +rem (c) Decker + +echo [#1] Build nanomsg, curl and pthreads ... +call marketmaker_build_depends.cmd +copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.lib marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\curl.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 +cd .. +mkdir build_win64_release +cd build_win64_release +cmake .. -G "Visual Studio 14 2015 Win64" + +rem Steps before build: +rem +rem crypto777\CMakeLists.txt +rem Add: +rem if(WIN32) +rem add_definitions(-DNATIVE_WINDOWS) +rem add_definitions(-DIGUANA_LOG2PACKETSIZE=20) +rem add_definitions(-DIGUANA_MAXPACKETSIZE=1572864) +rem include_directories("${CMAKE_SOURCE_DIR}/includes") +rem endif() +rem +rem iguana\exchanges\CMakeLists.txt +rem +rem if(WIN32) +rem add_definitions(-DNATIVE_WINDOWS) +rem add_definitions(-DIGUANA_LOG2PACKETSIZE=20) +rem add_definitions(-DIGUANA_MAXPACKETSIZE=1572864) +rem add_definitions(-D_CRT_SECURE_NO_WARNINGS) +rem include_directories("${CMAKE_SOURCE_DIR}/includes") +rem endif() +rem +rem iguana\exchanges\etomicswap\CMakeLists.txt +rem +rem if(WIN32) +rem add_definitions(-DNATIVE_WINDOWS) +rem add_definitions(-DIGUANA_LOG2PACKETSIZE=20) +rem add_definitions(-DIGUANA_MAXPACKETSIZE=1572864) +rem add_definitions(-D_CRT_SECURE_NO_WARNINGS) +rem add_definitions(-DNOMINMAX) +rem include_directories("${CMAKE_SOURCE_DIR}/includes") +rem endif() + +echo [#3] Build marketmaker-mainnet ... + +cmake --build . --config Release --target marketmaker-mainnet +cd .. \ No newline at end of file diff --git a/pthreadVC2.lib b/pthreadVC2.lib deleted file mode 100644 index d793e7144..000000000 Binary files a/pthreadVC2.lib and /dev/null differ diff --git a/pthreadvc2.dll b/pthreadvc2.dll deleted file mode 100644 index 93f562baa..000000000 Binary files a/pthreadvc2.dll and /dev/null differ