diff --git a/.gitignore b/.gitignore index 14b005133..3ae3a23ab 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 @@ -229,259 +233,10 @@ iguana/confs/630929d976025fafde221c7358eb5805f4359bad3c6b8bd50ad3f6e0a9b5ce78 iguana/confs/5f3283a017c31e52443d61cb43944e2157f7c03eb12d701ebf4a35a695688e1f - -iguana/DB/SWAPS/1313603851-3952777544 - -iguana/DB/SWAPS/1923456555-3815385469 - -iguana/DB/SWAPS/897416195-4050269921 - -iguana/DB/SWAPS/2465996447-4202128826 - -iguana/DB/SWAPS/3078036996-3700749298 - -iguana/DB/SWAPS/1061498231-3266306388 - -iguana/DB/SWAPS/1060082251-3390546616 - -iguana/SVM/rawfeatures/BTCD_BTC - -iguana/DB/SWAPS/1032184933-1028220623 - -iguana/DB/SWAPS/771249356-2746947221 - -iguana/DB/SWAPS/2311778512-3235676199 - -iguana/DB/SWAPS/3385048746-2109923340 - -iguana/DB/SWAPS/1739581643-2099619754 - -iguana/DB/SWAPS/2247429570-1367058185 - -iguana/DB/SWAPS/3178831915-912907861 - -iguana/DB/SWAPS/445514331-1083446761 - -iguana/DB/SWAPS/2510768478-2766365035 - -iguana/DB/SWAPS/2072817844-2263105627 - -iguana/DB/SWAPS/230888617-1894645930 - -iguana/DB/SWAPS/3606847984-2574036327 - -iguana/DB/SWAPS/2384443255-1263480722 - -iguana/DB/SWAPS/845549832-3630913950 - -iguana/DB/SWAPS/2050938501-203733478 - -iguana/DB/SWAPS/3434672913-3981690962 - -iguana/DB/SWAPS/2840127595-1174059534 - -iguana/DB/SWAPS/2448551545-1211445977 - -*.alicepayment - -*.myfee - -iguana/DB/SWAPS/1313312572-123661666 - -iguana/DB/SWAPS/3408402932-4088991610 - -iguana/DB/SWAPS/3772541120-2007204891 - -iguana/DB/SWAPS/784303571-1929722462 - -iguana/DB/SWAPS/3221116355-3522779294 - -iguana/DB/SWAPS/1703578312-1139459191 - -iguana/DB/SWAPS/1192374491-1050242469 - -iguana/DB/SWAPS/4244307493-1619487751 - -iguana/DB/SWAPS/3213119432-553439289 - -iguana/DB/SWAPS/3854521391-612984356 - -iguana/DB/SWAPS/3611231334-1171171579 - -iguana/DB/SWAPS/1505015888-2633757068 - -iguana/DB/SWAPS/3430299677-3087427598 - -iguana/DB/SWAPS/2275651697-591036515 - -iguana/DB/SWAPS/2180638961-896149751 - -iguana/DB/SWAPS/2349180798-2344225091 - -iguana/DB/SWAPS/1395238080-4120976642 - -iguana/DB/SWAPS/1914406677-1452353494 - -iguana/DB/SWAPS/3193054754-2514575257 - -iguana/DB/SWAPS/3004995589-1950720855 - -iguana/3193054754-2514575257 - -iguana/DB/SWAPS/2912654530-2125064238 - -iguana/DB/SWAPS/3448271011-3628813832 - -iguana/DB/SWAPS/3448271011-3628813832 - -iguana/DB/SWAPS/403615495-1237768524 - -iguana/DB/SWAPS/3448271011-3628813832 - -iguana/DB/SWAPS/403615495-1237768524 - -iguana/DB/SWAPS/3448271011-3628813832 - -iguana/DB/SWAPS/246664144-1570119145 - -iguana/DB/SWAPS/171316098-410428064 - -iguana/DB/SWAPS/178665381-1950467641 - -iguana/DB/SWAPS/4126499968-376410338 - -iguana/DB/SWAPS/1518259123-2214130634 - -iguana/DB/SWAPS/152114847-907489057 - -iguana/DB/SWAPS/61119357-1960547076 - -iguana/DB/SWAPS/26534791-3105729230 - -*.finished - -iguana/DB/SWAPS/2279906047-2580050792 - -iguana/DB/SWAPS/1672096208-4211948211 - -iguana/DB/SWAPS/3062665554-3128383014 - -iguana/DB/SWAPS/2668150969-2698996317 - -iguana/DB/SWAPS/3462690702-2419919594 - -iguana/DB/SWAPS/543051861-1532200070 - -iguana/DB/SWAPS/442294237-2721246052 - -iguana/DB/SWAPS/1247864366-3828803132 - -iguana/DB/SWAPS/2910626293-1439062588 - -iguana/DB/SWAPS/3893087081-2278083649 - -iguana/DB/SWAPS/2990527454-48620696 - -iguana/DB/SWAPS/217534954-2300638414 - -iguana/DB/SWAPS/2780026367-3028893038 - -iguana/DB/SWAPS/467080987-1442519493 - -iguana/DB/SWAPS/1504818827-1454232932 - -iguana/DB/SWAPS/4093850898-2949785771 - -iguana/DB/SWAPS.old/1247864366-3828803132 - -iguana/DB/SWAPS.old/.tmpmarker - -iguana/DB/SWAPS/2723832060-1788071166 - -iguana/DB/SWAPS/3210648667-2626363704 - -iguana/DB/SWAPS/415703857-2769362858 - -iguana/3193054754-2514575257 - -iguana/DB/SWAPS/2723832060-1788071166 - - - -iguana/DB/SWAPS/3213598586-2281632307 - -iguana/DB/SWAPS/2686675855-3655454671 - -iguana/DB/SWAPS/1878868608-154367763 - -iguana/DB/SWAPS/1306454711-1938980379 - -iguana/DB/SWAPS/912783809-2523701920 - -iguana/DB/SWAPS/1238069553-2363573428 - -iguana/DB/SWAPS/2895470622-2170247626 - -iguana/confs/ed476386688e486f359ce67e44ce4268a875125527e122ea9126ebc54f473d31 - -iguana/confs/f6e8e8ab82ed33b2de063d6820dcaefb99b95cf1aef6527b8f27e1e5b1fe882d - -iguana/e - -iguana/a - -iguana/t - -iguana/stats - -iguana/DEXstats - -iguana/DEXstats.dSYM/Contents/Info.plist - -iguana/DEXstats.dSYM/Contents/Resources/DWARF/DEXstats - -iguana/confs/dc54d862abd6809d9fd200759538014248f18a5a69e7bc22c0a1f2111a896157 - -iguana/confs/589983f94d17d8e0dc6fbf3fce34b20efc81183c0ab0158cf81a60f03711e15c - -iguana/confs/67201409eb7644e398c8090ac6e3ccf4b69d186b8478aa8488211e9b474dd245 - -iguana/confs/982dfa0e535a6e856cca3cd919af03f50050408fcfed1cd71bb4aa1e2e69070f - -iguana/confs/aa45c35599c9c75a9788fa9740ce8713cc457919e6f6f7d8d8115da5193f5722 - -iguana/confs/ab828d4425655df6bf409f0e23be49ae4a19b2c974008385b18a7a9c79b0314c - -iguana/confs/b29fa937dd00ed7dd73ff4eef8b49bd3103ebddaee9fae05f44ffed42c5a4611 - -iguana/confs/LTC_hdrs.txt - -iguana/confs/LTC_oldhdrs.txt - -iguana/DB/LTC_peers.dat - -iguana/debug.log - -iguana/DB/LTC/.tmpmarker - -iguana/DB/purgeable/LTC/.tmpmarker - -iguana/DB/SWAPS/654629381-1010651560 - -iguana/DB/SWAPS/1780095668-2225891679 - -iguana/DB/SWAPS/3085356347-2346291696 - -iguana/DB/SWAPS/1819165332-1507632737 - -iguana/DB/SWAPS/283982730-556239841 +iguana/marketmaker.dSYM/Contents/Resources/DWARF/marketmaker iguana/marketmaker.dSYM/Contents/Info.plist -iguana/client - -iguana/marketmaker.dSYM/Contents/Resources/DWARF/marketmaker - iguana/confs/97f18454bb61e9eb7a827cfbefe42fbf7ae2832dc74c4812bdaef8bcf5c10474 iguana/DB/PRICES/.tmpmarker @@ -499,3 +254,13 @@ iguana/DB/UNSPENTS/.tmpmarker iguana/DB/instantdex_RQ4z6KrMZeEnCSCsChv1ZoR9ExQitHjbpg_append.json iguana/DB/instantdex_RQ4z6KrMZeEnCSCsChv1ZoR9ExQitHjbpg.json + +build + +.idea +Release/* + +build_win64_release/* +DB/* + +iguana/exchanges/manychains 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..5730c4869 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,30 @@ +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 + +cache: + directories: + - $HOME/.hunter \ No newline at end of file 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/LEGAL/LICENSE b/LEGAL/LICENSE index 67f75dcd8..50c41bc79 100755 --- a/LEGAL/LICENSE +++ b/LEGAL/LICENSE @@ -1,4 +1,4 @@ -Copyright © 2013-2015 The SuperNET Developers. +Copyright © 2013-2018 The SuperNET Developers. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2, 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 d9dfd7341..b0c77724c 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#SuperNET Client "iguana" +# SuperNET Client "iguana" OS | Build Status -------------|------ @@ -22,7 +22,7 @@ iguana: most efficient bitcoin core implementation that can simultaneously be fu komodo: this is the top secret project I cant talk about publicly yet -> #TL;DR# +> # TL;DR > > ```sudo apt-get update; sudo apt-get install git libcurl4-openssl-dev build-essential libnanomsg-dev; git clone https://github.com/jl777/SuperNET; cd SuperNET; ./m_onetime m_unix;``` > @@ -40,14 +40,14 @@ TOOL_DIR := /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin MINGW := i586-mingw32 The above two definitions need to be changed to match the mingw install on your system. m_win32 and m_win64 just invokes the makefile in mingw32 and mingw64 -##For chrome app## +## For chrome app You need to make sure the nacl sdk is properly installed and you are able to build the examples. Now you will need to get the external libs, which can be built from scratch using naclports or there use the reference builds of libcurl.a and libz.a in the SuperNET/crypto777/pnacl_libs. You can just copy those over into $(NACL_SDK_ROOT)//lib/pnacl. -##For android## +## For android You have to build a native libnanomsg for android. This section is work in progress. Contact ca333@protonmail.ch for assistance on building latest iguana for android. -#ONETIME# +# ONETIME Now you are ready to build. I try to make the build process as simple as possible, so there are no `autoconf`, `autoreconf`, `configure`, `cmake`, `make`, to get properly installed and running and run, etc. You do need a C compiler, like gcc. @@ -82,12 +82,12 @@ To build just iguana, you can ```cd``` into SuperNET/iguana and do ```./m_unix`` ```./m_clean``` will remove the files created from the building -#RUNNING# +# RUNNING The native versions are command line applications: agents/iguana {JSON} The chrome app pexe requires that the chrome is launched with a command line parameter (tools/chrome.localhost) and then browse to *http://127.0.0.1:7777* to see the pexe -#SUPERUGLYGUI# +# SUPERUGLYGUI Once iguana is running, you can see the superuglyGUI at *http://127.0.0.1:7778/?method* by submitting API calls using the forms, you will see it go to some specific URL. You can also do a programmatic GET request to ```http://127.0.0.1:7778/api/``` @@ -134,9 +134,9 @@ on OSX mksquashfs is not native, you will need to install fuse: https://osxfuse. A Note on Installation from pebwindkraft at bitco.in ======================= Though I had xcode installed, aclocal didn’t work. I installed homebrew, and then: -# brew install autoconf -# brew install automake -# brew install gmp +`brew install autoconf` +`brew install automake` +`brew install gmp` 2.) libsecp256 it complained, that libsecp256 was not there in includes, so I linked it. @@ -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..de2123bc5 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,6 @@ +version: 1.0.{build} +branches: + only: + - etomic +build_script: +- cmd: marketmaker_build_etomic.cmd \ No newline at end of file diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index a2a6d2200..1fcfaefcb 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -931,41 +931,41 @@ 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]); + iguana_dPoWupdate(myinfo,myinfo->DPOWS[0]); endmilli = startmilli + 100; } else if ( myinfo->numdpows > 1 ) { - dp = &myinfo->DPOWS[counter % myinfo->numdpows]; + dp = myinfo->DPOWS[counter % myinfo->numdpows]; iguana_dPoWupdate(myinfo,dp); //if ( (counter % myinfo->numdpows) != 0 ) { //fprintf(stderr,"F "); - iguana_dPoWupdate(myinfo,&myinfo->DPOWS[0]); + iguana_dPoWupdate(myinfo,myinfo->DPOWS[0]); } 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.h b/basilisk/basilisk.h index 8d0c3da9d..0be9d7dd8 100755 --- a/basilisk/basilisk.h +++ b/basilisk/basilisk.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/basilisk/basilisk_DEX.c b/basilisk/basilisk_DEX.c index 17ed0816e..902f9d5eb 100755 --- a/basilisk/basilisk_DEX.c +++ b/basilisk/basilisk_DEX.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/basilisk/basilisk_MSG.c b/basilisk/basilisk_MSG.c index 0fba54c91..1210d39a9 100755 --- a/basilisk/basilisk_MSG.c +++ b/basilisk/basilisk_MSG.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/basilisk/basilisk_bitcoin.c b/basilisk/basilisk_bitcoin.c index 942539260..4d15df781 100755 --- a/basilisk/basilisk_bitcoin.c +++ b/basilisk/basilisk_bitcoin.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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 ) { @@ -585,7 +585,9 @@ char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coi if ( signedtxidp != 0 ) memset(signedtxidp,0,sizeof(*signedtxidp)); bitcoin_address(changeaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); - txfee = (coin->txfee + duplicates*coin->txfee*2); + txfee = (coin->txfee + duplicates*coin->txfee/10); + if ( strcmp(coin->symbol,"GAME") == 0 ) + printf("GAME txfee %.8f\n",dstr(txfee)); if ( (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,0,1,0)) != 0 ) { if ( duplicates <= 0 ) @@ -602,14 +604,14 @@ 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 ) { if ( *completedp != 0 ) { - printf("splitfunds signedtx.(%s)\n",signedtx); + printf("splitfunds %s signedtx.(%s)\n",coin->symbol,signedtx); if ( sendflag != 0 ) iguana_sendrawtransaction(myinfo,coin,signedtx); free(rawtx); diff --git a/basilisk/basilisk_swap.c b/basilisk/basilisk_swap.c index a142f8a12..e1982f25f 100755 --- a/basilisk/basilisk_swap.c +++ b/basilisk/basilisk_swap.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/basilisk/basilisk_tradebot.c b/basilisk/basilisk_tradebot.c index 2635cde97..40f4888a5 100755 --- a/basilisk/basilisk_tradebot.c +++ b/basilisk/basilisk_tradebot.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/basilisk/jumblr.c b/basilisk/jumblr.c index 9618a9421..8efb611ff 100755 --- a/basilisk/jumblr.c +++ b/basilisk/jumblr.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/basilisk/smartaddress.c b/basilisk/smartaddress.c index 727a54709..6339c9e19 100755 --- a/basilisk/smartaddress.c +++ b/basilisk/smartaddress.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/basilisk/tradebots_liquidity.c b/basilisk/tradebots_liquidity.c index b044accd4..6b3c00704 100755 --- a/basilisk/tradebots_liquidity.c +++ b/basilisk/tradebots_liquidity.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/basilisk/tradebots_marketmaker.c b/basilisk/tradebots_marketmaker.c index 575861fa6..525317c25 100755 --- a/basilisk/tradebots_marketmaker.c +++ b/basilisk/tradebots_marketmaker.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * 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..633c62c08 --- /dev/null +++ b/cpp-ethereum @@ -0,0 +1 @@ +Subproject commit 633c62c08bc73c7c3935c948a8d6c656a3659976 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_nonportable.c b/crypto777/OS_nonportable.c index 87e167afb..ca3f90695 100755 --- a/crypto777/OS_nonportable.c +++ b/crypto777/OS_nonportable.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/crypto777/OS_portable.c b/crypto777/OS_portable.c index 422b51427..f0fd12366 100755 --- a/crypto777/OS_portable.c +++ b/crypto777/OS_portable.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 8c109e5d0..06a06116c 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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/OS_time.c b/crypto777/OS_time.c index 2a1279730..d2dcae19a 100755 --- a/crypto777/OS_time.c +++ b/crypto777/OS_time.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/crypto777/SaM.c b/crypto777/SaM.c index e82802cea..08a0235de 100755 --- a/crypto777/SaM.c +++ b/crypto777/SaM.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index 775ec5f66..1ae71342e 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -73,20 +73,20 @@ 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 ) { if ( strcmp(command,"signrawtransaction") != 0 && strcmp(command,"getrawtransaction") != 0 ) - printf("<<<<<<<<<<< A bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,params); + printf("<<<<<<<<<<< A bitcoind_RPC: %s post_process_bitcoind_RPC.%s\n",debugstr,command); return(rpcstr); } json = cJSON_Parse(rpcstr); if ( json == 0 ) { - printf("<<<<<<<<<<< B bitcoind_RPC: %s post_process_bitcoind_RPC.%s can't parse.(%s) params.(%s)\n",debugstr,command,rpcstr,params); + printf("<<<<<<<<<<< B bitcoind_RPC: %s post_process_bitcoind_RPC.%s can't parse.(%s)\n",debugstr,command,rpcstr); free(rpcstr); return(0); } @@ -143,14 +143,15 @@ char *Jay_NXTrequest(char *command,char *params) char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout) { - static int didinit,count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY; + CURL *curl_handle; static int didinit,count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY; struct MemoryStruct chunk; - struct curl_slist *headers = NULL; struct return_string s; CURLcode res; CURL *curl_handle; + struct curl_slist *headers = NULL; struct return_string s; CURLcode res; char *bracket0,*bracket1,*retstr,*databuf = 0; long len; int32_t specialcase,numretries; double starttime; if ( didinit == 0 ) { didinit = 1; curl_global_init(CURL_GLOBAL_ALL); //init the curl session + //curl_handle = curl_easy_init(); } if ( (0) && (USE_JAY != 0 && (strncmp(url,"http://127.0.0.1:7876/nxt",strlen("http://127.0.0.1:7876/nxt")) == 0 || strncmp(url,"https://127.0.0.1:7876/nxt",strlen("https://127.0.0.1:7876/nxt")) == 0)) ) { @@ -164,7 +165,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/cJSON.c b/crypto777/cJSON.c index 54df964f5..d62b71683 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -669,7 +669,7 @@ void cJSON_Minify(char *json) // the following written by jl777 /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/crypto777/curve25519.c b/crypto777/curve25519.c index 264d59952..2f8f8dc13 100755 --- a/crypto777/curve25519.c +++ b/crypto777/curve25519.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index d08756752..03431da63 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/crypto777/iguana_serdes.c b/crypto777/iguana_serdes.c index f4ff2b923..a20b79205 100755 --- a/crypto777/iguana_serdes.c +++ b/crypto777/iguana_serdes.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index 5f978e305..05897a953 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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/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/crypto777/ramcoder.c b/crypto777/ramcoder.c index 54daeee5e..2608bf428 100755 --- a/crypto777/ramcoder.c +++ b/crypto777/ramcoder.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/datachain/datachain.c b/datachain/datachain.c index 4ce46416d..6f5172ed6 100755 --- a/datachain/datachain.c +++ b/datachain/datachain.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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/iguana_notary.c b/deprecated/iguana_notary.c new file mode 100755 index 000000000..420166fba --- /dev/null +++ b/deprecated/iguana_notary.c @@ -0,0 +1,1279 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + + +// Todo list: +// q) investigate if rebroadcast reorged local chain notary tx and scanning mempool is needed + +#define CHECKSIG 0xac + +#include "iguana777.h" +//#include "notaries.h" + +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,char *srccoin); + +#include "dpow/dpow_network.c" +#include "dpow/dpow_rpc.c" +#include "dpow/dpow_tx.c" +#include "dpow/dpow_fsm.c" +#include "dpow/dpow_prices.c" + +void dpow_fifoupdate(struct supernet_info *myinfo,struct dpow_checkpoint *fifo,struct dpow_checkpoint tip) +{ + int32_t i,ind; struct dpow_checkpoint newfifo[DPOW_FIFOSIZE]; + memset(newfifo,0,sizeof(newfifo)); + for (i=DPOW_FIFOSIZE-1; i>0; i--) + { + if ( (0) && bits256_nonz(fifo[i-1].blockhash.hash) != 0 && (tip.blockhash.height - fifo[i-1].blockhash.height) != i ) + printf("(%d != %d) ",(tip.blockhash.height - fifo[i-1].blockhash.height),i); + if ( (ind= (tip.blockhash.height - fifo[i-1].blockhash.height)) >= 0 && ind < DPOW_FIFOSIZE ) + newfifo[ind] = fifo[i-1]; + } + newfifo[0] = tip; + memcpy(fifo,newfifo,sizeof(newfifo)); + //for (i=0; itimestamp = timestamp; + checkpoint->blocktime = blocktime; + checkpoint->blockhash.hash = hash; + checkpoint->blockhash.height = height; +} + +void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t height,bits256 hash,uint32_t timestamp,uint32_t blocktime) +{ + //struct komodo_ccdataMoMoM mdata; cJSON *blockjson; uint64_t signedmask; struct iguana_info *coin; + void **ptrs; char str[65]; struct dpow_checkpoint checkpoint; int32_t freq,minsigs,i,ht; struct dpow_block *bp; + dpow_checkpointset(myinfo,&dp->last,height,hash,timestamp,blocktime); + checkpoint = dp->srcfifo[dp->srcconfirms]; + if ( strcmp("BTC",dp->dest) == 0 ) + { + freq = DPOW_CHECKPOINTFREQ; + minsigs = Notaries_BTCminsigs; //DPOW_MINSIGS; + } + else + { + 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 )//|| strcmp(dp->dest,"CHAIN") == 0 ) + { + //if ( dp->SRCREALTIME == 0 ) + // return; + if ( (coin= iguana_coinfind(dp->symbol)) != 0 ) + { + hash = dpow_getbestblockhash(myinfo,coin); + if ( bits256_nonz(hash) != 0 ) + { + if ( (blockjson= dpow_getblock(myinfo,coin,hash)) != 0 ) + { + height = jint(blockjson,"height"); + if ( dpow_hasnotarization(&signedmask,¬ht,myinfo,coin,blockjson,height,&mdata) <= 0 ) + { + if ( mdata.pairs != 0 ) + free(mdata.pairs); + blocktime = juint(blockjson,"time"); + free_json(blockjson); + if ( height > 0 && blocktime > 0 ) + { + dpow_checkpointset(myinfo,&dp->last,height,hash,timestamp,blocktime); + if ( (0) && strcmp("KMD",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 ) + { + printf("activehash.(%s) is current checkpoint, skip\n",bits256_str(str,dp->activehash)); + return; + } + else if ( bits256_nonz(dp->lastnotarized) != 0 && bits256_cmp(dp->lastnotarized,checkpoint.blockhash.hash) == 0 ) + { + printf("lastnotarized.(%s) is current checkpoint, skip\n",bits256_str(str,dp->lastnotarized)); + return; + } + if ( (0) && strcmp("KMD",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; + } else return; + }*/ + if ( bits256_nonz(checkpoint.blockhash.hash) != 0 && (checkpoint.blockhash.height % freq) == 0 ) + { + if ( (0) && strcmp("KMD",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) + 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; + 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; + 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); + } + } + } + } +} + +void dpow_approvedset(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_checkpoint *checkpoint,bits256 *txs,int32_t numtx) +{ + int32_t i,j; bits256 txid; + if ( txs != 0 ) + { + for (i=0; iapproved[j].hash) == 0 ) + { + if ( bits256_nonz(checkpoint->approved.hash) == 0 || dp->approved[j].height >= checkpoint->approved.height ) + checkpoint->approved = dp->approved[j]; + } + } + } + } + } +} + +void dpow_destconfirm(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_checkpoint *checkpoint) +{ + int32_t i; + if ( bits256_nonz(checkpoint->approved.hash) != 0 ) + { + for (i=DPOW_FIFOSIZE-1; i>0; i--) + dp->notarized[i] = dp->notarized[i-1]; + dp->notarized[0] = checkpoint->approved; + } +} + +void dpow_destupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t height,bits256 hash,uint32_t timestamp,uint32_t blocktime) +{ + dp->destupdated = timestamp; + dpow_checkpointset(myinfo,&dp->destchaintip,height,hash,timestamp,blocktime); + dpow_approvedset(myinfo,dp,&dp->destchaintip,dp->desttx,dp->numdesttx); + dpow_fifoupdate(myinfo,dp->destfifo,dp->destchaintip); + if ( strcmp(dp->dest,"BTC") == 0 ) + { + //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 +} + +void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp) +{ + 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,"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,&merkleroot,&blockhash,&blocktime,dp->desttx,&dp->numdesttx,dest)) != dp->destchaintip.blockhash.height && height >= 0 ) + { + char str[65]; + 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 ) + { + printf("iguana_dPoWupdate dest.%s reorg detected %d vs %d\n",dp->dest,height,dp->destchaintip.blockhash.height); + if ( height == dp->destchaintip.blockhash.height && bits256_cmp(blockhash,dp->destchaintip.blockhash.hash) != 0 ) + printf("UNEXPECTED ILLEGAL BLOCK in dest chaintip\n"); + } 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 || 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,&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 ) + dp->lastheight = height-1; + if ( height < dp->last.blockhash.height ) + { + printf("iguana_dPoWupdate src.%s reorg detected %d vs %d approved.%d notarized.%d\n",dp->symbol,height,dp->last.blockhash.height,dp->approved[0].height,dp->notarized[0].height); + if ( height <= dp->approved[0].height ) + { + if ( bits256_cmp(blockhash,dp->last.blockhash.hash) != 0 ) + printf("UNEXPECTED ILLEGAL BLOCK in src chaintip\n"); + } + else + { + while ( dp->lastheight <= height ) + { + blockhash = dpow_getblockhash(myinfo,src,dp->lastheight); + dpow_srcupdate(myinfo,dp,dp->lastheight++,blockhash,(uint32_t)time(NULL),blocktime); + } + } + } + else if ( strcmp(dp->symbol,"KMD") == 0 ) + { + while ( dp->lastheight <= height ) + { + blockhash = dpow_getblockhash(myinfo,src,dp->lastheight); + dpow_srcupdate(myinfo,dp,dp->lastheight++,blockhash,(uint32_t)time(NULL),blocktime); + } + } + else if ( time(NULL) > dp->lastsrcupdate+60 || height != dp->lastheight ) + { + dp->lastsrcupdate = (uint32_t)time(NULL); + dp->lastheight = height; + blockhash = dpow_getblockhash(myinfo,src,dp->lastheight); + dpow_srcupdate(myinfo,dp,dp->lastheight,blockhash,(uint32_t)time(NULL),blocktime); + } + } //else printf("error getchaintip for %s\n",dp->symbol); + } else printf("iguana_dPoWupdate missing src.(%s) %p or dest.(%s) %p\n",dp->symbol,src,dp->dest,dest); +} + +void dpow_addresses() +{ + int32_t i; char coinaddr[64]; uint8_t pubkey[33]; + for (i=0; iDPOWS[myinfo->numdpows]; + destvalid = srcvalid = 0; + if ( myinfo->NOTARY.RELAYID < 0 ) + { + if ( (retstr= basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(myinfo->ipaddr),myinfo->myaddr.persistent)) != 0 ) + { + printf("addrelay.(%s)\n",retstr); + free(retstr); + } + if ( myinfo->NOTARY.RELAYID < 0 ) + return(clonestr("{\"error\":\"must be running as notary node\"}")); + } + if ( dp->symbol[0] != 0 ) + return(clonestr("{\"error\":\"cant dPoW more than one coin at a time\"}")); + if ( pubkey == 0 || pubkey[0] == 0 || is_hexstr(pubkey,0) != 66 ) + 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 ( iguana_coinfind(dest) == 0 ) + return(clonestr("{\"error\":\"cant dPoW without KMD (dest)\"}")); + if ( myinfo->numdpows > 1 ) + { + for (i=1; inumdpows; i++) + if ( strcmp(symbol,myinfo->DPOWS[i].symbol) == 0 ) + { + dp->symbol[0] = 0; + return(clonestr("{\"error\":\"cant dPoW same coin again\"}")); + } + } + strcpy(dp->symbol,symbol); + if ( strcmp(dp->symbol,"KMD") == 0 ) + { + strcpy(dp->dest,"BTC"); + dp->srcconfirms = DPOW_KOMODOCONFIRMS; + } + else + { + strcpy(dp->dest,dest); + dp->srcconfirms = DPOW_THIRDPARTY_CONFIRMS; + } + if ( dp->srcconfirms > DPOW_FIFOSIZE ) + dp->srcconfirms = DPOW_FIFOSIZE; + if ( strcmp("BTC",dp->dest) == 0 ) + { + dp->freq = DPOW_CHECKPOINTFREQ; + dp->minsigs = Notaries_BTCminsigs; //DPOW_MINSIGS; + } + else + { + dp->minsigs = Notaries_minsigs; //DPOW_MIN_ASSETCHAIN_SIGS; + if ( strcmp("CHIPS",dp->symbol) == 0 || strncmp("TEST",dp->symbol,4) == 0) + dp->freq = DPOW_MAXFREQ; + else dp->freq = 1; + } + src = iguana_coinfind(dp->symbol); + destcoin = iguana_coinfind(dp->dest); + if ( src == 0 || destcoin == 0 ) + { + dp->symbol[0] = 0; + return(clonestr("{\"error\":\"source coin or dest coin not there\"}")); + } + char tmp[67]; + safecopy(tmp,pubkey,sizeof(tmp)); + decode_hex(dp->minerkey33,33,tmp); + bitcoin_address(srcaddr,src->chain->pubtype,dp->minerkey33,33); + if ( (retstr= dpow_validateaddress(myinfo,src,srcaddr)) != 0 ) + { + json = cJSON_Parse(retstr); + if ( (ismine= jobj(json,"ismine")) != 0 && is_cJSON_True(ismine) != 0 ) + srcvalid = 1; + else srcvalid = 0; + free(retstr); + retstr = 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 ) + destvalid = 1; + else destvalid = 0; + free(retstr); + retstr = 0; + } + for (i=0; i<33; i++) + printf("%02x",dp->minerkey33[i]); + printf(" DPOW with pubkey.(%s) %s.valid%d %s -> %s %s.valid%d\n",tmp,srcaddr,srcvalid,dp->symbol,dp->dest,destaddr,destvalid); + if ( srcvalid <= 0 || destvalid <= 0 ) + { + dp->symbol[0] = 0; + return(clonestr("{\"error\":\"source address or dest address has no privkey, importprivkey\"}")); + } + if ( bitcoin_pubkeylen(dp->minerkey33) <= 0 ) + { + dp->symbol[0] = 0; + return(clonestr("{\"error\":\"illegal pubkey\"}")); + } + if ( dp->blocks == 0 ) + { + dp->maxblocks = 10000; + dp->blocks = calloc(dp->maxblocks,sizeof(*dp->blocks)); + } + portable_mutex_init(&dp->paxmutex); + portable_mutex_init(&dp->dexmutex); + PAX_init(); + //printf(">>>>>>>>>>>>>>> call paxpending\n"); + //uint8_t buf[32768]; + //dpow_paxpending(buf); + myinfo->numdpows++; + return(clonestr("{\"result\":\"success\"}")); +} + +char *dpow_passthru(struct iguana_info *coin,char *function,char *hex) +{ + char params[32768]; int32_t len = 0; + if ( hex != 0 && hex[0] != 0 ) + { + len = (int32_t)strlen(hex) >> 1; + if ( len < sizeof(params)-1 ) + decode_hex((uint8_t *)params,(int32_t)strlen(hex),hex); + else len = 0; + } + params[len] = 0; + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,function,params)); +} + +TWO_STRINGS(zcash,passthru,function,hex) +{ + if ( (coin= iguana_coinfind("ZEC")) != 0 ) + return(dpow_passthru(coin,function,hex)); + else return(clonestr("{\"error\":\"ZEC not active, start in bitcoind mode\"}")); +} + +TWO_STRINGS(komodo,passthru,function,hex) +{ + if ( (coin= iguana_coinfind("KMD")) != 0 ) + return(dpow_passthru(coin,function,hex)); + else return(clonestr("{\"error\":\"KMD not active, start in bitcoind mode\"}")); +} + +THREE_STRINGS(iguana,passthru,asset,function,hex) +{ + if ( asset != 0 && (coin= iguana_coinfind(asset)) != 0 ) + return(dpow_passthru(coin,function,hex)); + else return(clonestr("{\"error\":\"assetchain not active, start in bitcoind mode\"}")); +} + +TWO_STRINGS(dex,send,hex,handler) +{ + uint8_t data[8192]; int32_t datalen; char *retstr; + if ( hex != 0 && (datalen= is_hexstr(hex,0)) > 0 && (datalen>>1) < sizeof(data) ) + { + datalen >>= 1; + decode_hex(data,datalen,hex); + if ( handler == 0 || handler[0] == 0 ) + handler = "DEX"; + if ( (retstr= dex_reqsend(myinfo,handler,data,datalen,1,"")) == 0 ) + return(clonestr("{\"result\":\"success\"}")); + else return(retstr); + } else return(clonestr("{\"error\":\"dex send: invalid hex\"}")); +} + +STRING_ARG(dpow,pending,fiat) +{ + struct dpow_info *dp; char base[64]; int32_t i; + if ( fiat != 0 && fiat[0] != 0 ) + { + for (i=0; fiat[i]!=0; i++) + base[i] = toupper((int32_t)fiat[i]); + base[i] = 0; + for (i=0; inumdpows; i++) + { + dp = &myinfo->DPOWS[i]; + if ( strcmp(dp->symbol,base) == 0 ) + return(jprint(dpow_withdraws_pending(dp),1)); + } + } + return(clonestr("[]")); +} + +STRING_ARG(dpow,bindaddr,ipaddr) +{ + uint32_t ipbits; char checkbuf[64]; + if ( ipaddr != 0 && ipaddr[0] != 0 ) + { + ipbits = (uint32_t)calc_ipbits(ipaddr); + expand_ipbits(checkbuf,ipbits); + if ( strcmp(ipaddr,checkbuf) == 0 ) + { + strcpy(myinfo->bindaddr,ipaddr); + return(clonestr("{\"result\":\"success\"}")); + } else return(clonestr("{\"error\":\"invalid bind ipaddr\"}")); + } else return(clonestr("{\"error\":\"no bind ipaddr\"}")); +} + +STRING_ARG(iguana,addnotary,ipaddr) +{ + static int32_t didinit; + if ( didinit == 0 ) + { + dpow_addresses(); + didinit = 1; + } + printf("addnotary (%s) -> (%s)\n",ipaddr,myinfo->ipaddr); + dpow_nanomsginit(myinfo,ipaddr); + return(clonestr("{\"result\":\"notary node added\"}")); +} + +char NOTARY_CURRENCIES[][65] = { + "REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "BOTS", "MGW", "COQUI", "WLC", "KV", "CEAL", "MESH", "MNZ", "CHIPS", "MSHARK", "AXO", "ETOMIC", "BTCH", "VOTE2018", "NINJA", "OOT", "CHAIN", "BNTN", "PRLPAY" +}; + +// "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) +{ + FILE *fp; uint64_t signedmask; long fpos,startfpos; int32_t i,height,iter,prevheight; + if ( (fp= fopen(fname,"rb")) != 0 ) + { + printf("opened %s\n",fname); + startfpos = 0; + prevheight = -1; + for (iter=0; iter<2; iter++) + { + while ( 1 ) + { + fpos = ftell(fp); + if (fread(&height,1,sizeof(height),fp) == sizeof(height) && fread(&signedmask,1,sizeof(signedmask),fp) == sizeof(signedmask) ) + { + //printf("%6d %016llx\n",height,(long long)signedmask); + if ( height < prevheight ) + { + startfpos = fpos; + if ( iter == 0 ) + printf("found reversed height %d vs %d\n",height,prevheight); + else printf("fpos.%ld fatal unexpected height reversal %d vs %d\n",fpos,height,prevheight); + } + if ( iter == 1 && (height >= 180000 || strcmp(fname,"signedmasks") != 0) ) + { + for (i=0; i<64; i++) + { + if ( ((1LL << i) & signedmask) != 0 ) + { + totals[i]++; + if ( dispflag > 1 ) + printf("%2d ",i); + } + } + if ( dispflag > 1 ) + printf("height.%d %016llx %s\n",height,(long long)signedmask,fname); + } + prevheight = height; + } else break; + } + if ( iter == 0 ) + { + prevheight = -1; + fseek(fp,startfpos,SEEK_SET); + printf("set startfpos %ld\n",startfpos); + } + } + fclose(fp); + if ( dispflag != 0 ) + { + printf("after %s\n",fname); + for (i=0; i= 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,mdata) > 0 && strcmp(symbol,coin->symbol) == 0 ) + { + // if ( Notaries_port != DPOW_SOCKPORT ) // keep going till valid MoM found, useful for new chains without any MoM + { + if ( bits256_nonz(MoM) == 0 || MoMdepth == 0 || *nothtp >= height || *nothtp < 0 ) + { + *nothtp = 0; + } + } + if ( mdata->pairs != 0 && mdata->numpairs > 0 ) + { + for (j=0; jnumpairs; j++) + { + if ( mdata->pairs[j].notarization_height > coin->MoMoMheight ) + { + coin->MoMoMheight = mdata->pairs[j].notarization_height; + printf("set %s MoMoMheight <- %d\n",coin->symbol,coin->MoMoMheight); + } + } + } + //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,struct komodo_ccdataMoMoM *mdata) +{ + int32_t i,n,hasnotarization = 0; bits256 txid; cJSON *txarray; + *nothtp = 0; + *signedmaskp = 0; + memset(mdata,0,sizeof(*mdata)); + if ( (txarray= jarray(&n,blockjson,"tx")) != 0 ) + { + 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,&mdata) > 0 ) + { + if ( mdata.pairs != 0 ) + free(mdata.pairs); + for (j=0; j<64; j++) + if ( ((1LL << j) & signedmask) != 0 ) + masksums[j]++; + } + free_json(blockjson); + } + } + array = cJSON_CreateArray(); + for (i=0; i current - numblocks ) + { + printf("ht.%d %llx vs current.%d - %d\n",height,(long long)signedmask,current,numblocks); + for (j=0; j<64; j++) + if ( ((1LL << j) & signedmask) != 0 ) + vals[j] += (double)DPOW_UTXOSIZE / SATOSHIDEN; + } + } else break; + } + fclose(fp); + } else return(clonestr("{\"error\":\"cant open signedmasks\"}")); + for (sum=j=0; j 0. ) + { + bitcoin_address(coinaddr,0,pubkeys[j],33); // fixed + sprintf(cmd,"bitcoin-cli sendtoaddress %s %f\n",coinaddr,val); + if ( sendflag != 0 && system(cmd) != 0 ) + printf("ERROR with (%s)\n",cmd); + else + { + printf("%s\n",cmd); + sum += val; + } + } + } + printf("%s sent %.8f BTC\n",sendflag!=0?"":"would have",sum); + return(clonestr("{\"result\":\"success\"}")); + } + else return(clonestr("{\"error\":\"cant find BTC\"}")); + } + for (i=0; iDPOWS[0].lastrecvmask; + for (i=0; i>= 1; + memset(data,0,sizeof(data)); + decode_hex(data,len,maskhex); + for (i=0; iDPOWS[0].cancelratify = 1; + return(clonestr("{\"result\":\"queued dpow cancel ratify\"}")); +} + +TWOINTS_AND_ARRAY(dpow,ratify,minsigs,timestamp,ratified) +{ + void **ptrs; bits256 zero; int32_t i; char *source; struct dpow_checkpoint checkpoint; + if ( ratified == 0 ) + return(clonestr("{\"error\":\"no ratified list for dpow ratify\"}")); + memset(zero.bytes,0,sizeof(zero)); + dpow_checkpointset(myinfo,&checkpoint,0,zero,timestamp,timestamp); + ptrs = calloc(1,sizeof(void *)*5 + sizeof(struct dpow_checkpoint)); + ptrs[0] = (void *)myinfo; + if ( (source= jstr(json,"source")) == 0 ) + source = "KMD"; + ptrs[1] = (void *)&myinfo->DPOWS[0]; + for (i=0; inumdpows; i++) + if ( strcmp(myinfo->DPOWS[0].symbol,source) == 0 ) + { + ptrs[1] = (void *)&myinfo->DPOWS[i]; + break; + } + ptrs[2] = (void *)(long)minsigs; + ptrs[3] = (void *)DPOW_RATIFYDURATION; + ptrs[4] = (void *)jprint(ratified,0); + memcpy(&ptrs[5],&checkpoint,sizeof(checkpoint)); + myinfo->DPOWS[0].cancelratify = 0; + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_statemachinestart,(void *)ptrs) != 0 ) + { + } + return(clonestr("{\"result\":\"started ratification\"}")); +} + +HASH_AND_STRING(dex,gettransaction,txid,symbol) +{ + /*char str[65],url[1024],*retstr; + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && myinfo->blocktrail_apikey[0] != 0 ) + { + sprintf(url,"https://api.blocktrail.com/v1/btc/transaction/%s?api_key=%s",bits256_str(str,txid),myinfo->blocktrail_apikey); + + sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/unspent-outputs?api_key=%s",address,myinfo->blocktrail_apikey); + }*/ + return(_dex_getrawtransaction(myinfo,symbol,txid)); +} + +HASH_AND_STRING_AND_INT(dex,gettxout,txid,symbol,vout) +{ + /*char str[65],url[1024],*retstr; + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && myinfo->blocktrail_apikey[0] != 0 ) + { + sprintf(url,"https://api.blocktrail.com/v1/btc/transaction/%s?api_key=%s",bits256_str(str,txid),myinfo->blocktrail_apikey); + }*/ + return(_dex_gettxout(myinfo,symbol,txid,vout)); +} + +TWO_STRINGS(dex,listunspent,symbol,address) +{ + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && myinfo->blocktrail_apikey[0] != 0 ) + { + char url[1024],*retstr,*coinaddr,*script; int32_t i,n,vout; cJSON *retjson,*data,*item,*item3,*data3; bits256 txid; uint64_t val; + sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/unspent-outputs?api_key=%s",address,myinfo->blocktrail_apikey); + if ( (retstr= issue_curl(url)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + data = jarray(&n,retjson,"data"); + data3 = cJSON_CreateArray(); + //[{"hash":"e0a40dac21103e92e0dc9311a0233640489afc5beb5ba3b009848a8e9151dc55","time":"2017-02-21T16:48:28+0000","confirmations":1,"is_coinbase":false,"value":4100000,"index":1,"address":"19rjYdJtRN3qoammX3r1gxy9bvh8p8DmRc","type":"pubkeyhash","multisig":null,"script":"OP_DUP OP_HASH160 6128e7459989d35d530bcd4066c9aaf1f925430a OP_EQUALVERIFY OP_CHECKSIG","script_hex":"76a9146128e7459989d35d530bcd4066c9aaf1f925430a88ac"}] + /*{ + "txid" : "e95d3083baf733dfda2fcd1110fe2937cb3580f8b1b237aad547528440dfa873", + "vout" : 1, + "address" : "RNgdefRo2iRLWqDXEogJrsTw35MgDPQP4R", + "account" : "", + "scriptPubKey" : "76a91493088c5f3546225e0ef6ba9c9c6a74d4c2df877388ac", + "amount" : 150.00000000, + "interest" : 0.30000000, + "confirmations" : 20599, + "spendable" : true + }*/ + for (i=0; iFULLNODE < 0 ) + return(jprint(dpow_listunspent(myinfo,coin,address),1)); + //printf("call _dex_listunspent\n"); + return(_dex_listunspent(myinfo,symbol,address)); +} + +TWO_STRINGS_AND_TWO_DOUBLES(dex,listtransactions,symbol,address,count,skip) +{ + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && myinfo->blocktrail_apikey[0] != 0 ) + { + char url[1024],*retstr,*retstr2; cJSON *retjson,*retjson2,*retjson3,*data,*data2; int32_t i,n; + sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/transactions?api_key=%s",address,myinfo->blocktrail_apikey); + if ( (retstr= issue_curl(url)) != 0 ) + { + sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/unconfirmed-transactions?api_key=%s",address,myinfo->blocktrail_apikey); + if ( (retstr2= issue_curl(url)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 && (retjson2= cJSON_Parse(retstr2)) != 0 ) + { + data = jarray(&n,retjson,"data"); + data2 = jarray(&n,retjson2,"data"); + retjson3 = jduplicate(data); + if ( n > 0 ) + { + for (i=0; i (%s)\n",retstr,retstr2,jprint(retjson3,0)); + free(retstr); + free(retstr2); + free_json(retjson); + free_json(retjson2); + return(jprint(retjson3,1)); + } + } + } + } + return(_dex_listtransactions(myinfo,symbol,address,count,skip)); +} + +STRING_ARG(dex,getinfo,symbol) +{ + return(_dex_getinfo(myinfo,symbol)); +} + +STRING_ARG(dex,getbestblockhash,symbol) +{ + return(_dex_getbestblockhash(myinfo,symbol)); +} + +STRING_ARG(dex,alladdresses,symbol) +{ + return(_dex_alladdresses(myinfo,symbol)); +} + +STRING_AND_INT(dex,getblockhash,symbol,height) +{ + return(_dex_getblockhash(myinfo,symbol,height)); +} + +HASH_AND_STRING(dex,getblock,hash,symbol) +{ + return(_dex_getblock(myinfo,symbol,hash)); +} + +TWO_STRINGS(dex,sendrawtransaction,symbol,signedtx) +{ + return(_dex_sendrawtransaction(myinfo,symbol,signedtx)); +} + +TWO_STRINGS(dex,importaddress,symbol,address) +{ + return(_dex_importaddress(myinfo,symbol,address)); +} + +TWO_STRINGS(dex,checkaddress,symbol,address) +{ + return(_dex_checkaddress(myinfo,symbol,address)); +} + +TWO_STRINGS(dex,validateaddress,symbol,address) +{ + return(_dex_validateaddress(myinfo,symbol,address)); +} + +STRING_ARG(dex,getmessage,argstr) +{ + return(_dex_getmessage(myinfo,argstr)); +} + +STRING_ARG(dex,psock,argstr) +{ + return(_dex_psock(myinfo,argstr)); +} + +STRING_ARG(dex,getnotaries,symbol) +{ + return(clonestr("{\"error\":\"dexgetnotaries deprecated\"}")); + //return(_dex_getnotaries(myinfo,symbol)); +} + +TWO_STRINGS(dex,kvsearch,symbol,key) +{ + if ( key == 0 || key[0] == 0 ) + return(clonestr("{\"error\":\"kvsearch parameter error\"}")); + return(_dex_kvsearch(myinfo,symbol,key)); +} + +THREE_STRINGS_AND_THREE_INTS(dex,kvupdate,symbol,key,value,flags,unused,unusedb) +{ + // need to have some micropayments between client/server, otherwise receiving server incurs costs + if ( key == 0 || key[0] == 0 || value == 0 || value[0] == 0 ) + return(clonestr("{\"error\":\"kvupdate parameter error\"}")); + if ( strcmp(symbol,"KV") == 0 ) + { + if ( flags > 1 ) + return(clonestr("{\"error\":\"only single duration updates via remote access\"}")); + else if ( strlen(key) > 64 || strlen(value) > 256 ) + return(clonestr("{\"error\":\"only keylen <=64 and valuesize <= 256 allowed via remote access\"}")); + else + { + //printf("call _dex_kvupdate.(%s) -> (%s) flags.%d\n",key,value,flags); + return(_dex_kvupdate(myinfo,symbol,key,value,flags)); + } + } else return(clonestr("{\"error\":\"free updates only on KV chain\"}")); +} + +#include "kmd_lookup.h" + +TWO_STRINGS(dex,listunspent2,symbol,address) +{ + cJSON *retjson; + if ( myinfo->DEXEXPLORER != 0 ) + { + if ( symbol != 0 && address != 0 && (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( coin != 0 ) + coin->DEXEXPLORER = myinfo->DEXEXPLORER * myinfo->IAMNOTARY * (iguana_isnotarychain(coin->symbol) >= 0); + if ( strcmp(coin->symbol,"BTC") == 0 || coin->DEXEXPLORER == 0 ) + return(clonestr("[]")); + if ( (retjson= kmd_listunspent(myinfo,coin,address)) != 0 ) + return(jprint(retjson,1)); + } + } + if ( symbol != 0 && address != 0 ) + return(_dex_listunspent2(myinfo,symbol,address)); + else return(clonestr("{\"error\":\"dex listunspent2 null symbol, address or coin\"}")); +} + +TWO_STRINGS_AND_TWO_DOUBLES(dex,listtransactions2,symbol,address,count,skip) +{ + cJSON *retjson; + if ( myinfo->DEXEXPLORER != 0 ) + { + if ( symbol != 0 && address != 0 && (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( coin != 0 ) + coin->DEXEXPLORER = myinfo->DEXEXPLORER * myinfo->IAMNOTARY * (iguana_isnotarychain(coin->symbol) >= 0); + if ( strcmp(coin->symbol,"BTC") == 0 || coin->DEXEXPLORER == 0 ) + return(clonestr("[]")); + if ( (retjson= kmd_listtransactions(myinfo,coin,address,count,skip)) != 0 ) + return(jprint(retjson,1)); + } + } + if ( symbol != 0 && address != 0 ) + return(_dex_listtransactions2(myinfo,symbol,address,count,skip)); + else return(clonestr("{\"error\":\"dex listunspent2 null symbol, address or coin\"}")); +} + +HASH_AND_STRING_AND_INT(dex,gettxin,txid,symbol,vout) +{ + if ( myinfo->DEXEXPLORER != 0 ) + { + if ( symbol != 0 && (coin= iguana_coinfind(symbol)) != 0 && coin->DEXEXPLORER != 0 ) + return(jprint(kmd_gettxin(coin,txid,vout),1)); + if ( coin != 0 ) + coin->DEXEXPLORER = myinfo->DEXEXPLORER * myinfo->IAMNOTARY * (iguana_isnotarychain(coin->symbol) >= 0); + } + if ( symbol != 0 ) + return(_dex_gettxin(myinfo,symbol,txid,vout)); + else return(clonestr("{\"error\":\"dex gettxin null symbolor coin\"}")); +} + +TWO_STRINGS(dex,listspent,symbol,address) +{ + if ( myinfo->DEXEXPLORER != 0 ) + { + if ( symbol != 0 && address != 0 && (coin= iguana_coinfind(symbol)) != 0 && coin->DEXEXPLORER != 0 ) + return(jprint(kmd_listspent(myinfo,coin,address),1)); + if ( coin != 0 ) + coin->DEXEXPLORER = myinfo->DEXEXPLORER * myinfo->IAMNOTARY * (iguana_isnotarychain(coin->symbol) >= 0); + } + if ( symbol != 0 && address != 0 ) + return(_dex_listspent(myinfo,symbol,address)); + else return(clonestr("{\"error\":\"dex listspent null symbol, address or coin\"}")); +} + +TWO_STRINGS(dex,getbalance,symbol,address) +{ + char url[512],*retstr; cJSON *retjson; uint64_t val; + if ( myinfo->DEXEXPLORER != 0 ) + { + //printf("DEXEXPLORER\n"); + if ( symbol != 0 && address != 0 && (coin= iguana_coinfind(symbol)) != 0 && coin->DEXEXPLORER != 0 ) + return(jprint(kmd_getbalance(myinfo,coin,address),1)); + if ( coin != 0 ) + coin->DEXEXPLORER = myinfo->DEXEXPLORER * myinfo->IAMNOTARY * (iguana_isnotarychain(coin->symbol) >= 0); + } + if ( symbol != 0 && address != 0 ) + { + if ( strcmp(symbol,"BTC") == 0 && myinfo->blocktrail_apikey[0] != 0 ) + { + sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s?api_key=%s",address,myinfo->blocktrail_apikey); + if ( (retstr= issue_curl(url)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + //printf("balance\n"); + if ( (val= j64bits(retjson,"balance")) != 0 ) + { + jdelete(retjson,"balance"); + jaddnum(retjson,"balance",dstr(val)); + } + //printf("sent\n"); + if ( (val= j64bits(retjson,"sent")) != 0 ) + { + jdelete(retjson,"sent"); + jaddnum(retjson,"sent",dstr(val)); + } + //printf("received\n"); + if ( (val= j64bits(retjson,"received")) != 0 ) + { + jdelete(retjson,"received"); + jaddnum(retjson,"received",dstr(val)); + } + //printf("unconfirmed_sent\n"); + if ( (val= j64bits(retjson,"unconfirmed_sent")) != 0 ) + { + jdelete(retjson,"unconfirmed_sent"); + jaddnum(retjson,"unconfirmed_sent",dstr(val)); + } + //printf("unconfirmed_received\n"); + if ( (val= j64bits(retjson,"unconfirmed_received")) != 0 ) + { + jdelete(retjson,"unconfirmed_received"); + jaddnum(retjson,"unconfirmed_received",dstr(val)); + } + //printf("blocktrail.(%s) -> (%s)\n",retstr,jprint(retjson,0)); + free(retstr); + retstr = jprint(retjson,1); + } + } + return(retstr); + } + return(_dex_getbalance(myinfo,symbol,address)); + } else return(clonestr("{\"error\":\"dex getbalance null symbol, address or coin\"}")); +} + +STRING_ARG(dex,explorer,symbol) +{ + if ( symbol != 0 && (coin= iguana_coinfind(symbol)) != 0 ) + { + myinfo->DEXEXPLORER = 1; + coin->DEXEXPLORER = 1; + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"coin not active\"}")); +} + +#include "../includes/iguana_apiundefs.h" 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.c b/gecko/gecko.c index f8bdaeea3..a825ee9ef 100755 --- a/gecko/gecko.c +++ b/gecko/gecko.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * 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/SuperNET_keys.c b/iguana/SuperNET_keys.c index 31cbe6869..8c4de8da8 100755 --- a/iguana/SuperNET_keys.c +++ b/iguana/SuperNET_keys.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -310,13 +310,70 @@ int32_t _SuperNET_encryptjson(struct supernet_info *myinfo,char *destfname,char return(0); } +int32_t curve25519_donna(uint8_t *mypublic,const uint8_t *secret,const uint8_t *basepoint); + +static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + +int32_t iguana_wifstr_valid(char *wifstr) +{ + bits256 privkey,cmpkey; uint8_t wiftype; char cmpstr[128],cmpstr2[128]; int32_t i,len,n,a,A; + if ( (len= (int32_t)strlen(wifstr)) < 50 || len > 54 ) + { + //printf("len.%d is wrong for wif %s\n",len,wifstr); + return(0); + } + memset(privkey.bytes,0,sizeof(privkey)); + memset(cmpkey.bytes,0,sizeof(cmpkey)); + for (i=n=a=A=0; wifstr[i]!=0; i++) + { + if ( strchr(base58_chars,wifstr[i]) == 0 ) + return(0); + if ( wifstr[i] >= '1' && wifstr[i] <= '9' ) + n++; + else if ( wifstr[i] >= 'A' && wifstr[i] <= 'Z' ) + A++; + else if ( wifstr[i] >= 'a' && wifstr[i] <= 'z' ) + a++; + } + if ( n == 0 || A == 0 || a == 0 ) + return(0); + if ( A > 5*a || a > 5*A || a > n*20 || A > n*20 ) // unlikely it is a real wif + { + //printf("reject wif %s due to n.%d a.%d A.%d (%d %d %d %d)\n",wifstr,n,a,A,A > 5*a,a < 5*A,a > n*20,A > n*20); + return(0); + } + bitcoin_wif2priv(&wiftype,&privkey,wifstr); + bitcoin_priv2wif(cmpstr,privkey,wiftype); + if ( strcmp(cmpstr,wifstr) == 0 ) + { + //printf("%s is valid wif\n",wifstr); + return(1); + } + else if ( bits256_nonz(privkey) != 0 ) + { + bitcoin_wif2priv(&wiftype,&cmpkey,cmpstr); + bitcoin_priv2wiflong(cmpstr2,privkey,wiftype); + if ( bits256_cmp(privkey,cmpkey) == 0 ) + return(1); + // char str[65],str2[65]; printf("mismatched wifstr %s -> %s -> %s %s %s\n",wifstr,bits256_str(str,privkey),cmpstr,bits256_str(str2,cmpkey),cmpstr2); + } + //char str[65]; printf("%s is not a wif, privkey.%s\n",wifstr,bits256_str(str,privkey)); + return(0); +} + void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256) { - bits256 hash; + static uint8_t basepoint[32] = {9}; bits256 hash; uint8_t addrtype,usedwif = 0; if ( dosha256 != 0 ) { memcpy(myinfo->secret,pass,passlen+1); - myinfo->myaddr.nxt64bits = conv_NXTpassword(myinfo->persistent_priv.bytes,myinfo->myaddr.persistent.bytes,pass,passlen); + if ( iguana_wifstr_valid((char *)pass) > 0 ) + { + usedwif = 1; + bitcoin_wif2priv(&addrtype,&myinfo->persistent_priv,(char *)pass); + curve25519_donna(myinfo->myaddr.persistent.bytes,myinfo->persistent_priv.bytes,basepoint); + } + else myinfo->myaddr.nxt64bits = conv_NXTpassword(myinfo->persistent_priv.bytes,myinfo->myaddr.persistent.bytes,pass,passlen); } else { @@ -329,6 +386,8 @@ void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,in bitcoin_pubkey33(myinfo->ctx,myinfo->persistent_pubkey33,myinfo->persistent_priv); bitcoin_address(myinfo->myaddr.BTC,0,myinfo->persistent_pubkey33,33); bitcoin_address(myinfo->myaddr.BTCD,60,myinfo->persistent_pubkey33,33); + if ( (0) && usedwif != 0 ) + printf("usedwif for %s %s\n",myinfo->myaddr.BTCD,myinfo->myaddr.BTC); } void SuperNET_parsemyinfo(struct supernet_info *myinfo,cJSON *msgjson) diff --git a/iguana/acsplit b/iguana/acsplit new file mode 100755 index 000000000..d5e0561d1 --- /dev/null +++ b/iguana/acsplit @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\""${1}"\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"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/client b/iguana/client new file mode 100755 index 000000000..93673afdd --- /dev/null +++ b/iguana/client @@ -0,0 +1,23 @@ +source randval +pkill -15 marketmaker; +git pull; +./m_mm; +#./m_mmosx; +./marketmaker "{\"client\":1,\"coins\":[{\"coin\":\"REVS\",\"active\":1, \"asset\":\"REVS\",\"rpcport\":10196},{\"coin\":\"JUMBLR\",\"active\":1, \"asset\":\"JUMBLR\",\"rpcport\":15106}, +{\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, +{\"coin\":\"DOGE\", \"name\":\"dogecoin\", \"pubtype\":30, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000000}, +{\"coin\":\"DGB\", \"name\":\"digibyte\", \"pubtype\":30, \"p2shtype\":5, \"wiftype\":128, \"txfee\":10000}, +{\"coin\":\"MZC\", \"name\":\"mazacoin\", \"pubtype\":50, \"p2shtype\":9, \"wiftype\":224, \"txfee\":0}, +{\"coin\":\"SYS\", \"name\":\"syscoin\", \"pubtype\":0, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000}, +{\"coin\":\"UNO\", \"name\":\"unobtanium\", \"pubtype\":130, \"p2shtype\":30, \"wiftype\":224, \"txfee\":1000000}, +{\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9, \"wiftype\":224, \"txfee\":10000}, +{\"coin\":\"ZEC\", \"name\":\"zcash\", \"pubtype\":184, \"p2shtype\":189, \"wiftype\":128, \"txfee\":10000}, +{\"coin\":\"BTM\", \"name\":\"bitmark\", \"pubtype\":85, \"p2shtype\":5, \"wiftype\":213, \"txfee\":0}, +{\"coin\":\"CARB\", \"name\":\"carboncoin\", \"pubtype\":47, \"p2shtype\":5, \"wiftype\":175, \"txfee\":0}, +{\"coin\":\"ANC\", \"name\":\"anoncoin\", \"pubtype\":23, \"p2shtype\":5, \"wiftype\":151, \"txfee\":2000000}, +{\"coin\":\"FRK\", \"name\":\"franko\", \"pubtype\":35, \"p2shtype\":5, \"wiftype\":163, \"txfee\":0}, +{\"coin\":\"GAME\", \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, +{\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, +{\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341},{\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167},{\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068},{\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890},{\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250},{\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516},{\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431},{\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114},{\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964},{\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386},{\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276},{\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":9747},{\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116},{\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455} +], \"userhome\":\"/${HOME#"/"}\",\"passphrase\":\"$randval\"}" & + diff --git a/iguana/coins/beer_7776 b/iguana/coins/beer_7776 new file mode 100755 index 000000000..7a603f360 --- /dev/null +++ b/iguana/coins/beer_7776 @@ -0,0 +1,2 @@ +#!/bin/bash +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\"}" diff --git a/iguana/coins/bntn_7776 b/iguana/coins/bntn_7776 new file mode 100755 index 000000000..73be9c02d --- /dev/null +++ b/iguana/coins/bntn_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"BNTN.conf\",\"path\":\"${HOME#"/"}/.komodo/BNTN\",\"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\":\"BNTN\",\"name\":\"BNTN\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"9918328e\",\"p2p\":14357,\"rpc\":14358,\"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/chain_7776 b/iguana/coins/chain_7776 new file mode 100755 index 000000000..7a0e5dec1 --- /dev/null +++ b/iguana/coins/chain_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"CHAIN.conf\",\"path\":\"${HOME#"/"}/.komodo/CHAIN\",\"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\":\"CHAIN\",\"name\":\"CHAIN\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"568ea9e0\",\"p2p\":15586,\"rpc\":15587,\"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/game_7776 b/iguana/coins/game_7776 new file mode 100755 index 000000000..655fae616 --- /dev/null +++ b/iguana/coins/game_7776 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7776" --data "{\"txfee\":0.01,\"conf\":\"gamecredits.conf\",\"path\":\"${HOME#"/"}/.gamecredits\",\"startpend\":8,\"endpend\":4,\"services\":129,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"GAME\",\"name\":\"gamecredits\",\"netmagic\":\"fbc0b6db\",\"p2p\":40002,\"rpc\":40001,\"pubval\":38,\"p2shval\":5,\"wifval\":166,\"txfee_satoshis\":\"1000000\",\"minconfirms\":2,\"genesishash\":\"91ec5f25ee9a0ffa1af7d4da4db9a552228dd2dc77cdb15b738be4e1f55f30ee\",\"genesis\":{\"hashalgo\":\"scrypt\",\"version\":1,\"timestamp\":1392757140,\"nBits\":\"1e0ffff0\",\"nonce\":2084565393,\"merkle_root\":\"d849db99a14164f4b4c8ad6d2d8d7e2b1ba7f89963e9f4bf9fad5ff1a4754429\"},\"alertpubkey\":\"04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284\",\"auxpow\":1,\"protover\":80006,\"isPoS\":0,\"fixit\":0}" 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/pizza_7776 b/iguana/coins/pizza_7776 new file mode 100755 index 000000000..baaf702fb --- /dev/null +++ b/iguana/coins/pizza_7776 @@ -0,0 +1,2 @@ +#!/bin/bash +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\"}" diff --git a/iguana/coins/prlpay_7776 b/iguana/coins/prlpay_7776 new file mode 100755 index 000000000..db7447d1f --- /dev/null +++ b/iguana/coins/prlpay_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"PRLPAY.conf\",\"path\":\"${HOME#"/"}/.komodo/PRLPAY\",\"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\":\"PRLPAY\",\"name\":\"PRLPAY\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"c58af861\",\"p2p\":9678,\"rpc\":9679,\"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..11a4fd1fa 100755 --- a/iguana/dPoW.h +++ b/iguana/dPoW.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,17 +16,20 @@ #ifndef INCLUDE_DPOW_H #define INCLUDE_DPOW_H +//#define DPOW_MAXMOMDEPTH (1440 * 7) + #define DPOW_FIRSTRATIFY 1000 +#define DPOW_MAXFREQ 100 #define DPOW_CHECKPOINTFREQ 10 #define DPOW_MINSIGS 13 #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_UTXOSIZE 50000 +#define DPOW_VERSION 0x1782 +#define DPOW_UTXOSIZE 10000//50000 #define DPOW_MINOUTPUT 6000 -#define DPOW_DURATION 600 +#define DPOW_DURATION 1200 #define DPOW_RATIFYDURATION (3600 * 24) //#define DPOW_ENTRIESCHANNEL ('e' | ('n' << 8) | ('t' << 16) | ('r' << 24)) @@ -46,8 +49,8 @@ #define DPOW_MAXRELAYS 64 #define DPOW_MAXSIGLEN 128 -#define DEX_VERSION 0x0105 -#define DPOW_SOCK 7775 +#define DEX_VERSION 0x0106 +#define DPOW_SOCKPORT 7775 #define DEX_SOCK 7774 #define PUB_SOCK 7773 #define REP_SOCK 7772 @@ -102,16 +105,19 @@ struct dpow_checkpoint bits256 miner; uint32_t blocktime,timestamp; }; +struct dpow_recvdata { uint64_t recvmask,bestmask; int8_t bestk; }; + 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_recvdata recv[64]; 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,lastnanosend; int32_t rawratifiedlens[2],height,numnotaries,numerrors,completed,minsigs,duration,numratified,isratify,require0,scores[DPOW_MAXRELAYS]; - int8_t myind,bestk,ratifybestk,pendingbestk,pendingratifybestk; + int8_t myind,bestk,ratifybestk,pendingbestk,pendingratifybestk,matches,bestmatches; cJSON *ratified; uint8_t ratified_pubkeys[DPOW_MAXRELAYS][33],ratifysigs[2][DPOW_MAXSIGLEN],ratifysiglens[2]; char handles[DPOW_MAXRELAYS][32]; @@ -135,21 +141,31 @@ struct dpow_info struct dpow_hashheight approved[DPOW_FIFOSIZE],notarized[DPOW_FIFOSIZE]; bits256 activehash,lastnotarized,srctx[DPOW_MAXTX],desttx[DPOW_MAXTX]; uint32_t SRCREALTIME,lastsrcupdate,destupdated,srcconfirms,numdesttx,numsrctx,lastsplit,cancelratify; - int32_t lastheight,maxblocks,SRCHEIGHT,SHORTFLAG,ratifying; + int32_t lastheight,maxblocks,SRCHEIGHT,DESTHEIGHT,prevDESTHEIGHT,SHORTFLAG,ratifying,minsigs,freq; struct pax_transaction *PAX; portable_mutex_t paxmutex,dexmutex; uint32_t ipbits[128],numipbits; - struct dpow_block **blocks; + struct dpow_block **blocks,*currentbp; }; + +struct komodo_ccdatapair { int32_t notarization_height; uint32_t MoMoMoffset; }; + +struct komodo_ccdataMoMoM +{ + bits256 MoMoM; + int32_t kmdstarti,kmdendi,MoMoMdepth,numpairs,len; + struct komodo_ccdatapair *pairs; +}; + 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,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,int32_t src_or_dest,struct dpow_block *bp); void dex_updateclient(struct supernet_info *myinfo); char *dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *data,int32_t datalen,int32_t M,char *field); char *basilisk_respond_addmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen,uint8_t *data,int32_t datalen,int32_t sendping,uint32_t duration); -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..66fab06f8 100755 --- a/iguana/dpow/dpow_fsm.c +++ b/iguana/dpow/dpow_fsm.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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,111 @@ 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,struct komodo_ccdataMoMoM + *mdata) +{ + 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)); + memset(mdata,0,sizeof(*mdata)); + 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 ) + { + uint32_t CCid,k; + offset += iguana_rwbignum(0,&opret[offset],sizeof(*MoMp),MoMp->bytes); + offset += iguana_rwnum(0,&opret[offset],sizeof(*MoMdepthp),(uint32_t *)MoMdepthp); + // MoMoM, depth, numpairs, (notarization ht, MoMoM offset) + if ( offset+52 <= opretlen ) + { + offset += iguana_rwnum(0,&opret[offset],sizeof(CCid),(uint8_t *)&CCid); + offset += iguana_rwnum(0,&opret[offset],sizeof(uint32_t),(uint8_t *)&mdata->kmdstarti); + offset += iguana_rwnum(0,&opret[offset],sizeof(uint32_t),(uint8_t *)&mdata->kmdendi); + offset += iguana_rwbignum(0,&opret[offset],sizeof(mdata->MoMoM),(uint8_t *)&mdata->MoMoM); + offset += iguana_rwnum(0,&opret[offset],sizeof(uint32_t),(uint8_t *)&mdata->MoMoMdepth); + offset += iguana_rwnum(0,&opret[offset],sizeof(uint32_t),(uint8_t *)&mdata->numpairs); + mdata->len += sizeof(mdata->MoMoM) + sizeof(uint32_t)*4; + if ( offset+mdata->numpairs*8 == opretlen ) + { + mdata->pairs = (struct komodo_ccdatapair *)calloc(mdata->numpairs,sizeof(*mdata->pairs)); + for (k=0; knumpairs; k++) + { + offset += iguana_rwnum(0,&opret[offset],sizeof(int32_t),(uint8_t *)&mdata->pairs[k].notarization_height); + offset += iguana_rwnum(0,&opret[offset],sizeof(uint32_t),(uint8_t *)&mdata->pairs[k].MoMoMoffset); + mdata->len += sizeof(uint32_t) * 2; + } + } else if ( mdata->numpairs > 0 ) + printf("offset.%d + %d*8 != opretlen.%d\n",offset,mdata->numpairs,opretlen); + } + } + } + return(-1); +} + +bits256 dpow_calcMoM(uint32_t *MoMdepthp,struct supernet_info *myinfo,struct iguana_info *coin,int32_t height) +{ + bits256 MoM; cJSON *MoMjson,*infojson; int32_t prevMoMheight; + *MoMdepthp = 0; + memset(MoM.bytes,0,sizeof(MoM)); + if ( (infojson= dpow_getinfo(myinfo,coin)) != 0 ) + { + if ( (prevMoMheight= jint(infojson,"prevMoMheight")) >= 0 ) + { + if ( prevMoMheight == 0 ) + prevMoMheight = 1; + *MoMdepthp = (height - prevMoMheight); + //printf("%s ht.%d prevMoM.%d -> depth %d\n",coin->symbol,height,prevMoMheight,*MoMdepthp); + if ( *MoMdepthp > 1440*30 ) + *MoMdepthp = 1440*30; + if ( *MoMdepthp > 0 && (MoMjson= issue_calcMoM(coin,height,*MoMdepthp)) != 0 ) + { + MoM = jbits256(MoMjson,"MoM"); + free_json(MoMjson); + } + } + free_json(infojson); + } + if ( bits256_nonz(MoM) == 0 ) + *MoMdepthp = 0; + 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,src_or_dest,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,25 +276,37 @@ 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; + memset(&MoM,0,sizeof(MoM)); if ( strcmp(src->symbol,"KMD") == 0 ) kmdheight = checkpoint.blockhash.height; else if ( strcmp(dest->symbol,"KMD") == 0 ) + { + MoM = dpow_calcMoM(&MoMdepth,myinfo,src,checkpoint.blockhash.height); kmdheight = dest->longestchain; + } 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; bp->destcoin = dest; bp->myind = -1; + for (i=0; inotaries)/sizeof(*bp->notaries); i++) + bp->notaries[i].bestk = -1; bp->opret_symbol = dp->symbol; if ( jsonstr != 0 && (ratified= cJSON_Parse(jsonstr)) != 0 ) { @@ -200,6 +316,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; + bp->pendingbestk = bp->bestk = -1; dp->blocks[checkpoint.blockhash.height] = bp; + dp->currentbp = 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 ) { @@ -299,9 +408,9 @@ void dpow_statemachinestart(void *ptr) { myind = i; ep = &bp->notaries[myind]; - for (j=0; j<33; j++) - printf("%02x",dp->minerkey33[j]); - printf(" MYIND.%d <<<<<<<<<<<<<<<<<<<<<<\n",myind); + //for (j=0; j<33; j++) + // printf("%02x",dp->minerkey33[j]); + //printf(" MYIND.%d <<<<<<<<<<<<<<<<<<<<<<\n",myind); } } if ( strcmp("KMD",src->symbol) == 0 ) @@ -314,9 +423,10 @@ void dpow_statemachinestart(void *ptr) printf(" statemachinestart this node %s %s is not official notary numnotaries.%d kmdht.%d bpht.%d\n",srcaddr,destaddr,bp->numnotaries,kmdheight,bp->height); free(ptr); dp->ratifying -= bp->isratify; + exit(-1); return; } - printf("myind.%d\n",myind); + //printf("myind.%d\n",myind); } else { @@ -326,7 +436,7 @@ void dpow_statemachinestart(void *ptr) return; } bp->myind = myind; - printf("[%d] notarize %s->%s %s ht.%d minsigs.%d duration.%d start.%u\n",bp->myind,dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height,minsigs,duration,checkpoint.timestamp); + printf("[%d] notarize %s->%s %s ht.%d minsigs.%d duration.%d start.%u MoM[%d] %s\n",bp->myind,dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height,minsigs,duration,checkpoint.timestamp,bp->MoMdepth,bits256_str(str2,bp->MoM)); if ( bp->isratify != 0 && memcmp(bp->notaries[0].pubkey,bp->ratified_pubkeys[0],33) != 0 ) { for (i=0; i<33; i++) @@ -336,6 +446,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 +464,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 ) @@ -375,6 +486,13 @@ void dpow_statemachinestart(void *ptr) bp->notaries[myind].ratifydestvout = ep->dest.prev_vout; } } + /*if ( strcmp(dp->symbol,"CHIPS") == 0 && myind == 0 ) + { + char str[65]; + printf(">>>>>>> CHIPS myind.%d %s/v%d\n",myind,bits256_str(str,bp->notaries[myind].src.prev_hash),bp->notaries[myind].src.prev_vout); + bp->desttxid = bp->notaries[myind].src.prev_hash; + dpow_signedtxgen(myinfo,dp,src,bp,bp->myind,1LL<myind,bp->myind,DPOW_SIGCHANNEL,0,0); + }*/ bp->recvmask |= (1LL << myind); bp->notaries[myind].othermask |= (1LL << myind); dp->checkpoint = checkpoint; @@ -384,10 +502,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 ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) //(checkpoint.blockhash.height % 100) != 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); dp->ratifying -= bp->isratify; + free(ptr); return; } sleep(1); @@ -395,12 +514,14 @@ void dpow_statemachinestart(void *ptr) starttime = (uint32_t)time(NULL); if ( bp->isratify == 0 ) { - //if ( (starttime= checkpoint.timestamp) == 0 ) - bp->starttime = starttime; - extralen = dpow_paxpending(extras,&bp->paxwdcrc); + bp->starttime = starttime; + if ( strcmp(bp->destcoin->symbol,"KMD") == 0 ) + src_or_dest = 0; + else src_or_dest = 1; + extralen = dpow_paxpending(extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp); 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)); + printf("PAXWDCRC.%x myind.%d isratify.%d DPOW.%s statemachine checkpoint.%d %s start.%u+dur.%d vs %ld MoM[%d] %s\n",bp->paxwdcrc,bp->myind,bp->isratify,src->symbol,checkpoint.blockhash.height,bits256_str(str,checkpoint.blockhash.hash),starttime,bp->duration,time(NULL),bp->MoMdepth,bits256_str(str2,bp->MoM)); for (i=0; iminerkey33[i+1]; //printf("start utxosync start.%u %u\n",starttime,(uint32_t)time(NULL)); @@ -410,20 +531,22 @@ void dpow_statemachinestart(void *ptr) { if ( bp->isratify == 0 ) { - if ( myinfo->DPOWS[0].ratifying != 0 ) + if ( myinfo->DPOWS[0]->ratifying != 0 ) { printf("break due to already ratifying\n"); break; } - extralen = dpow_paxpending(extras,&bp->paxwdcrc); + if ( strcmp(bp->destcoin->symbol,"KMD") == 0 ) + src_or_dest = 0; + else src_or_dest = 1; + extralen = dpow_paxpending(extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp); bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc; } - sleep(13); - if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) + if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) //(checkpoint.blockhash.height % 100) != 0 && { 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 +563,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 +581,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..dcbe6688b 100755 --- a/iguana/dpow/dpow_network.c +++ b/iguana/dpow/dpow_network.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -13,6 +13,11 @@ * * ******************************************************************************/ +extern uint16_t Notaries_port; +extern int32_t Notaries_numseeds; +extern char *Notaries_seeds[]; +extern char *Notaries_elected[65][2]; + struct signed_nnpacket { uint8_t sig64[64]; @@ -24,14 +29,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 +46,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; @@ -76,10 +81,22 @@ int32_t signed_nn_send(struct supernet_info *myinfo,void *ctx,bits256 privkey,in //printf(" signed pubkey\n"); if ( memcmp(pubkey33,signpubkey33,33) == 0 ) { - sentbytes = nn_send(sock,sigpacket,size + sizeof(*sigpacket),0); + sentbytes = 0; + for (j=0; j<100; j++) + { + struct nn_pollfd pfd; + pfd.fd = sock; + pfd.events = NN_POLLOUT; + if ( nn_poll(&pfd,1,10) > 0 ) + { + sentbytes = nn_send(sock,sigpacket,size + sizeof(*sigpacket),0); + break; + } + usleep(1000); + } //for (i=0; inumnotaries = 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]); @@ -1014,7 +1031,7 @@ char *_dex_getnotaries(struct supernet_info *myinfo,char *symbol) } } return(retstr); -} +}*/ char *_dex_alladdresses(struct supernet_info *myinfo,char *symbol) { @@ -1292,7 +1309,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 +1332,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 +1355,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 +1370,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 +1440,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; @@ -1444,13 +1462,34 @@ void dpow_nanomsginit(struct supernet_info *myinfo,char *ipaddr) dpow_addnotary(myinfo,0,ipaddr); } -void dpow_bestconsensus(struct dpow_block *bp) +void dpow_bestconsensus(struct dpow_info *dp,struct dpow_block *bp) { - int8_t bestks[64]; int32_t counts[64],i,j,numcrcs=0,numdiff,besti,best,bestmatches = 0,matches = 0; uint64_t masks[64],matchesmask,recvmask; uint32_t crcval=0; char srcaddr[64],destaddr[64]; + int8_t bestks[64]; uint32_t sortbuf[64],wts[64],owts[64],counts[64]; int32_t i,j,median,numcrcs=0,numdiff,besti,bestmatches = 0,matches = 0; uint64_t masks[64],matchesmask,recvmask,topmask; uint32_t crcval=0; char srcaddr[64],destaddr[64]; + memset(wts,0,sizeof(wts)); + memset(owts,0,sizeof(owts)); + for (i=0; inumnotaries; i++) + { + recvmask = bp->notaries[i].recvmask; + wts[i] = bitweight(recvmask); + for (j=0; jnumnotaries; j++) + if ( ((1LL << j) & recvmask) != 0 ) + owts[j]++; + } + topmask = 0xffffffffffffffffLL; + recvmask = 0; + for (i=0; inumnotaries; i++) + sortbuf[i] = (wts[i] * owts[i]); + revsort32(sortbuf,bp->numnotaries,sizeof(*sortbuf)); + median = sortbuf[bp->numnotaries / 2]; + if ( ((bp->height / dp->freq) % 10) == 0 ) + { + for (i=0; inumnotaries; i++) + if ( wts[i]*owts[i] < median ) + topmask &= ~(1LL << i); + } memset(masks,0,sizeof(masks)); memset(bestks,0xff,sizeof(bestks)); memset(counts,0,sizeof(counts)); - recvmask = 0; for (numdiff=i=0; inumnotaries; i++) { if ( bits256_nonz(bp->notaries[i].src.prev_hash) != 0 && bits256_nonz(bp->notaries[i].dest.prev_hash) != 0 ) @@ -1460,7 +1499,7 @@ void dpow_bestconsensus(struct dpow_block *bp) //if ( bp->require0 != 0 && (bp->notaries[i].bestmask & 1) == 0 ) // continue; for (j=0; jnotaries[i].bestk == bestks[j] && bp->notaries[i].bestmask == masks[j] ) + if ( bp->notaries[i].bestk == bestks[j] && bp->notaries[i].bestmask == masks[j] && bitweight(bp->notaries[i].bestmask) == bp->minsigs ) { counts[j]++; break; @@ -1474,27 +1513,46 @@ void dpow_bestconsensus(struct dpow_block *bp) numdiff++; } } - besti = -1, best = 0; + besti = -1, matches = 0; for (i=0; i best && bitweight(masks[i]) >= bp->minsigs ) + if ( counts[i] > matches && bitweight(masks[i]) == bp->minsigs ) { - best = counts[i]; + matches = counts[i]; besti = i; } } - if ( besti >= 0 && bestks[besti] >= 0 && masks[besti] != 0 && (recvmask & masks[besti]) == masks[besti] ) + for (i=0; inumnotaries; i++) + { + if ( ((1LL << i) & masks[besti]) != 0 ) + { + if ( bp->notaries[i].bestmask == masks[besti] ) + bestmatches++; + } + } + if ( (bestmatches > bp->bestmatches || (bestmatches == bp->bestmatches && matches > bp->matches)) && besti >= 0 && bestks[besti] >= 0 && masks[besti] != 0 && (recvmask & masks[besti]) == masks[besti] ) { + bp->matches = matches; + bp->bestmatches = bestmatches; bp->notaries[bp->myind].bestmask = bp->bestmask = masks[besti]; bp->notaries[bp->myind].bestk = bp->bestk = bestks[besti]; - //printf("set best.%d to (%d %llx) recv.%llx\n",best,bp->bestk,(long long)bp->bestmask,(long long)recvmask); + if ( 0 && bp->myind == 0 && strcmp("CHIPS",dp->symbol) == 0 ) + { + for (i=0; inumnotaries; i++) + printf("%d:%d%s ",wts[i],owts[i],wts[i]*owts[i]>median?"*":""); + printf("median.%d %s.%d set matches.%d best.%d to (%d %llx) recv.%llx topmask.%llx\n",sortbuf[bp->numnotaries/2],dp->symbol,bp->height,bp->matches,bp->bestmatches,bp->bestk,(long long)bp->bestmask,(long long)recvmask,(long long)topmask); + for (i=0; inumnotaries; i++) + if ( wts[i] == 0 || owts[i] == 0 ) + printf("%s.%d:%d ",Notaries_elected[i][0],wts[i],owts[i]); + printf(" <- problem nodes.%s\n",dp->symbol); + } } bp->recvmask |= recvmask; if ( bp->bestmask == 0 )//|| (time(NULL) / 180) != bp->lastepoch ) { bp->bestmask = dpow_notarybestk(bp->recvmask,bp,&bp->bestk); - if ( 0 && (time(NULL) / 180) != bp->lastepoch ) + if ( 0 && (time(NULL) / 180) != bp->lastepoch ) // diverges too fast { bp->lastepoch = (uint32_t)(time(NULL) / 180); printf("epoch %u\n",bp->lastepoch % bp->numnotaries); @@ -1505,7 +1563,7 @@ void dpow_bestconsensus(struct dpow_block *bp) void dpow_nanoutxoset(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_nanoutxo *np,struct dpow_block *bp,int32_t isratify) { - int32_t i,err,vout; cJSON *ujson; char coinaddr[64],str[65]; + int32_t i,err,vout,bestk; cJSON *ujson; char coinaddr[64],str[65]; if ( bp->myind < 0 ) return; if ( isratify != 0 ) @@ -1529,7 +1587,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 +1605,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; @@ -1570,7 +1628,7 @@ void dpow_nanoutxoset(struct supernet_info *myinfo,struct dpow_info *dp,struct d } else { - dpow_bestconsensus(bp); + dpow_bestconsensus(dp,bp); np->srcutxo = bp->notaries[bp->myind].src.prev_hash; np->srcvout = bp->notaries[bp->myind].src.prev_vout; np->destutxo = bp->notaries[bp->myind].dest.prev_hash; @@ -1583,12 +1641,12 @@ void dpow_nanoutxoset(struct supernet_info *myinfo,struct dpow_info *dp,struct d np->bestmask = bp->bestmask, np->bestk = bp->bestk; else np->bestk = bp->notaries[bp->myind].bestk; } else np->bestk = bp->pendingbestk; - if ( (int8_t)np->bestk >= 0 ) + if ( (bestk= (int8_t)bp->pendingbestk) >= 0 || (bestk= (int8_t)np->bestk) >= 0 ) { - if ( (np->siglens[0]= bp->notaries[bp->myind].src.siglens[bp->bestk]) > 0 ) - memcpy(np->sigs[0],bp->notaries[bp->myind].src.sigs[bp->bestk],np->siglens[0]); - if ( (np->siglens[1]= bp->notaries[bp->myind].dest.siglens[bp->bestk]) > 0 ) - memcpy(np->sigs[1],bp->notaries[bp->myind].dest.sigs[bp->bestk],np->siglens[1]); + if ( (np->siglens[0]= bp->notaries[bp->myind].src.siglens[bestk]) > 0 ) + memcpy(np->sigs[0],bp->notaries[bp->myind].src.sigs[bestk],np->siglens[0]); + if ( (np->siglens[1]= bp->notaries[bp->myind].dest.siglens[bestk]) > 0 ) + memcpy(np->sigs[1],bp->notaries[bp->myind].dest.sigs[bestk],np->siglens[1]); } } } @@ -1710,7 +1768,7 @@ void dpow_ratify_update(struct supernet_info *myinfo,struct dpow_info *dp,struct } } //printf("crcval.%x numcrcs.%d bestmatches.%d matchesmask.%llx\n",crcval,numcrcs,bestmatches,(long long)matchesmask); - if ( bestmatches >= bp->minsigs )//&& numcrcs >= bp->minsigs ) + if ( bestmatches == bp->minsigs )//&& numcrcs == bp->minsigs ) { if ( bp->pendingratifybestk != bp->ratifybestk || bp->pendingratifybestmask != bp->ratifybestmask ) { @@ -1733,11 +1791,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); } @@ -1775,7 +1833,7 @@ void dpow_ratify_update(struct supernet_info *myinfo,struct dpow_info *dp,struct void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint8_t senderind,int8_t bestk,uint64_t bestmask,uint64_t recvmask,bits256 srcutxo,uint16_t srcvout,bits256 destutxo,uint16_t destvout,uint8_t siglens[2],uint8_t sigs[2][DPOW_MAXSIGLEN],uint32_t paxwdcrc) { - bits256 srchash; int32_t i,flag,bestmatches = 0,matches = 0,paxmatches = 0,paxbestmatches = 0; + bits256 srchash; uint32_t now; int32_t i,flag,bestmatches = 0,matches = 0,paxmatches = 0,paxbestmatches = 0; if ( bp->myind < 0 ) return; if ( bp->isratify == 0 && bp->state != 0xffffffff && senderind >= 0 && senderind < bp->numnotaries && bits256_nonz(srcutxo) != 0 && bits256_nonz(destutxo) != 0 ) @@ -1784,6 +1842,7 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru { bp->notaries[senderind].src.prev_hash = srcutxo; bp->notaries[senderind].src.prev_vout = srcvout; + //char str[65]; printf("%s senderind.%d <- %s/v%d\n",dp->symbol,senderind,bits256_str(str,srcutxo),srcvout); } if ( bits256_nonz(destutxo) != 0 ) { @@ -1798,8 +1857,9 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru { //fprintf(stderr,"{%d %x} ",senderind,paxwdcrc); } - if ( (bp->notaries[senderind].bestk= bestk) >= 0 ) + if ( bestk >= 0 || bp->notaries[senderind].bestk < 0 ) { + bp->notaries[senderind].bestk = bestk; if ( (bp->notaries[senderind].src.siglens[bestk]= siglens[0]) != 0 ) { memcpy(bp->notaries[senderind].src.sigs[bestk],sigs[0],siglens[0]); @@ -1821,7 +1881,7 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru bp->recvmask |= (1LL << senderind) | (1LL << bp->myind); bp->bestmask = dpow_maskmin(bp->recvmask,bp,&bp->bestk); } - dpow_bestconsensus(bp); + dpow_bestconsensus(dp,bp); if ( bp->bestk >= 0 ) bp->notaries[bp->myind].bestk = bp->bestk; if ( bp->bestmask != 0 ) @@ -1831,6 +1891,7 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru if ( bp->bestk >= 0 ) { flag = -1; + now = (uint32_t)time(NULL); for (i=0; inumnotaries; i++) { if ( bp->paxwdcrc == bp->notaries[i].paxwdcrc ) @@ -1847,40 +1908,50 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru } //else printf("?%x ",bp->notaries[i].paxwdcrc); } } - else if ( i == senderind && ((1LL << bp->myind) & bp->bestmask) != 0 && ((1LL << i) & bp->bestmask) != 0 && ((1LL << bp->myind) & bp->notaries[i].recvmask) == 0 ) - flag = senderind; + else if ( i != bp->myind && i == senderind && ((1LL << bp->myind) & bp->bestmask) != 0 && ((1LL << i) & bp->bestmask) != 0 && ((1LL << bp->myind) & bp->notaries[i].recvmask) == 0 ) + { + if ( now > bp->lastnanosend+1 ) + flag = senderind; + } if ( 0 && bp->myind <= 1 && bp->notaries[i].paxwdcrc != 0 ) printf("%d.(%x %d %llx r%llx) ",i,bp->notaries[i].paxwdcrc,bp->notaries[i].bestk,(long long)bp->notaries[i].bestmask,(long long)bp->notaries[i].recvmask); } - if ( flag >= 0 ) + if ( flag >= 0 || now > bp->lastnanosend+13 ) { //printf("flag.%d -> send\n",flag); for (i=0; iminerkey33[i+1]; dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,0,bp->height,(void *)"ping",0); + bp->lastnanosend = now; } - if ( 0 && bp->myind <= 1 ) - printf("recv.%llx best.(%d %llx) m.%d p.%d:%d b.%d\n",(long long)bp->recvmask,bp->bestk,(long long)bp->bestmask,matches,paxmatches,paxbestmatches,bestmatches); - if ( bestmatches >= bp->minsigs && paxbestmatches >= bp->minsigs ) + if ( 0 && strcmp("CHIPS",dp->symbol) == 0 && bp->myind == 0 ) + printf("%s recv.%llx best.(%d %llx) m.%d p.%d:%d b.%d state.%d minsigs.%d\n",dp->symbol,(long long)bp->recvmask,bp->bestk,(long long)bp->bestmask,matches,paxmatches,paxbestmatches,bestmatches,bp->state,bp->minsigs); + if ( bestmatches == bp->minsigs && paxbestmatches == bp->minsigs && bp->bestk >= 0 && bp->bestmask != 0 ) { - if ( bp->pendingbestk != bp->bestk || bp->pendingbestmask != bp->bestmask ) + if ( bp->pendingbestk < 0 )//bp->pendingbestk != bp->bestk || bp->pendingbestmask != bp->bestmask ) { printf("new PENDING BESTK (%d %llx) state.%d\n",bp->bestk,(long long)bp->bestmask,bp->state); 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"); + dpow_signedtxgen(myinfo,dp,bp->destcoin,bp,bp->pendingbestk,bp->pendingbestmask,bp->myind,DPOW_SIGBTCCHANNEL,1,0); + //printf("finished signing\n"); + } + if ( (bp->pendingbestmask & (1LL << bp->myind)) != 0 && bits256_nonz(bp->desttxid) != 0 && bp->srcsigsmasks[bp->pendingbestk] == 0 ) + { + printf("generate sigs for bestk.%d %llx\n",bp->pendingbestk,(long long)bp->pendingbestmask); + dpow_signedtxgen(myinfo,dp,bp->srccoin,bp,bp->pendingbestk,bp->pendingbestmask,bp->myind,DPOW_SIGCHANNEL,0,0); } - if ( bp->destsigsmasks[bp->bestk] == bp->bestmask ) // have all sigs + if ( bp->destsigsmasks[bp->pendingbestk] == bp->pendingbestmask ) // have all sigs { if ( bp->state < 1000 ) - dpow_sigscheck(myinfo,dp,bp,bp->myind,1,bp->bestk,bp->bestmask,0,0); - if ( bp->srcsigsmasks[bp->bestk] == bp->bestmask ) // have all sigs + dpow_sigscheck(myinfo,dp,bp,bp->myind,1,bp->pendingbestk,bp->pendingbestmask,0,0); + if ( bp->srcsigsmasks[bp->pendingbestk] == bp->pendingbestmask ) // have all sigs { if ( bp->state != 0xffffffff ) - dpow_sigscheck(myinfo,dp,bp,bp->myind,0,bp->bestk,bp->bestmask,0,0); - } //else printf("srcmask.%llx != bestmask.%llx\n",(long long)bp->srcsigsmasks[bp->bestk],(long long)bp->bestmask); - } //else printf("destmask.%llx != bestmask.%llx\n",(long long)bp->destsigsmasks[bp->bestk],(long long)bp->bestmask); + dpow_sigscheck(myinfo,dp,bp,bp->myind,0,bp->pendingbestk,bp->pendingbestmask,0,0); + } // else if ( strcmp(dp->symbol,"CHIPS") == 0 || strcmp(dp->symbol,"GAME") == 0 )printf("srcmask.[%d:%d] %llx %llx != bestmask.%llx\n",bp->bestk,bp->pendingbestk,(long long)bp->srcsigsmasks[bp->pendingbestk],(long long)bp->srcsigsmasks[bp->bestk],(long long)bp->pendingbestmask); + } //else if ( strcmp(dp->symbol,"CHIPS") == 0 || strcmp(dp->symbol,"GAME") == 0 ) + //printf("destmask.%llx != bestmask.%llx\n",(long long)bp->destsigsmasks[bp->bestk],(long long)bp->bestmask); } } else @@ -1895,8 +1966,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() % 1024) == 0 || (bp->myind == 0 && (rand() % 50) == 0 && (strcmp(dp->symbol,"CHIPS") == 0 || strcmp(dp->symbol,"GAME") == 0)) ) + printf("%x ht.%d [%d] ips.%d %s NOTARIZE.%d matches.%d paxmatches.%d bestmatches.%d bestk.%d:%d %llx recv.%llx sigmasks.(%llx %llx) senderind.%d state.%x (%x %x %x) MoM.%s [%d]\n",bp->paxwdcrc,bp->height,bp->myind,dp->numipbits,dp->symbol,bp->minsigs,matches,paxmatches,bestmatches,bp->bestk,bp->pendingbestk,(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); } } @@ -1908,20 +1980,46 @@ void dpow_nanoutxoget(struct supernet_info *myinfo,struct dpow_info *dp,struct d } else { + int32_t i,bestmatches=0,matches = 0,dispflag = 0; dpow_notarize_update(myinfo,dp,bp,senderind,(int8_t)np->bestk,np->bestmask,np->recvmask,np->srcutxo,np->srcvout,np->destutxo,np->destvout,np->siglens,np->sigs,np->paxwdcrc); - if ( 0 && bp->myind <= 2 ) - printf("lag.[%d] RECV.%d r%llx (%d %llx) %llx/%llx\n",(int32_t)(time(NULL)-channel),senderind,(long long)np->recvmask,(int8_t)np->bestk,(long long)np->bestmask,(long long)np->srcutxo.txid,(long long)np->destutxo.txid); + if ( np->bestk >= 0 ) + { + if ( bp->recv[senderind].recvmask != np->recvmask || bp->recv[senderind].bestk != np->bestk || bp->recv[senderind].bestmask != np->bestmask ) + dispflag = 1; + bp->recv[senderind].recvmask = np->recvmask; + bp->recv[senderind].bestk = np->bestk; + bp->recv[senderind].bestmask = np->bestmask; + for (i=0; inumnotaries; i++) + { + if ( bp->recv[i].recvmask == np->recvmask && bp->recv[i].bestmask == np->bestmask && bp->recv[i].bestk == np->bestk ) + { + matches++; + if ( ((1LL << i) & np->bestmask) != 0 ) + bestmatches++; + } + } + } + if ( 0 && bp->myind == 0 && dispflag != 0 ) + { + printf("%s.%d RECV.%-2d %llx (%2d %llx) %llx/%llx matches.%-2d best.%-2d %s\n",dp->symbol,bp->height,senderind,(long long)np->recvmask,(int8_t)np->bestk,(long long)np->bestmask,(long long)np->srcutxo.txid,(long long)np->destutxo.txid,matches,bestmatches,Notaries_elected[senderind][0]); + } } //dpow_bestmask_update(myinfo,dp,bp,nn_senderind,nn_bestk,nn_bestmask,nn_recvmask); } 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) { - struct dpow_nanomsghdr *np; int32_t i,size,extralen=0,sentbytes = 0; uint32_t crc32,paxwdcrc; uint8_t extras[10000]; + struct dpow_nanomsghdr *np; int32_t i,maxiters,src_or_dest,size,extralen=0,sentbytes = 0; uint32_t crc32,paxwdcrc; uint8_t extras[10000]; if ( bp->myind < 0 ) + { + printf("bp->myind.%d error\n",bp->myind); return; + } if ( time(NULL) < myinfo->nanoinit+5 ) + { + printf("dpow_send waiting for init\n"); return; + } crc32 = calc_crc32(0,data,datalen); //dp->crcs[firstz] = crc32; size = (int32_t)(sizeof(*np) + datalen); @@ -1938,9 +2036,12 @@ 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); + if ( strcmp(bp->destcoin->symbol,"KMD") == 0 ) + src_or_dest = 0; + else src_or_dest = 1; + extralen = dpow_paxpending(extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp); bp->paxwdcrc = bp->notaries[bp->myind].paxwdcrc = np->notarize.paxwdcrc = paxwdcrc; - //dpow_bestconsensus(bp); + //dpow_bestconsensus(dp,bp); dpow_nanoutxoset(myinfo,dp,&np->notarize,bp,0); } else @@ -1965,22 +2066,25 @@ void dpow_send(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_blo memcpy(np->packet,data,datalen); sentbytes = -1; // deadlocks! portable_mutex_lock(&myinfo->dpowmutex); - for (i=0; i<100; i++) + maxiters = 100; + for (i=0; idpowsock; pfd.events = NN_POLLOUT; - if ( nn_poll(&pfd,1,100) > 0 ) + if ( nn_poll(&pfd,1,10) > 0 ) { sentbytes = signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->dpowsock,np,size); break; } usleep(1000); } + if ( i == maxiters ) + printf("maxiters expired for signed_nn_send dpowsock.%d\n",myinfo->dpowsock); //portable_mutex_unlock(&myinfo->dpowmutex); free(np); - if ( 0 && bp->myind <= 2 ) - printf("%d NANOSEND.%d ht.%d channel.%08x (%d) pax.%08x datalen.%d (%d %llx) (%d %llx) recv.%llx\n",i,sentbytes,np->height,np->channel,size,np->notarize.paxwdcrc,datalen,(int8_t)np->notarize.bestk,(long long)np->notarize.bestmask,bp->notaries[bp->myind].bestk,(long long)bp->notaries[bp->myind].bestmask,(long long)bp->recvmask); + if ( 0 && bp->myind == 0 ) + printf("%d NANOSEND.%d %s.%d channel.%08x (%d) pax.%08x datalen.%d (%d %llx) (%d %llx) recv.%llx\n",i,sentbytes,dp->symbol,np->height,np->channel,size,np->notarize.paxwdcrc,datalen,(int8_t)np->notarize.bestk,(long long)np->notarize.bestmask,bp->notaries[bp->myind].bestk,(long long)bp->notaries[bp->myind].bestmask,(long long)bp->recvmask); } void dpow_ipbitsadd(struct supernet_info *myinfo,struct dpow_info *dp,uint32_t *ipbits,int32_t numipbits,int32_t maxipbits,int32_t fromid,uint32_t senderipbits) @@ -2009,7 +2113,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); @@ -2057,9 +2161,9 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) dp = 0; for (i=0; inumdpows; i++) { - if ( strcmp(np->symbol,myinfo->DPOWS[i].symbol) == 0 ) + if ( strcmp(np->symbol,myinfo->DPOWS[i]->symbol) == 0 ) { - dp = &myinfo->DPOWS[i]; + dp = myinfo->DPOWS[i]; break; } } @@ -2093,7 +2197,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 ) @@ -2110,8 +2214,8 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) } else flags |= 2; 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 ) @@ -2154,7 +2258,7 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo) } else flags |= 4; if ( dexp != 0 ) nn_freemsg(dexp), dexp = 0; - } + }*/ if ( (num + n + num2) != lastval ) { //printf("lastval.%d: num.%d n.%d num2.%d rep packets\n",lastval,num,n,num2); @@ -2237,7 +2341,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 +2461,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..ed2773b1a 100755 --- a/iguana/dpow/dpow_prices.c +++ b/iguana/dpow/dpow_prices.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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..2b46b86b3 100755 --- a/iguana/dpow/dpow_rpc.c +++ b/iguana/dpow/dpow_rpc.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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,82 @@ 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)) +int32_t Notaries_num,Notaries_BTCminsigs = DPOW_MINSIGS; +int32_t 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 ) + { + sprintf(buf,"[\"%d\", \"%d\"]",height,MoMdepth); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"calc_MoM",buf)) != 0 ) + { + retjson = cJSON_Parse(retstr); + //printf("MoM.%s -> %s\n",buf,retstr); + free(retstr); + } + } + return(retjson); +} + +cJSON *dpow_MoMoMdata(struct iguana_info *coin,char *symbol,int32_t kmdheight) +{ + char buf[128],*retstr=0; cJSON *retjson = 0; struct iguana_info *src; + if ( coin->FULLNODE < 0 && strcmp(coin->symbol,"KMD") == 0 && (src= iguana_coinfind(symbol)) != 0 ) + { + sprintf(buf,"[\"%s\", \"%d\", \"%d\"]",symbol,kmdheight,src->MoMoMheight); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"MoMoMdata",buf)) != 0 ) + { + retjson = cJSON_Parse(retstr); + printf("MoMoM.%s -> %s\n",buf,retstr); + free(retstr); + } + usleep(10000); + } + return(retjson); +} + +int32_t dpow_paxpending(uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,int32_t src_or_dest,struct dpow_block *bp) +{ + struct iguana_info *coin,*kmdcoin=0; char *retstr,*hexstr; cJSON *retjson; int32_t hexlen=0,n=0; uint32_t paxwdcrc; paxwdcrc = 0; + //if ( Notaries_port != DPOW_SOCKPORT ) + { + n += iguana_rwbignum(1,&hex[n],sizeof(MoM),MoM.bytes); + n += iguana_rwnum(1,&hex[n],sizeof(MoMdepth),(uint32_t *)&MoMdepth); + if ( strcmp(bp->srccoin->symbol,"PIZZA") == 0 && src_or_dest == 0 && strcmp(bp->destcoin->symbol,"KMD") == 0 ) + { + kmdcoin = bp->destcoin; + if ( (bp->height % 10) == 0 && kmdcoin->lastbestheight > 100 && (retjson= dpow_MoMoMdata(kmdcoin,bp->srccoin->symbol,(kmdcoin->lastbestheight/10)*10 - 5)) != 0 ) + { + if ( (hexstr= jstr(retjson,"data")) != 0 && (hexlen= (int32_t)strlen(hexstr)) > 0 && n+hexlen/2 <= hexsize ) + { + hexlen >>= 1; + decode_hex(&hex[n],hexlen,hexstr), n += hexlen; + } + free_json(retjson); + } + } + paxwdcrc = calc_crc32(0,hex,n) & 0xffffff00; + paxwdcrc |= (n & 0xff); + if ( hexlen > 0 ) + printf("%s.ht.%d opretlen.%d src_or_dest.%d dest.(%s) lastbest.%d paxwdcrc.%x\n",bp->srccoin->symbol,bp->height,n,src_or_dest,bp->destcoin->symbol,kmdcoin!=0?((kmdcoin->lastbestheight/10)*10 - 5):-1,paxwdcrc); + } + *paxwdcrcp = paxwdcrc; + return(n); if ( (coin= iguana_coinfind("KMD")) != 0 ) { if ( coin->FULLNODE < 0 ) @@ -293,11 +375,25 @@ cJSON *dpow_getblock(struct supernet_info *myinfo,struct iguana_info *coin,bits2 char *dpow_validateaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address) { - char buf[128],*retstr=0; + char buf[128],*retstr=0; cJSON *retjson; if ( coin->FULLNODE < 0 ) { sprintf(buf,"\"%s\"",address); - retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"validateaddress",buf); + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,coin->validateaddress,buf); +//printf("%s %s %s %s %s\n",coin->symbol,coin->chain->serverport,coin->chain->userpass,coin->validateaddress,buf); + //printf("%s -> (%s)\n",buf,retstr!=0?retstr:"null"); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( strcmp(coin->symbol,"BTC") == 0 && jobj(retjson,"error") == 0 && jobj(retjson,"ismine") == 0 && strcmp(coin->validateaddress,"validateaddress") == 0 ) + { + printf("autochange %s validateaddress -> getaddressinfo\n",coin->symbol); + strcpy(coin->validateaddress,"getaddressinfo"); + free_json(retjson); + free(retjson); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,coin->validateaddress,buf)); + } + free_json(retjson); + } usleep(10000); } else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) @@ -467,7 +563,7 @@ cJSON *dpow_listtransactions(struct supernet_info *myinfo,struct iguana_info *co char *dpow_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx,cJSON *vins) { - cJSON *array,*privkeys,*item; char *wifstr,*str,*paramstr,*retstr; uint8_t script[256]; int32_t i,n,len,hashtype; struct vin_info V; struct iguana_waddress *waddr; struct iguana_waccount *wacct; + cJSON *array,*privkeys,*item,*retjson; char *wifstr,*str,*paramstr,*retstr; uint8_t script[256]; int32_t i,n,len,hashtype; struct vin_info V; struct iguana_waddress *waddr; struct iguana_waccount *wacct; if ( coin->FULLNODE < 0 ) { array = cJSON_CreateArray(); @@ -475,7 +571,17 @@ char *dpow_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *c jaddi(array,jduplicate(vins)); paramstr = jprint(array,1); //printf("signrawtransaction\n"); - retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"signrawtransaction",paramstr); + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,coin->signtxstr,paramstr); + if ( strcmp(coin->signtxstr,"signrawtransaction") == 0 && (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,"error") != 0 ) + { + strcpy(coin->signtxstr,"signrawtransactionwithwallet"); + free(retstr); + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,coin->signtxstr,paramstr); + } + free_json(retjson); + } //printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr); free(paramstr); usleep(10000); @@ -514,7 +620,7 @@ char *dpow_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *c } } retstr = bitcoinrpc_signrawtransaction(myinfo,coin,0,0,rawtx,vins,privkeys,"ALL"); - printf("call sign.(%s) vins.(%s) privs.(%s) -> (%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),retstr); + //printf("call sign.(%s) vins.(%s) privs.(%s) -> (%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),retstr); free_json(privkeys); return(retstr); } @@ -569,7 +675,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 +830,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 +842,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 +879,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 +929,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"); @@ -1082,7 +1191,7 @@ void dpow_issuer_voutupdate(struct dpow_info *dp,char *symbol,int32_t isspecial, if ( script[offset] == 'W' && strcmp(dp->symbol,"KMD") != 0 ) { // if valid add to pricefeed for issue - printf("WITHDRAW ht.%d txi.%d vout.%d %.8f opretlen.%d\n",height,txi,vout,dstr(fiatoshis),opretlen); + printf("notary vout.%s ht.%d txi.%d vout.%d %.8f opretlen.%d\n",symbol,height,txi,vout,dstr(fiatoshis),opretlen); if ( opretlen == 38 ) // any KMD tx { offset++; @@ -1243,7 +1352,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..4b3851dae 100755 --- a/iguana/dpow/dpow_tx.c +++ b/iguana/dpow/dpow_tx.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -54,7 +54,7 @@ uint64_t dpow_lastk_mask(struct dpow_block *bp,int8_t *lastkp) { bp->recvmask |= (1LL << k); mask |= (1LL << k); - if ( ++m >= bp->minsigs ) + if ( ++m == bp->minsigs ) { *lastkp = k; break; @@ -101,9 +101,8 @@ uint64_t dpow_ratifybest(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp) uint64_t dpow_notarybestk(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp) { - int32_t m,j,k; uint64_t bestmask,mask = 0;//bp->require0; + int32_t m,j,k; int8_t bestk = -1; uint64_t bestmask,mask = 0;//bp->require0; bestmask = 0; - *lastkp = -1; for (m=j=0; jnumnotaries; j++) { //k = (j + ((uint32_t)time(NULL) / 180)) % bp->numnotaries; @@ -115,12 +114,14 @@ uint64_t dpow_notarybestk(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp) mask |= (1LL << k); if ( ++m == bp->minsigs )//-bp->require0 ) { - *lastkp = k; + bestk = k; bestmask = mask;// | bp->require0; //printf("m.%d == minsigs.%d (%d %llx)\n",m,bp->minsigs,k,(long long)bestmask); } } } + if ( bestk >= 0 ) + *lastkp = bestk; return(bestmask); } @@ -169,6 +170,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,11 +227,9 @@ 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 ( bp->MoMdepth > 0 && strcmp(bp->destcoin->symbol,"KMD") == 0 ) // || strcmp(bp->srccoin->symbol,"KMD") == 0) ) { - for (i=0; iMoM,bp->MoMdepth,src_or_dest,bp); } satoshis = 0; len += iguana_rwnum(1,&serialized[len],sizeof(satoshis),&satoshis); @@ -482,17 +483,17 @@ void dpow_rawtxsign(struct supernet_info *myinfo,struct dpow_info *dp,struct igu retval = 0; break; } else printf("sig.%d of %d didnt match pubkey? (%s)\n",j,m,jprint(vinitem,0)); - } // else printf("notmine.(%s)\n",jprint(item,0)); + } else printf("notmine.(%s)\n",jprint(item,0)); } } else printf("no vin[] (%s)\n",jprint(txobj2,0)); free_json(txobj2); } else printf("cant parse.(%s)\n",rawtx2); free(rawtx2); - } //else printf("error decoding (%s) %s\n",signedtx==0?"":signedtx,jsonstr); + } else printf("error decoding (%s) %s\n",signedtx==0?"":signedtx,jsonstr); free_json(signobj); } else printf("error parsing.(%s)\n",jsonstr); free(jsonstr); - } + } else printf("%s null signature in dpow_rawtxsign\n",dp->symbol); } int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t myind,uint32_t deprec,int32_t src_or_dest,int32_t useratified) @@ -507,7 +508,7 @@ int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct dpow_info *dp,struc if ( (vins= dpow_vins(coin,bp,bestk,bestmask,1,src_or_dest,useratified)) != 0 ) { txid = dpow_notarytx(rawtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,bp->numratified!=0?bp->ratified_pubkeys:0,useratified*bp->numratified); - //char str[65]; printf("signedtxgen %s src_or_dest.%d (%d %llx) useratified.%d raw.(%s)\n",bits256_str(str,txid),src_or_dest,bestk,(long long)bestmask,useratified,rawtx); + //char str[65]; printf("%s signedtxgen %s src_or_dest.%d (%d %llx) useratified.%d raw.(%s)\n",dp->symbol,bits256_str(str,txid),src_or_dest,bestk,(long long)bestmask,useratified,rawtx); if ( bits256_nonz(txid) != 0 && rawtx[0] != 0 ) // send tx to share utxo set { if ( useratified != 0 ) @@ -571,7 +572,8 @@ void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_info *dp,struct dpo { dpow_notarytx(bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,pubkeys,numratified); // setcrcval signedtxid = dpow_notarytx(bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,1,src_or_dest,pubkeys,numratified); - //printf("src_or_dest.%d bestk.%d %llx %s numsigs.%d signedtx.(%s)\n",src_or_dest,bestk,(long long)bestmask,bits256_str(str,signedtxid),numsigs,bp->signedtx); + if ( strcmp("CHIPS",coin->symbol) == 0 ) + printf("src_or_dest.%d bestk.%d %llx %s numsigs.%d signedtx.(%s)\n",src_or_dest,bestk,(long long)bestmask,bits256_str(str,signedtxid),numsigs,bp->signedtx); bp->state = 1; if ( bits256_nonz(signedtxid) != 0 && numsigs == bp->minsigs ) { diff --git a/iguana/elected b/iguana/elected new file mode 100644 index 000000000..d22e0277c --- /dev/null +++ b/iguana/elected @@ -0,0 +1,80 @@ +{ +"port": 17775, +"BTCminsigs": 13, +"minsigs": 13, +"seeds": [ + "78.47.196.146", + "37.9.62.186", + "145.239.204.33", + "139.60.161.30", + "209.58.190.117", + "209.58.144.205", + "149.56.240.91", + "139.99.144.54" +], +"notaries": [ + {"dev1_jl777": "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, + {"dev2_kolo": "030f34af4b908fb8eb2099accb56b8d157d49f6cfb691baa80fdd34f385efed961" }, + {"dev3_kolo": "025af9d2b2a05338478159e9ac84543968fd18c45fd9307866b56f33898653b014" }, + {"dev4_decker": "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" }, + {"a-team_SH": "03b59ad322b17cb94080dc8e6dc10a0a865de6d47c16fb5b1a0b5f77f9507f3cce" }, + {"artik_AR": "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, + {"artik_EU": "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, + {"artik_NA": "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, + {"artik_SH": "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, + {"badass_EU": "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, + {"badass_NA": "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, + {"batman_AR": "033ecb640ec5852f42be24c3bf33ca123fb32ced134bed6aa2ba249cf31b0f2563" }, + {"batman_SH": "02ca5898931181d0b8aafc75ef56fce9c43656c0b6c9f64306e7c8542f6207018c" }, + {"ca333_EU": "03fc87b8c804f12a6bd18efd43b0ba2828e4e38834f6b44c0bfee19f966a12ba99" }, + {"chainmakers_EU": "02f3b08938a7f8d2609d567aebc4989eeded6e2e880c058fdf092c5da82c3bc5ee" }, + {"chainmakers_NA": "0276c6d1c65abc64c8559710b8aff4b9e33787072d3dda4ec9a47b30da0725f57a" }, + {"chainstrike_SH": "0370bcf10575d8fb0291afad7bf3a76929734f888228bc49e35c5c49b336002153" }, + {"cipi_AR": "02c4f89a5b382750836cb787880d30e23502265054e1c327a5bfce67116d757ce8" }, + {"cipi_NA": "02858904a2a1a0b44df4c937b65ee1f5b66186ab87a751858cf270dee1d5031f18" }, + {"crackers_EU": "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, + {"crackers_NA": "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, + {"dwy_EU": "0259c646288580221fdf0e92dbeecaee214504fdc8bbdf4a3019d6ec18b7540424" }, + {"emmanux_SH": "033f316114d950497fc1d9348f03770cd420f14f662ab2db6172df44c389a2667a" }, + {"etszombi_EU": "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, + {"fullmoon_AR": "03380314c4f42fa854df8c471618751879f9e8f0ff5dbabda2bd77d0f96cb35676" }, + {"fullmoon_NA": "030216211d8e2a48bae9e5d7eb3a42ca2b7aae8770979a791f883869aea2fa6eef" }, + {"fullmoon_SH": "03f34282fa57ecc7aba8afaf66c30099b5601e98dcbfd0d8a58c86c20d8b692c64" }, + {"goldenman_EU": "02d6f13a8f745921cdb811e32237bb98950af1a5952be7b3d429abd9152f8e388d" }, + {"indenodes_AR": "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, + {"indenodes_EU": "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, + {"indenodes_NA": "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, + {"indenodes_SH": "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, + {"jackson_AR": "038ff7cfe34cb13b524e0941d5cf710beca2ffb7e05ddf15ced7d4f14fbb0a6f69" }, + {"jeezy_EU": "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, + {"karasugoi_NA": "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, + {"komodoninja_EU": "038e567b99806b200b267b27bbca2abf6a3e8576406df5f872e3b38d30843cd5ba" }, + {"komodoninja_SH": "033178586896915e8456ebf407b1915351a617f46984001790f0cce3d6f3ada5c2" }, + {"komodopioneers_SH": "033ace50aedf8df70035b962a805431363a61cc4e69d99d90726a2d48fb195f68c" }, + {"libscott_SH": "03301a8248d41bc5dc926088a8cf31b65e2daf49eed7eb26af4fb03aae19682b95" }, + {"lukechilds_AR": "031aa66313ee024bbee8c17915cf7d105656d0ace5b4a43a3ab5eae1e14ec02696" }, + {"madmax_AR": "03891555b4a4393d655bf76f0ad0fb74e5159a615b6925907678edc2aac5e06a75" }, + {"meshbits_AR": "02957fd48ae6cb361b8a28cdb1b8ccf5067ff68eb1f90cba7df5f7934ed8eb4b2c" }, + {"meshbits_SH": "025c6e94877515dfd7b05682b9cc2fe4a49e076efe291e54fcec3add78183c1edb" }, + {"metaphilibert_AR": "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, + {"metaphilibert_SH": "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, + {"patchkez_SH": "0296270f394140640f8fa15684fc11255371abb6b9f253416ea2734e34607799c4" }, + {"pbca26_NA": "0276aca53a058556c485bbb60bdc54b600efe402a8b97f0341a7c04803ce204cb5" }, + {"peer2cloud_AR": "034e5563cb885999ae1530bd66fab728e580016629e8377579493b386bf6cebb15" }, + {"peer2cloud_SH": "03396ac453b3f23e20f30d4793c5b8ab6ded6993242df4f09fd91eb9a4f8aede84" }, + {"polycryptoblog_NA": "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, + {"hyper_AR": "020f2f984d522051bd5247b61b080b4374a7ab389d959408313e8062acad3266b4" }, + {"hyper_EU": "03d00cf9ceace209c59fb013e112a786ad583d7de5ca45b1e0df3b4023bb14bf51" }, + {"hyper_SH": "0383d0b37f59f4ee5e3e98a47e461c861d49d0d90c80e9e16f7e63686a2dc071f3" }, + {"hyper_NA": "03d91c43230336c0d4b769c9c940145a8c53168bf62e34d1bccd7f6cfc7e5592de" }, + {"popcornbag_AR": "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, + {"popcornbag_NA": "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, + {"alien_AR": "0348d9b1fc6acf81290405580f525ee49b4749ed4637b51a28b18caa26543b20f0" }, + {"alien_EU": "020aab8308d4df375a846a9e3b1c7e99597b90497efa021d50bcf1bbba23246527" }, + {"thegaltmines_NA": "031bea28bec98b6380958a493a703ddc3353d7b05eb452109a773eefd15a32e421" }, + {"titomane_AR": "029d19215440d8cb9cc6c6b7a4744ae7fb9fb18d986e371b06aeb34b64845f9325" }, + {"titomane_EU": "0360b4805d885ff596f94312eed3e4e17cb56aa8077c6dd78d905f8de89da9499f" }, + {"titomane_SH": "03573713c5b20c1e682a2e8c0f8437625b3530f278e705af9b6614de29277a435b" }, + {"webworker01_NA": "03bb7d005e052779b1586f071834c5facbb83470094cff5112f0072b64989f97d7" }, + {"xrobesx_NA": "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" } +]} diff --git a/iguana/elected.2017 b/iguana/elected.2017 new file mode 100644 index 000000000..9f9bfc7b1 --- /dev/null +++ b/iguana/elected.2017 @@ -0,0 +1 @@ +{"port":7775,"BTCminsigs":14,"minsigs":13,"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/elected.new b/iguana/elected.new new file mode 100644 index 000000000..a84e9aaed --- /dev/null +++ b/iguana/elected.new @@ -0,0 +1,84 @@ +{ +"port": 7775, +"BTCminsigs": 14, +"minsigs": 13, +"seeds": [ + "95.213.205.222", + "167.114.208.203", + "139.99.122.140", + "104.255.168.213", + "78.47.196.146", + "138.121.203.226", + "167.99.69.47", + "139.99.144.122", + "77.95.229.63", + "37.9.62.186", + "145.239.204.33", + "74.208.210.191" +], +"notaries": [ + {"dev1_jl777": "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, + {"dev2_kolo": "030f34af4b908fb8eb2099accb56b8d157d49f6cfb691baa80fdd34f385efed961" }, + {"dev3_kolo": "025af9d2b2a05338478159e9ac84543968fd18c45fd9307866b56f33898653b014" }, + {"dev4_decker": "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" }, + {"a-team_SH": "03b59ad322b17cb94080dc8e6dc10a0a865de6d47c16fb5b1a0b5f77f9507f3cce" }, + {"artik_AR": "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, + {"artik_EU": "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, + {"artik_NA": "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, + {"artik_SH": "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, + {"badass_EU": "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, + {"badass_NA": "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, + {"batman_AR": "033ecb640ec5852f42be24c3bf33ca123fb32ced134bed6aa2ba249cf31b0f2563" }, + {"batman_SH": "02ca5898931181d0b8aafc75ef56fce9c43656c0b6c9f64306e7c8542f6207018c" }, + {"ca333_EU": "03fc87b8c804f12a6bd18efd43b0ba2828e4e38834f6b44c0bfee19f966a12ba99" }, + {"chainmakers_EU": "02f3b08938a7f8d2609d567aebc4989eeded6e2e880c058fdf092c5da82c3bc5ee" }, + {"chainmakers_NA": "0276c6d1c65abc64c8559710b8aff4b9e33787072d3dda4ec9a47b30da0725f57a" }, + {"chainstrike_SH": "0370bcf10575d8fb0291afad7bf3a76929734f888228bc49e35c5c49b336002153" }, + {"cipi_AR": "02c4f89a5b382750836cb787880d30e23502265054e1c327a5bfce67116d757ce8" }, + {"cipi_NA": "02858904a2a1a0b44df4c937b65ee1f5b66186ab87a751858cf270dee1d5031f18" }, + {"crackers_EU": "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, + {"crackers_NA": "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, + {"dwy_EU": "0259c646288580221fdf0e92dbeecaee214504fdc8bbdf4a3019d6ec18b7540424" }, + {"emmanux_SH": "033f316114d950497fc1d9348f03770cd420f14f662ab2db6172df44c389a2667a" }, + {"etszombi_EU": "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, + {"fullmoon_AR": "03380314c4f42fa854df8c471618751879f9e8f0ff5dbabda2bd77d0f96cb35676" }, + {"fullmoon_NA": "030216211d8e2a48bae9e5d7eb3a42ca2b7aae8770979a791f883869aea2fa6eef" }, + {"fullmoon_SH": "03f34282fa57ecc7aba8afaf66c30099b5601e98dcbfd0d8a58c86c20d8b692c64" }, + {"goldenman_EU": "02d6f13a8f745921cdb811e32237bb98950af1a5952be7b3d429abd9152f8e388d" }, + {"indenodes_AR": "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, + {"indenodes_EU": "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, + {"indenodes_NA": "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, + {"indenodes_SH": "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, + {"jackson_AR": "038ff7cfe34cb13b524e0941d5cf710beca2ffb7e05ddf15ced7d4f14fbb0a6f69" }, + {"jeezy_EU": "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, + {"karasugoi_NA": "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, + {"komodoninja_EU": "038e567b99806b200b267b27bbca2abf6a3e8576406df5f872e3b38d30843cd5ba" }, + {"komodoninja_SH": "033178586896915e8456ebf407b1915351a617f46984001790f0cce3d6f3ada5c2" }, + {"komodopioneers_SH": "033ace50aedf8df70035b962a805431363a61cc4e69d99d90726a2d48fb195f68c" }, + {"libscott_SH": "03301a8248d41bc5dc926088a8cf31b65e2daf49eed7eb26af4fb03aae19682b95" }, + {"lukechilds_AR": "031aa66313ee024bbee8c17915cf7d105656d0ace5b4a43a3ab5eae1e14ec02696" }, + {"madmax_AR": "03891555b4a4393d655bf76f0ad0fb74e5159a615b6925907678edc2aac5e06a75" }, + {"meshbits_AR": "02957fd48ae6cb361b8a28cdb1b8ccf5067ff68eb1f90cba7df5f7934ed8eb4b2c" }, + {"meshbits_SH": "025c6e94877515dfd7b05682b9cc2fe4a49e076efe291e54fcec3add78183c1edb" }, + {"metaphilibert_AR": "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, + {"metaphilibert_SH": "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, + {"patchkez_SH": "0296270f394140640f8fa15684fc11255371abb6b9f253416ea2734e34607799c4" }, + {"pbca26_NA": "0276aca53a058556c485bbb60bdc54b600efe402a8b97f0341a7c04803ce204cb5" }, + {"peer2cloud_AR": "034e5563cb885999ae1530bd66fab728e580016629e8377579493b386bf6cebb15" }, + {"peer2cloud_SH": "03396ac453b3f23e20f30d4793c5b8ab6ded6993242df4f09fd91eb9a4f8aede84" }, + {"polycryptoblog_NA": "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, + {"hyper_AR": "020f2f984d522051bd5247b61b080b4374a7ab389d959408313e8062acad3266b4" }, + {"hyper_EU": "03d00cf9ceace209c59fb013e112a786ad583d7de5ca45b1e0df3b4023bb14bf51" }, + {"hyper_SH": "0383d0b37f59f4ee5e3e98a47e461c861d49d0d90c80e9e16f7e63686a2dc071f3" }, + {"hyper_NA": "03d91c43230336c0d4b769c9c940145a8c53168bf62e34d1bccd7f6cfc7e5592de" }, + {"popcornbag_AR": "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, + {"popcornbag_NA": "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, + {"alien_AR": "0348d9b1fc6acf81290405580f525ee49b4749ed4637b51a28b18caa26543b20f0" }, + {"alien_EU": "020aab8308d4df375a846a9e3b1c7e99597b90497efa021d50bcf1bbba23246527" }, + {"thegaltmines_NA": "031bea28bec98b6380958a493a703ddc3353d7b05eb452109a773eefd15a32e421" }, + {"titomane_AR": "029d19215440d8cb9cc6c6b7a4744ae7fb9fb18d986e371b06aeb34b64845f9325" }, + {"titomane_EU": "0360b4805d885ff596f94312eed3e4e17cb56aa8077c6dd78d905f8de89da9499f" }, + {"titomane_SH": "03573713c5b20c1e682a2e8c0f8437625b3530f278e705af9b6614de29277a435b" }, + {"webworker01_NA": "03bb7d005e052779b1586f071834c5facbb83470094cff5112f0072b64989f97d7" }, + {"xrobesx_NA": "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" } +]} 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/DEXstats.h b/iguana/exchanges/DEXstats.h index dc1f89864..c68bc3f33 100644 --- a/iguana/exchanges/DEXstats.h +++ b/iguana/exchanges/DEXstats.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -928,7 +928,7 @@ char *stats_prices(char *symbol,char *dest,struct DEXstats_disp *prices,int32_t #ifndef FROM_MARKETMAKER #ifndef FROM_PRIVATEBET -char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char *remoteaddr,uint16_t port) +char *stats_JSON(void *ctx,int32_t fastflag,char *myipaddr,int32_t mypubsock,cJSON *argjson,char *remoteaddr,uint16_t port) { char *method,*agent,*retstr,*source,*dest; struct tai T; uint32_t endtimestamp; struct DEXstats_disp prices[365]; int32_t leftdatenum,seconds,numdates; if ( (method= jstr(argjson,"method")) == 0 ) diff --git a/iguana/exchanges/LP_NXT.c b/iguana/exchanges/LP_NXT.c index 88626ec0f..c614b8617 100644 --- a/iguana/exchanges/LP_NXT.c +++ b/iguana/exchanges/LP_NXT.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -202,7 +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; - uint64_t txnum_marker = calc_nxt64bits("4114304329372848717"); // 8537615468620726612"); // 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..6533e6fbf 100644 --- a/iguana/exchanges/LP_RTmetrics.c +++ b/iguana/exchanges/LP_RTmetrics.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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..2201d67d7 100644 --- a/iguana/exchanges/LP_bitcoin.c +++ b/iguana/exchanges/LP_bitcoin.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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..7ecae6566 100644 --- a/iguana/exchanges/LP_cache.c +++ b/iguana/exchanges/LP_cache.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -53,11 +53,11 @@ struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 tx for (i=0; ioutpoints[i].value = LP_value_extract(vout,0); + tx->outpoints[i].value = LP_value_extract(vout,0,txid); 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 89483dd1e..3722ad819 100644 --- a/iguana/exchanges/LP_coins.c +++ b/iguana/exchanges/LP_coins.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -20,6 +20,19 @@ char *portstrs[][3] = { { "BTC", "8332" }, { "KMD", "7771" } }; +int32_t LP_is_slowcoin(char *symbol) +{ + if ( strcmp(symbol,"BTC") == 0 ) + return(2); + else if ( strcmp(symbol,"BCH") == 0 ) + return(1); + else if ( strcmp(symbol,"BTG") == 0 ) + return(1); + else if ( strcmp(symbol,"SBTC") == 0 ) + return(1); + else return(0); +} + uint16_t LP_rpcport(char *symbol) { int32_t i; @@ -236,6 +249,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 +296,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 +330,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,9 +363,13 @@ 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); + strcpy(coin->validateaddress,"validateaddress"); + strcpy(coin->getinfostr,"getinfo"); + strcpy(coin->estimatefeestr,"estimatefee"); return(coin); } @@ -375,7 +400,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 290844812..a8f169b6b 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -32,7 +32,7 @@ char *LP_numutxos() return(jprint(retjson,1)); } -char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port +char *stats_JSON(void *ctx,int32_t fastflag,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port { char *method,*userpass,*base,*rel,*coin,*passphrase,*retstr = 0; int32_t authenticated=0,changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; method = jstr(argjson,"method"); @@ -116,15 +116,18 @@ pricearray(base, rel, starttime=0, endtime=0, timescale=60) -> [timestamp, avebi getrawtransaction(coin, txid)\n\ inventory(coin, reset=0, [passphrase=])\n\ lastnonce()\n\ +cancel(uuid)\n\ buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce)\n\ sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)\n\ -withdraw(coin, outputs[])\n\ +withdraw(coin, outputs[], broadcast=0)\n\ +txblast(coin, utxotxid, utxovout, utxovalue, txfee, passphrase, 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\ +kickstart(requestid, quoteid)\n\ notarizations(coin)\n\ public API:\n \ getcoins()\n\ @@ -140,6 +143,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 +163,32 @@ 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\ +getfee(coin)\n\ +sleep(seconds=60)\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 +199,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 +237,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 ) @@ -263,9 +307,13 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ LP_deletemessages(jint(argjson,"firsti"),jint(argjson,"num")); return(clonestr("{\"result\":\"success\"}")); }*/ + else if ( strcmp(method,"cancel") == 0 ) + { + return(LP_cancel_order(jstr(argjson,"uuid"))); + } else if ( strcmp(method,"recentswaps") == 0 ) { - return(LP_recent_swaps(jint(argjson,"limit"))); + return(LP_recent_swaps(jint(argjson,"limit"),0)); } else if ( strcmp(method,"stop") == 0 ) { @@ -278,6 +326,13 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ LP_millistats_update(0); return(clonestr("{\"result\":\"success\"}")); } + else if ( strcmp(method,"sleep") == 0 ) + { + if ( jint(argjson,"seconds") == 0 ) + sleep(60); + else sleep(jint(argjson,"seconds")); + return(clonestr("{\"result\":\"success\",\"status\":\"feeling good after sleeping\"}")); + } else if ( strcmp(method,"getprices") == 0 ) return(LP_prices()); else if ( strcmp(method,"getpeers") == 0 ) @@ -300,6 +355,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)); @@ -315,16 +414,23 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ taddr = (jobj(argjson,"taddr") == 0) ? 0 : juint(argjson,"taddr"); return(LP_secretaddresses(ctx,jstr(argjson,"prefix"),jstr(argjson,"passphrase"),juint(argjson,"num"),taddr,pubtype)); } + else if ( strcmp(method,"kickstart") == 0 ) + { + uint32_t requestid,quoteid; + if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) + return(LP_kickstart(requestid,quoteid)); + else return(clonestr("{\"error\":\"kickstart needs requestid and quoteid\"}")); + } else if ( strcmp(method,"swapstatus") == 0 ) { uint32_t requestid,quoteid; if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) - return(basilisk_swapentry(requestid,quoteid,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 +449,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 +505,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,jstr(argjson,"uuid"))); } 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,jstr(argjson,"uuid"))); } else return(clonestr("{\"error\":\"no price set\"}")); } } @@ -426,7 +546,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 +555,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)); @@ -497,6 +607,19 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ return(jprint(LP_address_balance(ptr,jstr(argjson,"address"),1),1)); else return(clonestr("{\"error\":\"cant find coind\"}")); } + else if ( strcmp(method,"getfee") == 0 ) + { + uint64_t txfee; + if ( (ptr= LP_coinsearch(coin)) != 0 ) + { + txfee = LP_txfeecalc(ptr,0,0); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"coin",coin); + jaddnum(retjson,"txfee",dstr(txfee)); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"cant find coind\"}")); + } else if ( strcmp(method,"electrum") == 0 ) { if ( (ptr= LP_coinsearch(coin)) != 0 ) @@ -509,20 +632,58 @@ 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,"txblast") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + return(LP_txblast(ptr,argjson)); + else return(clonestr("{\"error\":\"cant find coind\"}")); } 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 +726,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 +747,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)); } } @@ -705,7 +866,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 ) @@ -752,16 +913,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..532f8f4d5 --- /dev/null +++ b/iguana/exchanges/LP_etomic.c @@ -0,0 +1,723 @@ + +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_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_forwarding.c b/iguana/exchanges/LP_forwarding.c index 749cf2f2e..82754e612 100644 --- a/iguana/exchanges/LP_forwarding.c +++ b/iguana/exchanges/LP_forwarding.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h index ed797f3ba..4080ba31c 100644 --- a/iguana/exchanges/LP_include.h +++ b/iguana/exchanges/LP_include.h @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -22,18 +22,22 @@ #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 +//#define fprintf fdontprintf dont do this! -voind dontprintf(char *formatstr,...) {} +void dontprintf(char *formatstr,...) {} +//void fdontprintf(FILE *fp,char *formatstr,...) {} #endif #define LP_MAJOR_VERSION "0" #define LP_MINOR_VERSION "1" -#define LP_BUILD_NUMBER "17763" +#define LP_BUILD_NUMBER "27774" #define LP_BARTERDEX_VERSION 1 #define LP_MAGICBITS 1 @@ -52,12 +56,12 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping #endif //#define LP_STRICTPEERS -#define LP_DISABLE_DISTCOMBINE +//#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 60 -#define LP_RESERVETIME 600 //(LP_AUTOTRADE_TIMEOUT * 2) +#define LP_AUTOTRADE_TIMEOUT 30 +#define LP_RESERVETIME (LP_AUTOTRADE_TIMEOUT * 3) #define ELECTRUM_TIMEOUT 13 #define LP_ELECTRUM_KEEPALIVE 60 #define LP_ELECTRUM_MAXERRORS 777 @@ -96,10 +100,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)) @@ -200,7 +204,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; @@ -233,7 +237,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; @@ -264,7 +268,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 { @@ -274,7 +278,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 uuidstr[65],Agui[65],Bgui[65],gui[65],src[65],dest[65],bobtomic[128],alicetomic[128],etomicsrc[65],etomicdest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)],bobDepositEthTx[75],bobPaymentEthTx[75],alicePaymentEthTx[75]; }; struct LP_outpoint @@ -298,12 +302,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],validateaddress[64]; // portfolio double price_kmd,force,perc,goal,goalperc,relvolume,rate; void *electrum; void *ctx; @@ -361,9 +365,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]; }; @@ -376,7 +381,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],uuidstr[65]; }; struct LP_endpoint { int32_t pair; char ipaddr[64]; uint16_t port; }; @@ -387,14 +392,14 @@ 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; struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim; bits256 privkeys[INSTANTDEX_DECKSIZE]; //struct basilisk_swapmessage *messages; int32_t nummessages,sentflag; - char Bdeposit[64],Bpayment[64]; + char Bdeposit[64],Bpayment[64],uuidstr[65]; uint64_t aliceid,otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; uint8_t persistent_pubkey33[33],persistent_other33[33],changermd160[20],pad[15],verifybuf[100000]; }; @@ -431,7 +436,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; }; @@ -455,7 +460,7 @@ struct LP_trade uint64_t aliceid; int64_t besttrust,bestunconfcredits; double bestprice; - uint32_t negotiationdone,bestresponse,connectsent,firsttime,lasttime,firstprocessed,lastprocessed,newtime; + uint32_t negotiationdone,bestresponse,connectsent,firsttime,lasttime,firstprocessed,lastprocessed,newtime,cancelled; char pairstr[64],funcid,iambob; struct LP_quoteinfo Qs[4],Q; }; @@ -476,9 +481,9 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba void LP_quotesinit(char *base,char *rel); int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,bits256 pubkey,char *jsonstr,int32_t freeflag); struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port); -uint64_t LP_value_extract(cJSON *obj,int32_t addinterest); +uint64_t LP_value_extract(cJSON *obj,int32_t addinterest,bits256 txid); 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); @@ -486,7 +491,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,char *uuidstr); //void LP_utxo_clientpublish(struct LP_utxoinfo *utxo); //int32_t LP_coinbus(uint16_t coin_busport); int32_t LP_nanomsg_recvs(void *ctx); @@ -494,6 +500,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); @@ -504,9 +511,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); @@ -516,6 +527,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); @@ -523,6 +535,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); @@ -532,9 +545,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); @@ -543,15 +556,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); @@ -559,6 +576,10 @@ 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); +int32_t LP_trades_canceluuid(char *uuidstr); +int _decreasing_uint64(const void *a,const void *b); +int32_t LP_alice_eligible(uint32_t quotetime); +int32_t LP_is_slowcoin(char *symbol); void LP_listunspent_query(char *symbol,char *coinaddr); int32_t bitcoin_priv2wif(char *symbol,uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype); @@ -566,5 +587,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 4dd519de7..63068518b 100644 --- a/iguana/exchanges/LP_instantdex.c +++ b/iguana/exchanges/LP_instantdex.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -65,7 +65,8 @@ void LP_instantdex_deposituniq(FILE *fp,bits256 txid) for (i=0; i 0 ) + { + for (j=0; jheight > 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,22 +324,118 @@ 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,utxotxid); + 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 ) + 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,interest; uint32_t expiration,claimtime; + if ( (txjson= LP_gettx("LP_claim_submit",coin->symbol,utxotxid,1)) != 0 ) { if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts >= 3 ) { vout0 = jitem(vouts,0); LP_destaddr(vinaddr,vout0); - satoshis = LP_value_extract(vout0,1); + satoshis = LP_value_extract(vout0,1,utxotxid); vout2 = jitem(vouts,2); LP_destaddr(destaddr,vout2); if ( strcmp(destaddr,coin->smartaddr) == 0 ) { vout1 = jitem(vouts,1); - weeksatoshis = LP_value_extract(vout1,0); + weeksatoshis = LP_value_extract(vout1,0,utxotxid); weeki = (int32_t)(weeksatoshis % 10000); for (iter=0; iter<2; iter++) for (j=-168; j<=168; j++) @@ -311,12 +448,15 @@ 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))); + jaddnum(item,"deposit",dstr(LP_value_extract(vout0,0,utxotxid))); if ( coin->electrum == 0 ) - jaddnum(item,"interest",dstr(satoshis)-dstr(LP_value_extract(vout0,0))); - else jaddnum(item,"interest",dstr(LP_komodo_interest(utxotxid,satoshis))); + interest = dstr(satoshis) - dstr(LP_value_extract(vout0,0,utxotxid)); + else interest = dstr(LP_komodo_interest(utxotxid,satoshis)); + jaddnum(item,"interest",interest); + //printf("%.8f %.8f %.8f\n",dstr(satoshis),dstr(LP_value_extract(vout0,0,utxotxid)),dstr(LP_komodo_interest(utxotxid,satoshis))); if ( claimtime <= expiration ) { printf("iter.%d j.%d claimtime.%u vs %u, wait %d seconds to %s claim %.8f\n",iter,j,claimtime,expiration,(int32_t)expiration-claimtime,bits256_str(str,utxotxid),dstr(satoshis)); @@ -403,7 +543,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 ) @@ -414,10 +554,10 @@ int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits2 } else { - amount64 = LP_value_extract(jitem(vouts,1),0); + amount64 = LP_value_extract(jitem(vouts,1),0,txid); weeki = (amount64 % 10000); item = jitem(vouts,0); - satoshis = LP_value_extract(item,0); + satoshis = LP_value_extract(item,0,txid); //char str[65]; printf("%s %s funded %.8f weeki.%d (%s)\n",bits256_str(str,txid),destaddr,dstr(satoshis),weeki,jprint(item,0)); if ( LP_destaddr(p2shaddr,item) == 0 ) { @@ -566,13 +706,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 ) { @@ -605,7 +745,7 @@ cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) 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 ( (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_messages.c b/iguana/exchanges/LP_messages.c index 80847ee5c..65770f164 100644 --- a/iguana/exchanges/LP_messages.c +++ b/iguana/exchanges/LP_messages.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/exchanges/LP_mmjson.c b/iguana/exchanges/LP_mmjson.c index 1239c4180..0dc67da56 100644 --- a/iguana/exchanges/LP_mmjson.c +++ b/iguana/exchanges/LP_mmjson.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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", "hyperdex", "uuid" }; +#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) @@ -285,7 +285,7 @@ char *MMJSON_decode(uint8_t *linebuf,int32_t len) { if ( ind != MMJSON_STRING ) { - printf("illegal field ind.%d (%s)\n",ind,jprint(lineobj,0)); + printf("illegal field i.%d ind.%d (%s) boundary.%d\n",i,ind,jprint(lineobj,0),MMJSON_BOUNDARY); free_json(lineobj); return(0); } @@ -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; @@ -579,7 +581,9 @@ int32_t MMJSON_encode(uint8_t *linebuf,char *line) s = jfieldname(ptr); if ( (ind= mmfind(s)) < 0 ) { - printf("missing field.(%s) add to MM_fields[]\n",s); + static uint32_t counter; + if ( counter++ < 3 ) + printf("missing field.(%s) add to MM_fields[]\n",s); linebuf[k++] = MMJSON_STRING; memcpy(&linebuf[k],s,strlen(s)+1); k += (int32_t)strlen(s) + 1; diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index 840be075e..7270ca787 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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,0,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,22 +413,24 @@ 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 ) { - if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 ) + if ( (retstr= stats_JSON(ctx,0,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 ) free(retstr); } //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,8 @@ 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; + static int32_t didfilescreate; + struct LP_address *ap=0; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t notarized,oldht,j,nonz; char *coins = _coins; if ( strcmp("BTC",coins) == 0 ) { strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); @@ -517,9 +531,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 +559,31 @@ 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; } + if ( didfilescreate == 0 && strcmp("KMD",coin->symbol) == 0 ) + { + LP_instantdex_filescreate(coin->smartaddr); + didfilescreate = 1; + } 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 +655,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 +664,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 +678,7 @@ void LP_coinsloop(void *_coins) } if ( coins == 0 ) return; - if ( nonz == 0 ) + //if ( nonz == 0 ) usleep(100000); } } @@ -795,7 +807,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)); + } } } } @@ -909,7 +939,11 @@ void LP_pubkeysloop(void *ctx) sleep(10); while ( LP_STOP_RECEIVED == 0 ) { - if ( strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") != 0 ) + if ( G.initializing != 0 ) + { + sleep(1); + continue; + } { LP_millistats_update(&LP_pubkeysloop_stats); if ( time(NULL) > lasttime+100 ) @@ -923,21 +957,69 @@ 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 i,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 ) + { + for (i=0; i<10; i++) + { + //fprintf(stderr,"check on alice expiration\n"); + LP_alice_eligible((uint32_t)time(NULL)); + sleep(6); + } + } } } @@ -948,6 +1030,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); @@ -983,8 +1070,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) { @@ -992,6 +1083,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 ) @@ -1018,27 +1110,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; + } } } } @@ -1092,6 +1195,11 @@ 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[1] > 0 ) @@ -1138,9 +1246,43 @@ void LP_reserved_msgs(void *ignore) 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]) ) { @@ -1164,13 +1306,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"); @@ -1237,6 +1379,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 @@ -1270,8 +1416,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 { @@ -1307,10 +1455,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); @@ -1370,6 +1518,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); @@ -1382,14 +1535,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; @@ -1442,7 +1600,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); @@ -1472,7 +1633,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..263618c39 100644 --- a/iguana/exchanges/LP_network.c +++ b/iguana/exchanges/LP_network.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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,127 @@ 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 ( 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 ) + { + //printf("deQ.(%s)\n",jprint(argjson,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 +569,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 +593,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 +613,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 +718,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 +737,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 +931,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 +942,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 +961,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 +971,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 c322b911e..b35d17a61 100644 --- a/iguana/exchanges/LP_ordermatch.c +++ b/iguana/exchanges/LP_ordermatch.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -24,6 +24,24 @@ 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 *uuidstr) +{ + char *msg; cJSON *retjson; + if ( IPC_ENDPOINT >= 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"method","failed"); + jaddstr(retjson,"uuid",uuidstr); + 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 +89,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 +121,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 +159,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 +200,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 +253,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 +265,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 +327,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 +403,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 +444,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 +463,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,qp->uuidstr); 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,qp->uuidstr); 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,qp->uuidstr); + printf("error launching swaploop\n"); + } + } + else + { + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-3003,qp->uuidstr); + printf("couldnt bind to any port %s\n",pairstr); + } + } + else + { + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-3004,qp->uuidstr); + printf("cant find privkey for %s\n",coin->smartaddr); } if ( retval < 0 ) { @@ -503,7 +567,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double return(retval); } -char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid,bits256 destpubkey) +char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid,bits256 destpubkey,char *uuidstr) { double price; price = 0.; @@ -512,10 +576,12 @@ 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; + strncpy(qp->uuidstr,uuidstr,sizeof(qp->uuidstr)-1); LP_query(ctx,myipaddr,mypubsock,"request",qp); LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = destpubkey; - char str[65]; printf("LP_trade %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),maxprice); - return(LP_recent_swaps(0)); + char str[65]; printf("LP_trade %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f etomicdest.(%s) uuid.%s\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),maxprice,qp->etomicdest,qp->uuidstr); + return(LP_recent_swaps(0,uuidstr)); } int32_t LP_quotecmp(int32_t strictflag,struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2) @@ -549,39 +615,46 @@ int32_t LP_alice_eligible(uint32_t quotetime) { if ( Alice_expiration != 0 && quotetime > Alice_expiration ) { + if ( LP_Alicequery.uuidstr[0] != 0 ) + LP_failedmsg(LP_Alicequery.R.requestid,LP_Alicequery.R.quoteid,-9999,LP_Alicequery.uuidstr); printf("time expired for Alice_request\n"); LP_alicequery_clear(); } return(Alice_expiration == 0 || time(NULL) < Alice_expiration); } -char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice +char *LP_cancel_order(char *uuidstr) { - 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 ) + int32_t num = 0; cJSON *retjson; + if ( uuidstr != 0 ) { - LP_aliceid(Q.tradeid,Q.aliceid,"error0",0,0); - clonestr("{\"error\":\"cant parse quote\"}"); - }*/ + num = LP_trades_canceluuid(uuidstr); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"numentries",num); + if ( strcmp(LP_Alicequery.uuidstr,uuidstr) == 0 ) + { + LP_failedmsg(LP_Alicequery.R.requestid,LP_Alicequery.R.quoteid,-9998,LP_Alicequery.uuidstr); + LP_alicequery_clear(); + jaddstr(retjson,"status","uuid canceled"); + } else jaddstr(retjson,"status","will stop trade negotiation, but if swap started it wont cancel"); + return(jprint(retjson,1)); + } + return(clonestr("{\"error\":\"uuid not cancellable\"}")); +} + +char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice +{ + cJSON *retjson; char otheraddr[64],*msg; double bid,ask,price,qprice; int32_t pairsock = -1; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct basilisk_swap *swap; struct iguana_info *coin; if ( bits256_cmp(qp->desthash,G.LP_mypub25519) != 0 ) { LP_aliceid(qp->tradeid,qp->aliceid,"error1",0,0); + LP_failedmsg(qp->R.requestid,qp->R.quoteid,-4000,qp->uuidstr); return(clonestr("{\"result\",\"update stats\"}")); } printf("CONNECTED numpending.%d tradeid.%u requestid.%u quoteid.%u pairstr.%s\n",G.LP_pendingswaps,qp->tradeid,qp->R.requestid,qp->R.quoteid,pairstr!=0?pairstr:""); LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-qp->txfee,qp->destcoin,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); //printf("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 +667,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,qp->uuidstr); printf("quote %s/%s validate error %.0f\n",qp->srccoin,qp->destcoin,qprice); return(clonestr("{\"error\":\"quote validation error\"}")); } @@ -603,6 +677,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,qp->uuidstr); return(clonestr("{\"error\":\"no price set\"}")); } //LP_RTmetrics_update(qp->srccoin,qp->destcoin); @@ -611,6 +686,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,qp->uuidstr); return(clonestr("{\"error\":\"cant get alicecoin\"}")); } qp->privkey = LP_privkey(coin->symbol,qp->destaddr,coin->taddr); @@ -623,11 +699,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,qp->uuidstr); 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,qp->uuidstr); jaddstr(retjson,"error","couldnt create pairsock"); } else if ( nn_connect(pairsock,pairstr) >= 0 ) @@ -648,6 +726,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 +740,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,qp->uuidstr); } } 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,qp->uuidstr); } - 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,15 +763,14 @@ 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,qp->uuidstr); return(clonestr("{\"error\",\"no privkey\"}")); } } int32_t LP_aliceonly(char *symbol) { - if ( strcmp(symbol,"GAME") == 0 ) - return(1); - else return(0); + return(0); } int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) @@ -702,7 +788,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 +853,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 +891,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 +908,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 +916,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.(%s)\n",bits256_str(str,G.LP_mypub25519),qp->uuidstr+32); + 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); + 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("%s/%s i.%d qprice %.8f myprice %.8f price %.8f [%.8f]\n",qp->srccoin,qp->destcoin,i,qprice,myprice,price,p); if ( LP_allocated(qp->txid,qp->vout) == 0 && LP_allocated(qp->txid2,qp->vout2) == 0 ) { + //printf("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 +1047,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 +1060,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 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)); + char *retstr; double qprice; + //char str[65]; printf("alice %s received RESERVED.(%s) %.8f\n",bits256_str(str,G.LP_mypub25519),qp->uuidstr+32,(double)qp->destsatoshis/(qp->satoshis+1)); *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,qp->uuidstr); return(0); } @@ -949,26 +1088,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.(%s)\n",bits256_str(str,G.LP_mypub25519),qp->uuidstr+32); 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,qp->uuidstr); + 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 uuid.%s\n",qp->uuidstr); 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,qp->uuidstr); //printf("LP_trades_alicevalidate error\n"); return(0); } @@ -1008,16 +1155,93 @@ int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) return(0); } +int32_t LP_trades_canceluuid(char *uuidstr) +{ + int32_t num = 0; struct LP_trade *qtp,*tp,*tmp; + HASH_ITER(hh,LP_trades,tp,tmp) + { + if ( strcmp(tp->Q.uuidstr,uuidstr) == 0 ) + { + tp->cancelled = (uint32_t)time(NULL); + num++; + } + } + DL_FOREACH_SAFE(LP_tradesQ,qtp,tmp) + { + if ( strcmp(qtp->Q.uuidstr,uuidstr) == 0 ) + { + qtp->cancelled = (uint32_t)time(NULL); + num++; + } + } + if ( num > 0 ) + fprintf(stderr,"uuid.%s %d cancelled\n",uuidstr,num); + return(num); +} + 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 || tp->cancelled != 0 ) + continue; + //printf("check %s\n",tp->Q.uuidstr+32); + 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 || tp->cancelled != 0 ) + { + //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); @@ -1027,9 +1251,17 @@ void LP_tradesloop(void *ctx) portable_mutex_lock(&LP_tradesmutex); DL_DELETE(LP_tradesQ,qtp); HASH_FIND(hh,LP_trades,&qtp->aliceid,sizeof(qtp->aliceid),tp); + if ( tp != 0 && tp->cancelled != 0 ) + + { + fprintf(stderr,"purging cancelled %s funcid.%d\n",tp->Q.uuidstr,tp->funcid); + HASH_DELETE(hh,LP_trades,tp); + free(tp); + continue; + } if ( tp == 0 ) { - if ( 0 && now > Q.timestamp+LP_AUTOTRADE_TIMEOUT*20 ) // eat expired + if ( now > Q.timestamp+LP_AUTOTRADE_TIMEOUT*2 || qtp->cancelled != 0 ) // eat expired free(qtp); else { @@ -1045,9 +1277,20 @@ void LP_tradesloop(void *ctx) { LP_trades_bestpricecheck(ctx,tp); } + else if ( tp->iambob == 0 && funcid == LP_CONNECTED ) + { + tp->negotiationdone = now; + //printf("alice sets negotiationdone.%u\n",now); + LP_trades_gotconnected(ctx,&tp->Q,&tp->Qs[LP_CONNECTED],tp->pairstr); + } nonz++; tp->firstprocessed = tp->lastprocessed = (uint32_t)time(NULL); - //printf("iambob.%d funcid.%d vs %d\n",tp->iambob,funcid,LP_REQUEST); + if ( funcid == LP_CONNECT && tp->negotiationdone == 0 ) // bob all done + { + tp->negotiationdone = now; + //printf("bob sets negotiationdone.%u\n",now); + LP_trades_gotconnect(ctx,&tp->Q,&tp->Qs[LP_CONNECT],tp->pairstr); + } } continue; } @@ -1055,85 +1298,46 @@ void LP_tradesloop(void *ctx) 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); +//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); - if ( tp->negotiationdone != 0 ) - continue; flag = 0; - if ( qtp->iambob == tp->iambob ) + if ( tp->iambob == 0 ) { - if ( tp->iambob == 0 ) + if ( funcid == LP_RESERVED ) { - if ( funcid == LP_RESERVED ) - { - if ( tp->connectsent == 0 ) - flag = LP_trades_bestpricecheck(ctx,tp); - } - else if ( funcid == LP_CONNECTED && tp->connectsent != 0 && tp->negotiationdone == 0 ) // alice all done - { - flag = 1; - tp->negotiationdone = now; - LP_trades_gotconnected(ctx,&tp->Q,&tp->Qs[LP_CONNECTED],tp->pairstr); - } + if ( tp->connectsent == 0 ) + flag = LP_trades_bestpricecheck(ctx,tp); } - else + else if ( funcid == LP_CONNECTED && tp->negotiationdone == 0 ) // alice all done tp->connectsent != 0 && { - if ( funcid == LP_CONNECT && tp->negotiationdone == 0 ) // bob all done - { - flag = 1; - tp->negotiationdone = now; - LP_trades_gotconnect(ctx,&tp->Q,&tp->Qs[LP_CONNECT],tp->pairstr); - } - } - if ( flag != 0 ) - { - tp->lastprocessed = (uint32_t)time(NULL); - nonz++; + 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; } } - 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); @@ -1160,33 +1364,40 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) safecopy(qtp->pairstr,pairstr,sizeof(qtp->pairstr)); DL_APPEND(LP_tradesQ,qtp); portable_mutex_unlock(&LP_tradesmutex); - //printf("queue.%d %p\n",funcid,qtp); + //printf("queue.%d uuid.(%s)\n",funcid,qtp->Q.uuidstr); } int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) { int32_t 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); - 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); - if ( Q.timestamp > 0 && time(NULL) > Q.timestamp + LP_AUTOTRADE_TIMEOUT*20 ) // eat expired packets + rq = ((uint64_t)Q.R.requestid << 32) | Q.R.quoteid; + if ( Q.uuidstr[0] == 0 || (Q.timestamp > 0 && time(NULL) > Q.timestamp + LP_AUTOTRADE_TIMEOUT*20) ) // eat expired packets, some old timestamps floating about? { - //printf("aliceid.%llu is expired by %d\n",(long long)Q.aliceid,(uint32_t)time(NULL) - (Q.timestamp + LP_AUTOTRADE_TIMEOUT*20)); - //return(1); + printf("uuid.%s aliceid.%llu is expired by %d\n",Q.uuidstr+32,(long long)Q.aliceid,(uint32_t)time(NULL) - (Q.timestamp + LP_AUTOTRADE_TIMEOUT*20)); + return(1); } - //LP_autoprices_update(method,Q.srccoin,dstr(Q.satoshis),Q.destcoin,dstr(Q.destsatoshis)); + LP_tradecommand_log(argjson); + qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); //jdouble(argjson,"price"); + //printf("%s\n",jprint(argjson,0)); + printf("%-4d uuid.%32s %12s %5s/%-5s %12.8f -> %12.8f (%11.8f) | RT.%d %d n%d\n",(uint32_t)time(NULL) % 3600,Q.uuidstr+32,method,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),qprice,LP_RTcount,LP_swapscount,G.netid); 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); @@ -1199,7 +1410,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 && (Q.vout != Q.vout2 || bits256_cmp(Q.txid,Q.txid2) != 0) ) // alice { if ( Qtrades == 0 ) { @@ -1215,12 +1426,22 @@ 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 ( 1 || Qtrades == 0 ) + if ( Qtrades == 0 ) LP_trades_gotconnected(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECTED); } @@ -1241,24 +1462,37 @@ 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 { - 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 ) - LP_trades_gotrequest(ctx,&Q,&Q2,jstr(argjson,"pair")); - else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_REQUEST); + //if ( LP_Alicemaxprice != 0. ) + // return(retval); + if ( Q.destvout != Q.feevout || bits256_cmp(Q.desttxid,Q.feetxid) != 0 ) + { + bestprice = LP_bob_competition(&counter,aliceid,qprice,-1); + 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 ( 1 || Qtrades == 0 ) + if ( Qtrades == 0 ) LP_trades_gotconnect(ctx,&Q,&Q2,jstr(argjson,"pair")); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECT); } @@ -1268,9 +1502,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,char *uuidstr) { - 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)); char _uuidstr[65]; basecoin = LP_coinfind(base); relcoin = LP_coinfind(rel); if ( gui == 0 ) @@ -1307,19 +1541,63 @@ 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); + if ( maxprice == 0. ) + return(clonestr("{\"error\":\"no orderbook entry found to handle request\"}")); + } 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; @@ -1335,7 +1613,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)); @@ -1344,10 +1622,40 @@ 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.); - return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); + LP_mypriceset(&changed,rel,base,1. / maxprice); + LP_mypriceset(&changed,base,rel,0.); + if ( uuidstr == 0 || uuidstr[0] == 0 ) + { + uint8_t uuidhash[256]; bits256 hash; uint64_t millis; int32_t len = 0; + memcpy(uuidhash,&G.LP_mypub25519,sizeof(bits256)), len += sizeof(bits256); + millis = OS_milliseconds(); + memcpy(&uuidhash[len],&millis,sizeof(millis)), len += sizeof(millis); + memcpy(&uuidhash[len],base,(int32_t)strlen(base)), len += (int32_t)strlen(base); + memcpy(&uuidhash[len],rel,(int32_t)strlen(rel)), len += (int32_t)strlen(rel); + vcalc_sha256(0,hash.bytes,uuidhash,len); + uuidstr = _uuidstr; + bits256_str(uuidstr,hash); + //char str[65]; printf("%s %llu %s %s -> uuid.%s\n",bits256_str(str,G.LP_mypub25519),(long long)millis,base,rel,uuidstr); + } + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey,uuidstr)); } diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c index dc324666f..1c4bf5a39 100644 --- a/iguana/exchanges/LP_peers.c +++ b/iguana/exchanges/LP_peers.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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..29d54d1ee 100644 --- a/iguana/exchanges/LP_portfolio.c +++ b/iguana/exchanges/LP_portfolio.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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 ) @@ -102,7 +110,7 @@ uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr) 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,"LTC") == 0 && ltc_btc > SMALLVAL ) + price = ltc_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 +636,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 +716,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 +757,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 +802,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)) != 0 ) { if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) { @@ -840,10 +896,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..0669b2c35 100644 --- a/iguana/exchanges/LP_prices.c +++ b/iguana/exchanges/LP_prices.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -114,7 +114,7 @@ void LP_pubkey_update(struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t reli DL_APPEND(pubp->quotes,pq); // already serialized as only path is via stats_JSON() //printf("create pubp quotes %d/%d\n",baseind,relind); } - //printf("%d/%d price %.8f balance %.8f %s num.%d %.8f %.8f\n",baseind,relind,price,dstr(balance),utxocoin,numutxos,dstr(minutxo),dstr(maxutxo)); +//printf("%d/%d price %.8f balance %.8f %s num.%d min %.8f max %.8f\n",baseind,relind,price,dstr(balance),utxocoin,numutxos,dstr(minutxo),dstr(maxutxo)); pq->price = price; if ( utxocoin != 0 && utxocoin[0] != 0 ) { @@ -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; @@ -1119,7 +1169,7 @@ cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,i void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *utxocoin,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo,int64_t unconfcredits) { struct LP_priceinfo *basepp,*relpp; uint32_t now; int64_t price64; struct LP_pubkey_info *pubp; char str[65],fname[512]; FILE *fp; - //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); +//printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s balance %.8f min %.8f max %.8f\n",base,rel,price,bits256_str(str,pubkey),dstr(balance),dstr(minutxo),dstr(maxutxo)); if ( LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) { //if ( (fp= basepp->fps[relpp->ind]) == 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..7d5403810 100644 --- a/iguana/exchanges/LP_privkey.c +++ b/iguana/exchanges/LP_privkey.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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..deaacf1c9 100644 --- a/iguana/exchanges/LP_remember.c +++ b/iguana/exchanges/LP_remember.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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]; @@ -64,9 +63,28 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx if ( swap->Bpayment[0] != 0 ) fprintf(fp,",\"%s\":\"%s\"","Bpayment",swap->Bpayment); fprintf(fp,",\"expiration\":%u",swap->I.expiration); + fprintf(fp,",\"uuid\":\"%s\"",swap->uuidstr); 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 ) @@ -100,6 +118,7 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx fprintf(fp,",\"Agui\":\"%s\"",G.gui); else fprintf(fp,",\"Bgui\":\"%s\"",G.gui); fprintf(fp,",\"gui\":\"%s\"",G.gui); + fprintf(fp,",\"uuid\":\"%s\"",swap->uuidstr); if ( memcmp(zeroes,swap->I.secretAm,20) != 0 ) { init_hexbytes_noT(secretAmstr,swap->I.secretAm,20); @@ -120,6 +139,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 +240,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 +303,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 +318,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 +414,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 +442,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); @@ -493,6 +631,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap) jaddnum(item,"critical",LP_swap_critical); jaddnum(item,"endcritical",LP_swap_endcritical); } + jaddstr(item,"uuid",rswap->uuidstr); jaddnum(item,"expiration",rswap->expiration);// - INSTANTDEX_LOCKTIME*2); jaddnum(item,"tradeid",rswap->tradeid); jaddnum(item,"requestid",rswap->requestid); @@ -502,9 +641,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 +686,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; @@ -549,9 +696,12 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t if ( (item= cJSON_Parse(fstr)) != 0 ) { rswap->iambob = jint(item,"iambob"); + safecopy(rswap->uuidstr,jstr(item,"uuid"),sizeof(rswap->uuidstr)); 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 +787,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 +820,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 +892,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,13 +937,14 @@ 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 ) { rswap->Dredeemlen >>= 1; decode_hex(rswap->Dredeemscript,rswap->Dredeemlen,rstr); } - rswap->values[i] = value = LP_value_extract(txobj,1); + rswap->values[i] = value = LP_value_extract(txobj,1,txid); if ( (symbol= jstr(txobj,"src")) != 0 ) { safecopy(rswap->src,symbol,sizeof(rswap->src)); @@ -792,9 +973,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 +993,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 +1069,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 +1097,27 @@ 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,"uuid",rswap.uuidstr); + 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 +1132,23 @@ 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,"uuid",rswap.uuidstr); + 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,"uuid",rswap.uuidstr); + 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 +1173,23 @@ 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,"uuid",rswap.uuidstr); + 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,"uuid",rswap.uuidstr); + 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 +1207,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 +1250,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 +1298,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 +1350,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 +1369,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 +1379,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 +1422,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 +1466,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 +1505,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 +1526,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 +1589,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 +1602,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 +1644,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,24 +1673,32 @@ 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\"}")); } +char *LP_kickstart(uint32_t requestid,uint32_t quoteid) +{ + char fname[512]; + sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + OS_portable_removefile(fname); + return(basilisk_swapentry(0,requestid,quoteid,1)); +} + extern struct LP_quoteinfo LP_Alicequery; extern uint32_t Alice_expiration; -char *LP_recent_swaps(int32_t limit) +char *LP_recent_swaps(int32_t limit,char *uuidstr) { char fname[512],*retstr,*base,*rel,*statusstr; long fsize,offset; FILE *fp; int32_t baseind,relind,i=0; uint32_t requestid,quoteid; cJSON *array,*item,*retjson,*subitem,*swapjson; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS]; double srcamount,destamount,netamounts[LP_MAXPRICEINFOS]; memset(KMDtotals,0,sizeof(KMDtotals)); @@ -1377,7 +1725,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 ) { @@ -1430,6 +1778,8 @@ char *LP_recent_swaps(int32_t limit) if ( time(NULL) < Alice_expiration ) { item = cJSON_CreateObject(); + if ( uuidstr != 0 ) + jaddstr(item,"uuid",uuidstr); jaddnum(item,"expiration",Alice_expiration); jaddnum(item,"timeleft",Alice_expiration-time(NULL)); jaddnum(item,"tradeid",LP_Alicequery.tradeid); @@ -1441,9 +1791,12 @@ 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)); + jaddbits256(item,"desthash",G.LP_mypub25519); + 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; + if ( uuidstr != 0 ) + jaddstr(retjson,"uuid",uuidstr); return(jprint(retjson,1)); } @@ -1469,14 +1822,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,10 +1851,11 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) } } free_json(retjson); + retjson = 0; } free(liststr); } - if ( (liststr= LP_recent_swaps(limit)) != 0 ) + if ( (liststr= LP_recent_swaps(limit,0)) != 0 ) { if ( (retjson= cJSON_Parse(liststr)) != 0 ) { @@ -1516,10 +1870,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); } @@ -1563,7 +1916,7 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) int32_t LP_pendingswap(uint32_t requestid,uint32_t quoteid) { cJSON *retjson,*array,*pending,*item; uint32_t r,q; char *retstr; int32_t i,n,retval = 0; - if ( (retstr= LP_recent_swaps(1000)) != 0 ) + if ( (retstr= LP_recent_swaps(1000,0)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index 76a4f820d..4680274ad 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -49,16 +49,17 @@ cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params) // bitcoind_passthru callers: "importaddress", "estimatefee", "getblockhash", "sendrawtransaction", "signrawtransaction" if ( coin != 0 ) { - //printf("issue.(%s, %s, %s, %s, %s)\n",coin->symbol,coin->serverport,coin->userpass,method,params); + if ( 0 && strcmp(method,"gettxout") == 0 && strcmp("BCH",coin->symbol) == 0 ) + 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,"getrawtransaction") == 0 || strcmp(method,"getblock") == 0 || strcmp(method,"getinfo") == 0 || strcmp(method,"getblockchaininfo") == 0 || strcmp(method,"importprivkey") == 0 || strcmp(method,"validateaddress") == 0 || strcmp(method,"getaddressinfo") == 0 || strcmp(method,"importaddress") == 0 ) { if ( coin->electrum == 0 ) { retstr = bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,method,params); - if ( 0 && strcmp("KMD",coin->symbol) == 0 ) - printf("%s.(%s %s): %s.%s -> (%s)\n",coin->symbol,coin->serverport,coin->userpass,method,params,retstr); + if ( 0 && strcmp("BCH",coin->symbol) == 0 ) + printf("%s.(%s %s): %s.%s -> (%s)\n",coin->symbol,coin->serverport,coin->userpass,method,params,retstr!=0?retstr:""); if ( retstr != 0 && retstr[0] != 0 ) { retjson = cJSON_Parse(retstr); @@ -76,7 +77,7 @@ cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params) } } } - } else retjson = cJSON_Parse("{\"result\":\"disabled\"}"); + } //else retjson = cJSON_Parse("{\"result\":\"disabled\"}"); } else printf("bitcoin_json cant talk to NULL coin\n"); return(retjson); } @@ -88,28 +89,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); @@ -120,8 +137,9 @@ int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin) uint64_t LP_RTsmartbalance(struct iguana_info *coin) { - cJSON *array,*item; char buf[512],*retstr; int32_t i,n; uint64_t valuesum,value; + cJSON *array,*item; char buf[512],*retstr; int32_t i,n; uint64_t valuesum,value; bits256 zero; valuesum = 0; + memset(zero.bytes,0,sizeof(zero)); sprintf(buf,"[0, 99999999, [\"%s\"]]",coin->smartaddr); retstr = bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,"listunspent",buf); if ( retstr != 0 && retstr[0] != 0 ) @@ -132,8 +150,9 @@ uint64_t LP_RTsmartbalance(struct iguana_info *coin) for (i=0; i %.8f\n",jprint(item,0),dstr(value)); } } free_json(array); @@ -163,10 +182,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 +212,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 +335,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()); @@ -325,7 +344,19 @@ cJSON *LP_validateaddress(char *symbol,char *address) else { sprintf(buf,"[\"%s\"]",address); - return(bitcoin_json(coin,"validateaddress",buf)); + if ( coin->validateaddress[0] == 0 ) + strcpy(coin->validateaddress,"validateaddress"); + if ( (retjson= bitcoin_json(coin,coin->validateaddress,buf)) != 0 ) + { + if ( strcmp(coin->symbol,"BTC") == 0 && jobj(retjson,"error") == 0 && jobj(retjson,"ismine") == 0 && strcmp(coin->validateaddress,"validateaddress") == 0 ) + { + printf("autochange %s validateaddress -> getaddressinfo\n",coin->symbol); + strcpy(coin->validateaddress,"getaddressinfo"); + free(retjson); + return(bitcoin_json(coin,coin->validateaddress,buf)); + } + } + return(retjson); } } @@ -354,7 +385,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 +416,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 +426,19 @@ 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; + usecache = 0; // disable unspents cache for native + //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 +448,29 @@ 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,buf,jprint(retjson,0)); + if ( (n= cJSON_GetArraySize(retjson)) > 0 ) + { + char str[65]; + 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 +505,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; @@ -464,7 +551,7 @@ int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t { *txidp = jbits256(item,"txid"); *voutp = juint(item,"vout"); - satoshis = LP_value_extract(item,0); + satoshis = LP_value_extract(item,0,*txidp); *heightp = LP_txheight(coin,*txidp); } else @@ -523,7 +610,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 +625,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 ) @@ -551,7 +641,7 @@ int32_t LP_importaddress(char *symbol,char *address) sprintf(buf,"[\"%s\", \"%s\", false]",address,address); if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"importaddress",buf)) != 0 ) { - //printf("importaddress.(%s %s) -> (%s)\n",symbol,address,retstr); + printf("importaddress.(%s %s) -> (%s)\n",symbol,address,retstr); free(retstr); } //else printf("importaddress.(%s %s)\n",symbol,address); return(1); @@ -573,13 +663,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 +688,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 +873,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 +997,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 +1126,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 +1138,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..1229c2782 100644 --- a/iguana/exchanges/LP_scan.c +++ b/iguana/exchanges/LP_scan.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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..edfdee35b 100644 --- a/iguana/exchanges/LP_secp.c +++ b/iguana/exchanges/LP_secp.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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 4ac5a051b..2c45e53ce 100644 --- a/iguana/exchanges/LP_signatures.c +++ b/iguana/exchanges/LP_signatures.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -41,13 +41,20 @@ 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); + jaddstr(retjson,"uuid",qp->uuidstr); 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 +111,32 @@ 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)); + safecopy(qp->uuidstr,jstr(argjson,"uuid"),sizeof(qp->uuidstr)); + 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 +151,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 +424,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 +442,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 +459,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; uint8_t pubkey33[33]; char *base,*rel,*argstr,coinaddr[64]; //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 +468,31 @@ 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"); + if ( jstr(argjson,"pubsecp") != 0 ) + { + static char lasterror[64]; + decode_hex(pubkey33,33,jstr(argjson,"pubsecp")); + bitcoin_address("KMD",coinaddr,0,60,pubkey33,33); + if ( strcmp(coinaddr,lasterror) != 0 ) + { + printf("sig failure.(%s) %s\n",jprint(argjson,0),coinaddr); + strcpy(lasterror,coinaddr); + } + } return(clonestr("{\"error\":\"sig failure\"}")); } } @@ -547,7 +593,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 +607,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 +672,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,25 +717,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,"connect") == 0 ) - { - sleep(1); - LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); - sleep(1); - LP_reserved_msg(0,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..b8e74e84c 100644 --- a/iguana/exchanges/LP_socket.c +++ b/iguana/exchanges/LP_socket.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -296,14 +296,14 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep { txid = jbits256(item,"txid"); v = jint(item,"vout"); - value = LP_value_extract(item,0); + value = LP_value_extract(item,0,txid); ht = LP_txheight(coin,txid); if ( (retjson= LP_gettxout(coin->symbol,coinaddr,txid,v)) != 0 ) free_json(retjson); 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); @@ -593,15 +613,23 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON if ( (ap= LP_address(coin,addr)) != 0 ) { if ( ap->unspenttime == 0 ) - usecache = 0; + { + ap->unspenttime = (uint32_t)time(NULL); + ap->unspentheight = height; + usecache = 1; + } else if ( ap->unspentheight < height ) usecache = 0; else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+13 ) usecache = 0; } + //usecache = 0; // disable unspents cache 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 +644,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 +670,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 +780,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); @@ -1037,7 +1069,7 @@ void LP_dedicatedloop(void *arg) else { #ifndef _WIN32 - printf("no more electrum data when expected2\n"); + printf("no more electrum data when expected2 len.%d n.%d\n",len,n); electrum_kickstart(ep); #endif break; diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c index e62279232..9268e2674 100644 --- a/iguana/exchanges/LP_statemachine.c +++ b/iguana/exchanges/LP_statemachine.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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 721a8c2ab..e62838ade 100644 --- a/iguana/exchanges/LP_stats.c +++ b/iguana/exchanges/LP_stats.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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); + } } } @@ -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..c28f06495 100644 --- a/iguana/exchanges/LP_swap.c +++ b/iguana/exchanges/LP_swap.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -18,9 +18,6 @@ // marketmaker // -/* - make sure to broadcast deposit before claiming refund, or to just skip it if neither is done - */ // included from basilisk.c @@ -34,23 +31,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 +59,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,13 +104,15 @@ depositspent.(f34e04ad74e290f63f3d0bccb7d0d50abfa54eea58de38816fdc596a19767add) alice.1 bob.0 */ - +#define TX_WAIT_TIMEOUT 1800 // hard to increase this without hitting protocol limits (2/4 hrs) uint32_t LP_atomic_locktime(char *base,char *rel) { - if ( strcmp(base,"BTC") != 0 && strcmp(rel,"BTC") != 0 ) - return(INSTANTDEX_LOCKTIME); - else return(INSTANTDEX_LOCKTIME * 10); + if ( strcmp(base,"BTC") == 0 && strcmp(rel,"BTC") == 0 ) + return(INSTANTDEX_LOCKTIME * 10); + else if ( LP_is_slowcoin(base) > 0 || LP_is_slowcoin(rel) > 0 ) + return(INSTANTDEX_LOCKTIME * 4); + else return(INSTANTDEX_LOCKTIME); } void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx) @@ -192,7 +207,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 +268,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 +276,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 +284,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 +488,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 +553,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 +568,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 +588,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 +600,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 +611,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 +648,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 +667,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 +687,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)); @@ -678,6 +705,7 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3 { if ( bits256_nonz(rawtx->I.signedtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) { + basilisk_dontforget_update(swap,rawtx); rawtx->I.actualtxid = LP_broadcast_tx(rawtx->name,rawtx->symbol,rawtx->txbytes,rawtx->I.datalen); if ( bits256_cmp(rawtx->I.actualtxid,rawtx->I.signedtxid) != 0 ) { @@ -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,137 @@ 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); + } +} + +int32_t LP_calc_waittimeout(char *symbol) +{ + int32_t waittimeout = TX_WAIT_TIMEOUT; + if ( strcmp(symbol,"BTC") == 0 ) + waittimeout *= 8; + else if ( LP_is_slowcoin(symbol) != 0 ) + waittimeout *= 4; + return(waittimeout); } 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 bobwaittimeout,alicewaittimeout,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; + bobwaittimeout = LP_calc_waittimeout(bobstr); + alicewaittimeout = LP_calc_waittimeout(alicestr); 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,bobwaittimeout,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,alicewaittimeout,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,99 +920,101 @@ 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,swap->uuidstr); + 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 bobwaittimeout,alicewaittimeout,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; + bobwaittimeout = LP_calc_waittimeout(bobstr); + alicewaittimeout = LP_calc_waittimeout(alicestr); if ( swap != 0 ) { printf("start swap iamalice pair.%d\n",swap->N.pair); if ( LP_sendwait("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) - 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,bobwaittimeout,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,bobwaittimeout,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,swap->uuidstr); + 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 +1028,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 +1083,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 +1094,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 +1117,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 +1169,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 +1211,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 +1229,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 +1241,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 +1298,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 +1308,27 @@ 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)); + memcpy(swap->uuidstr,qp->uuidstr,sizeof(swap->uuidstr)); 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..3e14102ab 100644 --- a/iguana/exchanges/LP_tradebots.c +++ b/iguana/exchanges/LP_tradebots.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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 ) @@ -322,7 +322,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) LP_tradebot_calcstats(bot); if ( bot->dead == 0 && bot->pause == 0 && bot->userpause == 0 && bot->numtrades < sizeof(bot->trades)/sizeof(*bot->trades) ) { - if ( (liststr= LP_recent_swaps(0)) != 0 ) + if ( (liststr= LP_recent_swaps(0,0)) != 0 ) { if ( (retjson= cJSON_Parse(liststr)) != 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)) != 0 ) { if ( (retjson2= cJSON_Parse(retstr)) != 0 ) { diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c index 6840a900f..826a7f1e2 100644 --- a/iguana/exchanges/LP_transaction.c +++ b/iguana/exchanges/LP_transaction.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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,22 +781,28 @@ 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 ) { obj = jitem(vouts,utxovout); - value = LP_value_extract(obj,1); + value = LP_value_extract(obj,1,utxotxid); //printf("value in vout.%d %.8f (%s)\n",vout,dstr(value),jprint(txobj,0)); } free_json(txobj); } 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,9 +1032,11 @@ 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; + if ( nLockTime > 1536000000 && minutes > 31*24*60 ) + minutes = 31 * 24 * 60; minutes -= 59; interest = ((nValue / 10512000) * minutes); } @@ -1077,7 +1110,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 +1118,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 +1214,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 +1227,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; @@ -1231,7 +1270,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf return(0); } amount += value; - printf("vout.%d %.8f -> total %.8f\n",i,dstr(value),dstr(amount)); + //printf("vout.%d %.8f -> total %.8f\n",i,dstr(value),dstr(amount)); } else { @@ -1274,7 +1313,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); } @@ -1312,6 +1369,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); @@ -1320,16 +1435,376 @@ 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,coinaddr) <= 0 ) + { + fprintf(stderr,"%s LP_createblasttransaction %s i.%d of %d is invalid\n",coin->symbol,coinaddr,i,numvouts); + return(0); + } + if ( (value= SATOSHIDEN * jdouble(item,coinaddr)) <= 0 ) + { + fprintf(stderr,"LP_createblasttransaction: cant get value %s i.%d of %d %s\n",coinaddr,i,numvouts,jprint(outputs,0)); + return(0); + } + amount += value; + //printf("vout.%d %.8f -> total %.8f\n",i,dstr(value),dstr(amount)); + } + else + { + fprintf(stderr,"LP_createblasttransaction: cant get fieldname.%d of %d %s\n",i,numvouts,jprint(outputs,0)); + return(0); + } + } + ignore_cltverr = 0; + suppress_pubkeys = 1; + memset(V,0,sizeof(*V)); + V->N = V->M = 1; + V->signers[0].privkey = privkey; + bitcoin_priv2wif(coin->symbol,coin->wiftaddr,wifstr,privkey,coin->wiftype); + bitcoin_priv2pub(ctx,coin->symbol,pubkey33,blastaddr,privkey,coin->taddr,coin->pubtype); + bitcoin_addr2rmd160("KMD",coin->taddr,&tmptype,rmd160,blastaddr); + V->suppress_pubkeys = suppress_pubkeys; + V->ignore_cltverr = ignore_cltverr; + change = (utxovalue - amount); + timestamp = (uint32_t)time(NULL); + locktime = 0; + txobj = bitcoin_txcreate(coin->symbol,coin->isPoS,locktime,coin->txversion,timestamp); + scriptlen = bitcoin_standardspend(script,0,rmd160); + init_hexbytes_noT(spendscriptstr,script,scriptlen); + vins = cJSON_CreateArray(); + jaddi(vins,LP_inputjson(utxotxid,utxovout,spendscriptstr)); + jdelete(txobj,"vin"); + jadd(txobj,"vin",jduplicate(vins)); + *vinsp = vins; + for (i=0; i> 1; + if ( spendlen < sizeof(script) ) + { + decode_hex(spendscript,spendlen,scriptstr); + //printf("i.%d using external script.(%s) %d\n",i,scriptstr,spendlen); + } + else + { + fprintf(stderr,"LP_createblasttransaction: 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 ) + { + value += change; + change = 0; + } + } + txobj = bitcoin_txoutput(txobj,spendscript,spendlen,value + adjust); + } + else + { + fprintf(stderr,"LP_createblasttransaction: cant get fieldname.%d of %d %s\n",i,numvouts,jprint(outputs,0)); + free_json(txobj); + return(0); + } + } + if ( change < 6000 || change < txfee ) + change = 0; + *changep = change; + if ( change != 0 ) + { + txobj = bitcoin_txoutput(txobj,script,scriptlen,change); + *changeoutp = numvouts; + } + if ( (rawtxbytes= bitcoin_json2hex(coin->symbol,coin->isPoS,&txid,txobj,V)) == 0 ) + fprintf(stderr,"LP_createblasttransaction: error making rawtx suppress.%d\n",suppress_pubkeys); + *txobjp = txobj; + return(rawtxbytes); +} + +char *bitcoin_signrawtransaction(int32_t *completedp,bits256 *signedtxidp,struct iguana_info *coin,char *rawtx,char *wifstr) +{ + char *retstr,*paramstr,*hexstr,*signedtx = 0; int32_t len; uint8_t *data; cJSON *signedjson; + *completedp = 0; + memset(signedtxidp,0,sizeof(*signedtxidp)); + paramstr = calloc(1,200000+1); + sprintf(paramstr,"[\"%s\", null, [\"%s\"]]",rawtx,wifstr); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,"signrawtransaction",paramstr)) != 0 ) + { + //printf("%s signed -> %s\n",coin->symbol,retstr); + if ( (signedjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (hexstr= jstr(signedjson,"hex")) != 0 ) + { + len = (int32_t)strlen(hexstr); + signedtx = calloc(1,len+1); + strcpy(signedtx,hexstr); + *completedp = is_cJSON_True(jobj(signedjson,"complete")); + len >>= 1; + data = malloc(len); + decode_hex(data,len,hexstr); + *signedtxidp = bits256_calctxid(coin->symbol,data,len); + free(data); + } + free_json(signedjson); + } + free(retstr); + } + free(paramstr); + return(signedtx); +} + +char *LP_txblast(struct iguana_info *coin,cJSON *argjson) +{ + static void *ctx; + int32_t broadcast,i,num,numblast,utxovout,completed=0,numvouts,changeout; char *passphrase,changeaddr[64],vinaddr[64],wifstr[65],blastaddr[65],str[65],*signret,*signedtx=0,*rawtx=0; struct vin_info V; uint32_t locktime,starttime; uint8_t pubkey33[33]; cJSON *retjson,*item,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 privkey,pubkey,checktxid,utxotxid,signedtxid; uint64_t txfee,utxovalue,change; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + if ( (passphrase= jstr(argjson,"password")) == 0 ) + return(clonestr("{\"error\":\"need password\"}")); + outputs = jarray(&numvouts,argjson,"outputs"); + utxotxid = jbits256(argjson,"utxotxid"); + utxovout = jint(argjson,"utxovout"); + if ( (numblast= jint(argjson,"numblast")) == 0 ) + numblast = 1000000; + utxovalue = j64bits(argjson,"utxovalue"); + txfee = juint(argjson,"txfee"); + broadcast = juint(argjson,"broadcast"); + conv_NXTpassword(privkey.bytes,pubkey.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,wifstr,privkey,coin->wiftype); + bitcoin_priv2pub(ctx,coin->symbol,pubkey33,blastaddr,privkey,coin->taddr,coin->pubtype); + safecopy(vinaddr,blastaddr,sizeof(vinaddr)); + safecopy(changeaddr,blastaddr,sizeof(changeaddr)); + privkeys = cJSON_CreateArray(); + jaddistr(privkeys,wifstr); + starttime = (uint32_t)time(NULL); + for (i=0; isymbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&msgtx,&signedtx,&signedtxid,&V,1,rawtx,vins,privkeys,coin->zcash)) < 0 ) + printf("LP_txblast: couldnt sign blast tx %s\n",bits256_str(str,signedtxid)); + else if ( completed == 0 ) + { + printf("LP_txblast incomplete signing blast tx (%s)\n",jprint(vins,0)); + break; + } + else + { + if ( broadcast != 0 ) + { + if ( (signret= LP_sendrawtransaction(coin->symbol,signedtx)) != 0 ) + { + printf("LP_txblast.%s broadcast (%s) vs %s\n",coin->symbol,bits256_str(str,signedtxid),signret); + if ( is_hexstr(signret,0) == 64 ) + { + decode_hex(checktxid.bytes,32,signret); + if ( bits256_cmp(checktxid,signedtxid) == 0 ) + { + printf("blaster i.%d of %d: %s/v%d %.8f\n",i,numblast,bits256_str(str,signedtxid),changeout,dstr(change)); + } else break; + } + else + { + printf("error sending tx:\n \"%s\" null '[\"%s\"]'\n",rawtx,wifstr); + break; + } + free(signret); + } + else + { + fprintf(stderr,"null return from LP_sendrawtransaction\n"); + break; + } + } else printf("blaster i.%d of %d: %s/v%d %.8f %s\n",i,numblast,bits256_str(str,signedtxid),changeout,dstr(change),signedtx); + } + } + else + { + fprintf(stderr,"error creating txblast rawtransaction\n"); + break; + } + if ( txobj != 0 ) + free_json(txobj), txobj = 0; + if ( rawtx != 0 ) + free(rawtx), rawtx = 0; + if ( signedtx != 0 ) + free(signedtx), signedtx = 0; + if ( changeout < 0 || change == 0 ) + break; + utxotxid = signedtxid; + utxovout = changeout; + utxovalue = change; + // good place to update outputs[] for a fully programmable blast + } + free_json(privkeys), privkeys = 0; + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"blastaddr",blastaddr); + jaddnum(retjson,"broadcast",broadcast); + jaddnum(retjson,"numblast",numblast); + jaddnum(retjson,"completed",i); + jaddbits256(retjson,"lastutxo",utxotxid); + jaddnum(retjson,"lastutxovout",utxovout); + jaddnum(retjson,"lastutxovalue",dstr(utxovalue)); + jaddnum(retjson,"elapsed",(uint32_t)time(NULL) - starttime); + jaddnum(retjson,"tx/sec",(double)i / ((uint32_t)time(NULL) - starttime + 1)); + return(jprint(retjson,1)); +} + char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) { static void *ctx; - int32_t iter,i,utxovout,autofee,completed=0,maxV,numvins,numvouts,datalen,suppress_pubkeys; bits256 privkey; struct LP_address *ap; char changeaddr[64],vinaddr[64],str[65],*signedtx=0,*rawtx=0; struct vin_info *V; uint32_t locktime; cJSON *retjson,*item,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 utxotxid,signedtxid; uint64_t txfee,newtxfee=10000; + int32_t broadcast,allocated_outputs=0,iter,i,num,utxovout,autofee,completed=0,maxV,numvins,numvouts,datalen,suppress_pubkeys; bits256 privkey; struct LP_address *ap; char changeaddr[64],vinaddr[64],str[65],*signret,*signedtx=0,*rawtx=0; struct vin_info *V; uint32_t locktime; cJSON *retjson,*item,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 utxotxid,signedtxid; uint64_t txfee=0,newtxfee=10000; +//printf("withdraw.%s %s\n",coin->symbol,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"); @@ -1352,17 +1827,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)); @@ -1374,18 +1844,18 @@ 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; - if ( iter == 0 && strcmp(coin->symbol,"BTC") == 0 ) + if ( autofee != 0 && iter == 0 && strcmp(coin->symbol,"BTC") == 0 ) { - newtxfee = LP_txfeecalc(coin,0,datalen); + txfee = newtxfee = LP_txfeecalc(coin,0,datalen); printf("txfee %.8f -> newtxfee %.8f, numvins.%d\n",dstr(txfee),dstr(newtxfee),numvins); for (i=0; i 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); + jaddnum(retjson,"txfee",txfee); 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,txfee; + if ( coin->etomic[0] == 0 ) + { + if ( coin->electrum != 0 ) + balance = LP_unspents_load(coin->symbol,coin->smartaddr); + else balance = LP_RTsmartbalance(coin); + if ( (txfee= coin->txfee) == 0 ) // BTC + txfee = LP_txfeecalc(coin,0,500); + balance -= (txfee + 100000); + //printf("balance %.8f, txfee %.8f, threshold %.8f\n",dstr(balance),dstr(txfee),dstr((1000000 - (txfee + 100000)))); + if ( balance > txfee && balance >= (1000000 - (txfee + 100000)) ) + { + halfval = (balance / 100) * 45; + 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("halfval %.8f autosplit.(%s)\n",dstr(halfval),jprint(argjson,0)); + retstr = LP_withdraw(coin,argjson); + free_json(argjson); + return(retstr); + } else return(clonestr("{\"error\":\"balance too small to autosplit, please make more deposits\"}")); + } + return(clonestr("{\"error\":\"couldnt 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); @@ -1458,49 +2014,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) @@ -1583,7 +2103,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); @@ -1594,8 +2114,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); @@ -1603,7 +2125,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); @@ -1686,7 +2208,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); @@ -1854,20 +2372,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); @@ -1880,7 +2399,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); } @@ -1897,7 +2416,7 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u { vout = jitem(vouts,v); if ( valuep != 0 ) - *valuep = LP_value_extract(vout,1); + *valuep = LP_value_extract(vout,1,signedtxid); LP_destaddr(coinaddr,vout); } free_json(txobj); @@ -1906,8 +2425,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 ) @@ -1931,13 +2451,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 ) { @@ -1968,9 +2488,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 ) { @@ -1978,48 +2498,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]; @@ -2031,8 +2518,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); @@ -2044,26 +2532,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 @@ -2074,29 +2562,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); } @@ -2106,8 +2605,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 ) { @@ -2118,22 +2618,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 ) { @@ -2142,7 +2643,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; @@ -2162,25 +2666,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 ) { @@ -2191,20 +2703,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 ) @@ -2213,6 +2742,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); @@ -2232,6 +2762,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++) @@ -2244,7 +2781,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..eb4b37131 100644 --- a/iguana/exchanges/LP_utxo.c +++ b/iguana/exchanges/LP_utxo.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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); } @@ -183,9 +206,9 @@ int32_t LP_nearestvalue(int32_t iambob,uint64_t *values,int32_t n,uint64_t targe return(mini); } -uint64_t LP_value_extract(cJSON *obj,int32_t addinterest) +uint64_t LP_value_extract(cJSON *obj,int32_t addinterest,bits256 utxotxid) { - double val = 0.; uint64_t value = 0; int32_t electrumflag; + double val = 0.; uint64_t interest,value = 0; int32_t electrumflag; electrumflag = (jobj(obj,"tx_hash") != 0); if ( electrumflag == 0 ) { @@ -195,8 +218,17 @@ uint64_t LP_value_extract(cJSON *obj,int32_t addinterest) } else value = j64bits(obj,"value"); if ( value != 0 ) { - if ( addinterest != 0 && jobj(obj,"interest") != 0 ) - value += (jdouble(obj,"interest") * SATOSHIDEN); + if ( addinterest != 0 ) + { + if ( jobj(obj,"interest") != 0 ) + value += (jdouble(obj,"interest") * SATOSHIDEN); + else + { + interest = LP_komodo_interest(utxotxid,value); + //char str[65]; printf("(%s) txid.%s %.8f + %.8f\n",jprint(obj,0),bits256_str(str,utxotxid),dstr(value),dstr(interest)); + value += interest; + } + } } return(value); } @@ -260,35 +292,72 @@ 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]; + //printf("buf[%d] %.8f -> maxp, m.%d/2 %.8f -> median\n",i,dstr(*maxp),m,dstr(*medianp)); + break; + } + } + } else printf("sort error? max %.8f != %.8f\n",dstr(max),dstr(buf[0])); + //printf("vs. max %.8f %s maxp %.8f median %.8f\n",dstr(max),coin->symbol,dstr(*maxp),dstr(*medianp)); + } + 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) { - struct LP_address_utxo *up,*tmp; struct LP_transaction *tx; cJSON *txout; int32_t n = 0; + struct LP_address_utxo *up,*tmp; struct LP_transaction *tx; cJSON *txout; int32_t i,n = 0; if ( strcmp(ap->coinaddr,coinaddr) != 0 ) printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr); //portable_mutex_lock(&LP_utxomutex); @@ -301,9 +370,9 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a { if ( (txout= LP_gettxout(coin->symbol,coinaddr,up->U.txid,up->U.vout)) != 0 ) { - if ( LP_value_extract(txout,0) == 0 ) + if ( LP_value_extract(txout,0,up->U.txid) == 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 +383,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; @@ -333,9 +402,15 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a } if ( LP_allocated(up->U.txid,up->U.vout) == 0 ) { - utxos[n++] = up; - if ( n >= max ) - break; + for (i=0; iU.vout == up->U.vout && bits256_cmp(utxos[i]->U.txid,up->U.txid) == 0 ) + break; + if ( i == n ) + { + utxos[n++] = up; + if ( n >= max ) + break; + } } //else printf("LP_allocated skip %u\n",LP_allocated(up->U.txid,up->U.vout)); } else @@ -381,9 +456,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 +468,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 +495,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 +534,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 +548,64 @@ 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 ) { + //printf("%s array.%s\n",coin->symbol,jprint(array,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 +657,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 +696,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 { @@ -708,7 +832,7 @@ int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array) val = j64bits(item,"value"); if ( coin->electrum == 0 && (txobj= LP_gettxout(coin->symbol,coinaddr,txid,v)) != 0 ) { - value = LP_value_extract(txobj,0); + value = LP_value_extract(txobj,0,txid); if ( value != 0 && value != val ) { char str[65]; printf("REJECT %s %s/v%d value.%llu vs %llu (%s)\n",coin->symbol,bits256_str(str,txid),v,(long long)value,(long long)val,jprint(txobj,0)); @@ -728,7 +852,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 +898,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); @@ -788,11 +912,11 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS for (i=0; ioutpoints[i].value = LP_value_extract(vout,0); + tx->outpoints[i].value = LP_value_extract(vout,0,txid); 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 +938,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 +955,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 +972,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 +993,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 +1025,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 +1043,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); } @@ -914,7 +1065,7 @@ uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_inf destaddr[0] = 0; if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) != 0 ) { - if ( (value= LP_value_extract(txobj,0)) == 0 ) + if ( (value= LP_value_extract(txobj,0,txid)) == 0 ) { char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",coin->symbol,bits256_str(str,txid),jprint(txobj,0),vout); } @@ -988,20 +1139,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")); + value = LP_value_extract(txobj,0,txid);//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 (%s)\n",coin->symbol,bits256_str(str,txid),vout,dstr(value),jprint(txobj,0)); 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):""); + } //else printf("null return from LP_gettxout %s %s %s/v%d\n",coin->symbol,coinaddr,bits256_str(str,txid),vout); + printf("pruned node or rpc access broken? 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,10 +1166,10 @@ 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); + amount = LP_value_extract(jitem(vouts,vout),0,txid); free_json(txjson); } } 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/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/cancel b/iguana/exchanges/cancel new file mode 100755 index 000000000..2f7bc1111 --- /dev/null +++ b/iguana/exchanges/cancel @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"cancel\",\"uuid\":\"\"}" 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 ea4959342..e41c4b7d7 100644 --- a/iguana/exchanges/coins +++ b/iguana/exchanges/coins @@ -1,3 +1,2 @@ -export coins="[{\"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}]" +export coins="[{\"coin\":\"MGO\",\"name\":\"mobilego\",\"etomic\":\"0x40395044Ac3c0C57051906dA938B54BD6557F212\",\"rpcport\":80},{\"coin\":\"DRGN\",\"name\":\"dragonchain\",\"etomic\":\"0x419c4db4b9e25d6db2ad9691ccb832c8d9fda05e\",\"rpcport\":80}, {\"coin\":\"GLD\",\"name\":\"goldcoin\",\"rpcport\":9332,\"pubtype\":32,\"p2shtype\":5,\"wiftype\":160,\"txfee\":100000}, {\"coin\":\"BTK\",\"name\":\"bitcointoken\",\"etomic\":\"0xdb8646F5b487B5Dd979FAC618350e85018F557d4\",\"rpcport\":80},{\"coin\":\"DGPT\",\"name\":\"digipulse\",\"etomic\":\"0xf6cFe53d6FEbaEEA051f400ff5fc14F0cBBDacA1\",\"rpcport\":80}, {\"coin\":\"OCT\",\"name\":\"octus\",\"etomic\":\"0x7e9d365C0C97Fe5FcAdcc1B513Af974b768C5867\",\"rpcport\":80},{\"coin\":\"STWY\",\"name\":\"storweeytoken\",\"etomic\":\"0x8a8c71f032362fca2994f75d854f911ec381ac5a\",\"rpcport\":80}, {\"coin\":\"SPK\",\"name\":\"Sparks\",\"rpcport\":8892,\"pubtype\":38,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\":\"PCL\",\"name\":\"peculium\",\"etomic\":\"0x3618516f45cd3c913f81f9987af41077932bc40d\",\"rpcport\":80}, {\"coin\":\"RLTY\",\"name\":\"smartrealty\",\"etomic\":\"0xbe99b09709fc753b09bcf557a992f6605d5997b0\",\"rpcport\":80},{\"coin\":\"CIX\",\"name\":\"cryptonetix\",\"etomic\":\"0x1175a66a5c3343Bbf06AA818BB482DdEc30858E0\",\"rpcport\":80}, {\"coin\":\"GLXT\",\"asset\":\"GLXT\",\"rpcport\":15723}, {\"coin\":\"PYRO\",\"name\":\"pyro\",\"confpath\":\"${HOME#}/.pyrocore/pyro.conf\",\"rpcport\":9696,\"pubtype\":55,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\": \"BNTN\",\"asset\": \"BNTN\",\"rpcport\": 14358},{\"coin\":\"ORE\",\"name\":\"galactrum\",\"rpcport\":6269,\"pubtype\":38,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"ELD\",\"name\":\"maker\",\"etomic\":\"0xaaf7d4cd097317d68174215395eb02c2cca81e31\",\"rpcport\":80}, {\"coin\":\"CENNZ\",\"name\":\"centrality\",\"etomic\":\"0x1122b6a0e00dce0563082b6e2953f3a943855c1f\",\"rpcport\":80}, {\"coin\":\"PGN\",\"name\":\"pigeon\",\"rpcport\":8756,\"pubtype\":55,\"p2shtype\":122,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"XCG\",\"name\":\"Xchange\",\"confpath\":\"${HOME#}/.Xchangecore/Xchange.conf\",\"rpcport\":9386,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"AXE\",\"name\":\"axe\",\"confpath\":\"${HOME#}/.axecore/axe.conf\",\"rpcport\":9337,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"PEW\",\"name\":\"brofist\",\"rpcport\":12454,\"pubtype\":55,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000,\"confpath\":\"${HOME#}/.brofistcore/brofist.conf\"}, {\"coin\":\"BCBC\",\"name\":\"bitcoin@cbc\",\"confpath\":\"${HOME#}/.bitcoin@cbc/bitcoin.conf\",\"rpcport\":8340,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"GRLC\",\"name\":\"garlicoin\",\"rpcport\":42068,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"EQL\",\"asset\":\"EQL\",\"rpcport\":10306}, {\"coin\":\"OCC\",\"name\":\"originalcryptocoin\",\"etomic\":\"0x0235fe624e044a05eed7a43e16e3083bc8a4287a\",\"rpcport\":80}, {\"coin\":\"DIN\",\"name\":\"dinero\",\"rpcport\":9998,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":204,\"txfee\":10000,\"confpath\":\"${HOME#}/.dinerocore/dinero.conf\"}, {\"coin\":\"BUCK\",\"name\":\"buck\",\"rpcport\":5739,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"LYS\",\"name\":\"lightyears\",\"etomic\":\"0xdd41fbd1ae95c5d9b198174a28e04be6b3d1aa27\",\"rpcport\":80}, {\"coin\":\"RAP\",\"name\":\"rapture\",\"rpcport\":14776,\"pubtype\":60,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000,\"confpath\":\"${HOME#}/.rapturecore/rapture.conf\"}, {\"coin\":\"RADIUS\",\"name\":\"radius\",\"rpcport\":4089,\"pubtype\":60,\"p2shtype\":16,\"wiftype\":15,\"txfee\":10000,\"confpath\":\"${HOME#}/.radiuscore/radius.conf\"},{\"coin\":\"BTCL\",\"name\":\"btclite\",\"etomic\":\"0x5acd19b9c91e596b1f062f18e3d02da7ed8d1e50\",\"rpcport\":80}, {\"coin\":\"SEQ\",\"name\":\"sequence\",\"rpcport\":16663,\"isPoS\":1,\"pubtype\":63,\"p2shtype\":64,\"wiftype\":170,\"txfee\":10000}, {\"coin\":\"DYN\",\"name\":\"dynamic\",\"rpcport\":33350,\"pubtype\":30,\"p2shtype\":10,\"wiftype\":140,\"txfee\":10000}, {\"coin\":\"SBTC\",\"name\":\"SuperBitcoin\",\"rpcport\":28282,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000,\"confpath\":\"${HOME#}/.sbtc/sbtc.conf\"}, {\"coin\":\"FJC\",\"name\":\"fujicoin\",\"rpcport\":3776,\"pubtype\":36,\"p2shtype\":16,\"wiftype\":164,\"txfee\":100000}, {\"coin\":\"AIR\",\"name\":\"airtoken\",\"etomic\":\"0x27dce1ec4d3f72c3e457cc50354f1f975ddef488\",\"rpcport\":80}, {\"coin\":\"VRT\",\"name\":\"virtus\",\"confpath\":\"${HOME#}/.virtuscore/virtus.conf\",\"rpcport\":13880,\"pubtype\":70,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"DRT\",\"name\":\"domraider\",\"etomic\":\"0x9af4f26941677c706cfecf6d3379ff01bb85d5ab\",\"rpcport\":80}, {\"coin\":\"BITS\",\"name\":\"bitstar\",\"rpcport\":15715,\"isPoS\":1,\"pubtype\":25,\"p2shtype\":8,\"wiftype\":153,\"txfee\":10000}, {\"coin\":\"FTC\",\"name\":\"feathercoin\",\"rpcport\":9337,\"pubtype\":14,\"p2shtype\":5,\"wiftype\":142,\"txfee\":1000000}, {\"coin\":\"PXT\",\"name\":\"populous-xbrl-token\",\"etomic\":\"0xc14830e53aa344e8c14603a91229a0b925b0b262\",\"rpcport\":80}, {\"coin\":\"USDT\",\"name\":\"tether\",\"etomic\":\"0xdac17f958d2ee523a2206206994597c13d831ec7\",\"rpcport\":80}, {\"coin\":\"ELI\",\"name\":\"elicoin\",\"rpcport\":9332,\"pubtype\":33,\"p2shtype\":102,\"wiftype\":205,\"txfee\":10000}, {\"coin\":\"SCRIV\",\"name\":\"scriv\",\"confpath\":\"${HOME#}/.scrivcore/scriv.conf\",\"rpcport\":7998,\"pubtype\":125,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"ELP\",\"name\":\"ellerium\",\"rpcport\":61020,\"pubtype\":23,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, {\"coin\":\"ROI\",\"name\":\"ROIcoin\",\"rpcport\":3376,\"pubtype\":60,\"p2shtype\":122,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"XCOIN\",\"name\":\"xcoin\",\"rpcport\":22717,\"pubtype\":137,\"p2shtype\":15,\"wiftype\":75,\"txfee\":100000}, {\"coin\":\"BBT\",\"name\":\"bitboost\",\"etomic\":\"0x1500205f50bf3fd976466d0662905c9ff254fc9c\",\"rpcport\":80}, {\"coin\":\"TRX\",\"name\":\"tron\",\"etomic\":\"0xf230b790e05390fc8295f4d3f60332c93bed42e2\",\"rpcport\":80}, {\"coin\":\"OMG\",\"name\":\"omisego\",\"etomic\":\"0xd26114cd6EE289AccF82350c8d8487fedB8A0C07\",\"rpcport\":80}, {\"coin\":\"ICX\",\"name\":\"icon\",\"etomic\":\"0xb5a5f22694352c15b00323844ad545abb2b11028\",\"rpcport\":80}, {\"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/dontrun_unless_you_have_very_reliable_network b/iguana/exchanges/dontrun_unless_you_have_very_reliable_network new file mode 100755 index 000000000..23a32adeb --- /dev/null +++ b/iguana/exchanges/dontrun_unless_you_have_very_reliable_network @@ -0,0 +1,9 @@ +#!/bin/bash +source passphrase +source coins +./stop +git pull; +cd ..; +./m_mm; +pkill -15 marketmaker; +stdbuf -oL $1 ./marketmaker "{\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & 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/fasttest b/iguana/exchanges/fasttest new file mode 100755 index 000000000..a420ed864 --- /dev/null +++ b/iguana/exchanges/fasttest @@ -0,0 +1,6 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"queueid\":1,\"userpass\":\"$userpass\",\"method\":\"sleep\",\"seconds\":10}" & +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"orderbook\",\"base\":\"REVS\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"orderbook\",\"base\":\"REVS\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"queueid\":2,\"userpass\":\"$userpass\",\"method\":\"getcoin\",\"coin\":\"REVS\",\"rel\":\"KMD\"}" 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/getfee b/iguana/exchanges/getfee new file mode 100755 index 000000000..147bd344f --- /dev/null +++ b/iguana/exchanges/getfee @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getfee\",\"coin\":\"BTC\"}" diff --git a/iguana/exchanges/install b/iguana/exchanges/install index 6f5c28723..6eba8d22a 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 client_osx client_static 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/kickstart b/iguana/exchanges/kickstart index 46e353ee2..af8cbae3e 100755 --- a/iguana/exchanges/kickstart +++ b/iguana/exchanges/kickstart @@ -1,3 +1,3 @@ #!/bin/bash source userpass -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"KMD\",\"ipaddr\":\"\",\"port\":0}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"kickstart\",\"requestid\":772275036,\"quoteid\":1846027555}" 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 73d9e33b2..aa0866b07 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -28,6 +28,7 @@ void PNACL_message(char *arg,...) #include #include +// #include "lib.h" #ifndef NATIVE_WINDOWS #include "OS_portable.h" #else @@ -36,7 +37,7 @@ void PNACL_message(char *arg,...) uint32_t DOCKERFLAG; #define MAX(a,b) ((a) > (b) ? (a) : (b)) -char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port); +char *stats_JSON(void *ctx,int32_t fastflag,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port); #include "stats.c" void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]); @@ -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; @@ -192,7 +263,7 @@ int main(int argc, const char * argv[]) } 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 buf[256],checkaddr[64],coinaddr[64],manystrs[64][128],cmd[64*128]; int32_t n,i,num; char *flag; + 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; @@ -212,22 +283,26 @@ int main(int argc, const char * argv[]) } if ( flag != 0 ) { - bitcoin_addr2rmd160("HUSH",28,&addrtype,rmd160,buf); - bitcoin_address("KMD",coinaddr,0,addrtype == 184 ? 60 : 85,rmd160,20); + addrstr = flag, floatstr = buf; + //addrstr = buf, floatstr = flag; + //bitcoin_addr2rmd160("HUSH",28,&addrtype,rmd160,buf); + bitcoin_addr2rmd160("BTC",0,&addrtype,rmd160,addrstr); + bitcoin_address("KMD",coinaddr,0,addrtype == 0 ? 60 : 85,rmd160,20); bitcoin_addr2rmd160("KMD",0,&checktype,checkrmd160,coinaddr); - bitcoin_address("HUSH",checkaddr,28,checktype == 60 ? 184 : 189,checkrmd160,20); - if ( memcmp(rmd160,checkrmd160,20) != 0 || strcmp(buf,checkaddr) != 0 ) + //bitcoin_address("HUSH",checkaddr,28,checktype == 60 ? 184 : 189,checkrmd160,20); + bitcoin_address("BTC",checkaddr,0,checktype == 60 ? 0 : 5,checkrmd160,20); + if ( memcmp(rmd160,checkrmd160,20) != 0 || strcmp(addrstr,checkaddr) != 0 ) { for (i=0; i<20; i++) printf("%02x",rmd160[i]); printf(" vs. "); for (i=0; i<20; i++) printf("%02x",checkrmd160[i]); - printf(" address calc error (%s).%d -> (%s).%d -> (%s) %.8f?\n",buf,addrtype,coinaddr,checktype,checkaddr,atof(flag)); + printf(" address calc error (%s).%d -> (%s).%d -> (%s) %.8f?\n",addrstr,addrtype,coinaddr,checktype,checkaddr,atof(floatstr)); } else { - val = atof(flag); + val = atof(floatstr); sprintf(manystrs[num++],"\\\"%s\\\":%0.8f",coinaddr,val); if ( num >= sizeof(manystrs)/sizeof(*manystrs) ) { @@ -235,12 +310,12 @@ int main(int argc, const char * argv[]) for (i=0; i #include #include "../../crypto777/OS_portable.h" +#define IGUANA_MAXRPCTHREADS 1 + #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define STATS_DESTDIR "/var/www/html" #define STATS_DEST "/var/www/html/DEXstats.json" #include "DEXstats.h" -char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char *remoteaddr,uint16_t port); +char *stats_JSON(void *ctx,int32_t fastflag,char *myipaddr,int32_t mypubsock,cJSON *argjson,char *remoteaddr,uint16_t port); +void LP_queuecommand(char **retstrp,char *buf,int32_t responsesock,int32_t stats_JSONonly,uint32_t queueid); extern uint32_t DOCKERFLAG; char *stats_validmethods[] = @@ -223,7 +226,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) return(-1); } } - if ( listen(sock,4096) != 0 ) + if ( listen(sock,512) != 0 ) { printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); if ( sock >= 0 ) @@ -329,11 +332,16 @@ cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) } extern void *bitcoin_ctx(); +extern int32_t IPC_ENDPOINT; +extern portable_mutex_t LP_gcmutex,LP_commandmutex; +extern struct rpcrequest_info *LP_garbage_collector; +uint16_t RPC_port; +static int32_t spawned,maxspawned; 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,0,"127.0.0.1",-1,argjson,remoteaddr,port)) != 0 ) { if ( (retitem= cJSON_Parse(retstr)) != 0 ) jaddi(retarray,retitem); @@ -531,7 +544,12 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po } } else retstr = clonestr("{\"error\":\"invalid remote method\"}"); #else - 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,0,myipaddr,-1,argjson,remoteaddr,port)) != 0 ) { if ( (retitem= cJSON_Parse(retstr)) != 0 ) jaddi(retarray,retitem); @@ -545,7 +563,7 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po } else { - cJSON *arg; + cJSON *arg; char *buf,*method; int32_t fastflag; if ( jstr(argjson,"agent") != 0 && strcmp(jstr(argjson,"agent"),"bitcoinrpc") != 0 && jobj(argjson,"params") != 0 ) { arg = jobj(argjson,"params"); @@ -555,19 +573,42 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po //printf("ARGJSON.(%s)\n",jprint(arg,0)); if ( userpass != 0 && jstr(arg,"userpass") == 0 ) jaddstr(arg,"userpass",userpass); + if ( (fastflag= jint(arg,"fast")) == 0 ) + { + if ( (method= jstr(arg,"method")) != 0 && (strcmp(method,"orderbook") == 0 || strcmp(method,"portfolio") == 0) ) + fastflag = 1*0; + } + if ( fastflag == 0 ) + portable_mutex_lock(&LP_commandmutex); #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); + //printf("Q command\n"); + LP_queuecommand(&retstr,buf,IPC_ENDPOINT,1,queueid); + free(buf); + retstr = clonestr("{\"result\":\"success\",\"status\":\"queued\"}"); + } else retstr = stats_JSON(ctx,jint(arg,"fast"),"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,jint(arg,"fast"),myipaddr,-1,arg,remoteaddr,port); #endif + if ( fastflag == 0 ) + portable_mutex_unlock(&LP_commandmutex); } free_json(argjson); } free_json(json); if ( tmpjson != 0 ) free(tmpjson); +//printf("stats_JSON rpc return.(%s)\n",retstr); return(retstr); } free_json(argjson); @@ -600,13 +641,8 @@ int32_t iguana_getheadersize(char *buf,int32_t recvlen) return(recvlen); } -uint16_t RPC_port; -extern portable_mutex_t LP_commandmutex,LP_gcmutex; -extern struct rpcrequest_info *LP_garbage_collector; - void LP_rpc_processreq(void *_ptr) { - static uint32_t spawned,maxspawned; char filetype[128],content_type[128]; int32_t recvlen,flag,postflag=0,contentlen,remains,sock,numsent,jsonflag=0,hdrsize,len; char helpname[512],remoteaddr[64],*buf,*retstr,space[8192],space2[32786],*jsonbuf; struct rpcrequest_info *req = _ptr; @@ -616,11 +652,11 @@ void LP_rpc_processreq(void *_ptr) sock = req->sock; recvlen = flag = 0; retstr = 0; - //space = calloc(1,size); jsonbuf = calloc(1,size); - //printf("alloc jsonbuf.%p\n",jsonbuf); remains = size-1; buf = jsonbuf; + if ( spawned < 0 ) + spawned = 0; spawned++; if ( spawned > maxspawned ) { @@ -683,9 +719,7 @@ void LP_rpc_processreq(void *_ptr) if ( recvlen > 0 ) { jsonflag = postflag = 0; - //portable_mutex_lock(&LP_commandmutex); retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,req->port); - //portable_mutex_unlock(&LP_commandmutex); if ( filetype[0] != 0 ) { static cJSON *mimejson; char *tmp,*typestr=0; long tmpsize; @@ -770,7 +804,8 @@ void LP_rpc_processreq(void *_ptr) //printf("free req.%p\n",req); free(req); } - spawned--; + if ( spawned > 0 ) + spawned--; } extern int32_t IAMLP,LP_STOP_RECEIVED; @@ -778,7 +813,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); @@ -800,7 +835,6 @@ void stats_rpcloop(void *args) //printf("after sock.%d\n",sock); clilen = sizeof(cli_addr); sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); -//#ifdef _WIN32 if ( sock < 0 ) { printf("iguana_rpcloop ERROR on accept port.%u usock.%d errno %d %s\n",port,sock,errno,strerror(errno)); @@ -808,16 +842,6 @@ void stats_rpcloop(void *args) bindsock = -1; continue; } -/*#else - if ( sock < 0 ) - { - //fprintf(stderr,"."); - if ( IAMLP == 0 ) - usleep(50000); - else usleep(2500); - continue; - } -#endif*/ memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); //printf("port.%u got incoming from %x\n",port,ipbits); if ( DOCKERFLAG != 0 && (DOCKERFLAG == 1 || ipbits == DOCKERFLAG) ) @@ -829,30 +853,17 @@ void stats_rpcloop(void *args) continue; } req = calloc(1,sizeof(*req)); - //printf("alloc req.%p\n",req); + //printf("LP_rpc_processreq req.%p\n",req); req->sock = sock; req->ipbits = ipbits; req->port = port; - LP_rpc_processreq(req); -continue; - // this leads to cant open file errors - if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) + if ( 1 || spawned >= (IGUANA_MAXRPCTHREADS-1) ) + LP_rpc_processreq(req); + // this might lead to "cant open file errors" + else 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); - DL_FOREACH_SAFE(LP_garbage_collector,req2,rtmp) - { - DL_DELETE(LP_garbage_collector,req2); - free(req2); - } - portable_mutex_unlock(&LP_gcmutex); - if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) - { - printf("error2 launching rpc handler on port %d, retval.%d\n",port,retval); - LP_rpc_processreq(req); - } + LP_rpc_processreq(req); } } printf("i got killed\n"); diff --git a/iguana/exchanges/supernet b/iguana/exchanges/supernet index 25e6af7e4..1b55eee6e 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\":570}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":0.20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":0.150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":0.375000}, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }, {\"coin\":\"utrum\",\"balance\":2100000}],\"divisor\":612529}" -#curl --url "http://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/txblast b/iguana/exchanges/txblast new file mode 100755 index 000000000..4ed3fc9e3 --- /dev/null +++ b/iguana/exchanges/txblast @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"broadcast\":1,\"numblast\":1000,\"password\":\"default\",\"utxotxid\":\"bf8b73b2f72fbff1546811749eba3a028bce6320e5cdf2ae1ae414277661fb13\",\"utxovout\":1,\"utxovalue\":100000000,\"txfee\":20000,\"method\":\"txblast\",\"coin\":\"PIZZA\",\"outputs\":[{\"RUgW6fLfVsLJ87Ng4zJTqNedJSKYQ9ToAf\":0.0001}, {\"RLMHGUQginEGrnRtHoFBPZhLC9jeVdt1th\":0.0001}]}" + 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/exchanges/withdraw b/iguana/exchanges/withdraw index 8a78fa5a1..021434103 100755 --- a/iguana/exchanges/withdraw +++ b/iguana/exchanges/withdraw @@ -1,3 +1,3 @@ #!/bin/bash source userpass -curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"withdraw\",\"coin\":\"KMD\",\"outputs\":[{\"RUgW6fLfVsLJ87Ng4zJTqNedJSKYQ9ToAf\":0.001}, {\"RUgW6fLfVsLJ87Ng4zJTqNedJSKYQ9ToAf\":0.002}]}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"withdraw\",\"coin\":\"KMD\",\"outputs\":[{\"RUgW6fLfVsLJ87Ng4zJTqNedJSKYQ9ToAf\":0.001}, {\"RUgW6fLfVsLJ87Ng4zJTqNedJSKYQ9ToAf\":0.002}],\"broadcast\":1}" diff --git a/iguana/exchanges777.h b/iguana/exchanges777.h index 960e500c3..25aa5d2b6 100755 --- a/iguana/exchanges777.h +++ b/iguana/exchanges777.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana777.c b/iguana/iguana777.c index d998b4b81..7e2906963 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -48,6 +48,10 @@ 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"); + strcpy(coin->validateaddress,"validateaddress"); + strcpy(coin->estimatefeestr,"estimatefee"); + strcpy(coin->signtxstr,"signrawtransaction"); coin->blockspacesize = IGUANA_MAXPACKETSIZE + 8192; coin->blockspace = calloc(1,coin->blockspacesize); if ( virtcoin != 0 || ((privatechain= jstr(argjson,"geckochain")) != 0 && privatechain[0] != 0) ) @@ -1216,12 +1220,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..bc4a45d60 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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[8192]; int32_t numdpows,dpowsock,dexsock,pubsock,repsock,subsock,reqsock; struct delayedPoW_info dPoW; struct basilisk_spend *spends; int32_t numspends; char bindaddr[64]; @@ -180,7 +180,7 @@ struct supernet_info #ifdef NOTARY_TESTMODE char dexseed_ipaddrs[1][64]; #else - char dexseed_ipaddrs[4][64]; + char dexseed_ipaddrs[8][64]; #endif uint32_t dexipbits[128]; int32_t numdexipbits; portable_mutex_t dexmutex; // compatibility diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c index 2463a09a8..9f30069fa 100755 --- a/iguana/iguana_accept.c +++ b/iguana/iguana_accept.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_bitmap.c b/iguana/iguana_bitmap.c index 89effe210..7535fb170 100755 --- a/iguana/iguana_bitmap.c +++ b/iguana/iguana_bitmap.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index 3c65b069c..512e7cb94 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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_bundles.c b/iguana/iguana_bundles.c index e7c53ae73..de933377b 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index 4fc5a0b76..2984bdf94 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -322,7 +322,7 @@ void iguana_chainparms(struct supernet_info *myinfo,struct iguana_chain *chain,c if ( (port= extract_userpass(chain->serverport,chain->userpass,chain->symbol,chain->userhome,path,conf)) != 0 ) chain->rpcport = port; //if ( conf[0] != 0 ) - printf("PATH.(%s) CONF.(%s)\n",path!=0?path:"",conf); + printf("PATH.(%s) CONF.(%s) txfee %.8f\n",path!=0?path:"",conf,dstr(chain->txfee)); if ( juint(argjson,"p2p") != 0 ) chain->portp2p = juint(argjson,"p2p"); else chain->portp2p = juint(argjson,"portp2p"); @@ -468,7 +468,7 @@ void iguana_chainparms(struct supernet_info *myinfo,struct iguana_chain *chain,c } } sprintf(chain->messagemagic,"%s Signed Message:\n",chain->name); - printf("COIN.%s serverport.(%s) RPCport.%u P2P.%u magic.%08x\n",chain->symbol,chain->serverport,chain->rpcport,chain->portp2p,*(uint32_t *)chain->netmagic); + printf("COIN.%s serverport.(%s) RPCport.%u P2P.%u magic.%08x txfee %.8f\n",chain->symbol,chain->serverport,chain->rpcport,chain->portp2p,*(uint32_t *)chain->netmagic,dstr(chain->txfee)); } } diff --git a/iguana/iguana_exchanges.c b/iguana/iguana_exchanges.c index d2cd1c267..510b7932e 100755 --- a/iguana/iguana_exchanges.c +++ b/iguana/iguana_exchanges.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index bb3c92135..48c91c757 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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..a5b12d6ec 100755 --- a/iguana/iguana_interpreter.c +++ b/iguana/iguana_interpreter.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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_json.c b/iguana/iguana_json.c index 99d851641..0bdbbfb43 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_mofn.c b/iguana/iguana_mofn.c index b4d34230d..cecc0de32 100755 --- a/iguana/iguana_mofn.c +++ b/iguana/iguana_mofn.c @@ -325,7 +325,7 @@ int maingen(int argc,char **argv) } /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index bbdd7a6d6..0ddd1c16f 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_notary.c b/iguana/iguana_notary.c index b4a1cdef1..89f39f504 100755 --- a/iguana/iguana_notary.c +++ b/iguana/iguana_notary.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -20,11 +20,11 @@ #define CHECKSIG 0xac #include "iguana777.h" -#include "notaries.h" +//#include "notaries.h" 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" @@ -34,7 +34,7 @@ int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct void dpow_fifoupdate(struct supernet_info *myinfo,struct dpow_checkpoint *fifo,struct dpow_checkpoint tip) { - int32_t i,ind; struct dpow_checkpoint newfifo[DPOW_FIFOSIZE]; + int32_t i,ind; struct dpow_checkpoint newfifo[DPOW_FIFOSIZE]; memset(newfifo,0,sizeof(newfifo)); for (i=DPOW_FIFOSIZE-1; i>0; i--) { @@ -58,100 +58,22 @@ 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; - } - else - { - 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 ( dp->DESTHEIGHT < dp->prevDESTHEIGHT+DPOW_CHECKPOINTFREQ ) + { + suppress = 1; + //fprintf(stderr,"suppress %s -> KMD\n",dp->symbol); + } + } + /*if ( strcmp(dp->dest,"KMD") == 0 )//|| strcmp(dp->dest,"CHAIN") == 0 ) { //if ( dp->SRCREALTIME == 0 ) // return; @@ -162,15 +84,18 @@ 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,&mdata) <= 0 ) { - height = jint(blockjson,"height"); + if ( mdata.pairs != 0 ) + free(mdata.pairs); 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("KMD",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,29 +108,51 @@ 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("KMD",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; } else return; - } - if ( bits256_nonz(checkpoint.blockhash.hash) != 0 && (checkpoint.blockhash.height % freq) == 0 ) + }*/ + if ( dp->freq <= 0 ) + dp->freq = 1; + if ( suppress == 0 && bits256_nonz(checkpoint.blockhash.hash) != 0 && (checkpoint.blockhash.height % dp->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("KMD",dp->symbol) == 0 ) + printf("%s/%s src ht.%d dest.%u nonz.%d %s minsigs.%d freq.%d\n",dp->symbol,dp->dest,checkpoint.blockhash.height,dp->destupdated,bits256_nonz(checkpoint.blockhash.hash),bits256_str(str,dp->last.blockhash.hash),dp->minsigs,dp->freq); dpow_heightfind(myinfo,dp,checkpoint.blockhash.height + 1000); - ptrs = calloc(1,sizeof(void *)*5 + sizeof(struct dpow_checkpoint)); + dp->prevDESTHEIGHT = dp->DESTHEIGHT; + 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; + ptrs[2] = (void *)(uint64_t)dp->minsigs; + 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 > DPOW_MAXFREQ*5 ) + { + if ( (0) && strcmp("CHIPS",dp->symbol) == 0 ) + printf("ht.%d maxblocks.%d\n",ht,dp->maxblocks); + for (i=ht-DPOW_MAXFREQ*5; i>ht-DPOW_MAXFREQ*100&&i>DPOW_MAXFREQ; i--) + { + if ( (bp= dp->blocks[i]) != 0 && bp->state == 0xffffffff ) //(i % DPOW_MAXFREQ) != 0 && + { + if ( dp->currentbp == dp->blocks[i] ) + dp->currentbp = 0; + dp->blocks[i] = 0; + Numallocated--; + free(bp); + } + } + } } } @@ -246,12 +193,13 @@ void dpow_destconfirm(struct supernet_info *myinfo,struct dpow_info *dp,struct d void dpow_destupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t height,bits256 hash,uint32_t timestamp,uint32_t blocktime) { dp->destupdated = timestamp; + dp->DESTHEIGHT = height; dpow_checkpointset(myinfo,&dp->destchaintip,height,hash,timestamp,blocktime); dpow_approvedset(myinfo,dp,&dp->destchaintip,dp->desttx,dp->numdesttx); 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 +207,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,17 +232,18 @@ 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 ) dp->lastheight = height-1; + 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->lastheight); + dp->SRCHEIGHT = height; if ( height < dp->last.blockhash.height ) { printf("iguana_dPoWupdate src.%s reorg detected %d vs %d approved.%d notarized.%d\n",dp->symbol,height,dp->last.blockhash.height,dp->approved[0].height,dp->notarized[0].height); @@ -307,12 +256,13 @@ void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp) { while ( dp->lastheight <= height ) { + printf("dp->lastheight.%d <= height.%d\n",dp->lastheight,height); blockhash = dpow_getblockhash(myinfo,src,dp->lastheight); dpow_srcupdate(myinfo,dp,dp->lastheight++,blockhash,(uint32_t)time(NULL),blocktime); } } } - else if ( strcmp(dp->symbol,"KMD") == 0 ) + else //if ( strcmp(dp->symbol,"KMD") == 0 ) { while ( dp->lastheight <= height ) { @@ -320,13 +270,13 @@ void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp) dpow_srcupdate(myinfo,dp,dp->lastheight++,blockhash,(uint32_t)time(NULL),blocktime); } } - else if ( time(NULL) > dp->lastsrcupdate+60 || height != dp->lastheight ) + /*else if ( time(NULL) > dp->lastsrcupdate+60 || height != dp->lastheight ) { dp->lastsrcupdate = (uint32_t)time(NULL); dp->lastheight = height; blockhash = dpow_getblockhash(myinfo,src,dp->lastheight); dpow_srcupdate(myinfo,dp,dp->lastheight,blockhash,(uint32_t)time(NULL),blocktime); - } + }*/ } //else printf("error getchaintip for %s\n",dp->symbol); } else printf("iguana_dPoWupdate missing src.(%s) %p or dest.(%s) %p\n",dp->symbol,src,dp->dest,dest); } @@ -334,9 +284,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; + if ( (dp= myinfo->DPOWS[myinfo->numdpows]) == 0 ) + myinfo->DPOWS[myinfo->numdpows] = calloc(1,sizeof(*dp)); + if ( (dp= myinfo->DPOWS[myinfo->numdpows]) == 0 ) + return(clonestr("{\"error\":\"dPoW cant allocate memory\"}")); + memset(dp,0,sizeof(*dp)); destvalid = srcvalid = 0; if ( myinfo->NOTARY.RELAYID < 0 ) { @@ -367,23 +322,24 @@ 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\"}")); - if ( myinfo->numdpows > 1 ) + else if ( iguana_coinfind(dest) == 0 ) + return(clonestr("{\"error\":\"cant dPoW without KMD (dest)\"}")); + if ( myinfo->numdpows > 0 ) { - 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 ) + for (i=0; inumdpows; i++) + if ( strcmp(symbol,myinfo->DPOWS[i]->symbol) == 0 ) { dp->symbol[0] = 0; return(clonestr("{\"error\":\"cant dPoW same coin again\"}")); @@ -397,14 +353,28 @@ 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; + if ( strcmp("BTC",dp->dest) == 0 ) + { + dp->freq = DPOW_CHECKPOINTFREQ; + dp->minsigs = Notaries_BTCminsigs; //DPOW_MINSIGS; + } + else + { + dp->minsigs = Notaries_minsigs; //DPOW_MIN_ASSETCHAIN_SIGS; + if ( freq == 0 && (strcmp("CHIPS",dp->symbol) == 0 || strncmp("TEST",dp->symbol,4) == 0) ) + dp->freq = DPOW_MAXFREQ; + else if ( freq > 2 ) + dp->freq = freq; + else dp->freq = 2; + } 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\"}")); @@ -418,23 +388,28 @@ TWO_STRINGS(iguana,dpow,symbol,pubkey) json = cJSON_Parse(retstr); if ( (ismine= jobj(json,"ismine")) != 0 && is_cJSON_True(ismine) != 0 ) srcvalid = 1; - else srcvalid = 0; + else + { + srcvalid = 0; + printf("src validation error %s %s %s\n",src->symbol,srcaddr,retstr); + } free(retstr); retstr = 0; - } - bitcoin_address(destaddr,dest->chain->pubtype,dp->minerkey33,33); - if ( (retstr= dpow_validateaddress(myinfo,dest,destaddr)) != 0 ) + } else printf("%s %s didnt return anything\n",src->symbol,srcaddr); + 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 ) destvalid = 1; - else destvalid = 0; + else + { + destvalid = 0; + printf("dest validation error %s %s %s\n",src->symbol,srcaddr,retstr); + } free(retstr); retstr = 0; - } - for (i=0; i<33; i++) - printf("%02x",dp->minerkey33[i]); - printf(" DPOW with pubkey.(%s) %s.valid%d %s -> %s %s.valid%d\n",tmp,srcaddr,srcvalid,dp->symbol,dp->dest,destaddr,destvalid); + } else printf("%s %s didnt return anything\n",destcoin->symbol,destaddr); if ( srcvalid <= 0 || destvalid <= 0 ) { dp->symbol[0] = 0; @@ -447,7 +422,7 @@ TWO_STRINGS(iguana,dpow,symbol,pubkey) } if ( dp->blocks == 0 ) { - dp->maxblocks = 1000000; + dp->maxblocks = 10000; dp->blocks = calloc(dp->maxblocks,sizeof(*dp->blocks)); } portable_mutex_init(&dp->paxmutex); @@ -457,6 +432,9 @@ TWO_STRINGS(iguana,dpow,symbol,pubkey) //uint8_t buf[32768]; //dpow_paxpending(buf); myinfo->numdpows++; + for (i=0; i<33; i++) + printf("%02x",dp->minerkey33[i]); + printf(" DPOW with pubkey.(%s) %s.valid%d %s -> %s %s.valid%d, num.%d freq.%d minsigs.%d\n",tmp,srcaddr,srcvalid,dp->symbol,dp->dest,destaddr,destvalid,myinfo->numdpows,dp->freq,dp->minsigs); return(clonestr("{\"result\":\"success\"}")); } @@ -520,7 +498,7 @@ STRING_ARG(dpow,pending,fiat) base[i] = 0; for (i=0; inumdpows; i++) { - dp = &myinfo->DPOWS[i]; + dp = myinfo->DPOWS[i]; if ( strcmp(dp->symbol,base) == 0 ) return(jprint(dpow_withdraws_pending(dp),1)); } @@ -556,9 +534,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", "BNTN", "PRLPAY" +}; + +// "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 +591,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= 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,mdata) > 0 && strcmp(symbol,coin->symbol) == 0 ) + { + // if ( Notaries_port != DPOW_SOCKPORT ) // keep going till valid MoM found, useful for new chains without any MoM + { + if ( bits256_nonz(MoM) == 0 || MoMdepth == 0 || *nothtp >= height || *nothtp < 0 ) + { + *nothtp = 0; + } + } + if ( mdata->pairs != 0 && mdata->numpairs > 0 ) + { + for (j=0; jnumpairs; j++) + { + if ( mdata->pairs[j].notarization_height > coin->MoMoMheight ) + { + coin->MoMoMheight = mdata->pairs[j].notarization_height; + printf("set %s MoMoMheight <- %d\n",coin->symbol,coin->MoMoMheight); + } + } + } + //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,struct komodo_ccdataMoMoM *mdata) +{ + int32_t i,n,hasnotarization = 0; bits256 txid; cJSON *txarray; + *nothtp = 0; + *signedmaskp = 0; + memset(mdata,0,sizeof(*mdata)); + if ( (txarray= jarray(&n,blockjson,"tx")) != 0 ) + { + 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,&mdata) > 0 ) + { + if ( mdata.pairs != 0 ) + free(mdata.pairs); + for (j=0; j<64; j++) + if ( ((1LL << j) & signedmask) != 0 ) + masksums[j]++; + } + free_json(blockjson); + } + } + array = cJSON_CreateArray(); + for (i=0; inumnotaries; i++) + { + item = cJSON_CreateObject(); + jaddstr(item,"notary",Notaries_elected[i][0]); + jaddnum(item,"bestk",bp->notaries[i].bestk); + sprintf(hexstr,"%16llx",(long long)bp->notaries[i].recvmask); + jaddstr(item,"recvmask",hexstr); + sprintf(hexstr,"%16llx",(long long)bp->notaries[i].bestmask); + jaddstr(item,"bestmask",hexstr); + jaddi(retjson,item); + } + return(retjson); +} + STRING_ARG(dpow,active,maskhex) { - uint8_t data[8],revdata[8]; int32_t i,len; uint64_t mask; cJSON *retjson,*array = cJSON_CreateArray(); + uint8_t data[8],revdata[8],pubkeys[64][33]; int32_t i,len,current,n; uint64_t mask; cJSON *infojson,*retjson,*array,*notarray; + array = cJSON_CreateArray(); + notarray = cJSON_CreateArray(); + if ( (infojson= dpow_getinfo(myinfo,coin)) != 0 ) + { + current = jint(infojson,"blocks"); + free_json(infojson); + } else return(clonestr("{\"error\":\"cant get current height\"}")); + n = komodo_notaries("KMD",pubkeys,current); if ( maskhex == 0 || maskhex[0] == 0 ) { - mask = myinfo->DPOWS[0].lastrecvmask; - for (i=0; i<64; i++) + return(jprint(dpow_recvmasks(myinfo,myinfo->DPOWS[0],myinfo->DPOWS[0]->currentbp),1)); + + /*mask = myinfo->DPOWS[0]->lastrecvmask; + for (i=0; i>= 1; @@ -747,22 +929,30 @@ STRING_ARG(dpow,active,maskhex) revdata[i] = data[len-1-i]; mask = 0; memcpy(&mask,revdata,sizeof(revdata)); - for (i=0; iDPOWS[0].cancelratify = 1; + myinfo->DPOWS[0]->cancelratify = 1; return(clonestr("{\"result\":\"queued dpow cancel ratify\"}")); } @@ -777,18 +967,18 @@ TWOINTS_AND_ARRAY(dpow,ratify,minsigs,timestamp,ratified) ptrs[0] = (void *)myinfo; if ( (source= jstr(json,"source")) == 0 ) source = "KMD"; - ptrs[1] = (void *)&myinfo->DPOWS[0]; + ptrs[1] = (void *)myinfo->DPOWS[0]; for (i=0; inumdpows; i++) - if ( strcmp(myinfo->DPOWS[0].symbol,source) == 0 ) + if ( strcmp(myinfo->DPOWS[0]->symbol,source) == 0 ) { - ptrs[1] = (void *)&myinfo->DPOWS[i]; + ptrs[1] = (void *)myinfo->DPOWS[i]; break; } ptrs[2] = (void *)(long)minsigs; ptrs[3] = (void *)DPOW_RATIFYDURATION; ptrs[4] = (void *)jprint(ratified,0); memcpy(&ptrs[5],&checkpoint,sizeof(checkpoint)); - myinfo->DPOWS[0].cancelratify = 0; + myinfo->DPOWS[0]->cancelratify = 0; if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_statemachinestart,(void *)ptrs) != 0 ) { } @@ -966,7 +1156,8 @@ STRING_ARG(dex,psock,argstr) STRING_ARG(dex,getnotaries,symbol) { - return(_dex_getnotaries(myinfo,symbol)); + return(clonestr("{\"error\":\"dexgetnotaries deprecated\"}")); + //return(_dex_getnotaries(myinfo,symbol)); } TWO_STRINGS(dex,kvsearch,symbol,key) @@ -1138,5 +1329,3 @@ STRING_ARG(dex,explorer,symbol) } #include "../includes/iguana_apiundefs.h" - - diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c index cbc23aa6c..14df8eaac 100755 --- a/iguana/iguana_payments.c +++ b/iguana/iguana_payments.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -462,6 +462,9 @@ char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJS printf("no spendscriptstr %d.(%s)\n",i,jprint(array,0)); continue; } + if ( strlen(spendscriptstr) != 50 || strncmp("76a914",spendscriptstr,6) != 0 || strcmp("88ac",&spendscriptstr[50-4]) != 0 ) + continue; +//printf("utxo.(%s)\n",jprint(item,0)); unspents = realloc(unspents,(1 + max) * sizeof(*unspents)); value = jdouble(item,"amount") * SATOSHIDEN; if ( (0) && jdouble(item,"interest") != 0 ) diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 8fd57e8a7..5b8c79854 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index ab73a9502..a7b83cd45 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_realtime.c b/iguana/iguana_realtime.c index ddd6d1685..7cd94b41d 100755 --- a/iguana/iguana_realtime.c +++ b/iguana/iguana_realtime.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index d7426af08..2ee4d411f 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -704,7 +704,7 @@ int32_t iguana_txmerkle(struct iguana_info *coin,bits256 *tree,int32_t treesize, { 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_rpc.c b/iguana/iguana_rpc.c index d79aefe24..47c8d7c64 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_scripts.c b/iguana/iguana_scripts.c index 57e8181d1..881f272e1 100755 --- a/iguana/iguana_scripts.c +++ b/iguana/iguana_scripts.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_secp.c b/iguana/iguana_secp.c index c53170908..c5606ca0f 100755 --- a/iguana/iguana_secp.c +++ b/iguana/iguana_secp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_sign.c b/iguana/iguana_sign.c index b1fee7f0e..9255581b9 100755 --- a/iguana/iguana_sign.c +++ b/iguana/iguana_sign.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_spendvectors.c b/iguana/iguana_spendvectors.c index 7a0cc5a27..a50a29582 100755 --- a/iguana/iguana_spendvectors.c +++ b/iguana/iguana_spendvectors.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_tradebots.c b/iguana/iguana_tradebots.c index c514ed4bd..7185770a9 100755 --- a/iguana/iguana_tradebots.c +++ b/iguana/iguana_tradebots.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_tx.c b/iguana/iguana_tx.c index ac6346fc8..a32b71ca4 100755 --- a/iguana/iguana_tx.c +++ b/iguana/iguana_tx.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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_txidfind.c b/iguana/iguana_txidfind.c index 6f9e81f52..d426c0e39 100755 --- a/iguana/iguana_txidfind.c +++ b/iguana/iguana_txidfind.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 2974c300f..86f391559 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_volatiles.c b/iguana/iguana_volatiles.c index b671f0012..db66927f0 100755 --- a/iguana/iguana_volatiles.c +++ b/iguana/iguana_volatiles.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index e125aea2a..a8b02d4e7 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -980,7 +980,7 @@ cJSON *iguana_privkeysjson(struct supernet_info *myinfo,struct iguana_info *coin if ( address != 0 ) { strcpy(&addresses[64 * n++],address); - } else printf("cant get address from.(%s)\n",jprint(item,0)); + } //else printf("cant get address from.(%s)\n",jprint(item,0)); } for (i=0; ichangeaddr,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..dd452c3df 100755 --- a/iguana/kmd_lookup.h +++ b/iguana/kmd_lookup.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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..254c6033c 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 @@ -16,11 +16,22 @@ source pubkey.txt sleep 4 curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"$myip\"}" sleep 3 -tests/addnotarys_7776 +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"78.47.196.146\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"82.202.193.98\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"54.95.68.31\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"142.54.164.114\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"45.7.229.33\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"103.6.12.111\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"155.254.17.21\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"138.121.203.210\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"209.58.169.65\"}" + +#tests/addnotarys_7776 coins/btc_7776 -coins/ltc_7776 +#coins/ltc_7776 coins/kmd_7776 coins/chips_7776 +coins/game_7776 ./wp_7776 coins/revs_7776 @@ -29,7 +40,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,7 +54,15 @@ coins/mnz_7776 coins/axo_7776 coins/etomic_7776 coins/btch_7776 +#coins/vote2018_7776 +coins/ninja_7776 +coins/oot_7776 +coins/bntn_7776 +coins/chain_7776 +coins/prlpay_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\"}" +sleep 30 curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KMD\",\"pubkey\":\"$pubkey\"}" diff --git a/iguana/m_notary_testnet b/iguana/m_notary_testnet new file mode 100755 index 000000000..0e377a239 --- /dev/null +++ b/iguana/m_notary_testnet @@ -0,0 +1,32 @@ +#!/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\":\"31.192.110.70\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"139.99.124.117\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"167.114.208.203\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"103.6.12.111\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"195.154.78.44\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"139.99.148.62\"}" +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..34d9840ed 100755 --- a/iguana/m_splitfund +++ b/iguana/m_splitfund @@ -2,61 +2,33 @@ 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\":\"BTC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KMD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"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\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SUPERNET\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DEX\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PANGEA\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JUMBLR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BET\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CRYPTO\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HODL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MSHARK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BOTS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MGW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"COQUI\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"WLC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KV\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CEAL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MESH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MNZ\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"AXO\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BTCH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ETOMIC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"VOTE2018\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CHIPS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NINJA\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"OOT\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BNTN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PRLPAY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CHAIN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"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..0f18c35b1 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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); @@ -2258,12 +2273,12 @@ void iguana_main(void *arg) #ifdef __APPLE__ iguana_appletests(myinfo); #endif - char *retstr; + /*char *retstr; if ( (retstr= _dex_getnotaries(myinfo,"KMD")) != 0 ) { printf("INITIAL NOTARIES.(%s)\n",retstr); free(retstr); - } + }*/ } } else 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/notaries.h b/iguana/notaries.h index f6c05a227..e94a3d503 100755 --- a/iguana/notaries.h +++ b/iguana/notaries.h @@ -15,7 +15,7 @@ #ifndef INCLUDE_NOTARIES_H #define INCLUDE_NOTARIES_H - +/* char *Notaries[][2] = { { "jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, @@ -56,46 +56,6 @@ char *Notaries[][2] = { "artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, { "eclips_EU", "0339369c1f5a2028d44be7be6f8ec3b907fdec814f87d2dead97cab4edb71a42e9" }, { "titomane_SH", "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" }, -/*{ "Server1","0221876c8259764224dc1a7b70ec956f3fbe9a768cd77f13082cfa60eb6aa2d068"}, - { "Server2","03c7c14e6b1f94585bb571cf3ee5eb9b9ab54bd23d0acb8cf13edad1c515842b66"}, - { "Server3","02d28f8992ff0cd68c5d558cf55ec5b3ada25151519a6cea8cef1bac04c40023b6"}, - { "Server4","02adc84814fee5864e67fd1b76f97fbe74d6bd07c62335e2f1da918f46d08d84ba"}, - { "Server5","033dcf1c8308a00533fd3206c2db4f38ace0e08ae089a93efd873c8a2f80c4a620"}, - { "Server6","030f9f354cc8e2eaead1d978cc4db7009715083220fe48252fb0b0680d3a63d5a4"}, - { "Server7","0235d73cf8bc250e7a7032898423f24e240f1267a3c809a557daa3c17108d7585e"}, - { "Server8","03feea6d8ce239043baa9f3c9a1f15213dd4ac73df2bae5da71034f803dc005587"}, - { "Server9","02bfe32e6ce78c3795f0a2aa7e0dd47c51c674742f99ba9a0aec6d0d82d3d476b0"}, - { "Server10","037b46bdc3933fda6f47d14c8931fb8fffc4db85e0981ec4857fd56ee43300a29a"}, - { "Server11","03e6e375c5d36ebfbef9bd97c8cacb2d7a8f54bf89926ebde77fe7cc8cfb3c8e89"}, - { "Server12","032eff141519c1c4b111b1e51e9c4306c9dcfab9357fd27291daa5c6b3736c59d7"}, - { "Server13","03ae5eb57512a756031f7fd516d0f46e984632f73855fdf53fd4a08fbdef284af0"}, - { "Server14","03755d02c5aab06def772438d2a3b3d98d316091747e12b4e85b3a253cf757a730"}, - { "Server15","0260348f92cde87639ba9afc9f02b2c71ab52dc5faa00d175d0e331f71c05a521c"}, - { "Server16","02714f1922b72cce03633720402783de4962432adb3d3e38c95da754d43926e6f5"}, - { "Server17","028a2957cd7b428c3ba7ee2974e8dbbed0ee836721d00db6ea66db8f65c163a582"}, - { "Server18","033b24621b85b0593a7dae5867d112d8b80406369b8b07dde8be6ec6eb123de5aa"}, - { "Server19","0334556377815054bc39eb67186b02bd44ffe5acc9547516de0a639bcb947e2afb"}, - { "Server20","02564d75bed700f431eaabd087d1fbf59a566775ec146a65ad5137cd6ca0ff9c6d"}, - { "Server21","02345e3f2d281b0109cdcae6c70728027801060f231fc740b258c48aa43d75de0d"}, - { "Server22","0224991d534b187e9636d47253b2769fba299a0649c39615f2f31997052345c37c"}, - { "Server23","021a5deb5336e7d914f84616243c12e45268941449f7f0eb6e9d6772e0a605a9af"}, - { "Server24","036f5ae3b01b030acf6d6bc987feec5de5c340ff43887834af18fb0dee3961967c"}, - { "Server25","0377e432331fcca2e39324fdb815ab91171f26d7b838de04b39e4a5787966bf10c"}, - { "Server26","02ac499362e35c2d47b83c3c985abced6f3cb8b3f5c872a1b5806e2abba175a497"}, - { "Server27","0269611d0a1eedc67c323b2e17d332731e267c4c25716f1fa956ce027f7bae787f"}, - { "Server28","0203835a4c208a2a7ae5bafea393f04aaf6e863c93a3bd61f3a59a2383b1f7af31"}, - { "Server29","02ffc70831ca50e4d44f67462405fba12df7b01477e55c12ef6e696e4b1522ce3b"}, - { "Server30","022ab58e8ee541952f9f992890335097fa18479b5f66ad5f1f4a0e8f60959f3d19"},*/ }; - -// RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc RDhEGYScNQYetCyG75Kf8Fg61UWPdwc1C5 RVKtRKozg8RKvEYCumMD43fCU6f212M5RD RDW8EDkCkzQ1LA4xbVUoAERsBVhhYRLXCr RREc88bQzxHCvzqErPDnTQH2Qg5yUtjbyp RJKWU7f77YVUHBgrfcTGHje26k7pfkkU3t RLVwuTM5TitV4Gk79Rja731RwYkAzz7GWn RNZKqUgoAPwWd7wNtuSKP7k1HSJAyPeH4N RVxtoUT9CXbC1LdhztNAf9yR5ySnFnSPQh RAxQTHdsy89tfSXwoce2sHeWrYXmDsMXQq RLNJ873AQ8Cnr8UfhRm9SXiVDaphoa4JTo RCA8H1npFPW5pnJRzycF8tFEJmn6XZhD4j RP4FSezvuXsBpfxj5sByJDneFB3XC9yNe5 RXqdRmv7n9hygf9C7f7vj4VQyNR9RvzXss RGosMyyAo573NrBdqUiQYQDsnV6kyY2oiq RDYsrWBZkYSWhRDupGRrfGqrVnFtK9hJGC RTw3vi3dGa9n8LLbKvk7jDAwLdt3A5ET7a RDY9LJZTEJ9FsvugUuD69gceA98uqan5XL R9tjkpdNbzw6mNfxorb5bvTPmsuon5aLrC R9Wtb6jReE9GrePGkCHzuyxD3hTTrnMcGY RRvaVyKS59NJWhPp8Pn7mVPGhMuhJJXrdh RSHdRnHHGdPtVej7fiehHBQ6dyTbEM1GHi RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY RJ9wAk3ZNrFwdso1RVbwASiqqQaDNyKjd2 RHPGxpiwRHP4dKZXjYPdpon1nCto7qVE8s RT2k2voy9n8jwppeTTJMQAhvaqA9pc9jHh RPJjzoKPb8idoUCT9XLBkNojNgysjJ5qrE RE3P8D8rcWZBeKmT8DURPdezW87MU5Ho3F RQeuhk4KcPM3F5hefwTBWezDdcktSGQQSq RFHRWQ5pAXNfmudHfxdxw3Wo8yFGoeDn6z RHASfhhM6bvDFakRDqkzA2wc3V4R4oNmXi RFssbc211PJdVy1bvcvAG5X2N4ovPAoy5o Numnotaries.32 - -/*RHASfhhM6bvDFakRDqkzA2wc3V4R4oNmXi c3a2395a3bb498ff684fd6730c205c691056364edaa71e70b1d74203bc52b57d -RDhEGYScNQYetCyG75Kf8Fg61UWPdwc1C5 ae2af56ca7f6cd178379a3c552c3681c99eba797b01f535ff1a743ca09485dea -RVKtRKozg8RKvEYCumMD43fCU6f212M5RD ade9979549cf703c6e997934f6116debe0ea2d5dd4f51665d9dfbef1fcc7d08a -RREc88bQzxHCvzqErPDnTQH2Qg5yUtjbyp b1269e90a052b3d3b5a2fc35cb7385e72bb36b2633ca824eb45291bc10d96795 -RCA8H1npFPW5pnJRzycF8tFEJmn6XZhD4j aec351cea264ff7411a32554edbd75df76bb47dbbf038fdc150284e325b319a7 -RJ9wAk3ZNrFwdso1RVbwASiqqQaDNyKjd2 a075c4800c538000be07eb25b4b521caa54c807385b932b790feba410c74b2aa -RHPGxpiwRHP4dKZXjYPdpon1nCto7qVE8s a036d9a442cb3275ca2f017fea4330c89619ea113820aff720d5f5ad0c9755e9*/ - + */ #endif 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/iguana/tests/active b/iguana/tests/active new file mode 100755 index 000000000..7618c3d8b --- /dev/null +++ b/iguana/tests/active @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"dpow\",\"method\":\"active\",\"maskhex\":\"7fc27f67df27e619\"}" diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index 48d39e417..46db910d3 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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_AND_DOUBLE(iguana,dpow,symbol,dest,pubkey,freq); STRING_ARG(iguana,peers,activecoin); STRING_AND_INT(iguana,maxpeers,activecoin,max); STRING_ARG(iguana,getconnectioncount,activecoin); diff --git a/includes/iguana_defines.h b/includes/iguana_defines.h index ba7e106cb..8016e8645 100755 --- a/includes/iguana_defines.h +++ b/includes/iguana_defines.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index ceb086e22..b0fa20b84 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -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_globals.h b/includes/iguana_globals.h index 31a91a073..17c217df2 100755 --- a/includes/iguana_globals.h +++ b/includes/iguana_globals.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/includes/iguana_structs.h b/includes/iguana_structs.h index e9fd52383..02939a582 100755 --- a/includes/iguana_structs.h +++ b/includes/iguana_structs.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -499,7 +499,7 @@ struct iguana_info uint32_t fastfind; FILE *fastfps[0x100]; uint8_t *fast[0x100]; int32_t *fasttables[0x100]; long fastsizes[0x100]; uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime; int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,PREFETCHLAG,estsize,activebundles; - int32_t MAXPEERS,MAXPENDINGREQUESTS,MAXBUNDLES,MAXSTUCKTIME,active,closestbundle,numemitted,lastsweep,numemit,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,FULLNODE,VALIDATENODE,origbalanceswritten,balanceswritten,lastRTheight,RTdatabad; + int32_t MoMoMheight,MAXPEERS,MAXPENDINGREQUESTS,MAXBUNDLES,MAXSTUCKTIME,active,closestbundle,numemitted,lastsweep,numemit,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,FULLNODE,VALIDATENODE,origbalanceswritten,balanceswritten,lastRTheight,RTdatabad; bits256 balancehash,allbundles; uint32_t lastsync,parsetime,numiAddrs,lastpossible,bundlescount,savedblocks,backlog,spendvectorsaved,laststats,lastinv2,symbolcrc,spendvalidated; char VALIDATEDIR[512]; int32_t longestchain,badlongestchain,longestchain_strange,RTramchain_busy,emitbusy,stuckiters,virtualchain,RTheight,RTreset_needed; @@ -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],validateaddress[64],estimatefeestr[64],signtxstr[64]; double txidfind_totalmillis,txidfind_num,spendtxid_totalmillis,spendtxid_num; struct iguana_monitorinfo monitoring[256]; int32_t notarychain,didaddresses; diff --git a/includes/iguana_types.h b/includes/iguana_types.h index 4a1b4647e..a536e9a1a 100755 --- a/includes/iguana_types.h +++ b/includes/iguana_types.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2017 The SuperNET Developers. * + * Copyright © 2014-2018 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/makeRelease.sh b/makeRelease.sh new file mode 100644 index 000000000..89f5c8a88 --- /dev/null +++ b/makeRelease.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +binaries=("iguana") + +for binary in "${binaries[@]}"; +do + # find the dylibs to copy for komodod + DYLIBS=`otool -L agents/$binary | grep "/usr/local" | awk -F' ' '{ print $1 }'` + echo "copying $DYLIBS to agents" + # copy the dylibs to the agents-dir + for dylib in $DYLIBS; do cp -rf $dylib agents/; done + + # modify komodod to point to dylibs + echo "modifying $binary to use local libraries" + for dylib in $DYLIBS; do install_name_tool -change $dylib @executable_path/`basename $dylib` agents/$binary; done; + chmod +x agents/$binary +done diff --git a/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