Browse Source

Merge pull request #1 from jl777/dev

Dev
blackjok3r
Alrighttt 6 years ago
committed by GitHub
parent
commit
67b73f45a6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .dockerignore
  2. 18
      .github/ISSUE_TEMPLATE/bug_report.md
  3. 8
      .gitignore
  4. 41
      .travis.yml
  5. 5
      CMakeLists.txt
  6. 10
      Dockerfile.clientnode
  7. 10
      Dockerfile.seednode
  8. 35
      Jenkinsfile
  9. 5
      OSlibs/win/mingw.h
  10. 32
      appveyor.yml
  11. 23
      basilisk/basilisk_bitcoin.c
  12. 2
      cpp-ethereum
  13. 1
      crypto777/CMakeLists.txt
  14. 8
      crypto777/OS_nonportable.c
  15. 1
      crypto777/OS_portable.h
  16. 187
      crypto777/bitcoind_RPC.c
  17. 6
      crypto777/cJSON.c
  18. 43
      docker-compose.yml
  19. 5
      etomic_build/client
  20. 4
      etomic_build/client/buy_BEER_OTHER
  21. 4
      etomic_build/client/client
  22. 8
      etomic_build/client/enable
  23. 1
      etomic_build/client/myipaddr
  24. 1
      etomic_build/client/passphrase
  25. 4
      etomic_build/client/setpassphrase
  26. 2
      etomic_build/client/userpass
  27. 2
      etomic_build/coins
  28. 3
      etomic_build/enable
  29. 1
      etomic_build/passphrase
  30. 5
      etomic_build/run
  31. 8
      etomic_build/seed/enable
  32. 1
      etomic_build/seed/myipaddr
  33. 1
      etomic_build/seed/passphrase
  34. 4
      etomic_build/seed/run
  35. 4
      etomic_build/seed/sell_BEER_OTHER
  36. 4
      etomic_build/seed/setpassphrase
  37. 2
      etomic_build/seed/userpass
  38. 2
      etomic_build/userpass
  39. 8
      iguana.vcxproj
  40. 1
      iguana/client
  41. 1
      iguana/coins/ccl_7776
  42. 1
      iguana/coins/dion_7776
  43. 4
      iguana/coins/emc2_7776
  44. 1
      iguana/coins/eql_7776
  45. 1
      iguana/coins/glxt_7776
  46. 3
      iguana/coins/hush_7776
  47. 1
      iguana/coins/kmdice_7776
  48. 1
      iguana/coins/mgnx_7776
  49. 1
      iguana/coins/pgt_7776
  50. 1
      iguana/coins/pirate_7776
  51. 2
      iguana/coins/rfox_7776
  52. 2
      iguana/coins/sec_7776
  53. 1
      iguana/coins/vrsc_7776
  54. 1
      iguana/coins/zilla_7776
  55. 12
      iguana/dPoW.h
  56. 61
      iguana/dpow/dpow_fsm.c
  57. 219
      iguana/dpow/dpow_network.c
  58. 91
      iguana/dpow/dpow_rpc.c
  59. 101
      iguana/dpow/dpow_tx.c
  60. 49
      iguana/dpowassets
  61. 10
      iguana/exchanges/CMakeLists.txt
  62. 362
      iguana/exchanges/LP_bitcoin.c
  63. 33
      iguana/exchanges/LP_coins.c
  64. 130
      iguana/exchanges/LP_commands.c
  65. 214
      iguana/exchanges/LP_etomic.c
  66. 2
      iguana/exchanges/LP_etomic.h
  67. 68
      iguana/exchanges/LP_include.h
  68. 6
      iguana/exchanges/LP_instantdex.c
  69. 6
      iguana/exchanges/LP_mmjson.c
  70. 254
      iguana/exchanges/LP_mpnet.c
  71. 96
      iguana/exchanges/LP_nativeDEX.c
  72. 13
      iguana/exchanges/LP_network.c
  73. 371
      iguana/exchanges/LP_ordermatch.c
  74. 32
      iguana/exchanges/LP_portfolio.c
  75. 87
      iguana/exchanges/LP_prices.c
  76. 278
      iguana/exchanges/LP_privkey.c
  77. 116
      iguana/exchanges/LP_remember.c
  78. 35
      iguana/exchanges/LP_rpc.c
  79. 7
      iguana/exchanges/LP_scan.c
  80. 2
      iguana/exchanges/LP_secp.c
  81. 58
      iguana/exchanges/LP_signatures.c
  82. 136
      iguana/exchanges/LP_socket.c
  83. 2
      iguana/exchanges/LP_statemachine.c
  84. 86
      iguana/exchanges/LP_swap.c
  85. 2
      iguana/exchanges/LP_tradebots.c
  86. 307
      iguana/exchanges/LP_transaction.c
  87. 61
      iguana/exchanges/LP_utxo.c
  88. 2
      iguana/exchanges/auto_chipsbtc
  89. 2
      iguana/exchanges/auto_chipskmd
  90. 2
      iguana/exchanges/autoprice
  91. 81
      iguana/exchanges/bitcoin.c
  92. 1
      iguana/exchanges/bitcoin.h
  93. 4
      iguana/exchanges/coins
  94. 89
      iguana/exchanges/etomicswap/etomiccurl.c
  95. 9
      iguana/exchanges/etomicswap/etomiccurl.h
  96. 302
      iguana/exchanges/etomicswap/etomiclib.cpp
  97. 49
      iguana/exchanges/etomicswap/etomiclib.h
  98. 2
      iguana/exchanges/fundvalue
  99. 3
      iguana/exchanges/gen64addrs
  100. 7
      iguana/exchanges/mm.c

3
.dockerignore

@ -0,0 +1,3 @@
.git
.vscode
cmake-build-debug

18
.github/ISSUE_TEMPLATE/bug_report.md

@ -0,0 +1,18 @@
---
name: Bug report
about: Marketmaker 1.0 bug report
---
**Describe the bug**
A clear and concise description of what the bug is.
**Please answer following questions and attach requested info - it'll help to solve issue faster**
- What OS do you use?
- What marketmaker version do you run?
- Attach your coins.json config.
- Provide your enable script with response.
- Provide other curl scripts (with responses) which were executed prior to error.
- Attach full marketmaker console logs (start collecting right after marketmaker execution).
- ***Make sure that you don't send your passphrase, userpass and privkeys. Your funds might be stolen if you reveal this info publicly!***
- Provide info for all nodes involved (e.g. if error occurs during atomic swap you should provide info for both Bob and Alice).

8
.gitignore

@ -263,4 +263,12 @@ Release/*
build_win64_release/* build_win64_release/*
DB/* DB/*
.env.client
.env.seed
etomic_build/client/DB
etomic_build/client/stats.log
etomic_build/client/unparsed.txt
etomic_build/seed/DB
etomic_build/seed/stats.log
etomic_build/seed/unparsed.txt
iguana/exchanges/manychains iguana/exchanges/manychains

41
.travis.yml

@ -4,12 +4,6 @@ matrix:
include: include:
- os: linux - os: linux
compiler: gcc compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7
env: OS_NAME=Linux MATRIX_EVAL="CC=gcc-7 && CXX=g++-7" env: OS_NAME=Linux MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
- os: osx - os: osx
compiler: clang compiler: clang
@ -17,14 +11,39 @@ matrix:
osx_image: xcode9.2 osx_image: xcode9.2
before_install: before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt-get update && sudo apt-get install -y g++-7; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then chmod +x travis_cmake_linux.sh && ./travis_cmake_linux.sh; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then chmod +x travis_cmake_mac.sh && ./travis_cmake_mac.sh; fi
- git submodule update --init --recursive - git submodule update --init --recursive
script: script:
- export VERSION=`echo "$(git tag -l --points-at HEAD)"`
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export THREAD_COUNT=`echo "$(nproc --all)"`; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export THREAD_COUNT=`echo "$(sysctl -n hw.physicalcpu)"`; fi
- mkdir build && cd build - 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" == "linux" ]]; then cmake -DMM_VERSION="$VERSION" -DCMAKE_C_COMPILER=/usr/bin/gcc-7 -DCMAKE_CXX_COMPILER=/usr/bin/g++-7 ..; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cmake ..; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cmake -DMM_VERSION="$VERSION" ..; fi
- cmake --build . --target marketmaker-mainnet - echo "cmake --build . --target marketmaker-mainnet -j $THREAD_COUNT"
- cmake --build . --target marketmaker-mainnet -j $THREAD_COUNT
- cmake --build . --target marketmaker-testnet -j $THREAD_COUNT
cache: cache:
directories: apt: true
- $HOME/.hunter directories:
- $HOME/.hunter
before_deploy:
- export TAG=`echo "$(git rev-parse --short HEAD)"`
- mkdir deploy
- strip iguana/exchanges/marketmaker-mainnet
- strip iguana/exchanges/marketmaker-testnet
- tar -cvzf deploy/marketmaker-"$TRAVIS_OS_NAME"-"$TAG".tar.gz -C iguana/exchanges marketmaker-mainnet marketmaker-testnet
deploy:
provider: releases
api_key:
secure: "JDwFBGO4WLra9bXr2dsovet8y/ymC0Y+LJNr5/qlUIDt97zVytGbIlUc8BuI2VZFcnAvrtfOGdCs9m/PcLzZd4bMxXSsuaU0AJk/Vj9KzrIIGPJ4uS39KpO1USUpPW+5e0Bisf30JN3N2NypwMbMu42TKjVqaXSbVQfh79Iu6PdnyfiFbbTEfMeiRRrD72c00rwAw7kmndf7Sv9MiMN8WTFe0cQz5eH8GU/BSbnDorSrtClU4r7McR98zXaig/8XVcT543tcqdYW95QO7OqOjAid3XzzA/bPUTjC/nF/AyTJDco26nts0bCrCYeZRXIWdEInFLIeRHhHD7sW7dILRT/I7WlaLWnRtwo8e1L+U1k1yZ84dQMpgBznttdwH3vSj0crwCbFuMaRMMbPeW0H8C1VitLy1mlapw3RDI9yKlcw4V6WjPbz0YKhAoZgT/M/SaGr4ZkoWNCPoV5+Gub78p24Y8Y9BptJgj5t9KAcmDwbJ9wPt006ObWnbXvapo+6N5Dk2zuyQe9seoupzy4CAiNdluzAAVWsV/SjnN2aapjXoxaAaLQC6T8C1l1BpYri9LSKrjerr4QLVl/nw2yovAKNEobLLBVpSwfg4R72fu1BMS65gVsOqtFfs+R47CY+1D1Slev+UmKNMdE51+aXM+1XeC6wDUS5d13mW1NLhOE="
file_glob: true
file: "deploy/*"
on:
tags: true
skip_cleanup: true

5
CMakeLists.txt

@ -13,6 +13,9 @@ set(CMAKE_CXX_EXTENSIONS Off)
include(cmake/DownloadProject.cmake) include(cmake/DownloadProject.cmake)
hunter_add_package(libsodium)
find_package(libsodium CONFIG REQUIRED)
# Download and install nanomsg at CMake configure time # Download and install nanomsg at CMake configure time
download_project(PROJ nanomsg download_project(PROJ nanomsg
GIT_REPOSITORY https://github.com/nanomsg/nanomsg.git GIT_REPOSITORY https://github.com/nanomsg/nanomsg.git
@ -24,7 +27,7 @@ download_project(PROJ nanomsg
) )
find_library(NANOMSG_LIBRARY NAMES nanomsg PATHS ${DEPS_INSTALL_PREFIX}/lib NO_DEFAULT_PATH) find_library(NANOMSG_LIBRARY NAMES nanomsg PATHS ${DEPS_INSTALL_PREFIX}/lib NO_DEFAULT_PATH)
include_directories("${CMAKE_SOURCE_DIR}") include_directories("${CMAKE_SOURCE_DIR}" ${LIBSODIUM_ROOT})
add_subdirectory(cpp-ethereum) add_subdirectory(cpp-ethereum)
add_subdirectory(iguana/exchanges) add_subdirectory(iguana/exchanges)
add_subdirectory(iguana/exchanges/etomicswap) add_subdirectory(iguana/exchanges/etomicswap)

10
Dockerfile.clientnode

@ -0,0 +1,10 @@
FROM ubuntu:17.10
USER root
RUN apt-get update && apt-get install -y rinetd curl libcurl3-gnutls
RUN echo "0.0.0.0 10271 10.100.0.1 10271" >> /etc/rinetd.conf
RUN echo "0.0.0.0 8923 10.100.0.1 8923" >> /etc/rinetd.conf
RUN echo "0.0.0.0 8232 10.100.0.1 8232" >> /etc/rinetd.conf
RUN useradd -u 111 jenkins
USER jenkins
WORKDIR /usr/mm/etomic_build/client
CMD /usr/sbin/rinetd && rm -rf DB && ./client

10
Dockerfile.seednode

@ -0,0 +1,10 @@
FROM ubuntu:17.10
USER root
RUN apt-get update && apt-get install -y rinetd curl libcurl3-gnutls
RUN echo "0.0.0.0 10271 10.100.0.1 10271" >> /etc/rinetd.conf
RUN echo "0.0.0.0 8923 10.100.0.1 8923" >> /etc/rinetd.conf
RUN echo "0.0.0.0 8232 10.100.0.1 8232" >> /etc/rinetd.conf
RUN useradd -u 111 jenkins
USER jenkins
WORKDIR /usr/mm/etomic_build/seed
CMD /usr/sbin/rinetd && rm -rf DB && ./run

35
Jenkinsfile

@ -1,11 +1,12 @@
pipeline { pipeline {
agent { agent any
docker {
image 'artempikulin/cmake-ubuntu'
}
}
stages { stages {
stage('Prepare') {
steps {
sh '''cp -r /root/.env.client .env.client
cp -r /root/.env.seed .env.seed'''
}
}
stage('Build') { stage('Build') {
steps { steps {
sh '''git submodule update --init --recursive sh '''git submodule update --init --recursive
@ -13,7 +14,27 @@ rm -rf build
mkdir build mkdir build
cd build cd build
cmake .. cmake ..
cmake --build . --target marketmaker-testnet''' cmake --build . --target marketmaker-testnet -j 4
cd ../
docker-compose build'''
}
}
stage('Trade BEER/ETH') {
steps {
sh '''docker-compose up -d
./start_BEER_OTHER_trade.sh ETH
timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f clientnode)
timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f seednode)
docker-compose down'''
}
}
stage('Trade ETH/BEER') {
steps {
sh '''docker-compose up -d
./start_BEER_OTHER_trade_inverted.sh ETH
timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f clientnode)
timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f seednode)
docker-compose down'''
} }
} }
} }

5
OSlibs/win/mingw.h

@ -5,8 +5,11 @@
#include <io.h> #include <io.h>
#define _USE_W32_SOCKETS 1 #define _USE_W32_SOCKETS 1
#define WIN32_LEAN_AND_MEAN
#ifdef MM_WIN_BUILD
#include <winsock2.h> #include <winsock2.h>
#endif
#include <windows.h> #include <windows.h>
#define PTW32_STATIC_LIB #define PTW32_STATIC_LIB
#include "pthread.h" #include "pthread.h"

32
appveyor.yml

@ -1,6 +1,30 @@
version: 1.0.{build} version: 1.0.{build}
branches:
only:
- etomic
build_script: build_script:
- cmd: marketmaker_build_etomic.cmd - cmd: marketmaker_build_etomic.cmd
cache:
- C:\.hunter
- marketmaker_depends
after_build:
- '7z a mm-win.zip
.\build_win64_release\iguana\exchanges\Release\marketmaker-mainnet.exe
.\marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl.dll
.\marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.dll
"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\redist\\x64\\Microsoft.VC140.CRT\\msvcp140.dll"
"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\redist\\x64\\Microsoft.VC140.CRT\\vcruntime140.dll"'
artifacts:
- path: mm-win.zip
name: marketmaker-mainnet
deploy:
release: v$(appveyor_build_version)
provider: GitHub
auth_token:
secure: iabzoz73JgtOIyE/Nmz4a4XefmK+7pIeup+1Hunj4hGKrdfesFN+176DMApgfu8t
artifact: marketmaker-mainnet
draft: false
prerelease: false
on:
branch: master
appveyor_repo_tag: false

23
basilisk/basilisk_bitcoin.c

@ -584,18 +584,31 @@ char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coi
*completedp = 0; *completedp = 0;
if ( signedtxidp != 0 ) if ( signedtxidp != 0 )
memset(signedtxidp,0,sizeof(*signedtxidp)); memset(signedtxidp,0,sizeof(*signedtxidp));
bitcoin_address(changeaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33);
if (strcmp(coin->chain->symbol, "HUSH") == 0)
bitcoin_address_ex(coin->chain->symbol, changeaddr, 0x1c, coin->chain->pubtype, myinfo->persistent_pubkey33, 33);
else
bitcoin_address(changeaddr, coin->chain->pubtype, myinfo->persistent_pubkey33, 33);
txfee = (coin->txfee + duplicates*coin->txfee/10); txfee = (coin->txfee + duplicates*coin->txfee/10);
if ( strcmp(coin->symbol,"GAME") == 0 ) if (strcmp(coin->symbol, "GAME") == 0 || strcmp(coin->symbol, "EMC2") == 0)
printf("GAME txfee %.8f\n",dstr(txfee)); printf("%s txfee %.8f\n", coin->symbol, dstr(txfee));
if ( (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,0,1,0)) != 0 )
uint32_t txversion = 1; // txversion = 1 for non-overwintered and non-sapling coins
if (coin->sapling != 0)
txversion = 4;
if ( (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,0,txversion,0)) != 0 )
{ {
if ( duplicates <= 0 ) if ( duplicates <= 0 )
duplicates = 1; duplicates = 1;
spendlen = bitcoin_pubkeyspend(script,0,pubkey33); spendlen = bitcoin_pubkeyspend(script,0,pubkey33);
for (i=0; i<duplicates; i++) for (i=0; i<duplicates; i++)
bitcoin_txoutput(txobj,script,spendlen,satoshis); bitcoin_txoutput(txobj,script,spendlen,satoshis);
//printf("JSON: %s\n", cJSON_Print(txobj));
//printf("addresses: %s\n", cJSON_Print(addresses));
rawtx = iguana_calcrawtx(myinfo,coin,&vins,txobj,satoshis * duplicates,changeaddr,txfee,addresses,0,0,0,0,"127.0.0.1",0,1); rawtx = iguana_calcrawtx(myinfo,coin,&vins,txobj,satoshis * duplicates,changeaddr,txfee,addresses,0,0,0,0,"127.0.0.1",0,1);
//printf("JSON: %s\n", cJSON_Print(txobj));
if ( strcmp(coin->chain->symbol,"BTC") == 0 && cJSON_GetArraySize(vins) > duplicates/2 ) if ( strcmp(coin->chain->symbol,"BTC") == 0 && cJSON_GetArraySize(vins) > duplicates/2 )
{ {
free(rawtx); free(rawtx);

2
cpp-ethereum

@ -1 +1 @@
Subproject commit 633c62c08bc73c7c3935c948a8d6c656a3659976 Subproject commit e804e95d9a71e87fc5e3e69a2888448f23bc724f

1
crypto777/CMakeLists.txt

@ -7,5 +7,6 @@ if(WIN32)
add_definitions(-DNATIVE_WINDOWS) add_definitions(-DNATIVE_WINDOWS)
add_definitions(-DIGUANA_LOG2PACKETSIZE=20) add_definitions(-DIGUANA_LOG2PACKETSIZE=20)
add_definitions(-DIGUANA_MAXPACKETSIZE=1572864) add_definitions(-DIGUANA_MAXPACKETSIZE=1572864)
add_definitions(-DMM_WIN_BUILD)
include_directories("${CMAKE_SOURCE_DIR}/includes") include_directories("${CMAKE_SOURCE_DIR}/includes")
endif() endif()

8
crypto777/OS_nonportable.c

@ -26,10 +26,10 @@
* not from the mingw header, so we need to include the windows header * not from the mingw header, so we need to include the windows header
* if we are compiling in windows 64bit * if we are compiling in windows 64bit
*/ */
//#if defined(_M_X64) #if defined(_M_X64)
//#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
//#include <WinSock2.h> #include <WinSock2.h>
//#endif #endif
#include "OS_portable.h" #include "OS_portable.h"

1
crypto777/OS_portable.h

@ -425,6 +425,7 @@ bits256 bits256_sha256(bits256 data);
void bits256_rmd160(uint8_t rmd160[20],bits256 data); void bits256_rmd160(uint8_t rmd160[20],bits256 data);
void bits256_rmd160_sha256(uint8_t rmd160[20],bits256 data); void bits256_rmd160_sha256(uint8_t rmd160[20],bits256 data);
double get_theoretical(double *avebidp,double *aveaskp,double *highbidp,double *lowaskp,double *CMC_averagep,double changes[3],char *name,char *base,char *rel,double *USD_averagep); double get_theoretical(double *avebidp,double *aveaskp,double *highbidp,double *lowaskp,double *CMC_averagep,double changes[3],char *name,char *base,char *rel,double *USD_averagep);
char *bitcoind_RPCnew(void *curl_handle,char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout);
extern char *Iguana_validcommands[]; extern char *Iguana_validcommands[];
extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY; extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY;

187
crypto777/bitcoind_RPC.c

@ -14,6 +14,7 @@
******************************************************************************/ ******************************************************************************/
//#define KEEPALIVE breaks marketmaker api
#ifndef FROM_JS #ifndef FROM_JS
#include "OS_portable.h" #include "OS_portable.h"
@ -74,7 +75,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
char *retstr = 0; char *retstr = 0;
cJSON *json,*result,*error; cJSON *json,*result,*error;
#ifndef FROM_MARKETMAKER #ifndef FROM_MARKETMAKER
usleep(1000); //usleep(1000);
#endif #endif
//printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); //printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr);
if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 ) if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 )
@ -131,7 +132,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
* *
************************************************************************/ ************************************************************************/
static int32_t USE_JAY; //static int32_t USE_JAY;
char *Jay_NXTrequest(char *command,char *params) char *Jay_NXTrequest(char *command,char *params)
{ {
@ -141,23 +142,28 @@ char *Jay_NXTrequest(char *command,char *params)
return(retstr); return(retstr);
} }
char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout)
static void bitcoind_init()
{ {
CURL *curl_handle; static int didinit,count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY; static int32_t didinit;
struct MemoryStruct chunk;
struct curl_slist *headers = NULL; struct return_string s; CURLcode res;
char *bracket0,*bracket1,*retstr,*databuf = 0; long len; int32_t specialcase,numretries; double starttime;
if ( didinit == 0 ) if ( didinit == 0 )
{ {
didinit = 1; didinit = 1;
curl_global_init(CURL_GLOBAL_ALL); //init the curl session curl_global_init(CURL_GLOBAL_ALL); //init the curl session
//curl_handle = curl_easy_init();
}
if ( (0) && (USE_JAY != 0 && (strncmp(url,"http://127.0.0.1:7876/nxt",strlen("http://127.0.0.1:7876/nxt")) == 0 || strncmp(url,"https://127.0.0.1:7876/nxt",strlen("https://127.0.0.1:7876/nxt")) == 0)) )
{
if ( (databuf= Jay_NXTrequest(command,params)) != 0 )
return(databuf);
} }
}
char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout)
{
#ifdef KEEPALIVE
static
#endif
CURL *curl_handle = 0;
static int count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY;
struct MemoryStruct chunk;
struct curl_slist *headers = NULL; struct return_string s; CURLcode res;
char *bracket0,*bracket1,*retstr,*databuf = 0; long len; int32_t specialcase,numretries; double starttime;
bitcoind_init();
numretries = 0; numretries = 0;
if ( debugstr != 0 && strcmp(debugstr,"BTCD") == 0 && command != 0 && strcmp(command,"SuperNET") == 0 ) if ( debugstr != 0 && strcmp(debugstr,"BTCD") == 0 && command != 0 && strcmp(command,"SuperNET") == 0 )
specialcase = 1; specialcase = 1;
@ -174,7 +180,8 @@ try_again:
if ( retstrp != 0 ) if ( retstrp != 0 )
*retstrp = 0; *retstrp = 0;
starttime = OS_milliseconds(); starttime = OS_milliseconds();
curl_handle = curl_easy_init(); if ( curl_handle == 0 )
curl_handle = curl_easy_init();
headers = curl_slist_append(0,"Expect:"); headers = curl_slist_append(0,"Expect:");
curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )"); curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )");
@ -244,7 +251,10 @@ try_again:
//laststart = milliseconds(); //laststart = milliseconds();
res = curl_easy_perform(curl_handle); res = curl_easy_perform(curl_handle);
curl_slist_free_all(headers); curl_slist_free_all(headers);
#ifndef KEEPALIVE
curl_easy_cleanup(curl_handle); curl_easy_cleanup(curl_handle);
curl_handle = 0;
#endif
if ( databuf != 0 ) // clean up temporary buffer if ( databuf != 0 ) // clean up temporary buffer
{ {
free(databuf); free(databuf);
@ -279,7 +289,7 @@ try_again:
count++; count++;
elapsedsum += (OS_milliseconds() - starttime); elapsedsum += (OS_milliseconds() - starttime);
if ( (count % 100000) == 0) if ( (count % 100000) == 0)
printf("%d: ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,elapsedsum/count,(OS_milliseconds() - starttime),command,url); printf("%d: %s ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,debugstr,elapsedsum/count,(OS_milliseconds() - starttime),command,url);
if ( retstrp != 0 ) if ( retstrp != 0 )
{ {
*retstrp = retstr; *retstrp = retstr;
@ -301,6 +311,153 @@ try_again:
} }
} }
char *bitcoind_RPCnew(void *curl_handle,char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout)
{
static int count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY;
struct MemoryStruct chunk;
struct curl_slist *headers = NULL; struct return_string s; CURLcode res;
char *bracket0,*bracket1,*retstr,*databuf = 0; long len; int32_t flag=0,specialcase,numretries; double starttime;
bitcoind_init();
numretries = 0;
if ( url[0] == 0 )
strcpy(url,"http://127.0.0.1:7776");
try_again:
if ( curl_handle == 0 )
{
curl_handle = curl_easy_init();
flag = 1;
}
if ( retstrp != 0 )
*retstrp = 0;
starttime = OS_milliseconds();
headers = curl_slist_append(0,"Expect:");
curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )");
curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl_handle,CURLOPT_URL, url);
if ( (0) )
{
init_string(&s);
curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulate); // send all data to this function
curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback
}
else
{
memset(&chunk,0,sizeof(chunk));
curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION,WriteMemoryCallback);
curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA,(void *)&chunk);
}
curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash
curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS, 1L); // no progress callback
if ( timeout > 0 )
{
if ( bitcoind_RPC_inittime != 0 )
{
#ifndef _WIN32
curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT,1);
#else
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, timeout*100);
#endif
} else curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT,timeout); // causes problems with iguana timeouts
}
if ( strncmp(url,"https",5) == 0 )
{
curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0);
curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYHOST,0);
}
if ( userpass != 0 )
curl_easy_setopt(curl_handle,CURLOPT_USERPWD, userpass);
databuf = 0;
if ( params != 0 )
{
if ( command != 0 )
{
len = strlen(params);
if ( len > 0 && params[0] == '[' && params[len-1] == ']' ) {
bracket0 = bracket1 = (char *)"";
}
else
{
bracket0 = (char *)"[";
bracket1 = (char *)"]";
}
char agentstr[64];
databuf = (char *)malloc(256 + strlen(command) + strlen(params));
if ( debugstr[0] != 0 )
sprintf(agentstr,"\"agent\":\"%s\",",debugstr);
else agentstr[0] = 0;
sprintf(databuf,"{\"id\":\"jl777\",%s\"method\":\"%s\",\"params\":%s%s%s}",agentstr,command,bracket0,params,bracket1);
//printf("url.(%s) userpass.(%s) databuf.(%s)\n",url,userpass,databuf);
//
} //else if ( specialcase != 0 ) fprintf(stderr,"databuf.(%s)\n",params);
curl_easy_setopt(curl_handle,CURLOPT_POST,1L);
if ( databuf != 0 )
curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,databuf);
else curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,params);
}
res = curl_easy_perform(curl_handle);
curl_slist_free_all(headers);
if ( databuf != 0 ) // clean up temporary buffer
{
free(databuf);
databuf = 0;
}
if ( flag != 0 )
{
curl_easy_cleanup(curl_handle);
curl_handle = 0;
}
retstr = chunk.memory; // retstr = s.ptr;
if ( res != CURLE_OK )
{
numretries++;
if ( timeout != 0 )
{
//printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,retstr,res);
free(retstr);
return(0);
}
else if ( numretries >= 4 )
{
printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries);
//printf("Maximum number of retries exceeded!\n");
free(retstr);
return(0);
}
free(retstr);
sleep((1<<numretries));
goto try_again;
}
else
{
if ( command != 0 )
{
count++;
elapsedsum += (OS_milliseconds() - starttime);
if ( (count % 100000) == 0)
printf("%d: ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,elapsedsum/count,(OS_milliseconds() - starttime),command,url);
if ( retstrp != 0 )
{
*retstrp = retstr;
return(retstr);
}
//printf("%s <- %s\n",url,command);
return(post_process_bitcoind_RPC(debugstr,command,retstr,params));
}
else
{
if ( (0) && specialcase != 0 )
fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: BTCD.(%s) -> (%s)\n",params,retstr);
count2++;
elapsedsum2 += (OS_milliseconds() - starttime);
if ( (count2 % 10000) == 0)
printf("%d: ave %9.6f | elapsed %.3f millis | NXT calls.(%s) cmd.(%s)\n",count2,elapsedsum2/count2,(double)(OS_milliseconds() - starttime),url,command);
return(retstr);
}
}
}
/************************************************************************ /************************************************************************
* *
* Initialize the string handler so that it is thread safe * Initialize the string handler so that it is thread safe

6
crypto777/cJSON.c

@ -902,10 +902,10 @@ char *get_cJSON_fieldname(cJSON *obj)
{ {
if ( obj != 0 ) if ( obj != 0 )
{ {
if ( obj->child != 0 && obj->child->string != 0 ) if ( obj->string != 0 )
return(obj->child->string);
else if ( obj->string != 0 )
return(obj->string); return(obj->string);
if ( obj->child != 0 && obj->child->string != 0 )
return(obj->child->string);
} }
return((char *)"<no cJSON string field>"); return((char *)"<no cJSON string field>");
} }

43
docker-compose.yml

@ -0,0 +1,43 @@
version: '2'
services:
seednode:
build:
context: ./
dockerfile: Dockerfile.seednode
volumes:
- ~/.zcash-params:/home/jenkins/.zcash-params
- ~/.komodo:/home/jenkins/.komodo
- ~/.zcash:/home/jenkins/.zcash
- .:/usr/mm
env_file:
- .env.seed
tty: true
networks:
default:
ipv4_address: 10.100.0.2
clientnode:
build:
context: ./
dockerfile: Dockerfile.clientnode
volumes:
- ~/.zcash-params:/home/jenkins/.zcash-params
- ~/.komodo:/home/jenkins/.komodo
- ~/.zcash:/home/jenkins/.zcash
- .:/usr/mm
links:
- seednode
tty: true
env_file:
- .env.client
networks:
default:
ipv4_address: 10.100.0.3
networks:
default:
driver: bridge
ipam:
config:
- subnet: 10.100.0.0/16
gateway: 10.100.0.1

5
etomic_build/client

@ -1,5 +0,0 @@
#!/bin/bash
source passphrase
source coins
./stop
iguana/exchanges/marketmaker "{\"netid\":9999,\"seednode\":\"5.9.253.204\",\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" &

4
etomic_build/client/buy_BEER_OTHER

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"$1\",\"rel\":\"BEER\",\"price\":1}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"buy\",\"base\":\"BEER\",\"rel\":\"$1\",\"relvolume\":0.1,\"price\":1}"

4
etomic_build/client/client

@ -0,0 +1,4 @@
#!/bin/bash
source passphrase
source ../coins
../../build/iguana/exchanges/marketmaker-testnet "{\"netid\":9999,\"seednode\":\"10.100.0.2\",\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}"

8
etomic_build/client/enable

@ -0,0 +1,8 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETOMIC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETH\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"NODEC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"JST\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BEER\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ZEC\"}"

1
etomic_build/client/myipaddr

@ -0,0 +1 @@
10.100.0.3

1
etomic_build/client/passphrase

@ -0,0 +1 @@
export passphrase="$PASSPHRASE"

4
etomic_build/client/setpassphrase

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
source passphrase
curl --url "http://127.0.0.1:7783" --data "{\"netid\":9999,\"seednode\":\"10.100.0.2\",\"userpass\":\"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f\",\"method\":\"passphrase\",\"passphrase\":\"$passphrase\",\"gui\":\"nogui\"}"

2
etomic_build/client/userpass

@ -0,0 +1,2 @@
#export userpass="<put the userpass value from the first API call here>"
export userpass="$USERPASS"

2
etomic_build/coins

File diff suppressed because one or more lines are too long

3
etomic_build/enable

@ -1,5 +1,4 @@
#!/bin/bash #!/bin/bash
source userpass source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETH\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETOMIC\"}" curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETOMIC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETH\"}"

1
etomic_build/passphrase

@ -1 +0,0 @@
export passphrase="<put a very strong passphrase here>"

5
etomic_build/run

@ -1,5 +0,0 @@
#!/bin/bash
source passphrase
source coins
./stop
$1 iguana/exchanges/marketmaker "{\"netid\":9999,\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" &

8
etomic_build/seed/enable

@ -0,0 +1,8 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETOMIC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETH\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"NODEC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"JST\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BEER\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ZEC\"}"

1
etomic_build/seed/myipaddr

@ -0,0 +1 @@
10.100.0.2

1
etomic_build/seed/passphrase

@ -0,0 +1 @@
export passphrase="$PASSPHRASE"

4
etomic_build/seed/run

@ -0,0 +1,4 @@
#!/bin/bash
source passphrase
source ../coins
../../build/iguana/exchanges/marketmaker-testnet "{\"netid\":9999,\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}"

4
etomic_build/seed/sell_BEER_OTHER

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"BEER\",\"rel\":\"$1\",\"price\":0.9}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"BEER\",\"rel\":\"$1\",\"basevolume\":0.1,\"price\":0.9}"

4
etomic_build/seed/setpassphrase

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
source passphrase
curl --url "http://127.0.0.1:7783" --data "{\"netid\":9999,\"seednode\":\"5.9.253.204\",\"userpass\":\"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f\",\"method\":\"passphrase\",\"passphrase\":\"$passphrase\",\"gui\":\"nogui\"}"

2
etomic_build/seed/userpass

@ -0,0 +1,2 @@
#export userpass="<put the userpass value from the first API call here>"
export userpass="$USERPASS"

2
etomic_build/userpass

@ -1,2 +1,2 @@
#export userpass="<put the userpass value from the first API call here>" #export userpass="<put the userpass value from the first API call here>"
export userpass="c3d8c2a364b7d18c1f9d7321d017b92e9f9c791e4f5c741214fefdea8a071256" export userpass="$USERPASS"

8
iguana.vcxproj

@ -113,14 +113,14 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;NATIVE_WINDOWS;WIN32;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;_CONSOLE;NATIVE_WINDOWS;WIN32;ISNOTARYNODE=1;LIQUIDITY_PROVIDER=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StructMemberAlignment>1Byte</StructMemberAlignment> <StructMemberAlignment>1Byte</StructMemberAlignment>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>.\OSlibs\win\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>.\OSlibs\win\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>pthread_lib.lib;Ws2_32.lib;nanomsg.lib;libcurl.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>pthread_lib.lib;Ws2_32.lib;nanomsg.lib;libcurl.lib;libsodium.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -151,7 +151,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN64;_WIN64;_CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN64;_WIN64;_CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;ISNOTARYNODE=1;LIQUIDITY_PROVIDER=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StructMemberAlignment>1Byte</StructMemberAlignment> <StructMemberAlignment>1Byte</StructMemberAlignment>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile> </ClCompile>
@ -160,7 +160,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Ws2_32.lib;Advapi32.lib;$(SolutionDir)OSlibs\win\x64\pthread_lib.lib;libcurl.lib;nanomsg.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Ws2_32.lib;Advapi32.lib;$(SolutionDir)OSlibs\win\x64\pthread_lib.lib;libcurl.lib;nanomsg.lib;libsodium.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>.\OSlibs\win\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>.\OSlibs\win\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>

1
iguana/client

@ -17,6 +17,7 @@ git pull;
{\"coin\":\"ANC\", \"name\":\"anoncoin\", \"pubtype\":23, \"p2shtype\":5, \"wiftype\":151, \"txfee\":2000000}, {\"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\":\"FRK\", \"name\":\"franko\", \"pubtype\":35, \"p2shtype\":5, \"wiftype\":163, \"txfee\":0},
{\"coin\":\"GAME\", \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"GAME\", \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000},
{\"coin\":\"EMC2\", \"name\":\"einsteinium\", \"pubtype\":33, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000},
{\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"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} {\"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\"}" & ], \"userhome\":\"/${HOME#"/"}\",\"passphrase\":\"$randval\"}" &

1
iguana/coins/ccl_7776

@ -0,0 +1 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"CCL.conf\",\"path\":\"${HOME#"/"}/.komodo/CCL\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"CCL\",\"name\":\"CCL\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"5c31ff66\",\"p2p\":20848,\"rpc\":20849,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}"

1
iguana/coins/dion_7776

@ -0,0 +1 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"DION.conf\",\"path\":\"${HOME#"/"}/.komodo/DION\",\"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\":\"DION\",\"name\":\"DION\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"1a8f06ea\",\"p2p\":23894,\"rpc\":23895,\"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\"}"

4
iguana/coins/emc2_7776

@ -0,0 +1,4 @@
#!/bin/bash
curl --url "http://127.0.0.1:7776" --data "{\"txfee\":0.01,\"conf\":\"einsteinium.conf\",\"path\":\"${HOME#"/"}/.einsteinium\",\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":68,\"endpend\":68,\"services\":129,\"maxpeers\":256,\"newcoin\":\"EMC2\",\"name\":\"Einsteinium\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"e8f1c4ac\",\"p2p\":41878,\"rpc\":41879,\"pubval\":33,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"1000000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"4e56204bb7b8ac06f860ff1c845f03f984303b5b97eb7b42868f714611aed94b\",\"genesis\":{\"version\":1,\"timestamp\":1392841423,\"nBits\":\"1e0ffff0\",\"nonce\":3236648,\"merkle_root\":\"b3e47e8776012ee4352acf603e6b9df005445dcba85c606697f422be3cc26f9b\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70015}"

1
iguana/coins/eql_7776

@ -0,0 +1 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"EQL.conf\",\"path\":\"${HOME#"/"}/.komodo/EQL\",\"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\":\"EQL\",\"name\":\"EQL\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"b890e458\",\"p2p\":10305,\"rpc\":10306,\"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\"}"

1
iguana/coins/glxt_7776

@ -0,0 +1 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"GLXT.conf\",\"path\":\"${HOME#"/"}/.komodo/GLXT\",\"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\":\"GLXT\",\"name\":\"GLXT\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"0beebb40\",\"p2p\":15722,\"rpc\":15723,\"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\"}"

3
iguana/coins/hush_7776

@ -0,0 +1,3 @@
#!/bin/bash
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"hush.conf\",\"path\":\"${HOME#"/"}/.hush\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":32,\"newcoin\":\"HUSH\",\"name\":\"Hush\",\"hasheaders\":0,\"useaddmultisig\":0,\"netmagic\":\"24e92764\",\"p2p\":8888,\"rpc\":8822,\"pubval\":184,\"p2shval\":189,\"wifval\":128,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"0003a67bc26fe564b75daf11186d360652eb435a35ba3d9d3e7e5d5f8e62dc17\",\"protover\":170002,\"genesisblock\":\"04000000000000000000000000000000000000000000000000000000000000000000000077e16b66afd4fe560cf16abf7bba8e661ba574b6389675a2366f19ecf939058300000000000000000000000000000000000000000000000000000000000000008be02d58ffff071f0000000000000000000000000000000000000000000000000000000000000512fd40050045f33727869d999e1d90de13eec508bb9eedf7c623ae0926922a749df12927967ce41f0363365e536a149ced0a25ce7258bcf4d36c9d69ea830ecafaac0a20576ee2405fa6e1ed91e5e5f3e72add8dae92175e05bb114100c654b90a0ea0e35e3ecee480d073b90c0d252963519492dce839f14bd3e54b017972fe05c30f61d73437d2ccb8a8dac1f33ba27c9d8a81bc02911a0f04f0af099ba8cc9114bd0de60fcd699673bc7a05d06baf544c5daa773991ff85c269c17f3a58618818f91d6ee9e4c393cd8d03428a2cc9be4243384caf197c77029b8c6c9387ab7a4966faac8efb13f7f9e259040fbbc1295551ad10084dba5ef0b732da7c90bd06026152acc74aad871aa3c2e46666d262129f07e128a0ea322b532851d649d2e0443954dafaaddfa6af28a70c786b94d904cb8ad3fda5364d9d5cccd1ce802f801dad25644a7dcab1c44191f24cdd8997f19c3602bc6e936aca34413a3270f837d94b211c5ad7533a070fe7b5651db5bf5d2aa13d503af5eef912fdcb5704a1bfc4c095d9b3da8f62261ed0dea089bf5b12db067ce1b4bee14f6515a180dedfeac9d794649da2b203e2a975db5c961daf788239ec722a7afbc63b8cb30c11e0ce1943f71981c3437530a4c0fcec0f9e7c6c1f5e85373ff132ddccb202916665c5559ddbcff20c743f15e2b7748a11d5de283f8cf190cb0c47feec730f6bde470ae172b9fdfc07e96362dd9238833876ff14b8028e811af7610b08842aac55f79f066e5df160104bd571f44fb16d7476e2626458c2992f6291781915d5ee927594c8a5966ba379ace56cf30a9c5f79e70fa6347e664796eea268d74862522ac275bf94ef2e406034ff121345351b92245ba834c752249d3506a111407bbd10e31b1167f9c3702fc54176e18ad8ca6211c892d4ba4598b3d834c2aa06392e21b4ff3d6d510132989a9828086bbbd1e03debe3fd44e34550c54103df97e25709e086efefc27013b9fc08bc777f96630876dfcba638d5f1f2fe10935d5fb950388ca485044535350e83267d0b5c75e5f570cd849d8567daecb90b011f72bccde31e8c6b13a630b82dc1fe68f7ef261013e2a91ed033c11fa201f4a32f7a05a58cbbce0a13f175c5e08a3ced164686a26277be7bbac9fed583276d12d67a12649b4f46e466bdc57bed60c3f8bd6e05f73d54686d36e97a6461cbda430abf9ec8df6699160822abbc947463338741c961fcaab0dbbd2a2b92084d0b372242e6103aa54479fc7b350f35c23eb1f3161352ec3e1ba178fd82147ff42ba02164405fe74606b6c525883dddc5fd8431bb49c889571c155974af19291e49f55fbfe7c823f526f77edc9bba773f9e370baf614175515eef3f7be1750ee2a3c915a0f8e3ea31bdd397668ebef7f0cf75ddecec887df2baf771e1013d2d4795c39ba8449c18d559eab9c2718f39531c0b632437506c9061ee9995e11173da85948b5b82e02e54977eb64db682af9a1993bbd16fcab3d55be7493a38ab9012d6c3f5834f3740fcc725aa70e0570b46073ad43c7b0a582af576f8e2afd4c6c75d933b0d8955a49c2b522d84a9fc9c75bbf2b5363667e5b42b420eddfa537ac5d15d7a4ea9c5dfd063cb03e81da219163fe7135d61db9d19f891e5784613a59df7ffefa2017f8d6edfde9ce19babd5963aae94ad7bfd52e736323c73f9765c9026f1b0a560dbdcc71563586f4ced072c0903bdf6362fe4f4c0cea265ad48a6639bccaa08b5593a9f0eeac5cfcc14ca6d2e7449ec029598b4061793745ba3e53dc289c16ee84c7c2575824e7a5e372d8c8e1bf0a2dfa90283a67bd305c684b39af1d109004522301344a9c346a0e227c45749aa24b11623211155bad78e1a137376738662a78619dceaf0c79f0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff071f0104455a6461736865353430656366313030303031383839383336633764343931613266343465366263363037366435396535653331373235353934366237316265336663353136ffffffff010000000000000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000\",\"debug\":0}"

1
iguana/coins/kmdice_7776

@ -0,0 +1 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"KMDICE.conf\",\"path\":\"${HOME#"/"}/.komodo/KMDICE\",\"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\":\"KMDICE\",\"name\":\"KMDICE\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"266bdd28\",\"p2p\":30176,\"rpc\":30177,\"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\"}"

1
iguana/coins/mgnx_7776

@ -0,0 +1 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MGNX.conf\",\"path\":\"${HOME#"/"}/.komodo/MGNX\",\"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\":\"MGNX\",\"name\":\"MGNX\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"a66a23df\",\"p2p\":20730,\"rpc\":20731,\"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\"}"

1
iguana/coins/pgt_7776

@ -0,0 +1 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"PGT.conf\",\"path\":\"${HOME#"/"}/.komodo/PGT\",\"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\":\"PGT\",\"name\":\"PGT\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"8c0d7ec8\",\"p2p\":46704,\"rpc\":46705,\"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\"}"

1
iguana/coins/pirate_7776

@ -0,0 +1 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"PIRATE.conf\",\"path\":\"${HOME#"/"}/.komodo/PIRATE\",\"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\":\"PIRATE\",\"name\":\"PIRATE\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"58e0b617\",\"p2p\":45452,\"rpc\":45453,\"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\"}"

2
iguana/coins/rfox_7776

@ -0,0 +1,2 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"RFOX.conf\",\"path\":\"${HOME#"/"}/.komodo/RFOX\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"RFOX\",\"name\":\"RFOX\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"4cad0644\",\"p2p\":32268,\"rpc\":32269,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}"

2
iguana/coins/sec_7776

@ -0,0 +1,2 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"SEC.conf\",\"path\":\"${HOME#"/"}/.komodo/SEC\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SEC\",\"name\":\"SEC\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"8f27938c\",\"p2p\":11539,\"rpc\":11540,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"185.148.145.43\"}"

1
iguana/coins/vrsc_7776

@ -0,0 +1 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"VRSC.conf\",\"path\":\"${HOME#"/"}/.komodo/VRSC\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"VRSC\",\"name\":\"Verus\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"91db4d20\",\"p2p\":27485,\"rpc\":27486,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"54.39.23.248\",\"sapling\":1}"

1
iguana/coins/zilla_7776

@ -0,0 +1 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"ZILLA.conf\",\"path\":\"${HOME#"/"}/.komodo/ZILLA\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"ZILLA\",\"name\":\"ZILLA\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"91db4d20\",\"p2p\":10040,\"rpc\":10041,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"54.39.23.248\"}"

12
iguana/dPoW.h

@ -29,7 +29,7 @@
#define DPOW_VERSION 0x1782 #define DPOW_VERSION 0x1782
#define DPOW_UTXOSIZE dpow_utxosize(coin->symbol) //10000 #define DPOW_UTXOSIZE dpow_utxosize(coin->symbol) //10000
#define DPOW_MINOUTPUT 6000 #define DPOW_MINOUTPUT 6000
#define DPOW_DURATION 1200 #define DPOW_DURATION 300
#define DPOW_RATIFYDURATION (3600 * 24) #define DPOW_RATIFYDURATION (3600 * 24)
//#define DPOW_ENTRIESCHANNEL ('e' | ('n' << 8) | ('t' << 16) | ('r' << 24)) //#define DPOW_ENTRIESCHANNEL ('e' | ('n' << 8) | ('t' << 16) | ('r' << 24))
@ -109,7 +109,7 @@ struct dpow_recvdata { uint64_t recvmask,bestmask; int8_t bestk; };
struct dpow_block struct dpow_block
{ {
bits256 hashmsg,desttxid,srctxid,beacon,commit,MoM; bits256 hashmsg,desttxid,srctxid,beacon,commit,MoM,mysrcutxo,mydestutxo;
struct iguana_info *srccoin,*destcoin; char *opret_symbol; struct iguana_info *srccoin,*destcoin; char *opret_symbol;
uint64_t destsigsmasks[DPOW_MAXRELAYS],srcsigsmasks[DPOW_MAXRELAYS]; uint64_t destsigsmasks[DPOW_MAXRELAYS],srcsigsmasks[DPOW_MAXRELAYS];
uint64_t recvmask,bestmask,ratifybestmask,ratifyrecvmask,pendingbestmask,pendingratifybestmask,ratifysigmasks[2]; uint64_t recvmask,bestmask,ratifybestmask,ratifyrecvmask,pendingbestmask,pendingratifybestmask,ratifysigmasks[2];
@ -119,6 +119,7 @@ struct dpow_block
int32_t rawratifiedlens[2],height,numnotaries,numerrors,completed,minsigs,duration,numratified,isratify,require0,scores[DPOW_MAXRELAYS]; int32_t rawratifiedlens[2],height,numnotaries,numerrors,completed,minsigs,duration,numratified,isratify,require0,scores[DPOW_MAXRELAYS];
int8_t myind,bestk,ratifybestk,pendingbestk,pendingratifybestk,matches,bestmatches; int8_t myind,bestk,ratifybestk,pendingbestk,pendingratifybestk,matches,bestmatches;
cJSON *ratified; cJSON *ratified;
uint16_t CCid;
uint8_t ratified_pubkeys[DPOW_MAXRELAYS][33],ratifysigs[2][DPOW_MAXSIGLEN],ratifysiglens[2]; uint8_t ratified_pubkeys[DPOW_MAXRELAYS][33],ratifysigs[2][DPOW_MAXSIGLEN],ratifysiglens[2];
char handles[DPOW_MAXRELAYS][32]; char handles[DPOW_MAXRELAYS][32];
char signedtx[32768]; uint8_t ratifyrawtx[2][32768]; uint32_t pendingcrcs[2]; char signedtx[32768]; uint8_t ratifyrawtx[2][32768]; uint32_t pendingcrcs[2];
@ -134,6 +135,8 @@ struct pax_transaction
char symbol[16],coinaddr[64]; uint8_t rmd160[20],shortflag; char symbol[16],coinaddr[64]; uint8_t rmd160[20],shortflag;
}; };
#define DPOW_MAXIPBITS 512
struct dpow_info struct dpow_info
{ {
char symbol[16],dest[16]; uint8_t minerkey33[33],minerid; uint64_t lastrecvmask; char symbol[16],dest[16]; uint8_t minerkey33[33],minerid; uint64_t lastrecvmask;
@ -143,8 +146,9 @@ struct dpow_info
uint32_t SRCREALTIME,lastsrcupdate,destupdated,srcconfirms,numdesttx,numsrctx,lastsplit,cancelratify; uint32_t SRCREALTIME,lastsrcupdate,destupdated,srcconfirms,numdesttx,numsrctx,lastsplit,cancelratify;
int32_t lastheight,maxblocks,SRCHEIGHT,DESTHEIGHT,prevDESTHEIGHT,SHORTFLAG,ratifying,minsigs,freq; int32_t lastheight,maxblocks,SRCHEIGHT,DESTHEIGHT,prevDESTHEIGHT,SHORTFLAG,ratifying,minsigs,freq;
struct pax_transaction *PAX; struct pax_transaction *PAX;
uint32_t fullCCid;
portable_mutex_t paxmutex,dexmutex; portable_mutex_t paxmutex,dexmutex;
uint32_t ipbits[128],numipbits; uint32_t ipbits[DPOW_MAXIPBITS],numipbits;
struct dpow_block **blocks,*currentbp; struct dpow_block **blocks,*currentbp;
}; };
@ -158,7 +162,7 @@ struct komodo_ccdataMoMoM
}; };
uint64_t dpow_notarybestk(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 dpow_paxpending(uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,int32_t src_or_dest,struct dpow_block *bp); int32_t dpow_paxpending(struct supernet_info *myinfo,uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,uint16_t CCid,int32_t src_or_dest,struct dpow_block *bp);
void dex_updateclient(struct supernet_info *myinfo); 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 *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); 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);

61
iguana/dpow/dpow_fsm.c

@ -143,7 +143,7 @@ int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct
{ {
addresses = cJSON_CreateArray(); addresses = cJSON_CreateArray();
jaddistr(addresses,coinaddr); jaddistr(addresses,coinaddr);
if ( (rawtx= iguana_utxoduplicates(myinfo,coin,dp->minerkey33,DPOW_UTXOSIZE,n,&completed,&signedtxid,0,addresses)) != 0 ) if ( myinfo->nosplit == 0 && (rawtx= iguana_utxoduplicates(myinfo,coin,dp->minerkey33,DPOW_UTXOSIZE,n,&completed,&signedtxid,0,addresses)) != 0 )
{ {
if ( (sendtx= dpow_sendrawtransaction(myinfo,coin,rawtx)) != 0 ) if ( (sendtx= dpow_sendrawtransaction(myinfo,coin,rawtx)) != 0 )
{ {
@ -235,7 +235,7 @@ bits256 dpow_calcMoM(uint32_t *MoMdepthp,struct supernet_info *myinfo,struct igu
bits256 MoM; cJSON *MoMjson,*infojson; int32_t prevMoMheight; bits256 MoM; cJSON *MoMjson,*infojson; int32_t prevMoMheight;
*MoMdepthp = 0; *MoMdepthp = 0;
memset(MoM.bytes,0,sizeof(MoM)); memset(MoM.bytes,0,sizeof(MoM));
if ( strcmp(coin->symbol,"GAME") == 0 ) // 80 byte OP_RETURN limit if ( strcmp(coin->symbol,"GAME") == 0 || strcmp(coin->symbol,"HUSH") == 0 || strcmp(coin->symbol,"EMC2") == 0 ) // 80 byte OP_RETURN limit
return(MoM); return(MoM);
if ( (infojson= dpow_getinfo(myinfo,coin)) != 0 ) if ( (infojson= dpow_getinfo(myinfo,coin)) != 0 )
{ {
@ -265,6 +265,7 @@ void dpow_statemachinestart(void *ptr)
void **ptrs = ptr; void **ptrs = ptr;
struct supernet_info *myinfo; struct dpow_info *dp; struct dpow_checkpoint checkpoint; struct supernet_info *myinfo; struct dpow_info *dp; struct dpow_checkpoint checkpoint;
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; 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;
char *destlockunspent=0,*srclockunspent=0,*destunlockunspent=0,*srcunlockunspent=0;
memset(&zero,0,sizeof(zero)); memset(&zero,0,sizeof(zero));
MoM = zero; MoM = zero;
srcprevtxid0 = destprevtxid0 = zero; srcprevtxid0 = destprevtxid0 = zero;
@ -302,6 +303,7 @@ void dpow_statemachinestart(void *ptr)
Numallocated++; Numallocated++;
bp->MoM = MoM; bp->MoM = MoM;
bp->MoMdepth = MoMdepth; bp->MoMdepth = MoMdepth;
bp->CCid = dp->fullCCid & 0xffff;
bp->minsigs = minsigs; bp->minsigs = minsigs;
bp->duration = duration; bp->duration = duration;
bp->srccoin = src; bp->srccoin = src;
@ -383,8 +385,13 @@ void dpow_statemachinestart(void *ptr)
return; return;
} }
dp->ratifying += bp->isratify; dp->ratifying += bp->isratify;
bitcoin_address(srcaddr,src->chain->pubtype,dp->minerkey33,33);
bitcoin_address(destaddr,dest->chain->pubtype,dp->minerkey33,33); if (strcmp(src->chain->symbol, "HUSH") == 0)
bitcoin_address_ex(src->chain->symbol, srcaddr, 0x1c, src->chain->pubtype, dp->minerkey33, 33);
else
bitcoin_address(srcaddr, src->chain->pubtype, dp->minerkey33, 33);
bitcoin_address(destaddr,dest->chain->pubtype,dp->minerkey33,33);
if ( kmdheight >= 0 ) if ( kmdheight >= 0 )
{ {
ht = kmdheight;///strcmp("KMD",src->symbol) == 0 ? kmdheight : bp->height; ht = kmdheight;///strcmp("KMD",src->symbol) == 0 ? kmdheight : bp->height;
@ -438,7 +445,7 @@ void dpow_statemachinestart(void *ptr)
return; return;
} }
bp->myind = myind; bp->myind = myind;
printf("[%d] notarize %s->%s %s ht.%d minsigs.%d duration.%d start.%u MoM[%d] %s\n",bp->myind,dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height,minsigs,duration,checkpoint.timestamp,bp->MoMdepth,bits256_str(str2,bp->MoM)); printf("[%d] notarize %s->%s %s ht.%d minsigs.%d duration.%d start.%u MoM[%d] %s CCid.%u\n",bp->myind,dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height,minsigs,duration,checkpoint.timestamp,bp->MoMdepth,bits256_str(str2,bp->MoM),bp->CCid);
if ( bp->isratify != 0 && memcmp(bp->notaries[0].pubkey,bp->ratified_pubkeys[0],33) != 0 ) if ( bp->isratify != 0 && memcmp(bp->notaries[0].pubkey,bp->ratified_pubkeys[0],33) != 0 )
{ {
for (i=0; i<33; i++) for (i=0; i<33; i++)
@ -487,6 +494,11 @@ void dpow_statemachinestart(void *ptr)
bp->notaries[myind].ratifydestutxo = ep->dest.prev_hash; bp->notaries[myind].ratifydestutxo = ep->dest.prev_hash;
bp->notaries[myind].ratifydestvout = ep->dest.prev_vout; bp->notaries[myind].ratifydestvout = ep->dest.prev_vout;
} }
else
{
bp->mysrcutxo = ep->src.prev_hash;
bp->mydestutxo = ep->dest.prev_hash;
}
} }
/*if ( strcmp(dp->symbol,"CHIPS") == 0 && myind == 0 ) /*if ( strcmp(dp->symbol,"CHIPS") == 0 && myind == 0 )
{ {
@ -495,6 +507,25 @@ void dpow_statemachinestart(void *ptr)
bp->desttxid = bp->notaries[myind].src.prev_hash; bp->desttxid = bp->notaries[myind].src.prev_hash;
dpow_signedtxgen(myinfo,dp,src,bp,bp->myind,1LL<<bp->myind,bp->myind,DPOW_SIGCHANNEL,0,0); dpow_signedtxgen(myinfo,dp,src,bp,bp->myind,1LL<<bp->myind,bp->myind,DPOW_SIGCHANNEL,0,0);
}*/ }*/
if ( (strcmp("KMD",dest->symbol) == 0 ) && (ep->dest.prev_vout != -1) )
{
// lock the dest utxo if destination coin is KMD.
if (dpow_lockunspent(myinfo,bp->destcoin,destaddr,bits256_str(str2,ep->dest.prev_hash),ep->dest.prev_vout) != 0)
printf(">>>> LOCKED %s UTXO.(%s) vout.(%d)\n",dest->symbol,bits256_str(str2,ep->dest.prev_hash),ep->dest.prev_vout);
else
printf("<<<< FAILED TO LOCK %s UTXO.(%s) vout.(%d)\n",dest->symbol,bits256_str(str2,ep->dest.prev_hash),ep->dest.prev_vout);
}
if ( ( strcmp("KMD",src->symbol) == 0 ) && (ep->src.prev_vout != -1) )
{
// lock the src coin selected utxo if the source coin is KMD.
if (dpow_lockunspent(myinfo,bp->srccoin,srcaddr,bits256_str(str2,ep->src.prev_hash),ep->src.prev_vout) != 0)
printf(">>>> LOCKED %s UTXO.(%s) vout.(%d\n",src->symbol,bits256_str(str2,ep->src.prev_hash),ep->src.prev_vout);
else
printf("<<<< FAILED TO LOCK %s UTXO.(%s) vout.(%d)\n",src->symbol,bits256_str(str2,ep->src.prev_hash),ep->src.prev_vout);
}
bp->recvmask |= (1LL << myind); bp->recvmask |= (1LL << myind);
bp->notaries[myind].othermask |= (1LL << myind); bp->notaries[myind].othermask |= (1LL << myind);
dp->checkpoint = checkpoint; dp->checkpoint = checkpoint;
@ -520,7 +551,7 @@ void dpow_statemachinestart(void *ptr)
if ( strcmp(bp->destcoin->symbol,"KMD") == 0 ) if ( strcmp(bp->destcoin->symbol,"KMD") == 0 )
src_or_dest = 0; src_or_dest = 0;
else src_or_dest = 1; else src_or_dest = 1;
extralen = dpow_paxpending(extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp); extralen = dpow_paxpending(myinfo,extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp);
bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc; bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc;
} }
printf("PAXWDCRC.%x myind.%d isratify.%d DPOW.%s statemachine checkpoint.%d %s start.%u+dur.%d vs %ld MoM[%d] %s\n",bp->paxwdcrc,bp->myind,bp->isratify,src->symbol,checkpoint.blockhash.height,bits256_str(str,checkpoint.blockhash.hash),starttime,bp->duration,time(NULL),bp->MoMdepth,bits256_str(str2,bp->MoM)); printf("PAXWDCRC.%x myind.%d isratify.%d DPOW.%s statemachine checkpoint.%d %s start.%u+dur.%d vs %ld MoM[%d] %s\n",bp->paxwdcrc,bp->myind,bp->isratify,src->symbol,checkpoint.blockhash.height,bits256_str(str,checkpoint.blockhash.hash),starttime,bp->duration,time(NULL),bp->MoMdepth,bits256_str(str2,bp->MoM));
@ -541,7 +572,7 @@ void dpow_statemachinestart(void *ptr)
if ( strcmp(bp->destcoin->symbol,"KMD") == 0 ) if ( strcmp(bp->destcoin->symbol,"KMD") == 0 )
src_or_dest = 0; src_or_dest = 0;
else src_or_dest = 1; else src_or_dest = 1;
extralen = dpow_paxpending(extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp); extralen = dpow_paxpending(myinfo,extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp);
bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc; bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc;
} }
if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) //(checkpoint.blockhash.height % 100) != 0 && if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) //(checkpoint.blockhash.height % 100) != 0 &&
@ -588,8 +619,22 @@ void dpow_statemachinestart(void *ptr)
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); 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->lastrecvmask = bp->recvmask;
dp->ratifying -= bp->isratify; dp->ratifying -= bp->isratify;
// unlock the dest utxo on KMD.
if ( (strcmp("KMD",dest->symbol) == 0 ) && (ep->dest.prev_vout != -1) )
{
if ( dpow_unlockunspent(myinfo,bp->destcoin,destaddr,bits256_str(str2,ep->dest.prev_hash),ep->dest.prev_vout) != 0 )
printf(">>>> UNLOCKED %s UTXO.(%s) vout.(%d)\n",dest->symbol,bits256_str(str2,ep->dest.prev_hash),ep->dest.prev_vout);
}
// unlock the src selected utxo on KMD.
if ( ( strcmp("KMD",src->symbol) == 0 ) && (ep->src.prev_vout != -1) )
{
if ( dpow_unlockunspent(myinfo,bp->srccoin,srcaddr,bits256_str(str2,ep->src.prev_hash),ep->src.prev_vout) != 0)
printf(">>>> UNLOCKED %s UTXO.(%s) vout.(%d)\n",src->symbol,bits256_str(str2,ep->src.prev_hash),ep->src.prev_vout);
}
// dp->blocks[bp->height] = 0; // dp->blocks[bp->height] = 0;
bp->state = 0xffffffff; bp->state = 0xffffffff;
free(ptr); free(ptr);
} }

219
iguana/dpow/dpow_network.c

@ -481,7 +481,7 @@ char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32
for (i=0; i<n; i++) for (i=0; i<n; i++)
if ( ipbits == myinfo->dexipbits[i] ) if ( ipbits == myinfo->dexipbits[i] )
break; break;
if ( i == n && n < 64 ) if ( i == n && n < DPOW_MAXIPBITS )
{ {
myinfo->dexipbits[n++] = ipbits; myinfo->dexipbits[n++] = ipbits;
qsort(myinfo->dexipbits,n,sizeof(uint32_t),_increasing_ipbits); qsort(myinfo->dexipbits,n,sizeof(uint32_t),_increasing_ipbits);
@ -1292,7 +1292,7 @@ struct dpow_nanomsghdr
{ {
bits256 srchash,desthash; bits256 srchash,desthash;
struct dpow_nanoutxo ratify,notarize; struct dpow_nanoutxo ratify,notarize;
uint32_t channel,height,size,datalen,crc32,myipbits,numipbits,ipbits[128]; uint32_t channel,height,size,datalen,crc32,myipbits,numipbits,ipbits[DPOW_MAXIPBITS];
char symbol[16]; char symbol[16];
uint8_t senderind,version0,version1,packet[]; uint8_t senderind,version0,version1,packet[];
} PACKED; } PACKED;
@ -1303,11 +1303,110 @@ struct dpow_block *dpow_heightfind(struct supernet_info *myinfo,struct dpow_info
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); 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);
void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,int32_t myind,int32_t src_or_dest,int8_t bestk,uint64_t bestmask,uint8_t pubkeys[64][33],int32_t numratified); void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,int32_t myind,int32_t src_or_dest,int8_t bestk,uint64_t bestmask,uint8_t pubkeys[64][33],int32_t numratified);
#ifdef CHECKNODEIP
int checknode(char *hostname, int portno, int timeout_rw)
{
#if defined(_linux) || defined(__linux__)
unsigned char iguana_reply[8]; // buffer for iguana reply
int sockfd;
struct sockaddr_in serv_addr;
struct hostent *server;
unsigned char reply_dat[] = { 0x00, 0x53, 0x50, 0x00, 0x00, 0x70, 0x00, 0x00 };
unsigned int reply_dat_len = 8;
struct timeval timeout;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) return(-1); // error opening socket
server = gethostbyname(hostname);
if (server == NULL) { close(sockfd); return(-2); } // no such host
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
timeout.tv_sec = timeout_rw;
timeout.tv_usec = 0;
if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
sizeof(timeout)) < 0)
{ close(sockfd); return(-3); } // set rcv timeout filed
if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,
sizeof(timeout)) < 0)
{ close(sockfd); return(-4); } // set send timeout filed
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
{ close(sockfd); return(-5); } // port is closed
int recv_count;
if( ( recv_count = recv(sockfd, iguana_reply , sizeof(iguana_reply) , 0)) < 0)
{ close(sockfd); return(-6); } // recv is failed
if ( recv_count != reply_dat_len ) { close(sockfd); return(-7); }// wrong reply size
if (memcmp(iguana_reply, reply_dat, reply_dat_len) != 0) { close(sockfd); return(-8); } // wrong / unknown reply, possible it's not iguana on remote
close(sockfd);
#endif // __linux__
return 0;
}
#endif
int32_t dpow_addnotary(struct supernet_info *myinfo,struct dpow_info *dp,char *ipaddr) int32_t dpow_addnotary(struct supernet_info *myinfo,struct dpow_info *dp,char *ipaddr)
{ {
char str[512]; uint32_t ipbits,*ptr; int32_t i,iter,n,retval = -1; char str[512]; uint32_t ipbits,*ptr; int32_t i,iter,n,retval = -1;
#ifdef CHECKNODEIP
// -B- [+] Decker ---
static uint32_t list_ipbits[DPOW_MAXIPBITS];
static int dead_or_alive[DPOW_MAXIPBITS]; // 0 - not set, -1 - dead, 1 - alive
static int list_ipsize;
int in_list_flag;
uint32_t ip_pattern;
// -E- [+] Decker ---
#endif
if ( myinfo->IAMNOTARY == 0 ) if ( myinfo->IAMNOTARY == 0 )
return(-1); return(-1);
//if ( strcmp(ipaddr,"88.99.251.101") == 0 || strcmp(ipaddr,"82.202.193.100") == 0 )
// return(-1);
#ifdef CHECKNODEIP
// -B- [+] Decker ---
// every new ip in BUS topology network goes to dead or white list forever, until iguana restart
ip_pattern = (uint32_t)calc_ipbits(ipaddr);
if ((list_ipsize == 0) || (list_ipsize > DPOW_MAXIPBITS-1)) {
for (int i_list = 0; i_list < DPOW_MAXIPBITS; i_list++) { list_ipbits[i_list] = 0; dead_or_alive[i_list] = 0; }
list_ipsize = 0;
in_list_flag = -1;
} else {
in_list_flag = -1;
for (int i_list = 0; i_list < list_ipsize; i_list++) if (list_ipbits[i_list] == ip_pattern) { in_list_flag = i_list; break; }
}
if (in_list_flag == -1) {
list_ipbits[list_ipsize] = ip_pattern;
if (checknode(ipaddr, Notaries_port, 5) != 0) {
dead_or_alive[list_ipsize] = -1;
list_ipsize++;
printf("[Decker] Node " "\033[31m" "%s:%d" "\033[0m" " is dead!\n", ipaddr, Notaries_port);
return -1;
} else {
dead_or_alive[list_ipsize] = 1;
list_ipsize++;
}
} else
if (dead_or_alive[in_list_flag] == -1) return -1;
// -E- [+] Decker ---
#endif
portable_mutex_lock(&myinfo->notarymutex); portable_mutex_lock(&myinfo->notarymutex);
if ( myinfo->dpowsock >= 0 )//&& myinfo->dexsock >= 0 ) if ( myinfo->dpowsock >= 0 )//&& myinfo->dexsock >= 0 )
{ {
@ -1327,7 +1426,7 @@ int32_t dpow_addnotary(struct supernet_info *myinfo,struct dpow_info *dp,char *i
for (i=0; i<n; i++) for (i=0; i<n; i++)
if ( ipbits == ptr[i] ) if ( ipbits == ptr[i] )
break; break;
if ( i == n && n < 64 ) if ( i == n && n < DPOW_MAXIPBITS )
{ {
ptr[n] = ipbits; ptr[n] = ipbits;
if ( iter == 0 && strcmp(ipaddr,myinfo->ipaddr) != 0 ) if ( iter == 0 && strcmp(ipaddr,myinfo->ipaddr) != 0 )
@ -1462,9 +1561,33 @@ void dpow_nanomsginit(struct supernet_info *myinfo,char *ipaddr)
dpow_addnotary(myinfo,0,ipaddr); dpow_addnotary(myinfo,0,ipaddr);
} }
int32_t dpow_crossconnected(uint64_t *badmaskp,struct dpow_block *bp,uint64_t bestmask)
{
int32_t i,j,n,num = 0; uint64_t mask;
*badmaskp = 0;
for (i=0; i<bp->numnotaries; i++)
{
mask = ((1LL << i) & bestmask);
if ( mask != 0 )
{
for (n=j=0; j<bp->numnotaries; j++)
{
if ( ((1LL << j) & bestmask) != 0 && (mask & bp->notaries[j].recvmask) != 0 )
n++;
}
//printf("%d ",n);
if ( n == bp->minsigs )
num++;
else *badmaskp |= mask;
}
}
//printf("-> num.%d for bestmask.%llx\n",num,(long long)bestmask);
return(num);
}
void dpow_bestconsensus(struct dpow_info *dp,struct dpow_block *bp) void dpow_bestconsensus(struct dpow_info *dp,struct dpow_block *bp)
{ {
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]; 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],badmask,matchesmask,recvmask,topmask; uint32_t crcval=0; char srcaddr[64],destaddr[64];
memset(wts,0,sizeof(wts)); memset(wts,0,sizeof(wts));
memset(owts,0,sizeof(owts)); memset(owts,0,sizeof(owts));
for (i=0; i<bp->numnotaries; i++) for (i=0; i<bp->numnotaries; i++)
@ -1519,8 +1642,11 @@ void dpow_bestconsensus(struct dpow_info *dp,struct dpow_block *bp)
//printf("(%d %llx).%d ",bestks[i],(long long)masks[i],counts[i]); //printf("(%d %llx).%d ",bestks[i],(long long)masks[i],counts[i]);
if ( counts[i] > matches && bitweight(masks[i]) == bp->minsigs ) if ( counts[i] > matches && bitweight(masks[i]) == bp->minsigs )
{ {
matches = counts[i]; if ( dpow_crossconnected(&badmask,bp,masks[i]) == bp->minsigs )
besti = i; {
matches = counts[i];
besti = i;
}
} }
} }
for (i=0; i<bp->numnotaries; i++) for (i=0; i<bp->numnotaries; i++)
@ -1537,7 +1663,9 @@ void dpow_bestconsensus(struct dpow_info *dp,struct dpow_block *bp)
bp->bestmatches = bestmatches; bp->bestmatches = bestmatches;
bp->notaries[bp->myind].bestmask = bp->bestmask = masks[besti]; bp->notaries[bp->myind].bestmask = bp->bestmask = masks[besti];
bp->notaries[bp->myind].bestk = bp->bestk = bestks[besti]; bp->notaries[bp->myind].bestk = bp->bestk = bestks[besti];
if ( 0 && bp->myind == 0 && strcmp("CHIPS",dp->symbol) == 0 ) if ( bp->myind == 0 )
printf("matches.%d bestmatches.%d recv.%llx (%d %llx)\n",matches,bestmatches,(long long)bp->recvmask,bp->bestk,(long long)bp->bestmask);
if ( 1 && bp->myind == 0 && strcmp("KMD",dp->symbol) == 0 )
{ {
for (i=0; i<bp->numnotaries; i++) for (i=0; i<bp->numnotaries; i++)
printf("%d:%d%s ",wts[i],owts[i],wts[i]*owts[i]>median?"*":""); printf("%d:%d%s ",wts[i],owts[i],wts[i]*owts[i]>median?"*":"");
@ -1838,16 +1966,24 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru
return; return;
if ( bp->isratify == 0 && bp->state != 0xffffffff && senderind >= 0 && senderind < bp->numnotaries && bits256_nonz(srcutxo) != 0 && bits256_nonz(destutxo) != 0 ) if ( bp->isratify == 0 && bp->state != 0xffffffff && senderind >= 0 && senderind < bp->numnotaries && bits256_nonz(srcutxo) != 0 && bits256_nonz(destutxo) != 0 )
{ {
if ( bits256_nonz(srcutxo) != 0 ) if ( bp->myind != senderind )
{ {
bp->notaries[senderind].src.prev_hash = srcutxo; if ( bits256_nonz(srcutxo) != 0 )
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); bp->notaries[senderind].src.prev_hash = srcutxo;
bp->notaries[senderind].src.prev_vout = srcvout;
//char str[65]; printf("%s senderind.%d <- %s/v%d\n",dp->symbol,senderind,bits256_str(str,srcutxo),srcvout);
}
if ( bits256_nonz(destutxo) != 0 )
{
bp->notaries[senderind].dest.prev_hash = destutxo;
bp->notaries[senderind].dest.prev_vout = destvout;
}
} }
if ( bits256_nonz(destutxo) != 0 ) else
{ {
bp->notaries[senderind].dest.prev_hash = destutxo; bp->notaries[bp->myind].src.prev_hash = bp->mysrcutxo;
bp->notaries[senderind].dest.prev_vout = destvout; bp->notaries[bp->myind].dest.prev_hash = bp->mydestutxo;
} }
if ( bestmask != 0 ) if ( bestmask != 0 )
bp->notaries[senderind].bestmask = bestmask; bp->notaries[senderind].bestmask = bestmask;
@ -1857,24 +1993,6 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru
{ {
//fprintf(stderr,"{%d %x} ",senderind,paxwdcrc); //fprintf(stderr,"{%d %x} ",senderind,paxwdcrc);
} }
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]);
if ( bestk == bp->bestk && bestmask == bp->bestmask )
bp->srcsigsmasks[bestk] |= (1LL << senderind);
else bp->srcsigsmasks[bestk] &= ~(1LL << senderind);
}
if ( (bp->notaries[senderind].dest.siglens[bestk]= siglens[1]) != 0 )
{
memcpy(bp->notaries[senderind].dest.sigs[bestk],sigs[1],siglens[1]);
if ( bestk == bp->bestk && bestmask == bp->bestmask )
bp->destsigsmasks[bestk] |= (1LL << senderind);
else bp->destsigsmasks[bestk] &= ~(1LL << senderind);
}
}
bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc; bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc;
if ( bp->bestmask == 0 ) if ( bp->bestmask == 0 )
{ {
@ -1888,6 +2006,27 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru
bp->notaries[bp->myind].bestmask = bp->bestmask; bp->notaries[bp->myind].bestmask = bp->bestmask;
if ( bp->recvmask != 0 ) if ( bp->recvmask != 0 )
bp->notaries[bp->myind].recvmask = bp->recvmask; bp->notaries[bp->myind].recvmask = bp->recvmask;
if ( bestk >= 0 || bp->notaries[senderind].bestk < 0 )
{
bp->notaries[senderind].bestk = bestk;
if ( bp->pendingbestk == bestk && bp->pendingbestmask == bp->bestmask )
{
if ( bp->notaries[senderind].src.siglens[bestk] == 0 && (bp->notaries[senderind].src.siglens[bestk]= siglens[0]) != 0 )
{
memcpy(bp->notaries[senderind].src.sigs[bestk],sigs[0],siglens[0]);
if ( bestk == bp->bestk && bestmask == bp->bestmask )
bp->srcsigsmasks[bestk] |= (1LL << senderind);
else bp->srcsigsmasks[bestk] &= ~(1LL << senderind);
}
if ( bp->notaries[senderind].dest.siglens[bestk] == 0 && (bp->notaries[senderind].dest.siglens[bestk]= siglens[1]) != 0 )
{
memcpy(bp->notaries[senderind].dest.sigs[bestk],sigs[1],siglens[1]);
if ( bestk == bp->bestk && bestmask == bp->bestmask )
bp->destsigsmasks[bestk] |= (1LL << senderind);
else bp->destsigsmasks[bestk] &= ~(1LL << senderind);
}
}
}
if ( bp->bestk >= 0 ) if ( bp->bestk >= 0 )
{ {
flag = -1; flag = -1;
@ -1924,8 +2063,8 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru
dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,0,bp->height,(void *)"ping",0); dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,0,bp->height,(void *)"ping",0);
bp->lastnanosend = now; bp->lastnanosend = now;
} }
if ( 0 && strcmp("CHIPS",dp->symbol) == 0 && bp->myind == 0 ) if ( 1 && strcmp("KMD",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); printf("%s recv.%llx best.(%d %llx) m.%d p.%d:%d b.%d state.%d minsigs.%d pend.%d\n",dp->symbol,(long long)bp->recvmask,bp->bestk,(long long)bp->bestmask,matches,paxmatches,paxbestmatches,bestmatches,bp->state,bp->minsigs,bp->pendingbestk);
if ( bestmatches == bp->minsigs && paxbestmatches == bp->minsigs && bp->bestk >= 0 && bp->bestmask != 0 ) if ( bestmatches == bp->minsigs && paxbestmatches == bp->minsigs && bp->bestk >= 0 && bp->bestmask != 0 )
{ {
if ( bp->pendingbestk < 0 )//bp->pendingbestk != bp->bestk || bp->pendingbestmask != bp->bestmask ) if ( bp->pendingbestk < 0 )//bp->pendingbestk != bp->bestk || bp->pendingbestmask != bp->bestmask )
@ -1949,8 +2088,8 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru
{ {
if ( bp->state != 0xffffffff ) if ( bp->state != 0xffffffff )
dpow_sigscheck(myinfo,dp,bp,bp->myind,0,bp->pendingbestk,bp->pendingbestmask,0,0); 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 || strcmp(dp->symbol,"EMC2") == 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 ) } //else if ( strcmp(dp->symbol,"CHIPS") == 0 || strcmp(dp->symbol,"GAME") == 0 || strcmp(dp->symbol,"EMC2") == 0 )
//printf("destmask.%llx != bestmask.%llx\n",(long long)bp->destsigsmasks[bp->bestk],(long long)bp->bestmask); //printf("destmask.%llx != bestmask.%llx\n",(long long)bp->destsigsmasks[bp->bestk],(long long)bp->bestmask);
} }
} }
@ -1967,7 +2106,7 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru
printf("mypaxcrc.%x\n",bp->paxwdcrc); printf("mypaxcrc.%x\n",bp->paxwdcrc);
} }
char str[65]; char str[65];
if ( (rand() % 1024) == 0 || (bp->myind == 0 && (rand() % 50) == 0 && (strcmp(dp->symbol,"CHIPS") == 0 || strcmp(dp->symbol,"GAME") == 0)) ) if ( (rand() % 130) == 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); 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);
} }
} }
@ -1999,7 +2138,7 @@ void dpow_nanoutxoget(struct supernet_info *myinfo,struct dpow_info *dp,struct d
} }
} }
} }
if ( 0 && bp->myind == 0 && dispflag != 0 ) if ( 1 && 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]); 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]);
} }
@ -2039,7 +2178,7 @@ void dpow_send(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_blo
if ( strcmp(bp->destcoin->symbol,"KMD") == 0 ) if ( strcmp(bp->destcoin->symbol,"KMD") == 0 )
src_or_dest = 0; src_or_dest = 0;
else src_or_dest = 1; else src_or_dest = 1;
extralen = dpow_paxpending(extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp); extralen = dpow_paxpending(myinfo,extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp);
bp->paxwdcrc = bp->notaries[bp->myind].paxwdcrc = np->notarize.paxwdcrc = paxwdcrc; bp->paxwdcrc = bp->notaries[bp->myind].paxwdcrc = np->notarize.paxwdcrc = paxwdcrc;
//dpow_bestconsensus(dp,bp); //dpow_bestconsensus(dp,bp);
dpow_nanoutxoset(myinfo,dp,&np->notarize,bp,0); dpow_nanoutxoset(myinfo,dp,&np->notarize,bp,0);
@ -2083,7 +2222,7 @@ void dpow_send(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_blo
printf("maxiters expired for signed_nn_send dpowsock.%d\n",myinfo->dpowsock); printf("maxiters expired for signed_nn_send dpowsock.%d\n",myinfo->dpowsock);
//portable_mutex_unlock(&myinfo->dpowmutex); //portable_mutex_unlock(&myinfo->dpowmutex);
free(np); free(np);
if ( 0 && bp->myind == 0 ) if ( 1 && 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); 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);
} }

91
iguana/dpow/dpow_rpc.c

@ -17,7 +17,7 @@
uint64_t dpow_utxosize(char *symbol) uint64_t dpow_utxosize(char *symbol)
{ {
if ( strcmp(symbol,"GAME") == 0 ) if ( strcmp(symbol,"GAME") == 0 || strcmp(symbol,"EMC2") == 0)
return(100000); return(100000);
else return(10000); else return(10000);
} }
@ -78,6 +78,17 @@ cJSON *dpow_getinfo(struct supernet_info *myinfo,struct iguana_info *coin)
return(json); return(json);
} }
uint32_t dpow_CCid(struct supernet_info *myinfo,struct iguana_info *coin)
{
uint32_t CCid = 0; cJSON *retjson;
if ( (retjson= dpow_getinfo(myinfo,coin)) != 0 )
{
CCid = juint(retjson,"CCid");
free_json(retjson);
}
return(CCid);
}
char *Notaries_elected[65][2]; char *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" }; //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_numseeds;// = (int32_t)(sizeof(seeds)/sizeof(*seeds))
@ -99,8 +110,7 @@ int32_t komodo_initjson(char *fname)
Notaries_port = port; Notaries_port = port;
if ( (num= juint(argjson,"BTCminsigs")) > Notaries_BTCminsigs ) if ( (num= juint(argjson,"BTCminsigs")) > Notaries_BTCminsigs )
Notaries_BTCminsigs = num; Notaries_BTCminsigs = num;
if ( (num= juint(argjson,"minsigs")) > Notaries_minsigs ) Notaries_minsigs = juint(argjson,"minsigs");
Notaries_minsigs = num;
if ( (array= jarray(&n,argjson,"seeds")) != 0 && n <= 64 ) if ( (array= jarray(&n,argjson,"seeds")) != 0 && n <= 64 )
{ {
for (i=0; i<n&&i<64; i++) for (i=0; i<n&&i<64; i++)
@ -226,7 +236,7 @@ bits256 dpow_getbestblockhash(struct supernet_info *myinfo,struct iguana_info *c
} }
else else
{ {
} }
if ( bits256_nonz(blockhash) != 0 ) if ( bits256_nonz(blockhash) != 0 )
{ {
@ -252,16 +262,16 @@ cJSON *issue_calcMoM(struct iguana_info *coin,int32_t height,int32_t MoMdepth)
return(retjson); return(retjson);
} }
cJSON *dpow_MoMoMdata(struct iguana_info *coin,char *symbol,int32_t kmdheight) cJSON *dpow_MoMoMdata(struct iguana_info *coin,char *symbol,int32_t kmdheight,uint16_t CCid)
{ {
char buf[128],*retstr=0; cJSON *retjson = 0; struct iguana_info *src; 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 ) if ( coin->FULLNODE < 0 && strcmp(coin->symbol,"KMD") == 0 && (src= iguana_coinfind(symbol)) != 0 )
{ {
sprintf(buf,"[\"%s\", \"%d\", \"%d\"]",symbol,kmdheight,src->MoMoMheight); sprintf(buf,"[\"%s\", \"%d\", \"%d\"]",symbol,kmdheight,CCid);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"MoMoMdata",buf)) != 0 ) if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"MoMoMdata",buf)) != 0 )
{ {
retjson = cJSON_Parse(retstr); retjson = cJSON_Parse(retstr);
printf("MoMoM.%s -> %s\n",buf,retstr); printf("%s kmdheight.%d CCid.%u MoMoM.%s -> %s\n",symbol,kmdheight,CCid,buf,retstr);
free(retstr); free(retstr);
} }
usleep(10000); usleep(10000);
@ -269,22 +279,29 @@ cJSON *dpow_MoMoMdata(struct iguana_info *coin,char *symbol,int32_t kmdheight)
return(retjson); return(retjson);
} }
int32_t dpow_paxpending(uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,int32_t src_or_dest,struct dpow_block *bp) int32_t dpow_paxpending(struct supernet_info *myinfo,uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,uint16_t CCid,int32_t src_or_dest,struct dpow_block *bp)
{ {
struct iguana_info *coin,*kmdcoin=0; char *retstr,*hexstr; cJSON *retjson; int32_t hexlen=0,n=0; uint32_t paxwdcrc; struct iguana_info *coin,*kmdcoin=0; char *retstr,*hexstr; cJSON *retjson,*infojson; int32_t kmdheight=0,hexlen=0,n=0; uint32_t paxwdcrc;
paxwdcrc = 0; paxwdcrc = 0;
if ( strcmp(bp->srccoin->symbol,"GAME") != 0 || src_or_dest != 0 ) if ( strcmp(bp->srccoin->symbol,"GAME") != 0 || strcmp(bp->srccoin->symbol,"EMC2") != 0 || src_or_dest != 0 )
{ {
n += iguana_rwbignum(1,&hex[n],sizeof(MoM),MoM.bytes); n += iguana_rwbignum(1,&hex[n],sizeof(MoM),MoM.bytes);
MoMdepth = (MoMdepth & 0xffff) | ((uint32_t)CCid<<16);
n += iguana_rwnum(1,&hex[n],sizeof(MoMdepth),(uint32_t *)&MoMdepth); 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 ) if ( strncmp(bp->srccoin->symbol,"TXSCL",5) == 0 && src_or_dest == 0 && strcmp(bp->destcoin->symbol,"KMD") == 0 )
{ {
kmdcoin = bp->destcoin; 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 ( (infojson= dpow_getinfo(myinfo,kmdcoin)) != 0 )
{
kmdheight = jint(infojson,"blocks");
free_json(infojson);
}
if ( (retjson= dpow_MoMoMdata(kmdcoin,bp->srccoin->symbol,kmdheight,bp->CCid)) != 0 )
{ {
if ( (hexstr= jstr(retjson,"data")) != 0 && (hexlen= (int32_t)strlen(hexstr)) > 0 && n+hexlen/2 <= hexsize ) if ( (hexstr= jstr(retjson,"data")) != 0 && (hexlen= (int32_t)strlen(hexstr)) > 0 && n+hexlen/2 <= hexsize )
{ {
hexlen >>= 1; hexlen >>= 1;
printf("add MoMoMdata.(%s)\n",hexstr);
decode_hex(&hex[n],hexlen,hexstr), n += hexlen; decode_hex(&hex[n],hexlen,hexstr), n += hexlen;
} }
free_json(retjson); free_json(retjson);
@ -353,6 +370,39 @@ bits256 dpow_getblockhash(struct supernet_info *myinfo,struct iguana_info *coin,
return(blockhash); return(blockhash);
} }
int dpow_lockunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,char *txid,int32_t vout)
{
char buf[128],*retstr;
if ( coin->FULLNODE < 0 )
{
sprintf(buf,"false, [{\"txid\":\"%s\",\"vout\":%d}]", txid, vout);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"lockunspent",buf)) != 0 )
{
//printf("RESULT.(%s)\n",retstr);
free(retstr);
return(1);
} // else printf("%s null retstr from (%s)n",coin->symbol,buf);
}
return(0);
}
int dpow_unlockunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,char *txid,int32_t vout)
{
char buf[128],*retstr;
if ( coin->FULLNODE < 0 )
{
sprintf(buf,"true, [{\"txid\":\"%s\",\"vout\":%d}]", txid, vout);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"lockunspent",buf)) != 0 )
{
//printf("RESULT.(%s)\n",retstr);
free(retstr);
return(1);
} //else printf("%s null retstr from (%s)n",coin->symbol,buf);
}
return(0);
}
cJSON *dpow_getblock(struct supernet_info *myinfo,struct iguana_info *coin,bits256 blockhash) cJSON *dpow_getblock(struct supernet_info *myinfo,struct iguana_info *coin,bits256 blockhash)
{ {
char buf[128],str[65],*retstr=0; cJSON *json = 0; char buf[128],str[65],*retstr=0; cJSON *json = 0;
@ -380,6 +430,13 @@ cJSON *dpow_getblock(struct supernet_info *myinfo,struct iguana_info *coin,bits2
return(json); return(json);
} }
int32_t dpow_is015(char *symbol)
{
if ( strcmp("CHIPS",symbol) == 0 || strcmp("GAME",symbol) == 0 || strcmp("EMC2",symbol) == 0 ) //strcmp("BTC",symbol) == 0 ||
return(1);
else return(0);
}
char *dpow_validateaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address) char *dpow_validateaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address)
{ {
char buf[128],*retstr=0; cJSON *retjson; char buf[128],*retstr=0; cJSON *retjson;
@ -391,7 +448,7 @@ char *dpow_validateaddress(struct supernet_info *myinfo,struct iguana_info *coin
//printf("%s -> (%s)\n",buf,retstr!=0?retstr:"null"); //printf("%s -> (%s)\n",buf,retstr!=0?retstr:"null");
if ( (retjson= cJSON_Parse(retstr)) != 0 ) 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 ) if ( dpow_is015(coin->symbol) != 0 && jobj(retjson,"error") == 0 && jobj(retjson,"ismine") == 0 && strcmp(coin->validateaddress,"validateaddress") == 0 )
{ {
printf("autochange %s validateaddress -> getaddressinfo\n",coin->symbol); printf("autochange %s validateaddress -> getaddressinfo\n",coin->symbol);
strcpy(coin->validateaddress,"getaddressinfo"); strcpy(coin->validateaddress,"getaddressinfo");
@ -581,7 +638,7 @@ char *dpow_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *c
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,coin->signtxstr,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 ( strcmp(coin->signtxstr,"signrawtransaction") == 0 && (retjson= cJSON_Parse(retstr)) != 0 )
{ {
if ( jobj(retjson,"error") != 0 ) if ( jobj(retjson,"error") != 0 && dpow_is015(coin->symbol) != 0 )
{ {
strcpy(coin->signtxstr,"signrawtransactionwithwallet"); strcpy(coin->signtxstr,"signrawtransactionwithwallet");
free(retstr); free(retstr);
@ -590,6 +647,9 @@ char *dpow_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *c
free_json(retjson); free_json(retjson);
} }
//printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr); //printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr);
/*if (coin->sapling != 0)
printf("[Decker] %s dpow_signrawtransaction.(%s) params.(%s)\n", coin->symbol, retstr, paramstr);*/
free(paramstr); free(paramstr);
usleep(10000); usleep(10000);
return(retstr); return(retstr);
@ -1230,7 +1290,7 @@ void dpow_issuer_voutupdate(struct dpow_info *dp,char *symbol,int32_t isspecial,
printf(" opret[%c] fiatoshis %.8f vs check %.8f\n",script[0],dstr(fiatoshis),dstr(checktoshis)); printf(" opret[%c] fiatoshis %.8f vs check %.8f\n",script[0],dstr(fiatoshis),dstr(checktoshis));
if ( seed == 0 || fiatoshis < checktoshis ) if ( seed == 0 || fiatoshis < checktoshis )
{ {
}*/ }*/
} }
} }
@ -1400,4 +1460,3 @@ int32_t dpow_issuer_iteration(struct dpow_info *dp,struct iguana_info *coin,int3
//printf("[%s -> %s] %s ht.%d current.%d\n",dp->symbol,dp->dest,coin->symbol,height,currentheight); //printf("[%s -> %s] %s ht.%d current.%d\n",dp->symbol,dp->dest,coin->symbol,height,currentheight);
return(height); return(height);
} }

101
iguana/dpow/dpow_tx.c

@ -101,7 +101,7 @@ 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) uint64_t dpow_notarybestk(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp)
{ {
int32_t m,j,k; int8_t bestk = -1; uint64_t bestmask,mask = 0;//bp->require0; int32_t m,j,k,z,n; int8_t bestk = -1; uint64_t bestmask,mask = 0;//bp->require0;
bestmask = 0; bestmask = 0;
for (m=j=0; j<bp->numnotaries; j++) for (m=j=0; j<bp->numnotaries; j++)
{ {
@ -111,12 +111,18 @@ uint64_t dpow_notarybestk(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp)
// continue; // continue;
if ( bits256_nonz(bp->notaries[k].src.prev_hash) != 0 && bits256_nonz(bp->notaries[k].dest.prev_hash) != 0 && bp->paxwdcrc == bp->notaries[k].paxwdcrc ) if ( bits256_nonz(bp->notaries[k].src.prev_hash) != 0 && bits256_nonz(bp->notaries[k].dest.prev_hash) != 0 && bp->paxwdcrc == bp->notaries[k].paxwdcrc )
{ {
mask |= (1LL << k); for (z=n=0; z<bp->numnotaries; z++)
if ( ++m == bp->minsigs )//-bp->require0 ) if ( (bp->notaries[z].recvmask & (1LL << k)) != 0 )
n++;
if ( n >= bp->numnotaries/2 )
{ {
bestk = k; mask |= (1LL << k);
bestmask = mask;// | bp->require0; if ( ++m == bp->minsigs )//-bp->require0 )
//printf("m.%d == minsigs.%d (%d %llx)\n",m,bp->minsigs,k,(long long)bestmask); {
bestk = k;
bestmask = mask;// | bp->require0;
//printf("m.%d == minsigs.%d (%d %llx)\n",m,bp->minsigs,k,(long long)bestmask);
}
} }
} }
} }
@ -193,7 +199,7 @@ struct dpow_block *dpow_heightfind(struct supernet_info *myinfo,struct dpow_info
return(bp); return(bp);
} }
int32_t dpow_voutstandard(struct dpow_block *bp,uint8_t *serialized,int32_t m,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified) int32_t dpow_voutstandard(struct supernet_info *myinfo,struct dpow_block *bp,uint8_t *serialized,int32_t m,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified)
{ {
uint32_t paxwdcrc=0,locktime=0,numvouts; struct iguana_info *coin; uint64_t satoshis,satoshisB; int32_t i,n=0,opretlen,len=0; uint8_t opret[16384],data[16384],extras[16384]; uint32_t paxwdcrc=0,locktime=0,numvouts; struct iguana_info *coin; uint64_t satoshis,satoshisB; int32_t i,n=0,opretlen,len=0; uint8_t opret[16384],data[16384],extras[16384];
numvouts = 2; numvouts = 2;
@ -232,7 +238,7 @@ int32_t dpow_voutstandard(struct dpow_block *bp,uint8_t *serialized,int32_t m,in
} }
if ( bp->MoMdepth > 0 && strcmp(bp->destcoin->symbol,"KMD") == 0 ) // || strcmp(bp->srccoin->symbol,"KMD") == 0) ) if ( bp->MoMdepth > 0 && strcmp(bp->destcoin->symbol,"KMD") == 0 ) // || strcmp(bp->srccoin->symbol,"KMD") == 0) )
{ {
n = dpow_paxpending(extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp); n = dpow_paxpending(myinfo,extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp);
} }
satoshis = 0; satoshis = 0;
len += iguana_rwnum(1,&serialized[len],sizeof(satoshis),&satoshis); len += iguana_rwnum(1,&serialized[len],sizeof(satoshis),&satoshis);
@ -258,46 +264,67 @@ int32_t dpow_voutstandard(struct dpow_block *bp,uint8_t *serialized,int32_t m,in
return(len); return(len);
} }
bits256 dpow_notarytx(char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t usesigs,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified) bits256 dpow_notarytx(struct supernet_info *myinfo,char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t usesigs,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified)
{ {
uint32_t k,m,numsigs,version,vout,crcval,sequenceid = 0xffffffff; bits256 zero; int32_t n,siglen,len; uint8_t serialized[32768],*sig; bits256 txid; struct dpow_entry *ep; struct dpow_coinentry *cp; uint32_t k,m,numsigs,version,vout,crcval,sequenceid = 0xffffffff; bits256 zero; int32_t n,siglen,len; uint8_t serialized[32768],*sig; bits256 txid; struct dpow_entry *ep; struct dpow_coinentry *cp;
signedtx[0] = 0; // int32_t preimage_len; uint8_t preimage[32768]; // here we will create preimage, when usesigs=0 (?)
struct iguana_info *coin = (src_or_dest != 0) ? bp->destcoin : bp->srccoin;
//printf("[Decker] dpow_notarytx: src.(%s) dst.(%s) src_or_dest.(%d) usesigs.(%d)\n", bp->srccoin->symbol, bp->destcoin->symbol, src_or_dest, usesigs);
signedtx[0] = 0;
*numsigsp = 0; *numsigsp = 0;
memset(zero.bytes,0,sizeof(zero)); memset(zero.bytes,0,sizeof(zero));
len = numsigs = 0; len = numsigs = 0;
version = 1; version = 1;
len += iguana_rwnum(1,&serialized[len],sizeof(version),&version);
if ( isPoS != 0 ) if (coin->sapling != 0) {
version = 4;
version = 1 << 31 | version; // overwintered
}
len += iguana_rwnum(1,&serialized[len],sizeof(version),&version);
if (coin->sapling != 0) {
uint32_t versiongroupid = 0x892f2085; // sapling
len += iguana_rwnum(1, &serialized[len], sizeof(versiongroupid), &versiongroupid);
}
if ( isPoS != 0 )
len += iguana_rwnum(1,&serialized[len],sizeof(bp->timestamp),&bp->timestamp); len += iguana_rwnum(1,&serialized[len],sizeof(bp->timestamp),&bp->timestamp);
m = bp->minsigs; m = bp->minsigs;
len += iguana_rwvarint32(1,&serialized[len],(uint32_t *)&m); len += iguana_rwvarint32(1,&serialized[len],(uint32_t *)&m);
for (k=m=0; k<bp->numnotaries; k++) // -- vins --
for (k=m=0; k<bp->numnotaries; k++)
{ {
siglen = 0; siglen = 0;
sig = 0; sig = 0;
if ( ((1LL << k) & bestmask) != 0 ) if ( ((1LL << k) & bestmask) != 0 )
{ {
if ( pubkeys != 0 && numratified > 0 ) if ( pubkeys != 0 && numratified > 0 ) // state [1]
{ {
//printf("[Decker] dpow_notarytx: state [1]\n");
if ( src_or_dest != 0 ) if ( src_or_dest != 0 )
{ {
txid = bp->notaries[k].ratifydestutxo; txid = bp->notaries[k].ratifydestutxo;
vout = bp->notaries[k].ratifydestvout; vout = bp->notaries[k].ratifydestvout;
} }
else else
{ {
txid = bp->notaries[k].ratifysrcutxo; txid = bp->notaries[k].ratifysrcutxo;
vout = bp->notaries[k].ratifysrcvout; vout = bp->notaries[k].ratifysrcvout;
} }
if ( bestk >= 0 )
if ( bestk >= 0 ) //
{ {
siglen = bp->notaries[k].ratifysiglens[src_or_dest]; siglen = bp->notaries[k].ratifysiglens[src_or_dest];
sig = bp->notaries[k].ratifysigs[src_or_dest]; sig = bp->notaries[k].ratifysigs[src_or_dest];
} }
//char str[65]; printf("j.%d k.%d m.%d vin.(%s) v%d siglen.%d\n",j,k,m,bits256_str(str,txid),vout,siglen); //char str[65]; printf("j.%d k.%d m.%d vin.(%s) v%d siglen.%d\n",j,k,m,bits256_str(str,txid),vout,siglen);
} }
else else // state [2]
{ {
//printf("[Decker] dpow_notarytx: state [2]\n");
ep = &bp->notaries[k]; ep = &bp->notaries[k];
cp = (src_or_dest != 0) ? &bp->notaries[k].dest : &bp->notaries[k].src; cp = (src_or_dest != 0) ? &bp->notaries[k].dest : &bp->notaries[k].src;
if ( bits256_nonz(cp->prev_hash) == 0 ) if ( bits256_nonz(cp->prev_hash) == 0 )
@ -315,7 +342,8 @@ bits256 dpow_notarytx(char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow
} }
len += iguana_rwbignum(1,&serialized[len],sizeof(txid),txid.bytes); len += iguana_rwbignum(1,&serialized[len],sizeof(txid),txid.bytes);
len += iguana_rwnum(1,&serialized[len],sizeof(vout),&vout); len += iguana_rwnum(1,&serialized[len],sizeof(vout),&vout);
if ( usesigs != 0 && bestk >= 0 )
if ( usesigs != 0 && bestk >= 0 ) // usesigs=1 -> insert signature
{ {
len += iguana_rwvarint32(1,&serialized[len],(uint32_t *)&siglen); len += iguana_rwvarint32(1,&serialized[len],(uint32_t *)&siglen);
if ( siglen > 0 && siglen <= sizeof(cp->sigs[bestk]) ) if ( siglen > 0 && siglen <= sizeof(cp->sigs[bestk]) )
@ -323,8 +351,9 @@ bits256 dpow_notarytx(char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow
memcpy(&serialized[len],sig,siglen); memcpy(&serialized[len],sig,siglen);
len += siglen; len += siglen;
numsigs++; numsigs++;
} else printf("Missing sig from k.%d\n",k); } //else printf("%s -> %s src_or_dest.%d Missing sig from k.%d\n",bp->srccoin->symbol,bp->destcoin->symbol,src_or_dest,k);
} else serialized[len++] = 0; } else serialized[len++] = 0; // usesigs=0 -> insert scriptlen = 0
len += iguana_rwnum(1,&serialized[len],sizeof(sequenceid),&sequenceid); len += iguana_rwnum(1,&serialized[len],sizeof(sequenceid),&sequenceid);
//printf("height.%d mod.%d VINI.%d <- i.%d j.%d\n",height,height % numnotaries,m,i,j); //printf("height.%d mod.%d VINI.%d <- i.%d j.%d\n",height,height % numnotaries,m,i,j);
m++; m++;
@ -332,13 +361,32 @@ bits256 dpow_notarytx(char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow
break; break;
} }
} }
if ( (n= dpow_voutstandard(bp,&serialized[len],m,src_or_dest,pubkeys,numratified)) < 0 ) // -- vins --
if ( (n= dpow_voutstandard(myinfo,bp,&serialized[len],m,src_or_dest,pubkeys,numratified)) < 0 )
{ {
printf("error dpow_voutstandard m.%d src_or_dest.%d\n",m,src_or_dest); printf("error dpow_voutstandard m.%d src_or_dest.%d\n",m,src_or_dest);
return(zero); return(zero);
} }
len += n; len += n;
if (coin->sapling != 0) {
uint32_t nExpiryHeight = 0;
uint64_t valueBalance = 0;
uint8_t nShieldedSpend = 0;
uint8_t nShieldedOutput = 0;
uint8_t nJoinSplit = 0;
len += iguana_rwnum(1, &serialized[len], sizeof(nExpiryHeight), &nExpiryHeight);
len += iguana_rwnum(1, &serialized[len], sizeof(valueBalance), &valueBalance);
len += iguana_rwnum(1, &serialized[len], sizeof(nShieldedSpend), &nShieldedSpend); // The number of Spend descriptions in vShieldedSpend
len += iguana_rwnum(1, &serialized[len], sizeof(nShieldedOutput), &nShieldedOutput); // The number of Output descriptions in vShieldedOutput
len += iguana_rwnum(1, &serialized[len], sizeof(nJoinSplit), &nJoinSplit); // The number of JoinSplit descriptions in vJoinSplit
}
// here if usesigs=0 we have unsigned tx (not preimage), if usesigs=1 - we have signed tx with sigs from nn_bus network (?)
init_hexbytes_noT(signedtx,serialized,len); init_hexbytes_noT(signedtx,serialized,len);
//printf("[Decker] dpow_notarytx: signedtx.(%s)\n", signedtx);
//printf("notarytx.(%s) opretlen.%d\n",signedtx,opretlen); //printf("notarytx.(%s) opretlen.%d\n",signedtx,opretlen);
if ( usesigs == 0 && bestk >= 0 ) if ( usesigs == 0 && bestk >= 0 )
{ {
@ -387,6 +435,7 @@ cJSON *dpow_vins(struct iguana_info *coin,struct dpow_block *bp,int8_t bestk,uin
item = cJSON_CreateObject(); item = cJSON_CreateObject();
jaddbits256(item,"txid",txid); jaddbits256(item,"txid",txid);
jaddnum(item,"vout",vout); jaddnum(item,"vout",vout);
jaddnum(item, "amount", dstr(dpow_utxosize(coin->symbol)));
if ( k == 0 && bp->require0 != 0 ) if ( k == 0 && bp->require0 != 0 )
{ {
script[0] = 0x76; script[0] = 0x76;
@ -510,7 +559,7 @@ int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct dpow_info *dp,struc
srchash.bytes[j] = dp->minerkey33[j+1]; srchash.bytes[j] = dp->minerkey33[j+1];
if ( (vins= dpow_vins(coin,bp,bestk,bestmask,1,src_or_dest,useratified)) != 0 ) if ( (vins= dpow_vins(coin,bp,bestk,bestmask,1,src_or_dest,useratified)) != 0 )
{ {
txid = dpow_notarytx(rawtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,bp->numratified!=0?bp->ratified_pubkeys:0,useratified*bp->numratified); txid = dpow_notarytx(myinfo,rawtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,bp->numratified!=0?bp->ratified_pubkeys:0,useratified*bp->numratified);
//char str[65]; printf("%s signedtxgen %s src_or_dest.%d (%d %llx) useratified.%d raw.(%s)\n",dp->symbol,bits256_str(str,txid),src_or_dest,bestk,(long long)bestmask,useratified,rawtx); //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 ( bits256_nonz(txid) != 0 && rawtx[0] != 0 ) // send tx to share utxo set
{ {
@ -573,9 +622,9 @@ void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_info *dp,struct dpo
channel = (src_or_dest != 0) ? DPOW_SIGBTCCHANNEL : DPOW_SIGCHANNEL; channel = (src_or_dest != 0) ? DPOW_SIGBTCCHANNEL : DPOW_SIGCHANNEL;
if ( bestk >= 0 && bp->state != 0xffffffff && coin != 0 ) if ( bestk >= 0 && bp->state != 0xffffffff && coin != 0 )
{ {
dpow_notarytx(bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,pubkeys,numratified); // setcrcval dpow_notarytx(myinfo,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); signedtxid = dpow_notarytx(myinfo,bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,1,src_or_dest,pubkeys,numratified);
if ( strcmp("GAME",coin->symbol) == 0 ) if ( strcmp("GAME",coin->symbol) == 0 || strcmp("EMC2",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); 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; bp->state = 1;
if ( bits256_nonz(signedtxid) != 0 && numsigs == bp->minsigs ) if ( bits256_nonz(signedtxid) != 0 && numsigs == bp->minsigs )
@ -609,7 +658,7 @@ void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_info *dp,struct dpo
else else
{ {
bp->state = 0xffffffff; bp->state = 0xffffffff;
printf("dpow_sigscheck: mismatched txid.%s vs %s\n",bits256_str(str,txid),retstr); printf("dpow_sigscheck.(%s): mismatched txid.%s vs %s\n",bp->signedtx,bits256_str(str,txid),retstr);
} }
free(retstr); free(retstr);
retstr = 0; retstr = 0;

49
iguana/dpowassets

@ -0,0 +1,49 @@
#!/bin/bash
set -x
source pubkey.txt
echo $pubkey
sleep 3
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"REVS\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"SUPERNET\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"DEX\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"PANGEA\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"JUMBLR\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"BET\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CRYPTO\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"HODL\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"MSHARK\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"BOTS\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"MGW\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"COQUI\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"WLC\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KV\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CEAL\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"MESH\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"MNZ\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"AXO\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"ETOMIC\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"BTCH\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CHAIN\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"NINJA\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"OOT\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"BNTN\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"PRLPAY\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"DSEC\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"GLXT\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"EQL\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"ZILLA\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CHIPS\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"GAME\",\"freq\":5,\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"RFOX\",\"freq\":10,\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"VRSC\",\"freq\":10,\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"SEC\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"CCL\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"HUSH\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"PIRATE\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"MGNX\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"EMC2\",\"freq\":5,\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"PGT\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KMDICE\",\"freq\":2,\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"DION\",\"pubkey\":\"$pubkey\"}"

10
iguana/exchanges/CMakeLists.txt

@ -1,6 +1,6 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 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_SOURCES mm.c ../mini-gmp.c ../groestl.c ../segwit_addr.c ../keccak.c LP_etomic.c)
set(MM_LIBS curl pthread libcrypto777 libjpeg libsecp256k1) set(MM_LIBS curl pthread libcrypto777 libjpeg libsecp256k1 libsodium::libsodium)
if(WIN32) 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) 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) set(MM_LIBS ${MM_LIBS} nanomsg)
@ -24,6 +24,7 @@ add_definitions(-DNATIVE_WINDOWS)
add_definitions(-DIGUANA_LOG2PACKETSIZE=20) add_definitions(-DIGUANA_LOG2PACKETSIZE=20)
add_definitions(-DIGUANA_MAXPACKETSIZE=1572864) add_definitions(-DIGUANA_MAXPACKETSIZE=1572864)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_definitions(-DMM_WIN_BUILD)
include_directories("${CMAKE_SOURCE_DIR}/includes") include_directories("${CMAKE_SOURCE_DIR}/includes")
endif() endif()
target_link_libraries(marketmaker-testnet ${MM_LIBS} etomiclib-testnet) target_link_libraries(marketmaker-testnet ${MM_LIBS} etomiclib-testnet)
@ -31,4 +32,9 @@ target_link_libraries(marketmaker-mainnet ${MM_LIBS} etomiclib-mainnet)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
target_link_libraries(marketmaker-mainnet -static-libgcc -static-libstdc++) target_link_libraries(marketmaker-mainnet -static-libgcc -static-libstdc++)
target_link_libraries(marketmaker-testnet -static-libgcc -static-libstdc++) target_link_libraries(marketmaker-testnet -static-libgcc -static-libstdc++)
endif() endif()
if(NOT DEFINED MM_VERSION)
SET(MM_VERSION UNKNOWN)
endif()
target_compile_definitions(marketmaker-mainnet PRIVATE -DMM_VERSION="${MM_VERSION}")
target_compile_definitions(marketmaker-testnet PRIVATE -DMM_VERSION="${MM_VERSION}")

362
iguana/exchanges/LP_bitcoin.c

@ -17,6 +17,23 @@
// LP_bitcoin.c // LP_bitcoin.c
// marketmaker // marketmaker
// //
#include <sodium/crypto_generichash_blake2b.h>
const unsigned char ZCASH_PREVOUTS_HASH_PERSONALIZATION[16] =
{'Z','c','a','s','h','P','r','e','v','o','u','t','H','a','s','h'};
const unsigned char ZCASH_SEQUENCE_HASH_PERSONALIZATION[16] =
{'Z','c','a','s','h','S','e','q','u','e','n','c','H','a','s','h'};
const unsigned char ZCASH_OUTPUTS_HASH_PERSONALIZATION[16] =
{'Z','c','a','s','h','O','u','t','p','u','t','s','H','a','s','h'};
const unsigned char ZCASH_JOINSPLITS_HASH_PERSONALIZATION[16] =
{'Z','c','a','s','h','J','S','p','l','i','t','s','H','a','s','h'};
const unsigned char ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION[16] =
{'Z','c','a','s','h','S','S','p','e','n','d','s','H','a','s','h'};
const unsigned char ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION[16] =
{'Z','c','a','s','h','S','O','u','t','p','u','t','H','a','s','h'};
const unsigned char ZCASH_SIG_HASH_SAPLING_PERSONALIZATION[16] =
{'Z','c','a','s','h','S','i','g','H','a','s','h', '\xBB', '\x09', '\xB8', '\x76'};
const unsigned char ZCASH_SIG_HASH_OVERWINTER_PERSONALIZATION[16] =
{'Z','c','a','s','h','S','i','g','H','a','s','h', '\x19', '\x1B', '\xA8', '\x5B'};
union iguana_stacknum { int32_t val; int64_t val64; uint8_t rmd160[20]; bits256 hash2; uint8_t pubkey[33]; uint8_t sig[74]; }; union iguana_stacknum { int32_t val; int64_t val64; uint8_t rmd160[20]; bits256 hash2; uint8_t pubkey[33]; uint8_t sig[74]; };
struct iguana_stackdata { uint8_t *data; uint16_t size; union iguana_stacknum U; }; struct iguana_stackdata { uint8_t *data; uint16_t size; union iguana_stacknum U; };
@ -2011,16 +2028,25 @@ int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,c
return(n); return(n);
} }
char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params) char *bitcoind_passthrut(char *coinstr,char *serverport,char *userpass,char *method,char *params,int32_t timeout)
{ {
if ( userpass[0] == 0 ) /*struct iguana_info *coin; char *retstr;
return(clonestr("{\"error\":\"no rpcusername rpcpassword in coin.conf\"}")); if ( (coin= LP_coinfind(coinstr)) != 0 )
return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,4)); {
portable_mutex_lock(&coin->curl_mutex);
retstr = bitcoind_RPCnew(coin->curl_handle,0,coinstr,serverport,userpass,method,params,timeout);
portable_mutex_unlock(&coin->curl_mutex);
return(retstr);
}*/
return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,timeout));
} }
char *bitcoind_passthrut(char *coinstr,char *serverport,char *userpass,char *method,char *params,int32_t timeout) char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params)
{ {
return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,timeout)); if ( userpass[0] == 0 )
return(clonestr("{\"error\":\"no rpcusername rpcpassword in coin.conf\"}"));
return(bitcoind_passthrut(coinstr,serverport,userpass,method,params,4));
//return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,4));
} }
bits256 bits256_calcaddrhash(char *symbol,uint8_t *serialized,int32_t len) bits256 bits256_calcaddrhash(char *symbol,uint8_t *serialized,int32_t len)
@ -2093,7 +2119,7 @@ int32_t bitcoin_addr2rmd160(char *symbol,uint8_t taddr,uint8_t *addrtypep,uint8_
} }
else if ( (strcmp(symbol,"GRS") == 0 || strcmp(symbol,"SMART") == 0) && (buf[20+offset]&0xff) == hash.bytes[0] && (buf[21+offset]&0xff) == hash.bytes[1] && (buf[22+offset]&0xff) == hash.bytes[2] && (buf[23+offset]&0xff) == hash.bytes[3] ) 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); return(20);
else else if ( strcmp(symbol,"BTC") != 0 || *addrtypep == 0 || *addrtypep == 5 )
{ {
int32_t i; int32_t i;
//if ( len > 20 ) //if ( len > 20 )
@ -2109,6 +2135,10 @@ 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) char *bitcoin_address(char *symbol,char *coinaddr,uint8_t taddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len)
{ {
static void *ctx; static void *ctx;
// Zcash testnet uses different taddr value for p2pk and p2sh addresses, that's why this hardcode is here
if (strcmp(symbol, "ZECTEST") == 0 && addrtype == 186) {
taddr = 28;
}
int32_t offset,i,len5; char prefixed[64]; uint8_t data[64],data5[64],bigpubkey[65]; bits256 hash; struct iguana_info *coin; int32_t offset,i,len5; char prefixed[64]; uint8_t data[64],data5[64],bigpubkey[65]; bits256 hash; struct iguana_info *coin;
#ifndef NOTETOMIC #ifndef NOTETOMIC
if ( (coin= LP_coinfind(symbol)) != 0 && coin->etomic[0] != 0 ) if ( (coin= LP_coinfind(symbol)) != 0 && coin->etomic[0] != 0 )
@ -2831,6 +2861,18 @@ cJSON *bitcoin_txcreate(char *symbol,int32_t isPoS,int64_t locktime,uint32_t txv
{ {
cJSON *json = cJSON_CreateObject(); cJSON *json = cJSON_CreateObject();
jaddnum(json,"version",txversion); jaddnum(json,"version",txversion);
if (txversion >= 3) {
cJSON_AddBoolToObject(json,"overwintered",1);
jaddnum(json,"expiryheight",0);
if (txversion == 3) {
jaddstr(json, "versiongroupid", "03c48270");
} else if (txversion == 4) {
jaddstr(json, "versiongroupid", "892f2085");
jaddnum(json, "valueBalance", 0.);
jadd(json, "vShieldedSpend", cJSON_CreateArray());
jadd(json, "vShieldedOutput", cJSON_CreateArray());
}
}
if ( locktime == 0 && strcmp(symbol,"KMD") == 0 ) if ( locktime == 0 && strcmp(symbol,"KMD") == 0 )
locktime = (uint32_t)time(NULL); locktime = (uint32_t)time(NULL);
jaddnum(json,"locktime",locktime); jaddnum(json,"locktime",locktime);
@ -3406,7 +3448,120 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht
printf("currently only SIGHASH_ALL supported, not %d\n",hashtype); printf("currently only SIGHASH_ALL supported, not %d\n",hashtype);
return(sigtxid); return(sigtxid);
} }
if ( (hashtype & SIGHASH_FORKID) == 0 || sbtcflag != 0 || btcpflag != 0 ) uint32_t overwintered = dest.version >> 31;
uint32_t version = dest.version & 0x7FFFFFFF;
if (overwintered && version >= 3) {
len = 0;
uint8_t for_sig_hash[1000], sig_hash[32];
len = iguana_rwnum(1, &for_sig_hash[len], sizeof(dest.version), &dest.version);
len += iguana_rwnum(1, &for_sig_hash[len], sizeof(dest.version_group_id), &dest.version_group_id);
uint8_t prev_outs[1000], hash_prev_outs[32];
int32_t prev_outs_len = 0;
for (i = 0; i < dest.tx_in; i++) {
prev_outs_len += iguana_rwbignum(1, &prev_outs[prev_outs_len], sizeof(dest.vins[i].prev_hash), dest.vins[i].prev_hash.bytes);
prev_outs_len += iguana_rwnum(1, &prev_outs[prev_outs_len], sizeof(dest.vins[i].prev_vout), &dest.vins[i].prev_vout);
}
crypto_generichash_blake2b_salt_personal(
hash_prev_outs,
32,
prev_outs,
(uint64_t)prev_outs_len,
NULL,
0,
NULL,
ZCASH_PREVOUTS_HASH_PERSONALIZATION
);
memcpy(&for_sig_hash[len], hash_prev_outs, 32);
len += 32;
uint8_t sequence[1000], sequence_hash[32];
int32_t sequence_len = 0;
for (i = 0; i < dest.tx_in; i++) {
sequence_len += iguana_rwnum(1, &sequence[sequence_len], sizeof(dest.vins[i].sequence),
&dest.vins[i].sequence);
}
crypto_generichash_blake2b_salt_personal(
sequence_hash,
32,
sequence,
(uint64_t)sequence_len,
NULL,
0,
NULL,
ZCASH_SEQUENCE_HASH_PERSONALIZATION
);
memcpy(&for_sig_hash[len], sequence_hash, 32);
len += 32;
uint8_t outputs[1000], hash_outputs[32];
int32_t outputs_len = 0;
for (i = 0; i < dest.tx_out; i++) {
outputs_len += iguana_rwnum(1, &outputs[outputs_len], sizeof(dest.vouts[i].value), &dest.vouts[i].value);
outputs[outputs_len++] = (uint8_t) dest.vouts[i].pk_scriptlen;
memcpy(&outputs[outputs_len], dest.vouts[i].pk_script, dest.vouts[i].pk_scriptlen);
outputs_len += dest.vouts[i].pk_scriptlen;
}
crypto_generichash_blake2b_salt_personal(
hash_outputs,
32,
outputs,
(uint64_t)outputs_len,
NULL,
0,
NULL,
ZCASH_OUTPUTS_HASH_PERSONALIZATION
);
memcpy(&for_sig_hash[len], hash_outputs, 32);
len += 32;
// no join splits, fill the hashJoinSplits with 32 zeros
memset(&for_sig_hash[len], 0, 32);
len += 32;
if (version > 3) {
// no shielded spends, fill the hashShieldedSpends with 32 zeros
memset(&for_sig_hash[len], 0, 32);
len += 32;
// no shielded outputs, fill the hashShieldedOutputs with 32 zeros
memset(&for_sig_hash[len], 0, 32);
len += 32;
}
len += iguana_rwnum(1, &for_sig_hash[len], sizeof(dest.lock_time), &dest.lock_time);
len += iguana_rwnum(1, &for_sig_hash[len], sizeof(dest.expiry_height), &dest.expiry_height);
if (version > 3) {
len += iguana_rwnum(1, &for_sig_hash[len], sizeof(dest.value_balance), &dest.value_balance);
}
len += iguana_rwnum(1, &for_sig_hash[len], sizeof(hashtype),&hashtype);
len += iguana_rwbignum(1,&for_sig_hash[len],sizeof(dest.vins[vini].prev_hash),dest.vins[vini].prev_hash.bytes);
len += iguana_rwnum(1,&for_sig_hash[len],sizeof(dest.vins[vini].prev_vout),&dest.vins[vini].prev_vout);
for_sig_hash[len++] = (uint8_t)spendlen;
memcpy(&for_sig_hash[len],spendscript,spendlen), len += spendlen;
len += iguana_rwnum(1,&for_sig_hash[len],sizeof(spendamount),&spendamount);
len += iguana_rwnum(1,&for_sig_hash[len],sizeof(dest.vins[vini].sequence),&dest.vins[vini].sequence);
unsigned const char *sig_hash_personal = ZCASH_SIG_HASH_OVERWINTER_PERSONALIZATION;
if (version == 4) {
sig_hash_personal = ZCASH_SIG_HASH_SAPLING_PERSONALIZATION;
}
crypto_generichash_blake2b_salt_personal(
sig_hash,
32,
for_sig_hash,
(uint64_t)len,
NULL,
0,
NULL,
sig_hash_personal
);
for (i=0; i<32; i++)
sigtxid.bytes[i] = sig_hash[i];
}
else if ( (hashtype & SIGHASH_FORKID) == 0 || sbtcflag != 0 || btcpflag != 0 )
{ {
for (i=0; i<dest.tx_in; i++) for (i=0; i<dest.tx_in; i++)
{ {
@ -3579,7 +3734,7 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht
return(sigtxid); return(sigtxid);
} }
int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgjoinsplit *msg) int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgjoinsplit *msg,uint32_t proof_size)
{ {
int32_t len = 0; int32_t len = 0;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->vpub_old),&msg->vpub_old); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->vpub_old),&msg->vpub_old);
@ -3599,9 +3754,9 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->vmacs[0]),msg->vmacs[0].bytes); len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->vmacs[0]),msg->vmacs[0].bytes);
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->vmacs[1]),msg->vmacs[1].bytes); len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->vmacs[1]),msg->vmacs[1].bytes);
if ( rwflag == 1 ) if ( rwflag == 1 )
memcpy(&serialized[len],msg->zkproof,sizeof(msg->zkproof)); memcpy(&serialized[len],msg->zkproof,proof_size);
else memcpy(msg->zkproof,&serialized[len],sizeof(msg->zkproof)); else memcpy(msg->zkproof,&serialized[len],proof_size);
len += sizeof(msg->zkproof); len += proof_size;
return(len); return(len);
} }
@ -3624,11 +3779,33 @@ uint32_t LP_sighash(char *symbol,int32_t zcash)
int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash)
{ {
int32_t i,j,n,segtxlen,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t *segtx=0,segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; uint64_t spendamount; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; int32_t i,j,n,segtxlen,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t *segtx=0,segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; uint64_t spendamount; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version);
uint32_t overwintered = msg->version >> 31;
uint32_t version = msg->version;
// for version 4 the ZK proof size is 192, otherwise 296
uint32_t zksnark_proof_size = ZKSNARK_PROOF_SIZE;
if (zcash) {
if (overwintered) {
version = msg->version & 0x7FFFFFFF;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version_group_id),&msg->version_group_id);
if (version >= 4) {
zksnark_proof_size = GROTH_PROOF_SIZE;
}
}
}
if ( json != 0 ) if ( json != 0 )
{ {
jaddnum(json,"version",msg->version); if (overwintered) {
jaddnum(json,"version",msg->version & 0x7FFFFFFF);
} else {
jaddnum(json, "version", msg->version);
}
cJSON_AddBoolToObject(json, "overwintered", overwintered);
if (overwintered) {
char group_id_str[10];
sprintf(group_id_str, "%x", msg->version_group_id);
jaddstr(json, "versiongroupid", group_id_str);
}
vinarray = cJSON_CreateArray(); vinarray = cJSON_CreateArray();
voutarray = cJSON_CreateArray(); voutarray = cJSON_CreateArray();
if ( rwflag == 0 ) if ( rwflag == 0 )
@ -3761,15 +3938,124 @@ int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shty
} }
} }
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time);
if (zcash && overwintered) {
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->expiry_height),&msg->expiry_height);
if (json != 0) {
jaddnum(json, "expiryheight", msg->expiry_height);
}
if (version >= 4) {
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->value_balance),&msg->value_balance);
if (json != 0) {
jaddnum(json, "valueBalance", dstr(msg->value_balance));
}
cJSON *v_shielded_spend = cJSON_CreateArray();
cJSON *v_shielded_output = cJSON_CreateArray();
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->shielded_spend_num),&msg->shielded_spend_num);
if (msg->shielded_spend_num > 0) {
if (extraused + sizeof(struct sapling_spend_description) * msg->shielded_spend_num > extralen) {
printf("extraused.%d + shielded_spend.%d > extralen.%d\n", extraused, msg->shielded_spend_num,
extralen);
return (-1);
}
msg->shielded_spends = (struct sapling_spend_description *) &extraspace[extraused];
extraused += (sizeof(struct sapling_spend_description) * msg->shielded_spend_num);
for (i = 0; i < msg->shielded_spend_num; i++) {
len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_spends[i].cv), msg->shielded_spends[i].cv.bytes);
len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_spends[i].anchor), msg->shielded_spends[i].anchor.bytes);
len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_spends[i].nullifier), msg->shielded_spends[i].nullifier.bytes);
len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_spends[i].rk), msg->shielded_spends[i].rk.bytes);
if (rwflag == 1) {
memcpy(&serialized[len], msg->shielded_spends[i].zkproof, GROTH_PROOF_SIZE);
} else {
memcpy(msg->shielded_spends[i].zkproof, &serialized[len], GROTH_PROOF_SIZE);
}
len += GROTH_PROOF_SIZE;
if (rwflag == 1) {
memcpy(&serialized[len], msg->shielded_spends[i].spend_auth_sig, SAPLING_AUTH_SIG_SIZE);
} else {
memcpy(msg->shielded_spends[i].spend_auth_sig, &serialized[len], SAPLING_AUTH_SIG_SIZE);
}
len += SAPLING_AUTH_SIG_SIZE;
if (json != 0) {
cJSON *spend_item = cJSON_CreateObject();
jaddbits256(spend_item, "cv", msg->shielded_spends[i].cv);
jaddbits256(spend_item, "anchor", msg->shielded_spends[i].anchor);
jaddbits256(spend_item, "nullifier", msg->shielded_spends[i].nullifier);
jaddbits256(spend_item, "rk", msg->shielded_spends[i].rk);
char proof_str[GROTH_PROOF_SIZE * 2 + 1];
init_hexbytes_noT(proof_str, msg->shielded_spends[i].zkproof, GROTH_PROOF_SIZE);
jaddstr(spend_item, "proof", proof_str);
char auth_sig_str[SAPLING_AUTH_SIG_SIZE * 2 + 1];
init_hexbytes_noT(auth_sig_str, msg->shielded_spends[i].spend_auth_sig, SAPLING_AUTH_SIG_SIZE);
jaddstr(spend_item, "spendAuthSig", auth_sig_str);
jaddi(v_shielded_spend, spend_item);
}
}
}
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->shielded_output_num),&msg->shielded_output_num);
if (msg->shielded_output_num > 0) {
if (extraused + sizeof(struct sapling_output_description) * msg->shielded_output_num > extralen) {
printf("extraused.%d + shielded_output.%d > extralen.%d\n", extraused, msg->shielded_output_num,
extralen);
return (-1);
}
msg->shielded_outputs = (struct sapling_output_description *) &extraspace[extraused];
extraused += (sizeof(struct sapling_output_description) * msg->shielded_output_num);
for (i = 0; i < msg->shielded_output_num; i++) {
len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_outputs[i].cv), msg->shielded_outputs[i].cv.bytes);
len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_outputs[i].cm), msg->shielded_outputs[i].cm.bytes);
len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_outputs[i].ephemeral_key), msg->shielded_outputs[i].ephemeral_key.bytes);
if (rwflag == 1) {
memcpy(&serialized[len], msg->shielded_outputs[i].enc_ciphertext, ENC_CIPHER_SIZE);
} else {
memcpy(msg->shielded_outputs[i].enc_ciphertext, &serialized[len], ENC_CIPHER_SIZE);
}
len += ENC_CIPHER_SIZE;
if (rwflag == 1) {
memcpy(&serialized[len], msg->shielded_outputs[i].out_ciphertext, OUT_CIPHER_SIZE);
} else {
memcpy(msg->shielded_outputs[i].out_ciphertext, &serialized[len], OUT_CIPHER_SIZE);
}
len += OUT_CIPHER_SIZE;
if (rwflag == 1) {
memcpy(&serialized[len], msg->shielded_outputs[i].zkproof, GROTH_PROOF_SIZE);
} else {
memcpy(msg->shielded_outputs[i].zkproof, &serialized[len], GROTH_PROOF_SIZE);
}
len += GROTH_PROOF_SIZE;
if (json != 0) {
cJSON *output_item = cJSON_CreateObject();
jaddbits256(output_item, "cv", msg->shielded_outputs[i].cv);
jaddbits256(output_item, "cmu", msg->shielded_outputs[i].cm);
jaddbits256(output_item, "ephemeralKey", msg->shielded_outputs[i].ephemeral_key);
char enc_cip_str[ENC_CIPHER_SIZE * 2 + 1];
init_hexbytes_noT(enc_cip_str, msg->shielded_outputs[i].enc_ciphertext, ENC_CIPHER_SIZE);
jaddstr(output_item, "encCiphertext", enc_cip_str);
char out_cip_str[OUT_CIPHER_SIZE * 2 + 1];
init_hexbytes_noT(out_cip_str, msg->shielded_outputs[i].out_ciphertext, OUT_CIPHER_SIZE);
jaddstr(output_item, "outCiphertext", out_cip_str);
jaddi(v_shielded_output, output_item);
char proof_str[GROTH_PROOF_SIZE * 2 + 1];
init_hexbytes_noT(proof_str, msg->shielded_outputs[i].zkproof, GROTH_PROOF_SIZE);
jaddstr(output_item, "proof", proof_str);
}
}
}
if (json != 0) {
cJSON_AddItemToObject(json, "vShieldedSpend", v_shielded_spend);
cJSON_AddItemToObject(json, "vShieldedOutput", v_shielded_output);
}
}
}
//printf("lock_time.%08x len.%d\n",msg->lock_time,len); //printf("lock_time.%08x len.%d\n",msg->lock_time,len);
if ( zcash == LP_IS_ZCASHPROTOCOL && msg->version > 1 ) if ( zcash == LP_IS_ZCASHPROTOCOL && msg->version > 1 )
{ {
uint32_t numjoinsplits; struct iguana_msgjoinsplit joinsplit; uint8_t joinsplitpubkey[33],joinsplitsig[64]; struct iguana_msgjoinsplit joinsplit; uint8_t joinsplitpubkey[33],joinsplitsig[64];
len += iguana_rwvarint32(rwflag,&serialized[len],&numjoinsplits); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->numjoinsplits),&msg->numjoinsplits);
if ( numjoinsplits > 0 ) if ( msg->numjoinsplits > 0 )
{ {
for (i=0; i<numjoinsplits; i++) for (i=0; i<msg->numjoinsplits; i++)
len += iguana_rwjoinsplit(rwflag,&serialized[len],&joinsplit); len += iguana_rwjoinsplit(rwflag,&serialized[len],&joinsplit,zksnark_proof_size);
if ( rwflag != 0 ) if ( rwflag != 0 )
{ {
memset(joinsplitpubkey,0,sizeof(joinsplitpubkey)); // for now memset(joinsplitpubkey,0,sizeof(joinsplitpubkey)); // for now
@ -3785,6 +4071,18 @@ int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shty
} }
} }
} }
if (zcash == 1 && msg->version >= 4 && !(msg->shielded_spend_num == 0 && msg->shielded_output_num == 0)) {
if (rwflag == 1) {
memcpy(&serialized[len],msg->binding_sig,64), len += 64;
} else {
memcpy(msg->binding_sig,&serialized[len],64), len += 64;
}
if (json != 0) {
char binding_sig_str[64 * 2 + 1];
init_hexbytes_noT(binding_sig_str, msg->binding_sig, 64);
jaddstr(json, "bindingSig", binding_sig_str);
}
}
if ( sigser != 0 && vinarray != 0 ) if ( sigser != 0 && vinarray != 0 )
{ {
for (i=0; i<msg->tx_in; i++) for (i=0; i<msg->tx_in; i++)
@ -3837,9 +4135,24 @@ bits256 iguana_parsetxobj(char *symbol,uint8_t isPoS,int32_t *txstartp,uint8_t *
if ( txobj == 0 ) if ( txobj == 0 )
return(txid); return(txid);
vpnstr[0] = 0; vpnstr[0] = 0;
if ( (msg->version= juint(txobj,"version")) == 0 ) uint32_t version = juint(txobj,"version");
if (version == 0 ) {
msg->version = 1; msg->version = 1;
} else {
msg->version = version;
}
if (is_cJSON_True(cJSON_GetObjectItem(txobj, "overwintered"))) {
msg->version = 1 << 31 | msg->version;
msg->version_group_id = (uint32_t)strtoul(jstr(txobj, "versiongroupid"), NULL, 16);
msg->expiry_height = juint(txobj, "expiryheight");
if (version >= 4) {
msg->value_balance = (uint64_t) (jdouble(txobj, "valueBalance") * SATOSHIDEN);
}
}
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version);
if (is_cJSON_True(cJSON_GetObjectItem(txobj, "overwintered"))) {
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version_group_id),&msg->version_group_id);
}
if ( isPoS != 0 ) if ( isPoS != 0 )
{ {
if ( (msg->timestamp= juint(txobj,"timestamp")) == 0 ) if ( (msg->timestamp= juint(txobj,"timestamp")) == 0 )
@ -3887,6 +4200,15 @@ bits256 iguana_parsetxobj(char *symbol,uint8_t isPoS,int32_t *txstartp,uint8_t *
} }
msg->lock_time = jint(txobj,"locktime"); msg->lock_time = jint(txobj,"locktime");
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time);
if (is_cJSON_True(cJSON_GetObjectItem(txobj, "overwintered"))) {
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->expiry_height),&msg->expiry_height);
if (version >= 4) {
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->value_balance),&msg->value_balance);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->shielded_spend_num),&msg->shielded_spend_num);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->shielded_output_num),&msg->shielded_output_num);
}
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->numjoinsplits),&msg->numjoinsplits);
}
//msg->txid = jbits256(txobj,"txid"); //msg->txid = jbits256(txobj,"txid");
*txstartp = 0; *txstartp = 0;
msg->allocsize = len; msg->allocsize = len;

33
iguana/exchanges/LP_coins.c

@ -251,10 +251,14 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif)
} }
#ifndef NOTETOMIC #ifndef NOTETOMIC
else if (coin->etomic[0] != 0) { else if (coin->etomic[0] != 0) {
//balance = LP_etomic_get_balance(coin, coin->smartaddr); int error = 0;
if (coin->inactive == 0) {
balance = LP_etomic_get_balance(coin, coin->smartaddr, &error);
} else {
balance = 0;
}
jaddnum(item,"height",-1); jaddnum(item,"height",-1);
//jaddnum(item,"balance",dstr(balance)); jaddnum(item,"balance",dstr(balance));
jaddnum(item,"balance",0);
} }
#endif #endif
else else
@ -373,7 +377,8 @@ struct iguana_info *LP_coinadd(struct iguana_info *cdata)
return(coin); return(coin);
} }
uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetname,int32_t isPoS,uint16_t port,uint8_t pubtype,uint8_t p2shtype,uint8_t wiftype,uint64_t txfee,double estimatedrate,int32_t longestchain,uint8_t wiftaddr,uint8_t taddr,uint16_t busport,char *confpath) void *curl_easy_init();
uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetname,int32_t isPoS,uint16_t port,uint8_t pubtype,uint8_t p2shtype,uint8_t wiftype,uint64_t txfee,double estimatedrate,int32_t longestchain,uint8_t wiftaddr,uint8_t taddr,uint16_t busport,char *confpath,uint8_t decimals,uint32_t txversion)
{ {
static void *ctx; static void *ctx;
char *name2; uint16_t origport = port; char *name2; uint16_t origport = port;
@ -381,7 +386,7 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse
safecopy(coin->symbol,symbol,sizeof(coin->symbol)); safecopy(coin->symbol,symbol,sizeof(coin->symbol));
if ( strcmp(symbol,"PART") == 0 ) if ( strcmp(symbol,"PART") == 0 )
coin->txversion = 160; coin->txversion = 160;
else coin->txversion = 1; else coin->txversion = txversion;
coin->updaterate = (uint32_t)time(NULL); coin->updaterate = (uint32_t)time(NULL);
coin->isPoS = isPoS; coin->isPoS = isPoS;
coin->taddr = taddr; coin->taddr = taddr;
@ -429,6 +434,14 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse
coin->zcash = LP_IS_BITCOINGOLD; coin->zcash = LP_IS_BITCOINGOLD;
printf("set coin.%s <- LP_IS_BITCOINGOLD %d\n",symbol,coin->zcash); printf("set coin.%s <- LP_IS_BITCOINGOLD %d\n",symbol,coin->zcash);
} }
else if ( strcmp(symbol,"CMM") == 0 )
{
coin->zcash = LP_IS_BITCOINCASH;
//printf("set coin.%s <- LP_IS_BITCOINCASH %d\n",symbol,coin->zcash);
}
coin->curl_handle = curl_easy_init();
portable_mutex_init(&coin->curl_mutex);
coin->decimals = decimals;
return(port); return(port);
} }
@ -472,7 +485,7 @@ struct iguana_info *LP_coinfind(char *symbol)
else if ( strcmp(symbol,"KMD") == 0 ) else if ( strcmp(symbol,"KMD") == 0 )
name = "komodo"; name = "komodo";
else return(0); else return(0);
port = LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0,0,busport,0); port = LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0,0,busport,0,0,0);
if ( port == 0 ) if ( port == 0 )
isinactive = 1; isinactive = 1;
else isinactive = 0; else isinactive = 0;
@ -514,7 +527,13 @@ struct iguana_info *LP_coincreate(cJSON *item)
} }
else if ( (name= jstr(item,"name")) == 0 ) else if ( (name= jstr(item,"name")) == 0 )
name = symbol; name = symbol;
if ( LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,juint(item,"wiftaddr"),juint(item,"taddr"),LP_busport(port),jstr(item,"confpath")) < 0 )
uint8_t decimals = juint(item,"decimals");
uint32_t txversion = juint(item, "txversion");
if (txversion == 0) {
txversion = 1;
}
if ( LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,juint(item,"wiftaddr"),juint(item,"taddr"),LP_busport(port),jstr(item,"confpath"),decimals,txversion) < 0 )
{ {
coin = LP_coinadd(&cdata); coin = LP_coinadd(&cdata);
coin->inactive = (uint32_t)time(NULL); coin->inactive = (uint32_t)time(NULL);

130
iguana/exchanges/LP_commands.c

@ -120,6 +120,7 @@ cancel(uuid)\n\
buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce)\n\ buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce)\n\
sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)\n\ sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)\n\
withdraw(coin, outputs[], broadcast=0)\n\ withdraw(coin, outputs[], broadcast=0)\n\
eth_withdraw(coin, to, amount, gas, gas_price, broadcast=0)\n\
txblast(coin, utxotxid, utxovout, utxovalue, txfee, passphrase, outputs[], broadcast=0)\n\ txblast(coin, utxotxid, utxovout, utxovalue, txfee, passphrase, outputs[], broadcast=0)\n\
sendrawtransaction(coin, signedtx)\n\ sendrawtransaction(coin, signedtx)\n\
swapstatus(pending=0, fast=0)\n\ swapstatus(pending=0, fast=0)\n\
@ -144,12 +145,14 @@ fundvalue(address="", holdings=[], divisor=0)\n\
orderbook(base, rel, duration=3600)\n\ orderbook(base, rel, duration=3600)\n\
getprices()\n\ getprices()\n\
inuse()\n\ inuse()\n\
movecoinbases(coin)\n\
getmyprice(base, rel)\n\ getmyprice(base, rel)\n\
getprice(base, rel)\n\ getprice(base, rel)\n\
//sendmessage(base=coin, rel="", pubkey=zero, <argjson method2>)\n\ //sendmessage(base=coin, rel="", pubkey=zero, <argjson method2>)\n\
//getmessages(firsti=0, num=100)\n\ //getmessages(firsti=0, num=100)\n\
//deletemessages(firsti=0, num=100)\n\ //deletemessages(firsti=0, num=100)\n\
secretaddresses(prefix='secretaddress', passphrase, num=10, pubtype=60, taddr=0)\n\ secretaddresses(prefix='secretaddress', passphrase, num=10, pubtype=60, taddr=0)\n\
gen64addrs(passphrase, taddr=0, pubtype=60)\n\
electrum(coin, ipaddr, port)\n\ electrum(coin, ipaddr, port)\n\
snapshot(coin, height)\n\ snapshot(coin, height)\n\
snapshot_balance(coin, height, addresses[])\n\ snapshot_balance(coin, height, addresses[])\n\
@ -172,10 +175,17 @@ unlockedspend(coin, txid)\n\
opreturndecrypt(coin, txid, passphrase)\n\ opreturndecrypt(coin, txid, passphrase)\n\
getendpoint(port=5555)\n\ getendpoint(port=5555)\n\
getfee(coin)\n\ getfee(coin)\n\
mpnet(onoff)\n\
sleep(seconds=60)\n\ sleep(seconds=60)\n\
listtransactions(coin, address, count=10, skip=0)\n\ listtransactions(coin, address, count=10, skip=0)\n\
jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
version\n\
\"}")); \"}"));
if ( strcmp(method,"version") == 0 ) {
retjson = cJSON_CreateObject();
jaddstr(retjson,"result",MM_VERSION);
return(jprint(retjson,1));
}
if ( (base= jstr(argjson,"base")) == 0 ) if ( (base= jstr(argjson,"base")) == 0 )
base = ""; base = "";
@ -231,12 +241,23 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
{ {
if ( (ptr= LP_coinsearch("KMD")) != 0 ) if ( (ptr= LP_coinsearch("KMD")) != 0 )
{ {
if ( jint(argjson,"weeks") <= 0 || jdouble(argjson,"amount") < 10. ) if ( jint(argjson,"weeks") <= 0 ) {
return(clonestr("{\"error\":\"instantdex_deposit needs to have weeks and amount\"}")); return(clonestr("{\"error\":\"instantdex_deposit weeks param must be greater than zero\"}"));
else return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jobj(argjson,"broadcast") != 0 ? jint(argjson,"broadcast") : 1)); }
if ( jdouble(argjson,"amount") < 10. ) {
return(clonestr("{\"error\":\"instantdex_deposit amount param must be equal or greater than 10\"}"));
}
return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jobj(argjson,"broadcast") != 0 ? jint(argjson,"broadcast") : 1));
} }
return(clonestr("{\"error\":\"cant find KMD\"}")); return(clonestr("{\"error\":\"cant find KMD\"}"));
} }
else if ( strcmp(method,"mpnet") == 0 )
{
G.mpnet = jint(argjson,"onoff");
printf("MPNET onoff.%d\n",G.mpnet);
return(clonestr("{\"status\":\"success\"}"));
}
else if ( strcmp(method,"getendpoint") == 0 ) else if ( strcmp(method,"getendpoint") == 0 )
{ {
int32_t err,mode; uint16_t wsport = 5555; char endpoint[64],bindpoint[64]; int32_t err,mode; uint16_t wsport = 5555; char endpoint[64],bindpoint[64];
@ -276,6 +297,10 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
} }
return(jprint(retjson,1)); return(jprint(retjson,1));
} }
else if ( strcmp(method,"verus") == 0 )
{
return(verusblocks());
}
else if ( strcmp(method,"instantdex_claim") == 0 ) else if ( strcmp(method,"instantdex_claim") == 0 )
{ {
if ( (ptr= LP_coinsearch("KMD")) != 0 ) if ( (ptr= LP_coinsearch("KMD")) != 0 )
@ -391,11 +416,6 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
jaddbits256(retjson,"privkey",privkey); jaddbits256(retjson,"privkey",privkey);
bitcoin_priv2wif(coin,wiftaddr,wifstr,privkey,wiftype); bitcoin_priv2wif(coin,wiftaddr,wifstr,privkey,wiftype);
jaddstr(retjson,"wif",wifstr); 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)); return(jprint(retjson,1));
} else return(clonestr("{\"error\":\"need to have passphrase\"}")); } else return(clonestr("{\"error\":\"need to have passphrase\"}"));
} }
@ -407,6 +427,13 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
{ {
return(LP_ticker(jstr(argjson,"base"),jstr(argjson,"rel"))); return(LP_ticker(jstr(argjson,"base"),jstr(argjson,"rel")));
} }
else if ( strcmp(method,"gen64addrs") == 0 )
{
uint8_t taddr,pubtype;
pubtype = (jobj(argjson,"pubtype") == 0) ? 60 : juint(argjson,"pubtype");
taddr = (jobj(argjson,"taddr") == 0) ? 0 : juint(argjson,"taddr");
return(LP_gen64addrs(ctx,jstr(argjson,"passphrase"),taddr,pubtype));
}
else if ( strcmp(method,"secretaddresses") == 0 ) else if ( strcmp(method,"secretaddresses") == 0 )
{ {
uint8_t taddr,pubtype; uint8_t taddr,pubtype;
@ -451,6 +478,12 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
} }
else if ( strcmp(method,"inuse") == 0 ) else if ( strcmp(method,"inuse") == 0 )
return(jprint(LP_inuse_json(),1)); return(jprint(LP_inuse_json(),1));
#ifndef NOTETOMIC
else if ( strcmp(method,"eth_gas_price") == 0 )
{
return LP_eth_gas_price();
}
#endif
else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 )
return(retstr); return(retstr);
if ( base[0] != 0 && rel[0] != 0 ) if ( base[0] != 0 && rel[0] != 0 )
@ -476,24 +509,50 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
{ {
return(jprint(LP_tradesarray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1)); return(jprint(LP_tradesarray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1));
} }
else if ( strcmp(method,"getprice") == 0 || strcmp(method,"getmyprice") == 0 )
{
double price,bid,ask;
if ( strcmp(method,"getprice") == 0 )
{
ask = LP_price(1,base,rel);
if ( (bid= LP_price(1,rel,base)) > SMALLVAL )
bid = 1./bid;
}
else
{
ask = LP_getmyprice(1,base,rel);
if ( (bid= LP_getmyprice(1,rel,base)) > SMALLVAL )
bid = 1./bid;
}
price = _pairaved(bid,ask);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"base",base);
jaddstr(retjson,"rel",rel);
jaddnum(retjson,"timestamp",time(NULL));
jaddnum(retjson,"bid",bid);
jaddnum(retjson,"ask",ask);
jaddnum(retjson,"price",price);
return(jprint(retjson,1));
}
else if ( strcmp(method,"orderbook") == 0 )
return(LP_orderbook(base,rel,jint(argjson,"duration")));
if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 ) if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 )
return(clonestr("{\"error\":\"at least one of coins disabled\"}")); return(clonestr("{\"error\":\"at least one of coins disabled\"}"));
price = jdouble(argjson,"price"); price = jdouble(argjson,"price");
if ( strcmp(method,"setprice") == 0 ) if ( strcmp(method,"setprice") == 0 )
{ {
if ( LP_mypriceset(&changed,base,rel,price) < 0 ) if ( LP_mypriceset(1,&changed,base,rel,price) < 0 )
return(clonestr("{\"error\":\"couldnt set price\"}")); return(clonestr("{\"error\":\"couldnt set price\"}"));
//else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 ) //else if ( LP_mypriceset(1,&changed,rel,base,1./price) < 0 )
// return(clonestr("{\"error\":\"couldnt set price\"}")); // return(clonestr("{\"error\":\"couldnt set price\"}"));
else if ( price == 0. || jobj(argjson,"broadcast") == 0 || jint(argjson,"broadcast") != 0 ) else if ( price == 0. || jobj(argjson,"broadcast") == 0 || jint(argjson,"broadcast") != 0 )
return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio)); return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio));
else return(clonestr("{\"result\":\"success\"}")); else return(clonestr("{\"result\":\"success\"}"));
} }
else if ( strcmp(method,"orderbook") == 0 )
return(LP_orderbook(base,rel,jint(argjson,"duration")));
else if ( strcmp(method,"myprice") == 0 ) else if ( strcmp(method,"myprice") == 0 )
{ {
if ( LP_myprice(&bid,&ask,base,rel) > SMALLVAL ) if ( LP_myprice(1,&bid,&ask,base,rel) > SMALLVAL )
{ {
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
jaddstr(retjson,"base",base); jaddstr(retjson,"base",base);
@ -514,7 +573,7 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
} else vol = jdouble(argjson,"relvolume"); } else vol = jdouble(argjson,"relvolume");
if ( price > SMALLVAL ) if ( price > SMALLVAL )
{ {
return(LP_autobuy(ctx,fomo,myipaddr,pubsock,base,rel,price,vol,jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0,jstr(argjson,"uuid"))); return(LP_autobuy(ctx,fomo,myipaddr,pubsock,base,rel,price,vol,jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0,jstr(argjson,"uuid"),jint(argjson,"fill"),jint(argjson,"gtc")));
} else return(clonestr("{\"error\":\"no price set\"}")); } else return(clonestr("{\"error\":\"no price set\"}"));
} }
else if ( strcmp(method,"sell") == 0 ) else if ( strcmp(method,"sell") == 0 )
@ -528,7 +587,7 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
} else vol = jdouble(argjson,"basevolume"); } else vol = jdouble(argjson,"basevolume");
if ( price > SMALLVAL ) if ( price > SMALLVAL )
{ {
return(LP_autobuy(ctx,fomo,myipaddr,pubsock,rel,base,1./price,vol,jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0,jstr(argjson,"uuid"))); return(LP_autobuy(ctx,fomo,myipaddr,pubsock,rel,base,1./price,vol,jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0,jstr(argjson,"uuid"),jint(argjson,"fill"),jint(argjson,"gtc")));
} else return(clonestr("{\"error\":\"no price set\"}")); } else return(clonestr("{\"error\":\"no price set\"}"));
} }
} }
@ -553,12 +612,35 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
jaddstr(retjson,"coin",coin); jaddstr(retjson,"coin",coin);
return(jprint(retjson,1)); return(jprint(retjson,1));
} }
#ifndef NOTETOMIC
if (strcmp(coin, "ETOMIC") == 0 && LP_RTsmartbalance(ptr) < 20 * SATOSHIDEN) {
if (get_etomic_from_faucet(ptr->smartaddr) != 1) {
return(clonestr("{\"error\":\"Could not get ETOMIC from faucet!\"}"));
}
}
if (ptr->etomic[0] != 0) {
if (isValidAddress(ptr->etomic) == 0) {
return(clonestr("{\"error\":\"'etomic' field is not valid address!\"}"));
}
struct iguana_info *etomic_coin = LP_coinsearch("ETOMIC");
if (etomic_coin->inactive != 0) {
return(clonestr("{\"error\":\"Enable ETOMIC first to use ETH/ERC20!\"}"));
}
if (ptr->decimals == 0 && strcmp(coin, "ETH") != 0) {
ptr->decimals = getErc20DecimalsZeroOnError(ptr->etomic);
if (ptr->decimals == 0) {
return(clonestr("{\"error\":\"Could not get token decimals or token has zero decimals which is not supported!\"}"));
}
}
}
#endif
if ( LP_conflicts_find(ptr) == 0 ) if ( LP_conflicts_find(ptr) == 0 )
{ {
cJSON *array; cJSON *array;
ptr->inactive = 0; ptr->inactive = 0;
if ( ptr->smartaddr[0] != 0 )
LP_unspents_load(coin,ptr->smartaddr);
LP_unspents_load(coin,ptr->smartaddr); LP_unspents_load(coin,ptr->smartaddr);
if ( strcmp(ptr->symbol,"KMD") == 0 ) if ( strcmp(ptr->symbol,"KMD") == 0 )
LP_importaddress("KMD",BOTS_BONDADDRESS); LP_importaddress("KMD",BOTS_BONDADDRESS);
@ -664,6 +746,10 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
return(LP_txblast(ptr,argjson)); return(LP_txblast(ptr,argjson));
else return(clonestr("{\"error\":\"cant find coind\"}")); else return(clonestr("{\"error\":\"cant find coind\"}"));
} }
else if ( strcmp(method,"movecoinbases") == 0 )
{
return(LP_movecoinbases(coin));
}
else if ( strcmp(method,"withdraw") == 0 ) else if ( strcmp(method,"withdraw") == 0 )
{ {
if ( (ptr= LP_coinsearch(coin)) != 0 ) if ( (ptr= LP_coinsearch(coin)) != 0 )
@ -766,7 +852,7 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
return(jprint(retjson,1)); return(jprint(retjson,1));
} }
else if ( strcmp(method,"myprices") == 0 ) else if ( strcmp(method,"myprices") == 0 )
return(LP_myprices()); return(LP_myprices(1));
else if ( strcmp(method,"trust") == 0 ) else if ( strcmp(method,"trust") == 0 )
return(LP_pubkey_trustset(jbits256(argjson,"pubkey"),jint(argjson,"trust"))); return(LP_pubkey_trustset(jbits256(argjson,"pubkey"),jint(argjson,"trust")));
else if ( strcmp(method,"trusted") == 0 ) else if ( strcmp(method,"trusted") == 0 )
@ -827,14 +913,14 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
double price,bid,ask; double price,bid,ask;
if ( strcmp(method,"getprice") == 0 ) if ( strcmp(method,"getprice") == 0 )
{ {
ask = LP_price(base,rel); ask = LP_price(1,base,rel);
if ( (bid= LP_price(rel,base)) > SMALLVAL ) if ( (bid= LP_price(1,rel,base)) > SMALLVAL )
bid = 1./bid; bid = 1./bid;
} }
else else
{ {
ask = LP_getmyprice(base,rel); ask = LP_getmyprice(1,base,rel);
if ( (bid= LP_getmyprice(rel,base)) > SMALLVAL ) if ( (bid= LP_getmyprice(1,rel,base)) > SMALLVAL )
bid = 1./bid; bid = 1./bid;
} }
price = _pairaved(bid,ask); price = _pairaved(bid,ask);

214
iguana/exchanges/LP_etomic.c

@ -22,6 +22,9 @@
// Created by artem on 24.01.18. // Created by artem on 24.01.18.
// //
#include "LP_etomic.h" #include "LP_etomic.h"
#define ALICE_PAYMENT_SENT 1
#define BOB_DEPOSIT_SENT 1
#define BOB_PAYMENT_SENT 1
int32_t LP_etomic_wait_for_confirmation(char *txId) int32_t LP_etomic_wait_for_confirmation(char *txId)
{ {
@ -38,13 +41,16 @@ void LP_etomic_pubkeystr_to_addr(char *pubkey, char *output)
char *LP_etomicalice_send_fee(struct basilisk_swap *swap) char *LP_etomicalice_send_fee(struct basilisk_swap *swap)
{ {
char amount[100], secretKey[70], dexaddr[50]; char amount[100], secretKey[70], dexaddr[50];
satoshisToWei(amount, swap->myfee.I.amount); satoshisToWei(amount, LP_DEXFEE(swap->I.alicerealsat));
swap->myfee.I.eth_amount = LP_DEXFEE(swap->I.alicerealsat);
uint8arrayToHex(secretKey, swap->persistent_privkey.bytes, 32); uint8arrayToHex(secretKey, swap->persistent_privkey.bytes, 32);
LP_etomic_pubkeystr_to_addr(INSTANTDEX_PUBKEY, dexaddr); LP_etomic_pubkeystr_to_addr(INSTANTDEX_PUBKEY, dexaddr);
if (strcmp(swap->I.alicestr,"ETH") == 0 ) { if (strcmp(swap->I.alicestr,"ETH") == 0 ) {
return(sendEth(dexaddr, amount, secretKey, 1)); return(sendEth(dexaddr, amount, secretKey, 1, 0, 0, 1));
} else { } else {
return(sendErc20(swap->I.alicetomic, dexaddr, amount, secretKey, 1)); struct iguana_info *alicecoin = LP_coinfind(swap->I.alicestr);
return(sendErc20(swap->I.alicetomic, dexaddr, amount, secretKey, 1, 0, 0, 1, alicecoin->decimals));
} }
} }
@ -55,7 +61,7 @@ uint8_t LP_etomic_verify_alice_fee(struct basilisk_swap *swap)
return(0); return(0);
} }
EthTxData data = getEthTxData(swap->otherfee.I.ethTxid); EthTxData data = getEthTxData(swap->otherfee.I.ethTxid);
if (strcmp(data.from, swap->I.etomicdest) != 0) { if (compareAddresses(data.from, swap->I.etomicdest) == 0) {
printf("Alice fee tx %s was sent from wrong address %s\n", swap->otherfee.I.ethTxid, data.from); printf("Alice fee tx %s was sent from wrong address %s\n", swap->otherfee.I.ethTxid, data.from);
return(0); return(0);
} }
@ -63,31 +69,33 @@ uint8_t LP_etomic_verify_alice_fee(struct basilisk_swap *swap)
char dexaddr[50]; char dexaddr[50];
LP_etomic_pubkeystr_to_addr(INSTANTDEX_PUBKEY, dexaddr); LP_etomic_pubkeystr_to_addr(INSTANTDEX_PUBKEY, dexaddr);
if ( strcmp(swap->I.alicestr,"ETH") == 0 ) { if ( strcmp(swap->I.alicestr,"ETH") == 0 ) {
if (strcmp(data.to, dexaddr) != 0) { if (compareAddresses(data.to, dexaddr) == 0) {
printf("Alice fee %s was sent to wrong address %s\n", swap->otherfee.I.ethTxid, data.to); printf("Alice fee %s was sent to wrong address %s\n", swap->otherfee.I.ethTxid, data.to);
return(0); return(0);
} }
uint64_t txValue = weiToSatoshi(data.valueHex); uint64_t txValue = weiToSatoshi(data.valueHex);
if (txValue != swap->otherfee.I.amount) { if (txValue != LP_DEXFEE(swap->I.alicerealsat)) {
printf("Alice fee %s amount %" PRIu64 " is not equal to expected %" PRIu64 "\n", swap->otherfee.I.ethTxid, txValue, swap->otherfee.I.amount); printf("Alice fee %s amount %" PRIu64 " is not equal to expected %" PRId64 "\n", swap->otherfee.I.ethTxid, txValue, LP_DEXFEE(swap->I.alicerealsat));
return(0); return(0);
} }
return(1); return(1);
} else { } else {
if (strcmp(data.to, swap->I.alicetomic) != 0) { struct iguana_info *alicecoin = LP_coinfind(swap->I.alicestr);
if (compareAddresses(data.to, swap->I.alicetomic) == 0) {
printf("Alice ERC20 fee %s token address %s is not equal to expected %s\n", swap->otherfee.I.ethTxid, data.to, swap->I.alicetomic); 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); return(0);
} }
char weiAmount[70]; char weiAmount[70];
satoshisToWei(weiAmount, swap->otherfee.I.amount); satoshisToWei(weiAmount, LP_DEXFEE(swap->I.alicerealsat));
return(verifyAliceErc20FeeData(swap->I.alicetomic, dexaddr, weiAmount, data.input)); return(verifyAliceErc20FeeData(swap->I.alicetomic, dexaddr, weiAmount, data.input, alicecoin->decimals));
} }
} }
char *LP_etomicalice_send_payment(struct basilisk_swap *swap) char *LP_etomicalice_send_payment(struct basilisk_swap *swap)
{ {
AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20; BasicTxData txData; AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20; BasicTxData txData;
swap->alicepayment.I.eth_amount = swap->I.alicerealsat;
// set input and txData fields from the swap data structure // set input and txData fields from the swap data structure
memset(&txData,0,sizeof(txData)); memset(&txData,0,sizeof(txData));
if ( strcmp(swap->I.alicestr,"ETH") == 0 ) if ( strcmp(swap->I.alicestr,"ETH") == 0 )
@ -100,28 +108,31 @@ char *LP_etomicalice_send_payment(struct basilisk_swap *swap)
strcpy(txData.from, swap->I.etomicdest); strcpy(txData.from, swap->I.etomicdest);
strcpy(txData.to, ETOMIC_ALICECONTRACT); strcpy(txData.to, ETOMIC_ALICECONTRACT);
satoshisToWei(txData.amount, swap->I.alicesatoshis); satoshisToWei(txData.amount, swap->I.alicerealsat);
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
return(aliceSendsEthPayment(input,txData)); return(aliceSendsEthPayment(input,txData));
} }
else else
{ {
struct iguana_info *alicecoin = LP_coinfind(swap->I.alicestr);
memset(&input20,0,sizeof(input20)); memset(&input20,0,sizeof(input20));
strcpy(input20.bobAddress, swap->I.etomicsrc); strcpy(input20.bobAddress, swap->I.etomicsrc);
uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20); uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20);
uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20); uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20);
uint8arrayToHex(input20.dealId, swap->alicepayment.I.actualtxid.bytes, 32); uint8arrayToHex(input20.dealId, swap->alicepayment.I.actualtxid.bytes, 32);
strcpy(input20.tokenAddress, swap->I.alicetomic); strcpy(input20.tokenAddress, swap->I.alicetomic);
satoshisToWei(input20.amount, swap->I.alicesatoshis); satoshisToWei(input20.amount, swap->I.alicerealsat);
input20.decimals = alicecoin->decimals;
strcpy(txData.from, swap->I.etomicdest); strcpy(txData.from, swap->I.etomicdest);
strcpy(txData.to, ETOMIC_ALICECONTRACT); strcpy(txData.to, ETOMIC_ALICECONTRACT);
strcpy(txData.amount, "0"); strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
uint64_t allowance = getErc20Allowance(swap->I.etomicdest, ETOMIC_ALICECONTRACT, swap->I.alicetomic); uint64_t allowance = getErc20Allowance(swap->I.etomicdest, ETOMIC_ALICECONTRACT, swap->I.alicetomic, alicecoin->decimals);
if (allowance < swap->I.alicesatoshis) { if (allowance < swap->I.alicerealsat) {
printf("Alice token allowance is too low, setting new allowance\n"); printf("Alice token allowance is too low, setting new allowance\n");
ApproveErc20Input approveErc20Input; ApproveErc20Input approveErc20Input;
strcpy(approveErc20Input.tokenAddress, swap->I.alicetomic); strcpy(approveErc20Input.tokenAddress, swap->I.alicetomic);
@ -149,20 +160,19 @@ uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId)
return(0); return(0);
} }
EthTxData data = getEthTxData(txId); EthTxData data = getEthTxData(txId);
if (strcmp(data.to, ETOMIC_ALICECONTRACT) != 0) { if (compareAddresses(data.to, ETOMIC_ALICECONTRACT) == 0) {
printf("Alice payment %s was sent to wrong address %s\n", txId, data.to); printf("Alice payment %s was sent to wrong address %s\n", txId, data.to);
return(0); return(0);
} }
if (strcmp(data.from, swap->I.etomicdest) != 0) { if (compareAddresses(data.from, swap->I.etomicdest) == 0) {
printf("Alice payment %s was done from wrong address %s\n", txId, data.from); printf("Alice payment %s was done from wrong address %s\n", txId, data.from);
return(0); return(0);
} }
AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20; AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20;
if ( strcmp(swap->I.alicestr,"ETH") == 0 ) { if ( strcmp(swap->I.alicestr,"ETH") == 0 ) {
uint64_t paymentAmount = weiToSatoshi(data.valueHex); uint64_t paymentAmount = weiToSatoshi(data.valueHex);
if (paymentAmount != swap->I.alicesatoshis) { if (paymentAmount != swap->I.alicerealsat) {
printf("Alice payment amount %" PRIu64 " does not match expected %" PRIu64 "\n", paymentAmount, swap->I.alicesatoshis); printf("Alice payment amount %" PRIu64 " does not match expected %" PRIu64 "\n", paymentAmount, swap->I.alicerealsat);
return(0); return(0);
} }
memset(&input,0,sizeof(input)); memset(&input,0,sizeof(input));
@ -173,13 +183,16 @@ uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId)
return(verifyAliceEthPaymentData(input, data.input)); return(verifyAliceEthPaymentData(input, data.input));
} else { } else {
struct iguana_info *alicecoin = LP_coinfind(swap->I.alicestr);
memset(&input20,0,sizeof(input20)); memset(&input20,0,sizeof(input20));
strcpy(input20.bobAddress, swap->I.etomicsrc); strcpy(input20.bobAddress, swap->I.etomicsrc);
uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20); uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20);
uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20); uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20);
uint8arrayToHex(input20.dealId, swap->alicepayment.I.actualtxid.bytes, 32); uint8arrayToHex(input20.dealId, swap->alicepayment.I.actualtxid.bytes, 32);
strcpy(input20.tokenAddress, swap->I.alicetomic); strcpy(input20.tokenAddress, swap->I.alicetomic);
satoshisToWei(input20.amount, swap->I.alicesatoshis); satoshisToWei(input20.amount, swap->I.alicerealsat);
input20.decimals = alicecoin->decimals;
return(verifyAliceErc20PaymentData(input20, data.input)); return(verifyAliceErc20PaymentData(input20, data.input));
} }
@ -187,11 +200,11 @@ uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId)
char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap) char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap)
{ {
if (waitForConfirmation(swap->alicePaymentEthTx) < 0) { if (waitForConfirmation(swap->eth_tx_ids[BASILISK_ALICEPAYMENT]) < 0) {
printf("Alice ETH payment %s is not found, can't reclaim\n", swap->alicePaymentEthTx); printf("Alice ETH payment %s is not found, can't reclaim\n", swap->eth_tx_ids[BASILISK_ALICEPAYMENT]);
return NULL; return NULL;
} }
EthTxReceipt receipt = getEthTxReceipt(swap->alicePaymentEthTx); EthTxReceipt receipt = getEthTxReceipt(swap->eth_tx_ids[BASILISK_ALICEPAYMENT]);
if (strcmp(receipt.status, "0x1") != 0) { if (strcmp(receipt.status, "0x1") != 0) {
printf("Alice payment receipt status failed, can't reclaim\n"); printf("Alice payment receipt status failed, can't reclaim\n");
return NULL; return NULL;
@ -201,13 +214,18 @@ char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap)
memset(&txData,0,sizeof(txData)); memset(&txData,0,sizeof(txData));
memset(&input,0,sizeof(input)); memset(&input,0,sizeof(input));
struct iguana_info *ecoin; struct iguana_info *ecoin, *alice_coin;
bits256 privkey; bits256 privkey;
ecoin = LP_coinfind("ETOMIC"); ecoin = LP_coinfind("ETOMIC");
alice_coin = LP_coinfind(swap->dest);
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
uint8arrayToHex(input.dealId, swap->txids[BASILISK_ALICEPAYMENT].bytes, 32); uint8arrayToHex(input.dealId, swap->txids[BASILISK_ALICEPAYMENT].bytes, 32);
satoshisToWei(input.amount, swap->destamount); if (alicePaymentStatus(input.dealId + 2) != ALICE_PAYMENT_SENT) {
printf("Alice payment smart contract status check failed, can't spend\n");
return NULL;
}
satoshisToWei(input.amount, swap->alicerealsat);
if (swap->alicetomic[0] != 0) { if (swap->alicetomic[0] != 0) {
strcpy(input.tokenAddress, swap->alicetomic); strcpy(input.tokenAddress, swap->alicetomic);
@ -223,6 +241,8 @@ char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap)
} }
uint8arrayToHex(input.bobSecret, invertedSecret.bytes, 32); uint8arrayToHex(input.bobSecret, invertedSecret.bytes, 32);
input.decimals = alice_coin->decimals;
strcpy(txData.from, swap->etomicdest); strcpy(txData.from, swap->etomicdest);
strcpy(txData.to, ETOMIC_ALICECONTRACT); strcpy(txData.to, ETOMIC_ALICECONTRACT);
strcpy(txData.amount, "0"); strcpy(txData.amount, "0");
@ -232,11 +252,11 @@ char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap)
char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap) char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap)
{ {
if (waitForConfirmation(swap->alicePaymentEthTx) < 0) { if (waitForConfirmation(swap->eth_tx_ids[BASILISK_ALICEPAYMENT]) < 0) {
printf("Alice ETH payment %s is not found, can't spend\n", swap->alicePaymentEthTx); printf("Alice ETH payment %s is not found, can't spend\n", swap->eth_tx_ids[BASILISK_ALICEPAYMENT]);
return NULL; return NULL;
} }
EthTxReceipt receipt = getEthTxReceipt(swap->alicePaymentEthTx); EthTxReceipt receipt = getEthTxReceipt(swap->eth_tx_ids[BASILISK_ALICEPAYMENT]);
if (strcmp(receipt.status, "0x1") != 0) { if (strcmp(receipt.status, "0x1") != 0) {
printf("Alice payment receipt status failed, can't spend\n"); printf("Alice payment receipt status failed, can't spend\n");
return NULL; return NULL;
@ -253,7 +273,12 @@ char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap)
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
uint8arrayToHex(input.dealId, swap->txids[BASILISK_ALICEPAYMENT].bytes, 32); uint8arrayToHex(input.dealId, swap->txids[BASILISK_ALICEPAYMENT].bytes, 32);
satoshisToWei(input.amount, swap->destamount); if (alicePaymentStatus(input.dealId + 2) != ALICE_PAYMENT_SENT) {
printf("Alice payment smart contract status check failed, can't spend\n");
return NULL;
}
satoshisToWei(input.amount, swap->alicerealsat);
if (swap->alicetomic[0] != 0) { if (swap->alicetomic[0] != 0) {
strcpy(input.tokenAddress, swap->alicetomic); strcpy(input.tokenAddress, swap->alicetomic);
@ -268,6 +293,8 @@ char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap)
} }
uint8arrayToHex(input.aliceSecret, invertedSecret.bytes, 32); uint8arrayToHex(input.aliceSecret, invertedSecret.bytes, 32);
uint8arrayToHex(input.bobHash, swap->secretBn, 20); uint8arrayToHex(input.bobHash, swap->secretBn, 20);
struct iguana_info *alice_coin = LP_coinfind(swap->dest);
input.decimals = alice_coin->decimals;
strcpy(txData.from, swap->etomicsrc); strcpy(txData.from, swap->etomicsrc);
strcpy(txData.to, ETOMIC_ALICECONTRACT); strcpy(txData.to, ETOMIC_ALICECONTRACT);
@ -292,24 +319,27 @@ char *LP_etomicbob_sends_deposit(struct basilisk_swap *swap)
strcpy(txData.from, swap->I.etomicsrc); strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.to, ETOMIC_BOBCONTRACT);
satoshisToWei(txData.amount, swap->bobdeposit.I.amount); satoshisToWei(txData.amount, LP_DEPOSITSATOSHIS(swap->I.bobrealsat));
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
return bobSendsEthDeposit(input, txData); return bobSendsEthDeposit(input, txData);
} else { } else {
struct iguana_info *bobcoin = LP_coinfind(swap->I.bobstr);
uint8arrayToHex(input20.depositId, swap->bobdeposit.I.actualtxid.bytes, 32); uint8arrayToHex(input20.depositId, swap->bobdeposit.I.actualtxid.bytes, 32);
strcpy(input20.aliceAddress, swap->I.etomicdest); strcpy(input20.aliceAddress, swap->I.etomicdest);
uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20); uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20);
satoshisToWei(input20.amount, swap->bobdeposit.I.amount); satoshisToWei(input20.amount, LP_DEPOSITSATOSHIS(swap->I.bobrealsat));
strcpy(input20.tokenAddress, swap->I.bobtomic); strcpy(input20.tokenAddress, swap->I.bobtomic);
input20.lockTime = swap->bobdeposit.I.locktime; input20.lockTime = swap->bobdeposit.I.locktime;
input20.decimals = bobcoin->decimals;
strcpy(txData.from, swap->I.etomicsrc); strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.to, ETOMIC_BOBCONTRACT);
strcpy(txData.amount, "0"); strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic); uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic, bobcoin->decimals);
if (allowance < swap->bobdeposit.I.amount) { if (allowance < LP_DEPOSITSATOSHIS(swap->I.bobrealsat)) {
printf("Bob token allowance is too low, setting new allowance\n"); printf("Bob token allowance is too low, setting new allowance\n");
ApproveErc20Input approveErc20Input; ApproveErc20Input approveErc20Input;
strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic); strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic);
@ -337,11 +367,11 @@ uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId)
return(0); return(0);
} }
EthTxData data = getEthTxData(txId); EthTxData data = getEthTxData(txId);
if (strcmp(data.to, ETOMIC_BOBCONTRACT) != 0) { if (compareAddresses(data.to, ETOMIC_BOBCONTRACT) == 0) {
printf("Bob deposit txid %s was sent to wrong address %s\n", txId, data.to); printf("Bob deposit txid %s was sent to wrong address %s\n", txId, data.to);
return(0); return(0);
} }
if (strcmp(data.from, swap->I.etomicsrc) != 0) { if (compareAddresses(data.from, swap->I.etomicsrc) == 0) {
printf("Bob deposit txid %s was sent from wrong address %s\n", txId, data.from); printf("Bob deposit txid %s was sent from wrong address %s\n", txId, data.from);
return(0); return(0);
} }
@ -351,8 +381,8 @@ uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId)
memset(&input20,0,sizeof(input20)); memset(&input20,0,sizeof(input20));
if ( strcmp(swap->I.bobstr,"ETH") == 0 ) { if ( strcmp(swap->I.bobstr,"ETH") == 0 ) {
uint64_t depositAmount = weiToSatoshi(data.valueHex); uint64_t depositAmount = weiToSatoshi(data.valueHex);
if (depositAmount != swap->bobdeposit.I.amount) { if (depositAmount != LP_DEPOSITSATOSHIS(swap->I.bobrealsat)) {
printf("Bob deposit %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, depositAmount, swap->bobdeposit.I.amount); printf("Bob deposit %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, depositAmount, LP_DEPOSITSATOSHIS(swap->I.bobrealsat));
return(0); return(0);
} }
uint8arrayToHex(input.depositId, swap->bobdeposit.I.actualtxid.bytes, 32); uint8arrayToHex(input.depositId, swap->bobdeposit.I.actualtxid.bytes, 32);
@ -362,12 +392,15 @@ uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId)
return verifyBobEthDepositData(input, data.input); return verifyBobEthDepositData(input, data.input);
} else { } else {
struct iguana_info *bobcoin = LP_coinfind(swap->I.bobstr);
uint8arrayToHex(input20.depositId, swap->bobdeposit.I.actualtxid.bytes, 32); uint8arrayToHex(input20.depositId, swap->bobdeposit.I.actualtxid.bytes, 32);
strcpy(input20.aliceAddress, swap->I.etomicdest); strcpy(input20.aliceAddress, swap->I.etomicdest);
uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20); uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20);
satoshisToWei(input20.amount, swap->bobdeposit.I.amount); satoshisToWei(input20.amount, LP_DEPOSITSATOSHIS(swap->I.bobrealsat));
strcpy(input20.tokenAddress, swap->I.bobtomic); strcpy(input20.tokenAddress, swap->I.bobtomic);
input20.lockTime = swap->bobdeposit.I.locktime; input20.lockTime = swap->bobdeposit.I.locktime;
input20.decimals = bobcoin->decimals;
return verifyBobErc20DepositData(input20, data.input); return verifyBobErc20DepositData(input20, data.input);
} }
@ -375,8 +408,8 @@ uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId)
char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap) char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap)
{ {
if (waitForConfirmation(swap->bobDepositEthTx) < 0) { if (waitForConfirmation(swap->eth_tx_ids[BASILISK_BOBDEPOSIT]) < 0) {
printf("Bob deposit %s is not found, can't refund\n", swap->bobDepositEthTx); printf("Bob deposit %s is not found, can't refund\n", swap->eth_tx_ids[BASILISK_BOBDEPOSIT]);
return NULL; return NULL;
} }
BobRefundsDepositInput input; BobRefundsDepositInput input;
@ -384,17 +417,23 @@ char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap)
memset(&txData,0,sizeof(txData)); memset(&txData,0,sizeof(txData));
memset(&input,0,sizeof(input)); memset(&input,0,sizeof(input));
struct iguana_info *ecoin; struct iguana_info *ecoin, *bobcoin;
bits256 privkey; bits256 privkey;
ecoin = LP_coinfind("ETOMIC"); ecoin = LP_coinfind("ETOMIC");
bobcoin = LP_coinfind(swap->src);
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
EthTxReceipt receipt = getEthTxReceipt(swap->bobDepositEthTx); EthTxReceipt receipt = getEthTxReceipt(swap->eth_tx_ids[BASILISK_BOBDEPOSIT]);
if (strcmp(receipt.status, "0x1") != 0) { if (strcmp(receipt.status, "0x1") != 0) {
printf("Bob deposit %s receipt status failed, can't refund\n", swap->bobDepositEthTx); printf("Bob deposit %s receipt status failed, can't refund\n", swap->eth_tx_ids[BASILISK_BOBDEPOSIT]);
return NULL; return NULL;
} }
uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32); uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32);
if (bobDepositStatus(input.depositId + 2) != BOB_DEPOSIT_SENT) {
printf("Bob deposit smart contract status check failed, can't claim\n");
return NULL;
}
strcpy(input.aliceAddress, swap->etomicdest); strcpy(input.aliceAddress, swap->etomicdest);
bits256 invertedSecret; bits256 invertedSecret;
@ -409,7 +448,8 @@ char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap)
} else { } else {
strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000");
} }
satoshisToWei(input.amount, swap->values[BASILISK_BOBDEPOSIT]); satoshisToWei(input.amount, LP_DEPOSITSATOSHIS(swap->bobrealsat));
input.decimals = bobcoin->decimals;
strcpy(txData.from, swap->etomicsrc); strcpy(txData.from, swap->etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.to, ETOMIC_BOBCONTRACT);
@ -435,24 +475,27 @@ char *LP_etomicbob_sends_payment(struct basilisk_swap *swap)
strcpy(txData.from, swap->I.etomicsrc); strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.to, ETOMIC_BOBCONTRACT);
satoshisToWei(txData.amount, swap->bobpayment.I.amount); satoshisToWei(txData.amount, swap->I.bobrealsat);
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
return bobSendsEthPayment(input, txData); return bobSendsEthPayment(input, txData);
} else { } else {
struct iguana_info *bobcoin = LP_coinfind(swap->I.bobstr);
uint8arrayToHex(input20.paymentId, swap->bobpayment.I.actualtxid.bytes, 32); uint8arrayToHex(input20.paymentId, swap->bobpayment.I.actualtxid.bytes, 32);
strcpy(input20.aliceAddress, swap->I.etomicdest); strcpy(input20.aliceAddress, swap->I.etomicdest);
uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20); uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20);
satoshisToWei(input20.amount, swap->bobpayment.I.amount); satoshisToWei(input20.amount, swap->I.bobrealsat);
strcpy(input20.tokenAddress, swap->I.bobtomic); strcpy(input20.tokenAddress, swap->I.bobtomic);
input20.lockTime = swap->bobpayment.I.locktime; input20.lockTime = swap->bobpayment.I.locktime;
input20.decimals = bobcoin->decimals;
strcpy(txData.from, swap->I.etomicsrc); strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.to, ETOMIC_BOBCONTRACT);
strcpy(txData.amount, "0"); strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic); uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic, bobcoin->decimals);
if (allowance < swap->bobpayment.I.amount) { if (allowance < swap->I.bobrealsat) {
printf("Bob token allowance is too low, setting new allowance\n"); printf("Bob token allowance is too low, setting new allowance\n");
ApproveErc20Input approveErc20Input; ApproveErc20Input approveErc20Input;
strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic); strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic);
@ -480,21 +523,20 @@ uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId)
return 0; return 0;
} }
EthTxData data = getEthTxData(txId); EthTxData data = getEthTxData(txId);
if (strcmp(data.to, ETOMIC_BOBCONTRACT) != 0) { if (compareAddresses(data.to, ETOMIC_BOBCONTRACT) == 0) {
printf("Bob payment %s was sent to wrong address %s\n", txId, data.to); printf("Bob payment %s was sent to wrong address %s\n", txId, data.to);
} }
if (strcmp(data.from, swap->I.etomicsrc) != 0) { if (compareAddresses(data.from, swap->I.etomicsrc) == 0) {
printf("Bob payment %s was sent from wrong address %s\n", txId, data.from); printf("Bob payment %s was sent from wrong address %s\n", txId, data.from);
} }
BobSendsEthPaymentInput input; BobSendsEthPaymentInput input;
BobSendsErc20PaymentInput input20; BobSendsErc20PaymentInput input20;
memset(&input,0,sizeof(input)); memset(&input,0,sizeof(input));
memset(&input20,0,sizeof(input20)); memset(&input20,0,sizeof(input20));
if ( strcmp(swap->I.bobstr,"ETH") == 0 ) { if ( strcmp(swap->I.bobstr,"ETH") == 0 ) {
uint64_t paymentAmount = weiToSatoshi(data.valueHex); uint64_t paymentAmount = weiToSatoshi(data.valueHex);
if (paymentAmount != swap->bobpayment.I.amount) { if (paymentAmount != swap->I.bobrealsat) {
printf("Bob payment %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, paymentAmount, swap->bobpayment.I.amount); printf("Bob payment %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, paymentAmount, swap->I.bobrealsat);
return(0); return(0);
} }
uint8arrayToHex(input.paymentId, swap->bobpayment.I.actualtxid.bytes, 32); uint8arrayToHex(input.paymentId, swap->bobpayment.I.actualtxid.bytes, 32);
@ -504,12 +546,15 @@ uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId)
return verifyBobEthPaymentData(input, data.input); return verifyBobEthPaymentData(input, data.input);
} else { } else {
struct iguana_info *bobcoin = LP_coinfind(swap->I.bobstr);
uint8arrayToHex(input20.paymentId, swap->bobpayment.I.actualtxid.bytes, 32); uint8arrayToHex(input20.paymentId, swap->bobpayment.I.actualtxid.bytes, 32);
strcpy(input20.aliceAddress, swap->I.etomicdest); strcpy(input20.aliceAddress, swap->I.etomicdest);
uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20); uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20);
satoshisToWei(input20.amount, swap->bobpayment.I.amount); satoshisToWei(input20.amount, swap->I.bobrealsat);
strcpy(input20.tokenAddress, swap->I.bobtomic); strcpy(input20.tokenAddress, swap->I.bobtomic);
input20.lockTime = swap->bobpayment.I.locktime; input20.lockTime = swap->bobpayment.I.locktime;
input20.decimals = bobcoin->decimals;
return verifyBobErc20PaymentData(input20, data.input); return verifyBobErc20PaymentData(input20, data.input);
} }
@ -517,8 +562,8 @@ uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId)
char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap) char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap)
{ {
if (waitForConfirmation(swap->bobPaymentEthTx) < 0) { if (waitForConfirmation(swap->eth_tx_ids[BASILISK_BOBPAYMENT]) < 0) {
printf("Bob payment %s is not found, can't reclaim\n", swap->bobPaymentEthTx); printf("Bob payment %s is not found, can't reclaim\n", swap->eth_tx_ids[BASILISK_BOBPAYMENT]);
return NULL; return NULL;
} }
BobReclaimsBobPaymentInput input; BobReclaimsBobPaymentInput input;
@ -526,17 +571,22 @@ char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap)
memset(&txData,0,sizeof(txData)); memset(&txData,0,sizeof(txData));
memset(&input,0,sizeof(input)); memset(&input,0,sizeof(input));
struct iguana_info *ecoin; struct iguana_info *ecoin, *bobcoin;
bits256 privkey; bits256 privkey;
ecoin = LP_coinfind("ETOMIC"); ecoin = LP_coinfind("ETOMIC");
bobcoin = LP_coinfind(swap->src);
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
EthTxReceipt receipt = getEthTxReceipt(swap->bobPaymentEthTx); EthTxReceipt receipt = getEthTxReceipt(swap->eth_tx_ids[BASILISK_BOBPAYMENT]);
if (strcmp(receipt.status, "0x1") != 0) { if (strcmp(receipt.status, "0x1") != 0) {
printf("Bob payment receipt status failed, can't reclaim\n"); printf("Bob payment receipt status failed, can't reclaim\n");
return NULL; return NULL;
} }
uint8arrayToHex(input.paymentId, swap->txids[BASILISK_BOBPAYMENT].bytes, 32); uint8arrayToHex(input.paymentId, swap->txids[BASILISK_BOBPAYMENT].bytes, 32);
if (bobPaymentStatus(input.paymentId + 2) != BOB_PAYMENT_SENT) {
printf("Bob payment smart contract status check failed, can't spend\n");
return NULL;
}
strcpy(input.aliceAddress, swap->etomicdest); strcpy(input.aliceAddress, swap->etomicdest);
uint8arrayToHex(input.aliceHash, swap->secretAm, 20); uint8arrayToHex(input.aliceHash, swap->secretAm, 20);
@ -545,7 +595,8 @@ char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap)
} else { } else {
strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000"); strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000");
} }
satoshisToWei(input.amount, swap->values[BASILISK_BOBPAYMENT]); satoshisToWei(input.amount, swap->bobrealsat);
input.decimals = bobcoin->decimals;
strcpy(txData.from, swap->etomicsrc); strcpy(txData.from, swap->etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.to, ETOMIC_BOBCONTRACT);
@ -556,8 +607,8 @@ char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap)
char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap) char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap)
{ {
if (waitForConfirmation(swap->bobPaymentEthTx) < 0) { if (waitForConfirmation(swap->eth_tx_ids[BASILISK_BOBPAYMENT]) < 0) {
printf("Bob payment %s is not found, can't spend\n", swap->bobPaymentEthTx); printf("Bob payment %s is not found, can't spend\n", swap->eth_tx_ids[BASILISK_BOBPAYMENT]);
return NULL; return NULL;
} }
AliceSpendsBobPaymentInput input; AliceSpendsBobPaymentInput input;
@ -565,18 +616,23 @@ char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap)
memset(&txData,0,sizeof(txData)); memset(&txData,0,sizeof(txData));
memset(&input,0,sizeof(input)); memset(&input,0,sizeof(input));
EthTxReceipt receipt = getEthTxReceipt(swap->bobPaymentEthTx); EthTxReceipt receipt = getEthTxReceipt(swap->eth_tx_ids[BASILISK_BOBPAYMENT]);
if (strcmp(receipt.status, "0x1") != 0) { if (strcmp(receipt.status, "0x1") != 0) {
printf("Bob payment %s receipt status failed, can't spend\n", swap->bobPaymentEthTx); printf("Bob payment %s receipt status failed, can't spend\n", swap->eth_tx_ids[BASILISK_BOBPAYMENT]);
return NULL; return NULL;
} }
struct iguana_info *ecoin; struct iguana_info *ecoin, *bobcoin;
bits256 privkey; bits256 privkey;
ecoin = LP_coinfind("ETOMIC"); ecoin = LP_coinfind("ETOMIC");
bobcoin = LP_coinfind(swap->src);
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
uint8arrayToHex(input.paymentId, swap->txids[BASILISK_BOBPAYMENT].bytes, 32); uint8arrayToHex(input.paymentId, swap->txids[BASILISK_BOBPAYMENT].bytes, 32);
satoshisToWei(input.amount, swap->values[BASILISK_BOBPAYMENT]); if (bobPaymentStatus(input.paymentId + 2) != BOB_PAYMENT_SENT) {
printf("Bob payment smart contract status check failed, can't spend\n");
return NULL;
}
satoshisToWei(input.amount, swap->bobrealsat);
if (swap->bobtomic[0] != 0) { if (swap->bobtomic[0] != 0) {
strcpy(input.tokenAddress, swap->bobtomic); strcpy(input.tokenAddress, swap->bobtomic);
@ -591,6 +647,7 @@ char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap)
invertedSecret.bytes[i] = swap->privAm.bytes[31 - i]; invertedSecret.bytes[i] = swap->privAm.bytes[31 - i];
} }
uint8arrayToHex(input.aliceSecret, invertedSecret.bytes, 32); uint8arrayToHex(input.aliceSecret, invertedSecret.bytes, 32);
input.decimals = bobcoin->decimals;
strcpy(txData.from, swap->etomicdest); strcpy(txData.from, swap->etomicdest);
strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.to, ETOMIC_BOBCONTRACT);
@ -601,8 +658,8 @@ char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap)
char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap) char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap)
{ {
if (waitForConfirmation(swap->bobDepositEthTx) < 0) { if (waitForConfirmation(swap->eth_tx_ids[BASILISK_BOBDEPOSIT]) < 0) {
printf("Bob deposit %s is not found, can't claim\n", swap->bobDepositEthTx); printf("Bob deposit %s is not found, can't claim\n", swap->eth_tx_ids[BASILISK_BOBDEPOSIT]);
return NULL; return NULL;
} }
AliceClaimsBobDepositInput input; AliceClaimsBobDepositInput input;
@ -610,19 +667,25 @@ char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap)
memset(&txData,0,sizeof(txData)); memset(&txData,0,sizeof(txData));
memset(&input,0,sizeof(input)); memset(&input,0,sizeof(input));
EthTxReceipt receipt = getEthTxReceipt(swap->bobDepositEthTx); EthTxReceipt receipt = getEthTxReceipt(swap->eth_tx_ids[BASILISK_BOBDEPOSIT]);
if (strcmp(receipt.status, "0x1") != 0) { if (strcmp(receipt.status, "0x1") != 0) {
printf("Bob deposit receipt status failed, can't claim\n"); printf("Bob deposit receipt status failed, can't claim\n");
return NULL; return NULL;
} }
struct iguana_info *ecoin; struct iguana_info *ecoin, *bobcoin;
bits256 privkey; bits256 privkey;
ecoin = LP_coinfind("ETOMIC"); ecoin = LP_coinfind("ETOMIC");
bobcoin = LP_coinfind(swap->src);
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr); privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32); uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32);
satoshisToWei(input.amount, swap->values[BASILISK_BOBDEPOSIT]); if (bobDepositStatus(input.depositId + 2) != BOB_DEPOSIT_SENT) {
printf("Bob deposit smart contract status check failed, can't claim\n");
return NULL;
}
satoshisToWei(input.amount, LP_DEPOSITSATOSHIS(swap->bobrealsat));
if (swap->bobtomic[0] != 0) { if (swap->bobtomic[0] != 0) {
strcpy(input.tokenAddress, swap->bobtomic); strcpy(input.tokenAddress, swap->bobtomic);
@ -632,6 +695,7 @@ char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap)
strcpy(input.bobAddress, swap->etomicsrc); strcpy(input.bobAddress, swap->etomicsrc);
uint8arrayToHex(input.bobHash, swap->secretBn, 20); uint8arrayToHex(input.bobHash, swap->secretBn, 20);
input.decimals = bobcoin->decimals;
strcpy(txData.from, swap->etomicdest); strcpy(txData.from, swap->etomicdest);
strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.to, ETOMIC_BOBCONTRACT);
@ -702,13 +766,13 @@ int32_t LP_etomic_pub2addr(char *coinaddr,uint8_t pub64[64])
uint8_t LP_etomic_is_empty_tx_id(char *txId) uint8_t LP_etomic_is_empty_tx_id(char *txId)
{ {
if (strcmp(txId, EMPTY_ETH_TX_ID) == 0) { if (txId[0] == 0 || strcmp(txId, EMPTY_ETH_TX_ID) == 0) {
return 1; return 1;
} }
return 0; return 0;
} }
uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr) uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr, int *error)
{ {
if (coin->etomic[0] == 0) { if (coin->etomic[0] == 0) {
printf("Trying to get etomic balance for non-etomic coin %s!", coin->symbol); printf("Trying to get etomic balance for non-etomic coin %s!", coin->symbol);
@ -716,8 +780,8 @@ uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr)
} }
if (strcmp(coin->symbol, "ETH") == 0) { if (strcmp(coin->symbol, "ETH") == 0) {
return getEthBalance(coinaddr); return getEthBalance(coinaddr, error);
} else { } else {
return getErc20BalanceSatoshi(coinaddr, coin->etomic); return getErc20BalanceSatoshi(coinaddr, coin->etomic, coin->decimals, error);
} }
} }

2
iguana/exchanges/LP_etomic.h

@ -49,7 +49,7 @@ int32_t LP_etomic_pub2addr(char *coinaddr,uint8_t pub64[64]);
uint8_t LP_etomic_is_empty_tx_id(char *txId); uint8_t LP_etomic_is_empty_tx_id(char *txId);
uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr); uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr, int *error);
void LP_etomic_pubkeystr_to_addr(char *pubkey, char *output); void LP_etomic_pubkeystr_to_addr(char *pubkey, char *output);

68
iguana/exchanges/LP_include.h

@ -59,7 +59,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
//#define LP_DISABLE_DISTCOMBINE //#define LP_DISABLE_DISTCOMBINE
#define LP_MAXVINS 64 #define LP_MAXVINS 64
#define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) #define LP_HTTP_TIMEOUT 10 // 1 is too small due to edge cases of time(NULL)
#define LP_AUTOTRADE_TIMEOUT 30 #define LP_AUTOTRADE_TIMEOUT 30
#define LP_RESERVETIME (LP_AUTOTRADE_TIMEOUT * 3) #define LP_RESERVETIME (LP_AUTOTRADE_TIMEOUT * 3)
#define ELECTRUM_TIMEOUT 13 #define ELECTRUM_TIMEOUT 13
@ -141,6 +141,10 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#define SIGHASH_FORKID 0x40 #define SIGHASH_FORKID 0x40
#define ZKSNARK_PROOF_SIZE 296 #define ZKSNARK_PROOF_SIZE 296
#define GROTH_PROOF_SIZE 192
#define SAPLING_AUTH_SIG_SIZE 64
#define ENC_CIPHER_SIZE 580
#define OUT_CIPHER_SIZE 80
#define ZCASH_SOLUTION_ELEMENTS 1344 #define ZCASH_SOLUTION_ELEMENTS 1344
#define LP_REQUEST 0 #define LP_REQUEST 0
@ -165,13 +169,17 @@ struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_scrip
struct iguana_msgtx struct iguana_msgtx
{ {
uint32_t version,tx_in,tx_out,lock_time; uint32_t version,version_group_id,tx_in,tx_out,lock_time,expiry_height;
struct iguana_msgvin *vins; struct iguana_msgvin *vins;
struct iguana_msgvout *vouts; struct iguana_msgvout *vouts;
struct sapling_spend_description *shielded_spends;
struct sapling_output_description *shielded_outputs;
bits256 txid; bits256 txid;
int32_t allocsize,timestamp,numinputs,numoutputs; int32_t allocsize,timestamp,numinputs,numoutputs;
int64_t inputsum,outputsum,txfee; int64_t inputsum,outputsum,txfee;
uint8_t *serialized; uint8_t *serialized,shielded_spend_num,shielded_output_num,numjoinsplits;
uint64_t value_balance;
uint8_t binding_sig[64];
}; };
struct iguana_msgjoinsplit struct iguana_msgjoinsplit
@ -183,6 +191,16 @@ struct iguana_msgjoinsplit
uint8_t ciphertexts[2][601]; uint8_t ciphertexts[2][601];
}; };
struct sapling_spend_description {
bits256 cv,anchor,nullifier,rk;
uint8_t zkproof[GROTH_PROOF_SIZE],spend_auth_sig[SAPLING_AUTH_SIG_SIZE];
};
struct sapling_output_description {
bits256 cv,cm,ephemeral_key;
uint8_t zkproof[GROTH_PROOF_SIZE],enc_ciphertext[ENC_CIPHER_SIZE],out_ciphertext[OUT_CIPHER_SIZE];
};
struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; };
struct vin_info struct vin_info
@ -206,7 +224,7 @@ struct basilisk_rawtxinfo
{ {
char destaddr[64],ethTxid[75]; char destaddr[64],ethTxid[75];
bits256 txid,signedtxid,actualtxid; bits256 txid,signedtxid,actualtxid;
int64_t amount,change,inputsum; int64_t amount,change,inputsum,eth_amount;
int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys; int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys;
uint32_t locktime,crcs[2]; uint32_t locktime,crcs[2];
uint8_t addrtype,pubkey33[33],rmd160[20]; uint8_t addrtype,pubkey33[33],rmd160[20];
@ -220,7 +238,7 @@ struct basilisk_request
bits256 desthash; bits256 desthash;
char src[68],dest[68]; char src[68],dest[68];
uint64_t destamount; uint64_t destamount;
int32_t optionhours,DEXselector; uint32_t optionhours,DEXselector;
}; };
struct basilisk_rawtx struct basilisk_rawtx
@ -241,7 +259,7 @@ struct basilisk_swapinfo
bits256 myhash,otherhash,orderhash; bits256 myhash,otherhash,orderhash;
uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration; 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; int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad,aliceistrusted,bobistrusted,otheristrusted,otherstrust,alicemaxconfirms,bobmaxconfirms;
int64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee; int64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee,alicerealsat,bobrealsat;
bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn; bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn;
uint32_t crcs_mypub[2],crcs_mychoosei[2],crcs_myprivs[2],crcs_mypriv[2]; uint32_t crcs_mypub[2],crcs_mychoosei[2],crcs_myprivs[2],crcs_mypriv[2];
@ -256,29 +274,31 @@ struct basilisk_swapinfo
uint8_t userdata_bobrefund[256],userdata_bobrefundlen; uint8_t userdata_bobrefund[256],userdata_bobrefundlen;
}; };
#define BASILISK_ALICESPEND 0 #define BASILISK_MYFEE 0
#define BASILISK_BOBSPEND 1 #define BASILISK_OTHERFEE 1
#define BASILISK_BOBPAYMENT 2 #define BASILISK_BOBDEPOSIT 2
#define BASILISK_ALICEPAYMENT 3 #define BASILISK_ALICEPAYMENT 3
#define BASILISK_BOBDEPOSIT 4 #define BASILISK_BOBPAYMENT 4
#define BASILISK_OTHERFEE 5 #define BASILISK_ALICESPEND 5
#define BASILISK_MYFEE 6 #define BASILISK_BOBSPEND 6
#define BASILISK_BOBREFUND 7 #define BASILISK_BOBREFUND 7
#define BASILISK_BOBRECLAIM 8 #define BASILISK_BOBRECLAIM 8
#define BASILISK_ALICERECLAIM 9 #define BASILISK_ALICERECLAIM 9
#define BASILISK_ALICECLAIM 10 #define BASILISK_ALICECLAIM 10
//0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0 //0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0
static char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" }; static char *txnames[] = { "myfee", "otherfee", "bobdeposit", "alicepayment", "bobpayment", "alicespend", "bobspend", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" };
struct LP_swap_remember struct LP_swap_remember
{ {
bits256 pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)]; bits256 pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)];
uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid; uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid,alicerealsat,bobrealsat;
int64_t values[sizeof(txnames)/sizeof(*txnames)]; int64_t values[sizeof(txnames)/sizeof(*txnames)];
uint32_t finishtime,tradeid,requestid,quoteid,plocktime,dlocktime,expiration,state,otherstate; uint32_t finishtime,tradeid,requestid,quoteid,plocktime,dlocktime,expiration,state,otherstate;
int32_t iambob,finishedflag,origfinishedflag,Predeemlen,Dredeemlen,sentflags[sizeof(txnames)/sizeof(*txnames)]; 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]; uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],Predeemscript[1024],Dredeemscript[1024],pubkey33[33],other33[33];
char uuidstr[65],Agui[65],Bgui[65],gui[65],src[65],dest[65],bobtomic[128],alicetomic[128],etomicsrc[65],etomicdest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)],bobDepositEthTx[75],bobPaymentEthTx[75],alicePaymentEthTx[75]; char uuidstr[65],Agui[65],Bgui[65],gui[65],src[65],dest[65],bobtomic[128],alicetomic[128],etomicsrc[65],etomicdest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)];
char eth_tx_ids[sizeof(txnames)/sizeof(*txnames)][75];
int64_t eth_values[sizeof(txnames)/sizeof(*txnames)];
}; };
struct LP_outpoint struct LP_outpoint
@ -303,7 +323,7 @@ struct iguana_info
{ {
UT_hash_handle hh; UT_hash_handle hh;
portable_mutex_t txmutex,addrmutex,addressutxo_mutex; 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; uint64_t txfee,do_autofill_merge;
int32_t numutxos,notarized,longestchain,firstrefht,firstscanht,lastscanht,height; uint16_t busport,did_addrutxo_reset; 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; 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; uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag,userconfirms,isassetchain,maxconfirms;
@ -311,14 +331,15 @@ struct iguana_info
// portfolio // portfolio
double price_kmd,force,perc,goal,goalperc,relvolume,rate; double price_kmd,force,perc,goal,goalperc,relvolume,rate;
void *electrum; void *ctx; void *electrum; void *ctx;
uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB; uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB,fillsatoshis;
uint8_t pubkey33[33],zcash; uint8_t pubkey33[33],zcash,decimals;
int32_t privkeydepth; int32_t privkeydepth,bobfillheight;
void *curl_handle; portable_mutex_t curl_mutex;
bits256 cachedtxid,notarizationtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen; bits256 cachedtxid,notarizationtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen;
bits256 cachedmerkle,notarizedhash; int32_t cachedmerkleheight; bits256 cachedmerkle,notarizedhash; int32_t cachedmerkleheight;
}; };
struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t vout,height; }; struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t height; uint32_t vout:30,suppress:1,pad:1; };
struct LP_utxostats { uint32_t sessionid,lasttime,errors,swappending,spentflag,lastspentcheck,bestflag; }; struct LP_utxostats { uint32_t sessionid,lasttime,errors,swappending,spentflag,lastspentcheck,bestflag; };
@ -377,9 +398,10 @@ struct LP_quoteinfo
{ {
struct basilisk_request R; struct basilisk_request R;
bits256 srchash,desthash,txid,txid2,desttxid,feetxid,privkey; bits256 srchash,desthash,txid,txid2,desttxid,feetxid,privkey;
double maxprice;
int64_t othercredits; int64_t othercredits;
uint64_t satoshis,txfee,destsatoshis,desttxfee,aliceid; uint64_t satoshis,txfee,destsatoshis,desttxfee,aliceid;
uint32_t timestamp,quotetime,tradeid; uint32_t timestamp,quotetime,tradeid,gtc,fill,mpnet;
int32_t vout,vout2,destvout,feevout,pair; int32_t vout,vout2,destvout,feevout,pair;
char srccoin[65],coinaddr[64],destcoin[65],destaddr[64],gui[64],etomicsrc[65],etomicdest[65],uuidstr[65]; char srccoin[65],coinaddr[64],destcoin[65],destaddr[64],gui[64],etomicsrc[65],etomicdest[65],uuidstr[65];
}; };
@ -427,7 +449,7 @@ struct LP_swapstats
struct LP_pubswap { struct LP_pubswap *next,*prev; struct LP_swapstats *swap; }; struct LP_pubswap { struct LP_pubswap *next,*prev; struct LP_swapstats *swap; };
#define LP_MAXPRICEINFOS 256 #define LP_MAXPRICEINFOS 255
struct LP_pubkey_info struct LP_pubkey_info
{ {
UT_hash_handle hh; UT_hash_handle hh;
@ -531,6 +553,7 @@ void HashKeccak(uint8_t *hash,void *data,size_t len);
void test_validate(struct iguana_info *coin,char *signedtx); void test_validate(struct iguana_info *coin,char *signedtx);
void LP_instantdex_depositadd(char *coinaddr,bits256 txid); 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); int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid,char *refaddr,char *origcoinaddr);
char *LP_autofillbob(struct iguana_info *coin,uint64_t satoshis);
void LP_ports(uint16_t *pullportp,uint16_t *pubportp,uint16_t *busportp,uint16_t netid); void LP_ports(uint16_t *pullportp,uint16_t *pubportp,uint16_t *busportp,uint16_t netid);
int32_t LP_destaddr(char *destaddr,cJSON *item); int32_t LP_destaddr(char *destaddr,cJSON *item);
int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration); int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration);
@ -580,6 +603,7 @@ int32_t LP_trades_canceluuid(char *uuidstr);
int _decreasing_uint64(const void *a,const void *b); int _decreasing_uint64(const void *a,const void *b);
int32_t LP_alice_eligible(uint32_t quotetime); int32_t LP_alice_eligible(uint32_t quotetime);
int32_t LP_is_slowcoin(char *symbol); int32_t LP_is_slowcoin(char *symbol);
void LP_alicequery_clear();
void LP_listunspent_query(char *symbol,char *coinaddr); void LP_listunspent_query(char *symbol,char *coinaddr);
int32_t bitcoin_priv2wif(char *symbol,uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype); int32_t bitcoin_priv2wif(char *symbol,uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype);

6
iguana/exchanges/LP_instantdex.c

@ -639,7 +639,7 @@ int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue)
printf("unfinished alice %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis))); printf("unfinished alice %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis)));
} }
} }
//printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue));
} }
if ( 0 && credits != 0 ) if ( 0 && credits != 0 )
printf("%s %s othercredits %.8f debits %.8f + %.8f -> %.8f\n",coin->symbol,coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue),dstr(credits - (swaps_kmdvalue+kmdvalue))); printf("%s %s othercredits %.8f debits %.8f + %.8f -> %.8f\n",coin->symbol,coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue),dstr(credits - (swaps_kmdvalue+kmdvalue)));
@ -679,9 +679,9 @@ int64_t LP_instantdex_proofcheck(char *symbol,char *coinaddr,cJSON *proof,int32_
credits = ap->instantdex_credits; credits = ap->instantdex_credits;
ap->didinstantdex = 1; ap->didinstantdex = 1;
ap->instantdextime = (uint32_t)time(NULL); ap->instantdextime = (uint32_t)time(NULL);
if ( 0 && ap->instantdex_credits > 0 ) if ( 1 && ap->instantdex_credits > 0 )
printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits)); printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits));
} //else printf("cant find ap.%p or already did %d %.8f\n",ap,ap!=0?ap->didinstantdex:-1,ap!=0?dstr(ap->instantdex_credits):-1); } else printf("cant find ap.%p or already did %d %.8f\n",ap,ap!=0?ap->didinstantdex:-1,ap!=0?dstr(ap->instantdex_credits):-1);
} }
return(credits); return(credits);
} }

6
iguana/exchanges/LP_mmjson.c

@ -259,7 +259,11 @@ int32_t MMJSON_decodeitem(cJSON *lineobj,uint8_t *linebuf,int32_t i,int32_t len,
arbstr[j++] = c; arbstr[j++] = c;
} }
arbstr[j] = 0; arbstr[j] = 0;
jaddstr(lineobj,fieldstr,arbstr); if (strcmp(fieldstr, "txChain") == 0) {
cJSON_AddItemToObject(lineobj, fieldstr, cJSON_Parse(arbstr));
} else {
jaddstr(lineobj, fieldstr, arbstr);
}
break; break;
default: default:
if ( valind < MMJSON_BOUNDARY ) if ( valind < MMJSON_BOUNDARY )

254
iguana/exchanges/LP_mpnet.c

@ -0,0 +1,254 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_mpnet.c
// marketmaker
//
bits256 MPNET_txids[1024];
int32_t num_MPNET_txids;
int32_t LP_tradecommand(int32_t from_mpnet,void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen);
int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson);
void LP_gtc_addorder(struct LP_quoteinfo *qp);
char *LP_withdraw(struct iguana_info *coin,cJSON *argjson);
int32_t LP_mpnet_find(bits256 txid)
{
int32_t i;
for (i=0; i<num_MPNET_txids; i++)
if ( bits256_cmp(txid,MPNET_txids[i]) == 0 )
return(i);
return(-1);
}
int32_t LP_mpnet_add(bits256 txid)
{
if ( num_MPNET_txids < sizeof(MPNET_txids)/sizeof(*MPNET_txids) )
{
MPNET_txids[num_MPNET_txids++] = txid;
return(num_MPNET_txids);
}
printf("MPNET_txids[] overflow\n");
return(-1);
}
int32_t LP_mpnet_remove(bits256 txid)
{
int32_t i;
if ( (i= LP_mpnet_find(txid)) >= 0 )
{
MPNET_txids[i] = MPNET_txids[--num_MPNET_txids];
return(i);
}
return(-1);
}
int32_t LP_mpnet_addorder(struct LP_quoteinfo *qp)
{
uint64_t destvalue,destvalue2;
if ( LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) > 0 )
{
LP_gtc_addorder(qp);
return(0);
}
return(-1);
}
void LP_mpnet_init() // problem is coins not enabled yet
{
char fname[1024],line[8192]; FILE *fp; struct LP_quoteinfo Q; cJSON *argjson;
sprintf(fname,"%s/GTC/orders",GLOBAL_DBDIR), OS_compatible_path(fname);
if ( (fp= fopen(fname,"rb+")) != 0 )
{
while ( fgets(line,sizeof(line),fp) > 0 )
{
if ( (argjson= cJSON_Parse(line)) != 0 )
{
if ( LP_quoteparse(&Q,argjson) == 0 )
{
if ( LP_mpnet_addorder(&Q) == 0 )
printf("GTC %s",line);
}
free_json(argjson);
}
}
fclose(fp);
}
}
void LP_mpnet_send(int32_t localcopy,char *msg,int32_t sendflag,char *otheraddr)
{
char fname[1024]; int32_t len; FILE *fp; char *hexstr,*retstr; cJSON *argjson,*outputs,*item; struct iguana_info *coin; uint8_t linebuf[8192];
if ( localcopy != 0 )
{
sprintf(fname,"%s/GTC/orders",GLOBAL_DBDIR), OS_compatible_path(fname);
if ( (fp= fopen(fname,"rb+")) == 0 )
fp = fopen(fname,"wb+");
else fseek(fp,0,SEEK_END);
fprintf(fp,"%s\n",msg);
fclose(fp);
}
if ( G.mpnet != 0 && sendflag != 0 && (coin= LP_coinfind("CHIPS")) != 0 && coin->inactive == 0 )
{
len = MMJSON_encode(linebuf,msg);
//curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"withdraw\",\"coin\":\"CHIPS\",\"outputs\":[{\"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj\":0.0001}],\"opreturn\":\"deadbeef\"}"
if ( len > 0 )
{
argjson = cJSON_CreateObject();
outputs = cJSON_CreateArray();
if ( otheraddr != 0 && otheraddr[0] != 0 )
{
item = cJSON_CreateObject();
jaddnum(item,otheraddr,dstr(10000));
jaddi(outputs,item);
}
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,dstr(10000));
jaddi(outputs,item);
jadd(argjson,"outputs",outputs);
jaddnum(argjson,"broadcast",1);
jaddstr(argjson,"coin",coin->symbol);
hexstr = calloc(1,len*2 + 1);
init_hexbytes_noT(hexstr,linebuf,len);
jaddstr(argjson,"opreturn",hexstr);
free(hexstr);
retstr = LP_withdraw(coin,argjson);
free_json(argjson);
if ( retstr != 0 )
{
//printf("mpnet.%s\n",retstr);
free(retstr);
}
}
}
}
cJSON *LP_mpnet_parse(struct iguana_info *coin,bits256 txid)
{
cJSON *txobj,*vouts,*sobj,*argjson = 0; char *decodestr,*hexstr; uint8_t *buf,linebuf[8192]; int32_t len,n,hlen;
if ( (txobj= LP_gettx("mpnet",coin->symbol,txid,0)) != 0 )
{
if ( (vouts= jarray(&n,txobj,"vout")) != 0 )
{
if ( (sobj= jobj(jitem(vouts,n-1),"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (hlen= strlen(hexstr)) < sizeof(linebuf)*2 )
{
len = (hlen >> 1);
decode_hex(linebuf,len,hexstr);
buf = linebuf;
//printf("hexstr.(%s)\n",hexstr);
if ( *buf == 0x6a )
{
buf++, len--;
if ( *buf == 0x4d )
{
buf++, len--;
n = buf[0] + buf[1]*256;
buf += 2, len -= 2;
if ( n == len )
{
if ( (decodestr= MMJSON_decode(buf,len)) != 0 )
argjson = cJSON_Parse(decodestr);
}
}
}
if ( 0 && argjson == 0 )
printf("unhandled case.(%s)\n",hexstr);
}
}
if ( 0 && argjson == 0 )
printf("unhandled tx.(%s)\n",jprint(txobj,0));
free_json(txobj);
}
return(argjson);
}
// 2151978
// 404bc4ac452db07ed16376b3d7e77dbfc22b4a68f7243797125bd0d3bdddf8d1
// 893b46634456034a6d5d73b67026aa157b5e2addbfc6344dfbea6bae85f7dde0
// 717c7ef9de8504bd331f3ef52ed0a16ea0e070434e12cb4d63f5f081e999c43d dup
void LP_mpnet_process(void *ctx,char *myipaddr,int32_t pubsock,struct iguana_info *coin,bits256 txid)
{
cJSON *argjson; char str[65];
if ( LP_mpnet_find(txid) < 0 )
{
//printf("unique %s\n",bits256_str(str,txid));
if ( (argjson= LP_mpnet_parse(coin,txid)) != 0 )
{
//printf("MPNET.(%s)\n",jprint(argjson,0));
LP_tradecommand(1,ctx,myipaddr,pubsock,argjson,0,0);
free_json(argjson);
}
LP_mpnet_add(txid);
}
}
cJSON *LP_mpnet_get(void *ctx,char *myipaddr,int32_t pubsock,struct iguana_info *coin)
{
static int32_t lastheight; static bits256 lasthash;
int32_t i,n=0,numtx,checkht = 0,height = 0; bits256 latesthash,hash,txid,zero; char hashstr[65],str[65]; cJSON *txs,*blockjson;
memset(zero.bytes,0,sizeof(zero));
latesthash = LP_getbestblockhash(coin);
bits256_str(hashstr,latesthash);
if ( (blockjson= LP_blockjson(&checkht,coin->symbol,hashstr,0)) != 0 )
{
hash = latesthash;
while ( bits256_cmp(lasthash,hash) != 0 && n++ < 3 )
{
if ( (txs= jarray(&numtx,blockjson,"tx")) != 0 )
{
for (i=0; i<numtx; i++)
{
txid = jbits256i(txs,i);
LP_mpnet_process(ctx,myipaddr,pubsock,coin,txid);
LP_mpnet_remove(txid);
//printf("ht.%d n.%d i.%d %s\n",checkht,n,i,bits256_str(str,txid));
}
}
hash = jbits256(blockjson,"previousblockhash");
free_json(blockjson);
bits256_str(hashstr,hash);
if ( (blockjson= LP_blockjson(&checkht,coin->symbol,hashstr,0)) == 0 )
break;
}
lasthash = latesthash;
if ( blockjson != 0 )
free_json(blockjson);
if ( (txs= LP_getmempool(coin->symbol,coin->smartaddr,zero,zero)) != 0 )
{
numtx = cJSON_GetArraySize(txs);
for (i=0; i<numtx; i++)
{
txid = jbits256i(txs,i);
LP_mpnet_process(ctx,myipaddr,pubsock,coin,txid);
//printf("mp i.%d %s\n",i,bits256_str(str,txid));
}
}
}
return(0);
}
void LP_mpnet_check(void *ctx,char *myipaddr,int32_t pubsock)
{
static uint32_t lasttime;
struct iguana_info *coin = LP_coinfind("CHIPS");
if ( coin != 0 && coin->inactive == 0 && time(NULL) > lasttime+5 )
{
LP_mpnet_get(ctx,myipaddr,pubsock,coin);
lasttime = (uint32_t)time(NULL);
}
}

96
iguana/exchanges/LP_nativeDEX.c

@ -30,6 +30,9 @@
// there is an issue about waiting for notarization for a swap that never starts (expiration ok) // there is an issue about waiting for notarization for a swap that never starts (expiration ok)
#include <stdio.h> #include <stdio.h>
#ifndef MM_VERSION
#define MM_VERSION "UNKNOWN"
#endif
long LP_cjson_allocated,LP_cjson_total,LP_cjson_count; long LP_cjson_allocated,LP_cjson_total,LP_cjson_count;
@ -90,7 +93,7 @@ void LP_millistats_update(struct LP_millistats *mp)
#include "LP_etomic.h" #include "LP_etomic.h"
#endif #endif
portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex,LP_tradesmutex,LP_commandQmutex,LP_blockinit_mutex,LP_pendswap_mutex,LP_listmutex; portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex,LP_tradesmutex,LP_commandQmutex,LP_blockinit_mutex,LP_pendswap_mutex,LP_listmutex,LP_gtcmutex;
int32_t LP_canbind; int32_t LP_canbind;
char *Broadcaststr,*Reserved_msgs[2][1000]; char *Broadcaststr,*Reserved_msgs[2][1000];
int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; int32_t num_Reserved_msgs[2],max_Reserved_msgs[2];
@ -117,10 +120,10 @@ struct LP_globals
{ {
//struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2]; //struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2];
bits256 LP_mypub25519,LP_privkey,LP_mypriv25519,LP_passhash; bits256 LP_mypub25519,LP_privkey,LP_mypriv25519,LP_passhash;
uint64_t LP_skipstatus[10000]; uint64_t LP_skipstatus[10000], LP_required_etomic_balance;
uint16_t netid; uint16_t netid;
uint8_t LP_myrmd160[20],LP_pubsecp[33]; uint8_t LP_myrmd160[20],LP_pubsecp[33];
uint32_t LP_sessionid,counter; uint32_t LP_sessionid,counter,mpnet;
int32_t LP_IAMLP,LP_pendingswaps,USERPASS_COUNTER,LP_numprivkeys,initializing,waiting,LP_numskips; int32_t LP_IAMLP,LP_pendingswaps,USERPASS_COUNTER,LP_numprivkeys,initializing,waiting,LP_numskips;
char seednode[64],USERPASS[65],USERPASS_WIFSTR[64],LP_myrmd160str[41],gui[65],LP_NXTaddr[64]; char seednode[64],USERPASS[65],USERPASS_WIFSTR[64],LP_myrmd160str[41],gui[65],LP_NXTaddr[64];
struct LP_privkey LP_privkeys[100]; struct LP_privkey LP_privkeys[100];
@ -176,6 +179,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_
#include "LP_bitcoin.c" #include "LP_bitcoin.c"
#include "LP_coins.c" #include "LP_coins.c"
#include "LP_rpc.c" #include "LP_rpc.c"
#include "LP_mpnet.c"
#include "LP_NXT.c" #include "LP_NXT.c"
#include "LP_cache.c" #include "LP_cache.c"
#include "LP_RTmetrics.c" #include "LP_RTmetrics.c"
@ -202,7 +206,7 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson
char *retstr=0; cJSON *retjson; bits256 zero; char *retstr=0; cJSON *retjson; bits256 zero;
if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 ) if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 )
return(0); return(0);
if ( stats_JSONonly != 0 || LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) if ( stats_JSONonly != 0 || LP_tradecommand(0,ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 )
{ {
if ( (retstr= stats_JSON(ctx,0,myipaddr,pubsock,argjson,"127.0.0.1",stats_JSONonly)) != 0 ) if ( (retstr= stats_JSON(ctx,0,myipaddr,pubsock,argjson,"127.0.0.1",stats_JSONonly)) != 0 )
{ {
@ -423,7 +427,7 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int
/*if ( (argjson= cJSON_Parse(str)) != 0 ) /*if ( (argjson= cJSON_Parse(str)) != 0 )
{ {
//portable_mutex_lock(&LP_commandmutex); //portable_mutex_lock(&LP_commandmutex);
if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,0,0) <= 0 ) if ( LP_tradecommand(0,ctx,myipaddr,pubsock,argjson,0,0) <= 0 )
{ {
if ( (retstr= stats_JSON(ctx,0,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 ) if ( (retstr= stats_JSON(ctx,0,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 )
free(retstr); free(retstr);
@ -480,6 +484,8 @@ int32_t LP_nanomsg_recvs(void *ctx)
nonz += LP_sock_check("PULL",ctx,origipaddr,-1,LP_mypullsock,"127.0.0.1",1); 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);
//if ( G.mpnet != 0 )
LP_mpnet_check(ctx,origipaddr,LP_mypubsock);
return(nonz); return(nonz);
} }
@ -513,21 +519,21 @@ void command_rpcloop(void *ctx)
void LP_coinsloop(void *_coins) void LP_coinsloop(void *_coins)
{ {
static int32_t didfilescreate; static int32_t didfilescreate;
struct LP_address *ap=0; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t notarized,oldht,j,nonz; char *coins = _coins; struct LP_address *ap=0; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65],*retstr,*hexstr,*txidstr; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t notarized,oldht,j,nonz; char *coins = _coins;
if ( strcmp("BTC",coins) == 0 ) if ( strcmp("BTC",coins) == 0 )
{ {
strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop");
LP_coinsloopBTC_stats.threshold = 20000.; LP_coinsloopBTC_stats.threshold = 200000.;
} }
else if ( strcmp("KMD",coins) == 0 ) else if ( strcmp("KMD",coins) == 0 )
{ {
strcpy(LP_coinsloopKMD_stats.name,"KMD coin loop"); strcpy(LP_coinsloopKMD_stats.name,"KMD coin loop");
LP_coinsloopKMD_stats.threshold = 10000.; LP_coinsloopKMD_stats.threshold = 100000.;
} }
else else
{ {
strcpy(LP_coinsloop_stats.name,"other coins loop"); strcpy(LP_coinsloop_stats.name,"other coins loop");
LP_coinsloop_stats.threshold = 5000.; LP_coinsloop_stats.threshold = 50000.;
} }
while ( LP_STOP_RECEIVED == 0 ) while ( LP_STOP_RECEIVED == 0 )
{ {
@ -576,6 +582,29 @@ void LP_coinsloop(void *_coins)
LP_address_utxo_reset(&num,coin); LP_address_utxo_reset(&num,coin);
coin->did_addrutxo_reset = 1; coin->did_addrutxo_reset = 1;
} }
//free_json(LP_address_balance(coin,coin->smartaddr,1)); expensive invoking gettxout
if ( coin->do_autofill_merge != 0 )
{
if ( (retstr= LP_autofillbob(coin,coin->do_autofill_merge*1.02)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (hexstr= jstr(retjson,"hex")) != 0 )
{
if ( (txidstr= LP_sendrawtransaction(coin->symbol,hexstr,0)) != 0 )
{
printf("autofill created %s\n",txidstr);
free(txidstr);
coin->fillsatoshis = coin->do_autofill_merge;
coin->do_autofill_merge = 0;
coin->bobfillheight = LP_getheight(&notarized,coin);
}
}
free_json(retjson);
}
free(retstr);
}
}
if ( coin->longestchain == 1 ) // special init value if ( coin->longestchain == 1 ) // special init value
coin->longestchain = LP_getheight(&notarized,coin); coin->longestchain = LP_getheight(&notarized,coin);
if ( (ep= coin->electrum) != 0 ) if ( (ep= coin->electrum) != 0 )
@ -656,6 +685,7 @@ void LP_coinsloop(void *_coins)
continue; 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
if ( coin->lastscanht < coin->longestchain )
{ {
nonz++; nonz++;
if ( strcmp("BTC",coins) == 0 )//&& coin->lastscanht < coin->longestchain-3 ) if ( strcmp("BTC",coins) == 0 )//&& coin->lastscanht < coin->longestchain-3 )
@ -664,7 +694,7 @@ void LP_coinsloop(void *_coins)
{ {
if ( LP_blockinit(coin,coin->lastscanht) < 0 ) if ( LP_blockinit(coin,coin->lastscanht) < 0 )
{ {
printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht); printf("please ignore this blockinit.%s %d error\n",coin->symbol,coin->lastscanht);
sleep(10); sleep(10);
break; break;
} }
@ -890,6 +920,24 @@ void gameaddrs()
} }
} }
void emc2addrs()
{
struct iguana_info *emc2coin,*kmdcoin; int32_t i; uint8_t pubkey33[33]; char emc2addr[64],kmdaddr[64];
emc2coin = LP_coinfind("EMC2");
kmdcoin = LP_coinfind("KMD");
if ( emc2coin != 0 && kmdcoin != 0 )
{
for (i=0; i<64; i++)
{
decode_hex(pubkey33,33,Notaries_elected1[i][1]);
bitcoin_address(emc2coin->symbol,emc2addr,emc2coin->taddr,emc2coin->pubtype,pubkey33,33);
bitcoin_address(kmdcoin->symbol,kmdaddr,kmdcoin->taddr,kmdcoin->pubtype,pubkey33,33);
printf("{\"%s\", \"%s\", \"%s\", \"%s\"},\n",Notaries_elected1[i][0],Notaries_elected1[i][1],kmdaddr,emc2addr);
}
}
}
void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins)
{ {
int32_t i,n,notarized; cJSON *item; char *symbol,*etomic; struct iguana_info *coin; int32_t i,n,notarized; cJSON *item; char *symbol,*etomic; struct iguana_info *coin;
@ -945,6 +993,10 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins)
{ {
gameaddrs(); gameaddrs();
} }
else if ( 0 && strcmp(coin->symbol,"EMC2") == 0 )
{
emc2addrs();
}
else if ( 0 && strcmp(coin->symbol,"SMART") == 0 ) else if ( 0 && strcmp(coin->symbol,"SMART") == 0 )
{ {
uint8_t txdata[8129]; int32_t len; bits256 txid,txid2,ktxid; char str[65]; uint8_t txdata[8129]; int32_t len; bits256 txid,txid2,ktxid; char str[65];
@ -1003,7 +1055,10 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint
} }
if ( (netid > 0 && netid < 9) && (seednode == 0 || seednode[0] == 0) ) if ( (netid > 0 && netid < 9) && (seednode == 0 || seednode[0] == 0) )
{ {
sprintf(fixedseed,"5.9.253.%d",195 + netid); if ( (netid & 1) != 0 )
strcpy(fixedseed,"46.4.78.11");
else strcpy(fixedseed,"46.4.87.18");
//sprintf(fixedseed,"5.9.253.%d",195 + netid);
seednode = fixedseed; seednode = fixedseed;
} }
if ( seednode == 0 || seednode[0] == 0 ) if ( seednode == 0 || seednode[0] == 0 )
@ -1098,6 +1153,7 @@ void LP_swapsloop(void *ctx)
if ( (sp->finished= LP_swapwait(0,sp->requestid,sp->quoteid,-1,0)) != 0 ) if ( (sp->finished= LP_swapwait(0,sp->requestid,sp->quoteid,-1,0)) != 0 )
{ {
} }
sleep(3);
} }
} }
if ( nonz == 0 ) if ( nonz == 0 )
@ -1108,7 +1164,8 @@ void LP_swapsloop(void *ctx)
LP_alice_eligible((uint32_t)time(NULL)); LP_alice_eligible((uint32_t)time(NULL));
sleep(6); sleep(6);
} }
} } else sleep(10);
LP_gtc_iteration(ctx,LP_myipaddr,LP_mypubsock);
} }
} }
@ -1193,7 +1250,7 @@ void queue_loop(void *ctx)
} }
if ( (json= cJSON_Parse((char *)ptr->msg)) != 0 ) if ( (json= cJSON_Parse((char *)ptr->msg)) != 0 )
{ {
if ( 1 && ptr->msglen < sizeof(linebuf) ) if ( ptr->msglen < sizeof(linebuf) )
{ {
if ( (k= MMJSON_encode(linebuf,(char *)ptr->msg)) > 0 ) if ( (k= MMJSON_encode(linebuf,(char *)ptr->msg)) > 0 )
{ {
@ -1392,8 +1449,7 @@ extern int32_t bitcoind_RPC_inittime;
void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybusport,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson) void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybusport,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson)
{ {
char *myipaddr=0,version[64]; long filesize,n; int32_t valid,timeout; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128],*coins_str=0; cJSON *coinsjson=0; void *ctx = bitcoin_ctx(); char *myipaddr=0; long filesize,n; int32_t valid,timeout; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128],*coins_str=0; cJSON *coinsjson=0; void *ctx = bitcoin_ctx();
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; bitcoind_RPC_inittime = 1;
if ( LP_MAXPRICEINFOS > 256 ) if ( LP_MAXPRICEINFOS > 256 )
{ {
@ -1401,7 +1457,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
exit(-1); exit(-1);
} }
LP_showwif = juint(argjson,"wif"); LP_showwif = juint(argjson,"wif");
printf("showwif.%d %s %u\n",LP_showwif,version,calc_crc32(0,version,(int32_t)strlen(version))); printf("showwif.%d version: %s %u\n",LP_showwif,MM_VERSION,calc_crc32(0,MM_VERSION,(int32_t)strlen(MM_VERSION)));
if ( passphrase == 0 || passphrase[0] == 0 ) if ( passphrase == 0 || passphrase[0] == 0 )
{ {
printf("jeezy says we cant use the nullstring as passphrase and I agree\n"); printf("jeezy says we cant use the nullstring as passphrase and I agree\n");
@ -1472,13 +1528,14 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
portable_mutex_init(&LP_blockinit_mutex); portable_mutex_init(&LP_blockinit_mutex);
portable_mutex_init(&LP_pendswap_mutex); portable_mutex_init(&LP_pendswap_mutex);
portable_mutex_init(&LP_listmutex); portable_mutex_init(&LP_listmutex);
portable_mutex_init(&LP_gtcmutex);
myipaddr = clonestr("127.0.0.1"); myipaddr = clonestr("127.0.0.1");
#ifndef _WIN32 #ifndef _WIN32
#ifndef FROM_JS #ifndef FROM_JS
if ( system("curl -s4 checkip.amazonaws.com > myipaddr") == 0 ) char ipfname[64];
strcpy(ipfname,"myipaddr");
if ( access( ipfname, F_OK ) != -1 || system("curl -s4 checkip.amazonaws.com > myipaddr") == 0 )
{ {
char ipfname[64];
strcpy(ipfname,"myipaddr");
if ( (myipaddr= OS_filestr(&filesize,ipfname)) != 0 && myipaddr[0] != 0 ) if ( (myipaddr= OS_filestr(&filesize,ipfname)) != 0 && myipaddr[0] != 0 )
{ {
n = strlen(myipaddr); n = strlen(myipaddr);
@ -1620,6 +1677,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
int32_t nonz,didremote=0; int32_t nonz,didremote=0;
LP_statslog_parse(); LP_statslog_parse();
bitcoind_RPC_inittime = 0; bitcoind_RPC_inittime = 0;
//LP_mpnet_init(); seems better to have the GUI send in persistent orders, exit mm is a cancel all
while ( LP_STOP_RECEIVED == 0 ) while ( LP_STOP_RECEIVED == 0 )
{ {
nonz = 0; nonz = 0;

13
iguana/exchanges/LP_network.c

@ -27,6 +27,7 @@ struct psock
} *PSOCKS; } *PSOCKS;
uint16_t Numpsocks,Psockport = MIN_PSOCK_PORT,Pcmdport = MAX_PSOCK_PORT; uint16_t Numpsocks,Psockport = MIN_PSOCK_PORT,Pcmdport = MAX_PSOCK_PORT;
extern portable_mutex_t LP_commandQmutex;
#ifdef FROM_JS #ifdef FROM_JS
@ -879,8 +880,16 @@ char *LP_psock(int32_t *pullsockp,char *ipaddr,int32_t ispaired,int32_t cmdchann
char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired,int32_t cmdchannel) char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired,int32_t cmdchannel)
{ {
char str[65],url[512],*retstr; char str[65],url[512],*retstr; bits256 pub25519; int32_t netid;
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); #ifdef FROM_MARKETMAKER
pub25519 = G.LP_mypub25519;
netid = G.netid;
#else
extern bits256 BET_mypub25519;
pub25519 = BET_mypub25519;
netid = 0;
#endif
sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d&cmdchannel=%d&pubkey=%s&netid=%d",destip,destport-1,ispaired,cmdchannel,bits256_str(str,pub25519),netid);
//return(LP_issue_curl("psock",destip,destport,url)); //return(LP_issue_curl("psock",destip,destport,url));
retstr = issue_curlt(url,LP_HTTP_TIMEOUT*10); retstr = issue_curlt(url,LP_HTTP_TIMEOUT*10);
printf("issue_LP_psock got (%s) from %s\n",retstr,url); // this is needed?! printf("issue_LP_psock got (%s) from %s\n",retstr,url); // this is needed?!

371
iguana/exchanges/LP_ordermatch.c

@ -18,6 +18,14 @@
// LP_ordermatch.c // LP_ordermatch.c
// marketmaker // marketmaker
// //
struct LP_gtcorder
{
struct LP_gtcorder *next,*prev;
struct LP_quoteinfo Q;
uint32_t cancelled,pending;
} *GTCorders;
struct LP_quoteinfo LP_Alicequery,LP_Alicereserved; struct LP_quoteinfo LP_Alicequery,LP_Alicereserved;
double LP_Alicemaxprice; double LP_Alicemaxprice;
bits256 LP_Alicedestpubkey,LP_bobs_reserved; bits256 LP_Alicedestpubkey,LP_bobs_reserved;
@ -190,12 +198,12 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str
if ( strcmp(autxo->coinaddr,qp->destaddr) != 0 ) if ( strcmp(autxo->coinaddr,qp->destaddr) != 0 )
return(-10); return(-10);
} }
if ( autxo != 0 && destvalue < qp->desttxfee+qp->destsatoshis ) if ( strcmp(destcoin, "ETOMIC") != 0 && autxo != 0 && destvalue < qp->desttxfee+qp->destsatoshis )
{ {
printf("destvalue %.8f destsatoshis %.8f is too small txfee %.8f?\n",dstr(destvalue),dstr(qp->destsatoshis),dstr(qp->desttxfee)); printf("destvalue %.8f destsatoshis %.8f is too small txfee %.8f?\n",dstr(destvalue),dstr(qp->destsatoshis),dstr(qp->desttxfee));
return(-11); return(-11);
} }
if ( butxo != 0 && srcvalue < qp->txfee+qp->satoshis ) if ( strcmp(srccoin, "ETOMIC") != 0 && butxo != 0 && srcvalue < qp->txfee+qp->satoshis )
{ {
printf("srcvalue %.8f [%.8f] satoshis %.8f is too small txfee %.8f?\n",dstr(srcvalue),dstr(srcvalue) - dstr(qp->txfee+qp->satoshis),dstr(qp->satoshis),dstr(qp->txfee)); 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); return(-33);
@ -213,7 +221,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str
printf("error -14: txfee %.8f < %.8f or desttxfee %.8f < %.8f\n",dstr(qp->txfee),dstr(LP_REQUIRED_TXFEE*txfee),dstr(qp->desttxfee),dstr(LP_REQUIRED_TXFEE*desttxfee)); 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); return(-14);
} }
if ( butxo != 0 ) if ( butxo != 0 && strcmp(srccoin, "ETOMIC") != 0)
{ {
if ( qp->satoshis < (srcvalue / LP_MINVOL) || srcvalue < qp->txfee*LP_MINSIZE_TXFEEMULT ) if ( qp->satoshis < (srcvalue / LP_MINVOL) || srcvalue < qp->txfee*LP_MINSIZE_TXFEEMULT )
{ {
@ -413,14 +421,22 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb
memset(butxo,0,sizeof(*butxo)); memset(butxo,0,sizeof(*butxo));
if ( iambob != 0 ) if ( iambob != 0 )
{ {
targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee) + 3*txfee; if (strcmp(coin->symbol, "ETOMIC") == 0) {
targetval = 100000000 + 3*txfee;
} else {
targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee) + 3*txfee;
}
targetval2 = (targetval / 8) * 9 + 3*txfee; targetval2 = (targetval / 8) * 9 + 3*txfee;
fee = txfee; fee = txfee;
ratio = LP_MINVOL; ratio = LP_MINVOL;
} }
else else
{ {
targetval = relvolume*SATOSHIDEN + 3*desttxfee; if (strcmp(coin->symbol, "ETOMIC") == 0) {
targetval = 100000000 + 3*desttxfee;
} else {
targetval = relvolume*SATOSHIDEN + 3*desttxfee;
}
targetval2 = (targetval / 777) + 3*desttxfee; targetval2 = (targetval / 777) + 3*desttxfee;
fee = desttxfee; fee = desttxfee;
ratio = LP_MINCLIENTVOL; ratio = LP_MINCLIENTVOL;
@ -429,7 +445,7 @@ struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iamb
{ {
if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 )
{ {
if ( 0 ) if ( 1 )
{ {
int32_t i; int32_t i;
for (i=0; i<m; i++) for (i=0; i<m; i++)
@ -494,7 +510,7 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double
} }
if ( bits256_nonz(privkey) != 0 && bits256_cmp(G.LP_mypub25519,qp->srchash) == 0 ) 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); LP_requestinit(&qp->R,qp->srchash,qp->desthash,base,qp->satoshis-qp->txfee,rel,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector,qp->fill,qp->gtc);
dtrust = LP_dynamictrust(qp->othercredits,qp->desthash,LP_kmdvalue(qp->destcoin,qp->destsatoshis)); 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 ) if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp,dtrust > 0)) == 0 )
{ {
@ -517,27 +533,35 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double
LP_importaddress(qp->destcoin,qp->destaddr); LP_importaddress(qp->destcoin,qp->destaddr);
LP_otheraddress(qp->srccoin,otheraddr,qp->destcoin,qp->destaddr); LP_otheraddress(qp->srccoin,otheraddr,qp->destcoin,qp->destaddr);
LP_importaddress(qp->srccoin,otheraddr); 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)); bits256 zero;
break; memset(zero.bytes,0,sizeof(zero));
sleep(10); for (i=0; i<1; i++)
if ( swap->received != 0 )
{ {
printf("swap %u-%u has started t%u\n",swap->I.req.requestid,swap->I.req.quoteid,swap->received); LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0));
break; break;
sleep(10);
if ( swap->received != 0 )
{
printf("swap %u-%u has started t%u\n",swap->I.req.requestid,swap->I.req.quoteid,swap->received);
break;
}
printf("bob tries %u-%u again i.%d\n",swap->I.req.requestid,swap->I.req.quoteid,i);
LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0));
} }
printf("bob tries %u-%u again i.%d\n",swap->I.req.requestid,swap->I.req.quoteid,i); sleep(1);
printf("send CONNECT for %u-%u\n",qp->R.requestid,qp->R.quoteid);
LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0));
if ( IPC_ENDPOINT >= 0 )
LP_queuecommand(0,jprint(reqjson,0),IPC_ENDPOINT,-1,0);
} }
sleep(1); if ( qp->mpnet != 0 && qp->gtc == 0 )
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)); char *msg = jprint(reqjson,0);
if ( IPC_ENDPOINT >= 0 ) LP_mpnet_send(0,msg,1,qp->destaddr);
LP_queuecommand(0,jprint(reqjson,1),IPC_ENDPOINT,-1,0); free(msg);
else free_json(reqjson); }
free_json(reqjson);
retval = 0; retval = 0;
} }
else else
@ -567,10 +591,60 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double
return(retval); return(retval);
} }
void LP_gtc_iteration(void *ctx,char *myipaddr,int32_t mypubsock)
{
struct LP_gtcorder *gtc,*tmp; struct LP_quoteinfo *qp; uint64_t destvalue,destvalue2; uint32_t oldest = 0;
if ( Alice_expiration != 0 )
return;
DL_FOREACH_SAFE(GTCorders,gtc,tmp)
{
qp = &gtc->Q;
if ( gtc->cancelled == 0 && (oldest == 0 || gtc->pending < oldest) )
oldest = gtc->pending;
}
DL_FOREACH_SAFE(GTCorders,gtc,tmp)
{
qp = &gtc->Q;
if ( gtc->cancelled == 0 && LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 )
{
gtc->cancelled = (uint32_t)time(NULL);
LP_failedmsg(qp->R.requestid,qp->R.quoteid,-9997,qp->uuidstr);
}
if ( gtc->cancelled != 0 )
{
portable_mutex_lock(&LP_gtcmutex);
DL_DELETE(GTCorders,gtc);
free(gtc);
portable_mutex_unlock(&LP_gtcmutex);
}
else
{
if ( gtc->pending <= oldest+60 && time(NULL) > gtc->pending+600 )//LP_AUTOTRADE_TIMEOUT*10 )
{
gtc->pending = qp->timestamp = (uint32_t)time(NULL);
LP_query(ctx,myipaddr,mypubsock,"request",qp);
LP_Alicequery = *qp, LP_Alicemaxprice = gtc->Q.maxprice, Alice_expiration = qp->timestamp + 2*LP_AUTOTRADE_TIMEOUT, LP_Alicedestpubkey = qp->srchash;
char str[65]; printf("LP_gtc fill.%d gtc.%d %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f etomicdest.(%s) uuid.%s fill.%d gtc.%d\n",qp->fill,qp->gtc,qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),gtc->Q.maxprice,qp->etomicdest,qp->uuidstr,qp->fill,qp->gtc);
break;
}
}
}
}
void LP_gtc_addorder(struct LP_quoteinfo *qp)
{
struct LP_gtcorder *gtc;
gtc = calloc(1,sizeof(*gtc));
gtc->Q = *qp;
gtc->pending = (uint32_t)time(NULL);
portable_mutex_lock(&LP_gtcmutex);
DL_APPEND(GTCorders,gtc);
portable_mutex_unlock(&LP_gtcmutex);
}
char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid,bits256 destpubkey,char *uuidstr) 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; struct LP_gtcorder *gtc;
price = 0.;
memset(qp->txid.bytes,0,sizeof(qp->txid)); memset(qp->txid.bytes,0,sizeof(qp->txid));
qp->txid2 = qp->txid; qp->txid2 = qp->txid;
qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout);
@ -578,9 +652,25 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q
qp->tradeid = LP_rand(); qp->tradeid = LP_rand();
qp->srchash = destpubkey; qp->srchash = destpubkey;
strncpy(qp->uuidstr,uuidstr,sizeof(qp->uuidstr)-1); strncpy(qp->uuidstr,uuidstr,sizeof(qp->uuidstr)-1);
LP_query(ctx,myipaddr,mypubsock,"request",qp); qp->maxprice = maxprice;
LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = destpubkey; qp->timestamp = (uint32_t)time(NULL);
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); if ( qp->gtc != 0 )
{
//strcpy(&qp->uuidstr[strlen(qp->uuidstr)-6],"cccccc");
LP_gtc_addorder(qp);
}
{
LP_query(ctx,myipaddr,mypubsock,"request",qp);
LP_Alicequery = *qp, LP_Alicemaxprice = qp->maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = qp->srchash;
}
if ( qp->gtc == 0 )
{
cJSON *reqjson = LP_quotejson(qp);
char *msg = jprint(reqjson,1);
LP_mpnet_send(1,msg,1,0);
free(msg);
}
char str[65]; printf("LP_trade mpnet.%d fill.%d gtc.%d %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f etomicdest.(%s) uuid.%s fill.%d gtc.%d\n",qp->mpnet,qp->fill,qp->gtc,qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),qp->maxprice,qp->etomicdest,qp->uuidstr,qp->fill,qp->gtc);
return(LP_recent_swaps(0,uuidstr)); return(LP_recent_swaps(0,uuidstr));
} }
@ -615,7 +705,7 @@ int32_t LP_alice_eligible(uint32_t quotetime)
{ {
if ( Alice_expiration != 0 && quotetime > Alice_expiration ) if ( Alice_expiration != 0 && quotetime > Alice_expiration )
{ {
if ( LP_Alicequery.uuidstr[0] != 0 ) if ( LP_Alicequery.uuidstr[0] != 0 && LP_Alicequery.gtc == 0 )
LP_failedmsg(LP_Alicequery.R.requestid,LP_Alicequery.R.quoteid,-9999,LP_Alicequery.uuidstr); LP_failedmsg(LP_Alicequery.R.requestid,LP_Alicequery.R.quoteid,-9999,LP_Alicequery.uuidstr);
printf("time expired for Alice_request\n"); printf("time expired for Alice_request\n");
LP_alicequery_clear(); LP_alicequery_clear();
@ -628,16 +718,45 @@ char *LP_cancel_order(char *uuidstr)
int32_t num = 0; cJSON *retjson; int32_t num = 0; cJSON *retjson;
if ( uuidstr != 0 ) if ( uuidstr != 0 )
{ {
num = LP_trades_canceluuid(uuidstr); if ( uuidstr[0] == 'G' )
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); struct LP_gtcorder *gtc,*tmp;
LP_alicequery_clear(); DL_FOREACH_SAFE(GTCorders,gtc,tmp)
jaddstr(retjson,"status","uuid canceled"); {
} else jaddstr(retjson,"status","will stop trade negotiation, but if swap started it wont cancel"); if ( strcmp(gtc->Q.uuidstr,uuidstr) == 0 )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"cancelled",uuidstr);
jaddnum(retjson,"pending",gtc->pending);
if ( gtc->cancelled == 0 )
{
gtc->cancelled = (uint32_t)time(NULL);
jaddstr(retjson,"status","uuid canceled");
LP_failedmsg(gtc->Q.R.requestid,gtc->Q.R.quoteid,-9997,gtc->Q.uuidstr);
}
else
{
jaddstr(retjson,"status","uuid already canceled");
LP_failedmsg(gtc->Q.R.requestid,gtc->Q.R.quoteid,-9996,gtc->Q.uuidstr);
}
}
}
return(clonestr("{\"error\":\"gtc uuid not found\"}"));
}
else
{
num = LP_trades_canceluuid(uuidstr);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddnum(retjson,"numentries",num);
if ( strcmp(LP_Alicequery.uuidstr,uuidstr) == 0 )
{
LP_failedmsg(LP_Alicequery.R.requestid,LP_Alicequery.R.quoteid,-9998,LP_Alicequery.uuidstr);
LP_alicequery_clear();
jaddstr(retjson,"status","uuid canceled");
} else jaddstr(retjson,"status","will stop trade negotiation, but if swap started it wont cancel");
}
return(jprint(retjson,1)); return(jprint(retjson,1));
} }
return(clonestr("{\"error\":\"uuid not cancellable\"}")); return(clonestr("{\"error\":\"uuid not cancellable\"}"));
@ -645,16 +764,22 @@ char *LP_cancel_order(char *uuidstr)
char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice
{ {
cJSON *retjson; char otheraddr[64],*msg; double bid,ask,price,qprice; int32_t pairsock = -1; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct basilisk_swap *swap; struct iguana_info *coin; cJSON *retjson; char otheraddr[64],*msg; double bid,ask,price,qprice; int32_t changed,pairsock = -1; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct basilisk_swap *swap; struct iguana_info *coin;
if ( bits256_cmp(qp->desthash,G.LP_mypub25519) != 0 ) if ( bits256_cmp(qp->desthash,G.LP_mypub25519) != 0 )
{ {
LP_aliceid(qp->tradeid,qp->aliceid,"error1",0,0); LP_aliceid(qp->tradeid,qp->aliceid,"error1",0,0);
LP_failedmsg(qp->R.requestid,qp->R.quoteid,-4000,qp->uuidstr); LP_failedmsg(qp->R.requestid,qp->R.quoteid,-4000,qp->uuidstr);
return(clonestr("{\"result\",\"update stats\"}")); 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:""); printf("CONNECTED mpnet.%d fill.%d gtc.%d numpending.%d tradeid.%u requestid.%u quoteid.%u pairstr.%s\n",qp->mpnet,qp->fill,qp->gtc,G.LP_pendingswaps,qp->tradeid,qp->R.requestid,qp->R.quoteid,pairstr!=0?pairstr:"");
LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-qp->txfee,qp->destcoin,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-qp->txfee,qp->destcoin,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector,qp->fill,qp->gtc);
//printf("calculated requestid.%u quoteid.%u\n",qp->R.requestid,qp->R.quoteid); //printf("calculated requestid.%u quoteid.%u\n",qp->R.requestid,qp->R.quoteid);
if ( LP_Alicequery.srccoin[0] != 0 && LP_Alicequery.destcoin[0] != 0 )
{
LP_mypriceset(0,&changed,LP_Alicequery.destcoin,LP_Alicequery.srccoin,0.);
LP_mypriceset(0,&changed,LP_Alicequery.srccoin,LP_Alicequery.destcoin,0.);
}
LP_alicequery_clear();
memset(&LP_Alicereserved,0,sizeof(LP_Alicereserved)); memset(&LP_Alicereserved,0,sizeof(LP_Alicereserved));
LP_aliceid(qp->tradeid,qp->aliceid,"connected",qp->R.requestid,qp->R.quoteid); LP_aliceid(qp->tradeid,qp->aliceid,"connected",qp->R.requestid,qp->R.quoteid);
autxo = &A; autxo = &A;
@ -671,7 +796,7 @@ char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice
printf("quote %s/%s validate error %.0f\n",qp->srccoin,qp->destcoin,qprice); printf("quote %s/%s validate error %.0f\n",qp->srccoin,qp->destcoin,qprice);
return(clonestr("{\"error\":\"quote validation error\"}")); return(clonestr("{\"error\":\"quote validation error\"}"));
} }
if ( LP_myprice(&bid,&ask,qp->srccoin,qp->destcoin) <= SMALLVAL || bid <= SMALLVAL ) if ( LP_myprice(0,&bid,&ask,qp->srccoin,qp->destcoin) <= SMALLVAL || bid <= SMALLVAL )
{ {
printf("this node has no price for %s/%s (%.8f %.8f)\n",qp->destcoin,qp->srccoin,bid,ask); printf("this node has no price for %s/%s (%.8f %.8f)\n",qp->destcoin,qp->srccoin,bid,ask);
LP_availableset(qp->desttxid,qp->vout); LP_availableset(qp->desttxid,qp->vout);
@ -862,7 +987,7 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo
double LP_trades_bobprice(double *bidp,double *askp,struct LP_quoteinfo *qp) double LP_trades_bobprice(double *bidp,double *askp,struct LP_quoteinfo *qp)
{ {
double price; struct iguana_info *coin; char str[65]; double price; struct iguana_info *coin; char str[65];
price = LP_myprice(bidp,askp,qp->srccoin,qp->destcoin); price = LP_myprice(1,bidp,askp,qp->srccoin,qp->destcoin);
if ( (coin= LP_coinfind(qp->srccoin)) == 0 || price <= SMALLVAL || *askp <= SMALLVAL ) if ( (coin= LP_coinfind(qp->srccoin)) == 0 || price <= SMALLVAL || *askp <= SMALLVAL )
{ {
//printf("this node has no price for %s/%s\n",qp->srccoin,qp->destcoin); //printf("this node has no price for %s/%s\n",qp->srccoin,qp->destcoin);
@ -906,7 +1031,7 @@ double LP_trades_pricevalidate(struct LP_quoteinfo *qp,struct iguana_info *coin,
printf("quote %s/%s validate error %.0f\n",qp->srccoin,qp->destcoin,qprice); printf("quote %s/%s validate error %.0f\n",qp->srccoin,qp->destcoin,qprice);
return(-3); return(-3);
} }
if ( qprice < (price - 0.00000001) * 0.998 ) if ( qprice < (price - 0.00000001) * 0.998)
{ {
printf(" quote price %.8f (%llu/%llu %.8f) too low vs %.8f for %s/%s price %.8f %.8f\n",qprice,(long long)qp->destsatoshis,(long long)(qp->satoshis-qp->txfee),(double)qp->destsatoshis/(qp->satoshis-qp->txfee),price,qp->srccoin,qp->destcoin,price,(price - 0.00000001) * 0.998); 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(-77);
@ -916,10 +1041,11 @@ double LP_trades_pricevalidate(struct LP_quoteinfo *qp,struct iguana_info *coin,
struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr)
{ {
double price=0.,p=0.,qprice,myprice,bestprice,range,bid,ask; struct iguana_info *coin,*othercoin; struct LP_utxoinfo A,B,*autxo,*butxo; cJSON *reqjson; char str[65]; struct LP_address_utxo *utxos[4096]; int32_t i,r,counter,max = (int32_t)(sizeof(utxos)/sizeof(*utxos)); int32_t voliters=10,priceiters=33;
double price=0.,p=0.,qprice,myprice,bestprice,range,bid,ask; uint64_t satoshis; struct iguana_info *coin,*othercoin; struct LP_utxoinfo A,B,*autxo,*butxo; cJSON *reqjson,*retjson; char str[65],*retstr,*txidstr,*hexstr; struct LP_address_utxo *utxos[4096]; int32_t i,j,notarized,r,num,counter,max = (int32_t)(sizeof(utxos)/sizeof(*utxos));
*newqp = *qp; *newqp = *qp;
qp = newqp; qp = newqp;
//printf("bob %s received REQUEST.(%s)\n",bits256_str(str,G.LP_mypub25519),qp->uuidstr+32); printf("bob %s received REQUEST.(%s) mpnet.%d fill.%d gtc.%d\n",bits256_str(str,G.LP_mypub25519),qp->uuidstr+32,qp->mpnet,qp->fill,qp->gtc);
if ( (coin= LP_coinfind(qp->srccoin)) == 0 || (othercoin= LP_coinfind(qp->destcoin)) == 0 ) if ( (coin= LP_coinfind(qp->srccoin)) == 0 || (othercoin= LP_coinfind(qp->destcoin)) == 0 )
return(0); return(0);
if ( (myprice= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) if ( (myprice= LP_trades_bobprice(&bid,&ask,qp)) == 0. )
@ -970,7 +1096,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru
} }
else else
{ {
//printf("ignore as qprice %.8f vs myprice %.8f\n",qprice,myprice); printf("%s/%s ignore as qprice %.8f vs myprice %.8f\n",qp->srccoin,qp->destcoin,qprice,myprice);
return(0); return(0);
} }
//LP_RTmetrics_update(qp->srccoin,qp->destcoin); //LP_RTmetrics_update(qp->srccoin,qp->destcoin);
@ -997,46 +1123,85 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru
return(0); return(0);
} }
} }
LP_address_utxo_reset(&num,coin);
i = 0; i = 0;
while ( i < 33 && price >= myprice ) while ( i < priceiters && price >= myprice )
{ {
if ( (butxo= LP_address_myutxopair(butxo,1,utxos,max,LP_coinfind(qp->srccoin),qp->coinaddr,qp->txfee,dstr(qp->destsatoshis),price,qp->desttxfee)) != 0 ) for (j=0; j<voliters; j++)
{ {
strcpy(qp->gui,G.gui); printf("priceiter.%d voliter.%d price %.8f vol %.8f\n",i,j,price,dstr(qp->destsatoshis));
strcpy(qp->coinaddr,coin->smartaddr); if ( (butxo= LP_address_myutxopair(&B,1,utxos,max,coin,qp->coinaddr,qp->txfee,dstr(qp->destsatoshis),price,qp->desttxfee)) != 0 )
qp->srchash = G.LP_mypub25519; {
qp->txid = butxo->payment.txid; strcpy(qp->gui,G.gui);
qp->vout = butxo->payment.vout; strcpy(qp->coinaddr,coin->smartaddr);
qp->txid2 = butxo->deposit.txid; qp->srchash = G.LP_mypub25519;
qp->vout2 = butxo->deposit.vout; qp->txid = butxo->payment.txid;
qp->satoshis = butxo->swap_satoshis;// + qp->txfee; qp->vout = butxo->payment.vout;
qp->quotetime = (uint32_t)time(NULL); qp->txid2 = butxo->deposit.txid;
qp->vout2 = butxo->deposit.vout;
if (coin->etomic[0] == 0) {
qp->satoshis = butxo->swap_satoshis;// + qp->txfee;
} else {
qp->satoshis = LP_basesatoshis(dstr(qp->destsatoshis), price, qp->txfee, qp->desttxfee);
}
qp->quotetime = (uint32_t)time(NULL);
break;
}
if ( qp->fill != 0 )
break;
qp->destsatoshis = (qp->destsatoshis * 2) / 3;
} }
else if ( butxo != 0 && j < voliters )
{ {
printf("i.%d cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f\n",i,(long long)qp->aliceid,qp->srccoin,qp->destcoin,dstr(LP_basesatoshis(dstr(qp->destsatoshis),price,qp->txfee,qp->desttxfee)),dstr(qp->destsatoshis)); if ( qp->satoshis <= qp->txfee )
return(0); return(0);
p = (double)qp->destsatoshis / (qp->satoshis - qp->txfee);
if ( LP_trades_pricevalidate(qp,coin,p) < 0. )
{
if ( qp->fill != 0 )
return(0);
price *= 0.995;
i++;
continue;
}
if ( i == 0 && p < myprice )
{
price = qprice;
printf("reset price <- qprice %.8f\n",qprice);
}
else
{
if ( qprice >= p || qp->fill != 0 )
break;
price *= 0.995;
}
if ( qp->fill != 0 )
break;
i++;
} }
if ( qp->satoshis <= qp->txfee ) else if ( qp->fill != 0 || i == priceiters )
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("i.%d cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f txfee %.8f\n",i,(long long)qp->aliceid,qp->srccoin,qp->destcoin,dstr(LP_basesatoshis(dstr(qp->destsatoshis),price,qp->txfee,qp->desttxfee)),dstr(qp->destsatoshis),dstr(qp->txfee));
printf("reset price <- qprice %.8f\n",qprice); if ( qp->gtc != 0 && qp->fill != 0 && coin != 0 && coin->electrum == 0 )
{
LP_address_utxo_reset(&num,coin);
satoshis = LP_basesatoshis(dstr(qp->destsatoshis),price,qp->txfee,qp->desttxfee) + 3*qp->txfee;
if ( LP_getheight(&notarized,coin) > coin->bobfillheight+3 && fabs((double)coin->fillsatoshis - satoshis)/satoshis > 0.1 )
{
printf("queue up do_autofill_merge %.8f\n",dstr(satoshis));
coin->do_autofill_merge = satoshis;
}
}
return(0);
} }
else else
{ {
if ( qprice >= p )
break;
price *= 0.995; price *= 0.995;
i++;
} }
i++;
} }
printf("%s/%s i.%d qprice %.8f myprice %.8f price %.8f [%.8f]\n",qp->srccoin,qp->destcoin,i,qprice,myprice,price,p); printf("%s/%s i.%d j.%d qprice %.8f myprice %.8f price %.8f [%.8f]\n",qp->srccoin,qp->destcoin,i,j,qprice,myprice,price,p);
if ( LP_allocated(qp->txid,qp->vout) == 0 && LP_allocated(qp->txid2,qp->vout2) == 0 ) if ( butxo != 0 && bits256_nonz(qp->txid) != 0 && bits256_nonz(qp->txid2) != 0 && LP_allocated(qp->txid,qp->vout) == 0 && LP_allocated(qp->txid2,qp->vout2) == 0 )
{ {
//printf("found unallocated txids\n"); //printf("found unallocated txids\n");
reqjson = LP_quotejson(qp); reqjson = LP_quotejson(qp);
@ -1047,10 +1212,18 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru
jaddnum(reqjson,"quotetime",qp->quotetime); jaddnum(reqjson,"quotetime",qp->quotetime);
jaddnum(reqjson,"pending",qp->timestamp + LP_RESERVETIME); jaddnum(reqjson,"pending",qp->timestamp + LP_RESERVETIME);
jaddstr(reqjson,"method","reserved"); jaddstr(reqjson,"method","reserved");
LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); {
bits256 zero; LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0));
memset(zero.bytes,0,sizeof(zero)); bits256 zero;
LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); memset(zero.bytes,0,sizeof(zero));
LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0));
}
if ( qp->mpnet != 0 && qp->gtc == 0 )
{
char *msg = jprint(reqjson,0);
LP_mpnet_send(0,msg,1,qp->destaddr);
free(msg);
}
free_json(reqjson); free_json(reqjson);
//printf("Send RESERVED id.%llu\n",(long long)qp->aliceid); //printf("Send RESERVED id.%llu\n",(long long)qp->aliceid);
return(qp); return(qp);
@ -1061,7 +1234,7 @@ struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,stru
struct LP_quoteinfo *LP_trades_gotreserved(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp) struct LP_quoteinfo *LP_trades_gotreserved(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp)
{ {
char *retstr; double qprice; char *retstr; double qprice;
//char str[65]; printf("alice %s received RESERVED.(%s) %.8f\n",bits256_str(str,G.LP_mypub25519),qp->uuidstr+32,(double)qp->destsatoshis/(qp->satoshis+1)); char str[65]; printf("alice %s received RESERVED.(%s) %.8f mpnet.%d fill.%d gtc.%d\n",bits256_str(str,G.LP_mypub25519),qp->uuidstr+32,(double)qp->destsatoshis/(qp->satoshis+1),qp->mpnet,qp->fill,qp->gtc);
*newqp = *qp; *newqp = *qp;
qp = newqp; qp = newqp;
if ( (qprice= LP_trades_alicevalidate(ctx,qp)) > 0. ) if ( (qprice= LP_trades_alicevalidate(ctx,qp)) > 0. )
@ -1103,7 +1276,7 @@ struct LP_quoteinfo *LP_trades_gotconnect(void *ctx,struct LP_quoteinfo *qp,stru
struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr)
{ {
char *retstr; int32_t changed; double val; char *retstr; int32_t changed; double val;
//char str[65]; printf("alice %s received CONNECTED.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); char str[65]; printf("alice %s received CONNECTED.(%llu) mpnet.%d fill.%d gtc.%d\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid,qp->mpnet,qp->fill,qp->gtc);
*newqp = *qp; *newqp = *qp;
qp = newqp; qp = newqp;
if ( (val= LP_trades_alicevalidate(ctx,qp)) > 0. ) if ( (val= LP_trades_alicevalidate(ctx,qp)) > 0. )
@ -1112,7 +1285,7 @@ struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,st
LP_aliceid(qp->tradeid,qp->aliceid,"connected",0,0); LP_aliceid(qp->tradeid,qp->aliceid,"connected",0,0);
if ( (retstr= LP_connectedalice(qp,pairstr)) != 0 ) if ( (retstr= LP_connectedalice(qp,pairstr)) != 0 )
free(retstr); free(retstr);
LP_mypriceset(&changed,qp->destcoin,qp->srccoin,0.); LP_mypriceset(0,&changed,qp->destcoin,qp->srccoin,0.);
LP_alicequery_clear(); LP_alicequery_clear();
return(qp); return(qp);
} else LP_failedmsg(qp->R.requestid,qp->R.quoteid,val,qp->uuidstr); } else LP_failedmsg(qp->R.requestid,qp->R.quoteid,val,qp->uuidstr);
@ -1367,7 +1540,7 @@ void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid)
//printf("queue.%d uuid.(%s)\n",funcid,qtp->Q.uuidstr); //printf("queue.%d uuid.(%s)\n",funcid,qtp->Q.uuidstr);
} }
int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) int32_t LP_tradecommand(int32_t from_mpnet,void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen)
{ {
int32_t Qtrades = 1; int32_t Qtrades = 1;
char *method,str[65]; int32_t i,num,DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; cJSON *proof; uint64_t rq; struct iguana_info *coin; struct LP_quoteinfo Q,Q2; int32_t counter,retval=-1; char *method,str[65]; int32_t i,num,DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; cJSON *proof; uint64_t rq; struct iguana_info *coin; struct LP_quoteinfo Q,Q2; int32_t counter,retval=-1;
@ -1380,7 +1553,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
} }
if ( Q.satoshis < Q.txfee ) if ( Q.satoshis < Q.txfee )
return(1); return(1);
LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector,Q.fill,Q.gtc);
rq = ((uint64_t)Q.R.requestid << 32) | Q.R.quoteid; 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? if ( Q.uuidstr[0] == 0 || (Q.timestamp > 0 && time(NULL) > Q.timestamp + LP_AUTOTRADE_TIMEOUT*20) ) // eat expired packets, some old timestamps floating about?
{ {
@ -1390,7 +1563,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
LP_tradecommand_log(argjson); LP_tradecommand_log(argjson);
qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); //jdouble(argjson,"price"); qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); //jdouble(argjson,"price");
//printf("%s\n",jprint(argjson,0)); //printf("%s\n",jprint(argjson,0));
printf("%-4d uuid.%32s %12s %5s/%-5s %12.8f -> %12.8f (%11.8f) | RT.%d %d n%d\n",(uint32_t)time(NULL) % 3600,Q.uuidstr+32,method,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),qprice,LP_RTcount,LP_swapscount,G.netid); printf("%-4d uuid.%32s M.%d g.%d f.%d %12s %5s/%-5s %12.8f -> %12.8f (%11.8f) | RT.%d %d n%d\n",(uint32_t)time(NULL) % 3600,Q.uuidstr+32,from_mpnet,Q.gtc,Q.fill,method,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),qprice,LP_RTcount,LP_swapscount,G.netid);
retval = 1; retval = 1;
aliceid = j64bits(argjson,"aliceid"); aliceid = j64bits(argjson,"aliceid");
if ( strcmp(method,"reserved") == 0 ) if ( strcmp(method,"reserved") == 0 )
@ -1438,7 +1611,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
if ( i == sizeof(rqs)/sizeof(*rqs) ) if ( i == sizeof(rqs)/sizeof(*rqs) )
i = (rand() % (sizeof(rqs)/sizeof(*rqs))); i = (rand() % (sizeof(rqs)/sizeof(*rqs)));
rqs[i] = rq; rqs[i] = rq;
//printf("CONNECTED.(%s)\n",jprint(argjson,0)); printf("CONNECTED.(%s)\n",jprint(argjson,0));
if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 )
Q.othercredits = LP_instantdex_proofcheck(Q.srccoin,Q.coinaddr,proof,num); Q.othercredits = LP_instantdex_proofcheck(Q.srccoin,Q.coinaddr,proof,num);
if ( Qtrades == 0 ) if ( Qtrades == 0 )
@ -1446,7 +1619,9 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECTED); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECTED);
} }
} }
price = LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin); if ( strcmp(method,"request") == 0 || strcmp(method,"connect") == 0 ) // bob
price = LP_myprice(1,&bid,&ask,Q.srccoin,Q.destcoin);
else price = LP_myprice(0,&bid,&ask,Q.srccoin,Q.destcoin); // alice
if ( (coin= LP_coinfind(Q.srccoin)) == 0 || coin->inactive != 0 ) if ( (coin= LP_coinfind(Q.srccoin)) == 0 || coin->inactive != 0 )
{ {
//printf("%s is not active\n",Q.srccoin); //printf("%s is not active\n",Q.srccoin);
@ -1459,7 +1634,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
} }
if ( LP_aliceonly(Q.srccoin) > 0 ) if ( LP_aliceonly(Q.srccoin) > 0 )
{ {
printf("{\"error\":\"GAME can only be alice coin\"}\n"); printf("{\"error\":\"alice only coins can only be alice coin\"}\n");
return(retval); return(retval);
} }
if ( strcmp(method,"request") == 0 ) // bob if ( strcmp(method,"request") == 0 ) // bob
@ -1469,6 +1644,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
if ( Q.destvout != Q.feevout || bits256_cmp(Q.desttxid,Q.feetxid) != 0 ) if ( Q.destvout != Q.feevout || bits256_cmp(Q.desttxid,Q.feetxid) != 0 )
{ {
bestprice = LP_bob_competition(&counter,aliceid,qprice,-1); bestprice = LP_bob_competition(&counter,aliceid,qprice,-1);
//printf("bestprice %.8f\n",bestprice);
if ( Qtrades == 0 )//|| (bits256_cmp(Q.srchash,G.LP_mypub25519) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0) ) 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")); LP_trades_gotrequest(ctx,&Q,&Q2,jstr(argjson,"pair"));
else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_REQUEST); else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_REQUEST);
@ -1489,7 +1665,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
if ( i == sizeof(rqs)/sizeof(*rqs) ) if ( i == sizeof(rqs)/sizeof(*rqs) )
i = (rand() % (sizeof(rqs)/sizeof(*rqs))); i = (rand() % (sizeof(rqs)/sizeof(*rqs)));
rqs[i] = rq; rqs[i] = rq;
//printf("CONNECT.(%s)\n",jprint(argjson,0)); printf("CONNECT.(%s)\n",jprint(argjson,0));
if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 ) if ( (proof= jarray(&num,argjson,"proof")) != 0 && num > 0 )
Q.othercredits = LP_instantdex_proofcheck(Q.destcoin,Q.destaddr,proof,num); Q.othercredits = LP_instantdex_proofcheck(Q.destcoin,Q.destaddr,proof,num);
if ( Qtrades == 0 ) if ( Qtrades == 0 )
@ -1502,7 +1678,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
return(retval); return(retval);
} }
char *LP_autobuy(void *ctx,int32_t fomoflag,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration,char *gui,uint32_t nonce,bits256 destpubkey,uint32_t tradeid,char *uuidstr) char *LP_autobuy(void *ctx,int32_t fomoflag,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration,char *gui,uint32_t nonce,bits256 destpubkey,uint32_t tradeid,char *uuidstr,int32_t fillflag,int32_t gtcflag)
{ {
uint64_t desttxfee,txfee,balance; uint32_t lastnonce; int64_t bestsatoshis=0,destsatoshis; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,B,A; struct LP_quoteinfo Q; bits256 pubkeys[100]; struct LP_address_utxo *utxos[4096]; int32_t num=0,maxiters=100,i,max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); char _uuidstr[65]; 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); basecoin = LP_coinfind(base);
@ -1589,6 +1765,10 @@ char *LP_autobuy(void *ctx,int32_t fomoflag,char *myipaddr,int32_t mypubsock,cha
memset(&A,0,sizeof(A)); memset(&A,0,sizeof(A));
if ( (autxo= LP_address_myutxopair(&A,0,utxos,max,relcoin,relcoin->smartaddr,txfee,dstr(destsatoshis),maxprice,desttxfee)) != 0 ) if ( (autxo= LP_address_myutxopair(&A,0,utxos,max,relcoin,relcoin->smartaddr,txfee,dstr(destsatoshis),maxprice,desttxfee)) != 0 )
break; break;
if ( fillflag != 0 )
{
return(clonestr("{\"error\":\"cant find a deposit that is big enough in size. make another deposit that is just a bit larger than what you want to trade\"}"));
}
destsatoshis *= 0.98; destsatoshis *= 0.98;
if ( destsatoshis < desttxfee*LP_MINSIZE_TXFEEMULT ) if ( destsatoshis < desttxfee*LP_MINSIZE_TXFEEMULT )
break; break;
@ -1604,13 +1784,13 @@ char *LP_autobuy(void *ctx,int32_t fomoflag,char *myipaddr,int32_t mypubsock,cha
autxo->swap_satoshis = destsatoshis; autxo->swap_satoshis = destsatoshis;
//printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->swap_satoshis)); //printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->swap_satoshis));
} }
else if ( autxo->swap_satoshis - desttxfee < destsatoshis ) else if ( autxo->swap_satoshis - desttxfee < destsatoshis && relcoin->etomic[0] == 0)
{ {
autxo->swap_satoshis -= desttxfee; autxo->swap_satoshis -= desttxfee;
destsatoshis = autxo->swap_satoshis; destsatoshis = autxo->swap_satoshis;
printf("second path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->swap_satoshis)); printf("second path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->swap_satoshis));
} }
if ( destsatoshis < (autxo->payment.value / LP_MINCLIENTVOL) || autxo->payment.value < desttxfee*LP_MINSIZE_TXFEEMULT ) if ( relcoin->etomic[0] == 0 && (destsatoshis < (autxo->payment.value / LP_MINCLIENTVOL) || autxo->payment.value < desttxfee*LP_MINSIZE_TXFEEMULT ))
{ {
printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value)); printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value));
return(clonestr("{\"error\":\"cant find a deposit that is close enough in size. make another deposit that is a bit larger than what you want to trade\"}")); return(clonestr("{\"error\":\"cant find a deposit that is close enough in size. make another deposit that is a bit larger than what you want to trade\"}"));
@ -1640,8 +1820,11 @@ char *LP_autobuy(void *ctx,int32_t fomoflag,char *myipaddr,int32_t mypubsock,cha
} }
} }
int32_t changed; int32_t changed;
LP_mypriceset(&changed,rel,base,1. / maxprice); Q.mpnet = G.mpnet;
LP_mypriceset(&changed,base,rel,0.); Q.fill = fillflag;
Q.gtc = gtcflag;
LP_mypriceset(0,&changed,rel,base,1. / maxprice);
LP_mypriceset(0,&changed,base,rel,0.);
if ( uuidstr == 0 || uuidstr[0] == 0 ) if ( uuidstr == 0 || uuidstr[0] == 0 )
{ {
uint8_t uuidhash[256]; bits256 hash; uint64_t millis; int32_t len = 0; uint8_t uuidhash[256]; bits256 hash; uint64_t millis; int32_t len = 0;

32
iguana/exchanges/LP_portfolio.c

@ -95,14 +95,18 @@ uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr)
cJSON *array,*item; bits256 zero; int32_t i,n; uint64_t valuesum,satoshisum,value; cJSON *array,*item; bits256 zero; int32_t i,n; uint64_t valuesum,satoshisum,value;
valuesum = satoshisum = 0; valuesum = satoshisum = 0;
memset(zero.bytes,0,sizeof(zero)); memset(zero.bytes,0,sizeof(zero));
/*
#ifndef NOTETOMIC #ifndef NOTETOMIC
struct iguana_info *coin = LP_coinfind(symbol); struct iguana_info *coin = LP_coinfind(symbol);
if (coin->etomic[0] != 0) { if (coin->etomic[0] != 0 && coin->inactive == 0) {
valuesum = LP_etomic_get_balance(coin, coinaddr); int error = 0;
uint64_t etomic_balance = LP_etomic_get_balance(coin, coinaddr, &error);
if (error == 0) {
valuesum = etomic_balance;
} else {
valuesum = *valuep;
}
} else } else
#endif #endif
*/
if ( (array= LP_listunspent(symbol,coinaddr,zero,zero)) != 0 ) if ( (array= LP_listunspent(symbol,coinaddr,zero,zero)) != 0 )
{ {
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
@ -152,7 +156,7 @@ char *LP_portfolio()
coin->balanceA = LP_balance(&coin->valuesumA,0,coin->symbol,coin->smartaddr); coin->balanceA = LP_balance(&coin->valuesumA,0,coin->symbol,coin->smartaddr);
coin->balanceB = LP_balance(&coin->valuesumB,1,coin->symbol,coin->smartaddr); coin->balanceB = LP_balance(&coin->valuesumB,1,coin->symbol,coin->smartaddr);
if ( strcmp(coin->symbol,"KMD") != 0 ) if ( strcmp(coin->symbol,"KMD") != 0 )
coin->price_kmd = LP_price(coin->symbol,"KMD"); coin->price_kmd = LP_price(1,coin->symbol,"KMD");
else coin->price_kmd = 1.; else coin->price_kmd = 1.;
coin->maxamount = coin->valuesumA; coin->maxamount = coin->valuesumA;
if ( coin->valuesumB > coin->maxamount ) if ( coin->valuesumB > coin->maxamount )
@ -274,7 +278,7 @@ void LP_autopriceset(int32_t ind,void *ctx,int32_t dir,struct LP_priceinfo *base
oppomargin = basepp->buymargins[relpp->ind]; oppomargin = basepp->buymargins[relpp->ind];
if ( (fixedprice= basepp->fixedprices[relpp->ind]) > SMALLVAL ) if ( (fixedprice= basepp->fixedprices[relpp->ind]) > SMALLVAL )
{ {
LP_mypriceset(&changed,relpp->symbol,basepp->symbol,fixedprice); LP_mypriceset(1,&changed,relpp->symbol,basepp->symbol,fixedprice);
//printf("autoprice FIXED %s/%s <- %.8f\n",basepp->symbol,relpp->symbol,fixedprice); //printf("autoprice FIXED %s/%s <- %.8f\n",basepp->symbol,relpp->symbol,fixedprice);
LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,fixedprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,fixedprice);
return; return;
@ -285,7 +289,7 @@ void LP_autopriceset(int32_t ind,void *ctx,int32_t dir,struct LP_priceinfo *base
factor = basepp->factors[relpp->ind]; factor = basepp->factors[relpp->ind];
if ( fabs(price) < SMALLVAL && refbase != 0 && refrel != 0 ) if ( fabs(price) < SMALLVAL && refbase != 0 && refrel != 0 )
{ {
price = LP_myprice(&bid,&ask,refbase,refrel); price = LP_myprice(1,&bid,&ask,refbase,refrel);
//printf("%s/%s USE ref %s/%s %.8f factor %.8f offset %.8f margin %.8f/%.8f\n",basepp->symbol,relpp->symbol,refbase,refrel,price,factor,offset,oppomargin,margin); //printf("%s/%s USE ref %s/%s %.8f factor %.8f offset %.8f margin %.8f/%.8f\n",basepp->symbol,relpp->symbol,refbase,refrel,price,factor,offset,oppomargin,margin);
} }
if ( LP_pricevalid(price) > 0 ) if ( LP_pricevalid(price) > 0 )
@ -312,7 +316,7 @@ void LP_autopriceset(int32_t ind,void *ctx,int32_t dir,struct LP_priceinfo *base
newprice = LP_autorefs[ind].lastask; newprice = LP_autorefs[ind].lastask;
//printf("autopriceset %s/%s <- %.8f %.8f (%.8f %.8f)\n",basepp->symbol,relpp->symbol,price,newprice,LP_autorefs[ind].lastbid,LP_autorefs[ind].lastask); //printf("autopriceset %s/%s <- %.8f %.8f (%.8f %.8f)\n",basepp->symbol,relpp->symbol,price,newprice,LP_autorefs[ind].lastbid,LP_autorefs[ind].lastask);
} }
LP_mypriceset(&changed,relpp->symbol,basepp->symbol,newprice); LP_mypriceset(1,&changed,relpp->symbol,basepp->symbol,newprice);
if ( changed != 0 || time(NULL) > lasttime+LP_ORDERBOOK_DURATION*.777) if ( changed != 0 || time(NULL) > lasttime+LP_ORDERBOOK_DURATION*.777)
{ {
lasttime = (uint32_t)time(NULL); lasttime = (uint32_t)time(NULL);
@ -582,9 +586,9 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp)
LP_autorefs[i].lastask = askprice; LP_autorefs[i].lastask = askprice;
else LP_autorefs[i].lastask = (LP_autorefs[i].lastask * 0.9) + (0.1 * askprice); else LP_autorefs[i].lastask = (LP_autorefs[i].lastask * 0.9) + (0.1 * askprice);
askprice = LP_autorefs[i].lastask; askprice = LP_autorefs[i].lastask;
LP_mypriceset(&changed,rel,base,bidprice); LP_mypriceset(1,&changed,rel,base,bidprice);
LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,bidprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,bidprice);
LP_mypriceset(&changed,base,rel,askprice); LP_mypriceset(1,&changed,base,rel,askprice);
LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,askprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,askprice);
//printf("price %.8f -> %.8f %.8f\n",price,bidprice,askprice); //printf("price %.8f -> %.8f %.8f\n",price,bidprice,askprice);
} }
@ -626,7 +630,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp)
LP_autorefs[i].lastbid = newprice; LP_autorefs[i].lastbid = newprice;
else LP_autorefs[i].lastbid = (LP_autorefs[i].lastbid * 0.99) + (0.01 * newprice); else LP_autorefs[i].lastbid = (LP_autorefs[i].lastbid * 0.99) + (0.01 * newprice);
newprice = LP_autorefs[i].lastbid; newprice = LP_autorefs[i].lastbid;
LP_mypriceset(&changed,rel,base,newprice); LP_mypriceset(1,&changed,rel,base,newprice);
LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice);
//printf("%s/%s price %.8f margin %.8f/%.8f newprice %.8f %.8f\n",base,rel,price,buymargin,sellmargin,newprice,(1. / newprice) * (1. + sellmargin)); //printf("%s/%s price %.8f margin %.8f/%.8f newprice %.8f %.8f\n",base,rel,price,buymargin,sellmargin,newprice,(1. / newprice) * (1. + sellmargin));
newprice = (1. / price) * (1. + sellmargin); newprice = (1. / price) * (1. + sellmargin);
@ -634,7 +638,7 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp)
LP_autorefs[i].lastask = newprice; LP_autorefs[i].lastask = newprice;
else LP_autorefs[i].lastask = (LP_autorefs[i].lastask * 0.99) + (0.01 * newprice); else LP_autorefs[i].lastask = (LP_autorefs[i].lastask * 0.99) + (0.01 * newprice);
newprice = LP_autorefs[i].lastask; newprice = LP_autorefs[i].lastask;
LP_mypriceset(&changed,base,rel,newprice); LP_mypriceset(1,&changed,base,rel,newprice);
LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice);
} //else printf("null return from CMC\n"); } //else printf("null return from CMC\n");
} }
@ -782,7 +786,7 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str
char *retstr2; uint64_t txfee,desttxfee; double bid,ask,maxprice; bits256 zero; uint32_t requestid,quoteid,iter,i; cJSON *retjson2; struct LP_utxoinfo A; struct LP_address_utxo *utxos[1000]; int32_t max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); char *retstr2; uint64_t txfee,desttxfee; double bid,ask,maxprice; bits256 zero; uint32_t requestid,quoteid,iter,i; cJSON *retjson2; struct LP_utxoinfo A; struct LP_address_utxo *utxos[1000]; int32_t max=(int32_t)(sizeof(utxos)/sizeof(*utxos));
LP_txfees(&txfee,&desttxfee,buy->symbol,sell->symbol); LP_txfees(&txfee,&desttxfee,buy->symbol,sell->symbol);
requestid = quoteid = 0; requestid = quoteid = 0;
LP_myprice(&bid,&ask,buy->symbol,sell->symbol); LP_myprice(1,&bid,&ask,buy->symbol,sell->symbol);
maxprice = ask; maxprice = ask;
if ( setbaserel != 0 ) if ( setbaserel != 0 )
{ {
@ -802,7 +806,7 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str
//if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 ) //if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 )
{ {
memset(zero.bytes,0,sizeof(zero)); memset(zero.bytes,0,sizeof(zero));
if ( (retstr2= LP_autobuy(ctx,0,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1,zero,1,0)) != 0 ) if ( (retstr2= LP_autobuy(ctx,0,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1,zero,1,0,0,0)) != 0 )
{ {
if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) if ( (retjson2= cJSON_Parse(retstr2)) != 0 )
{ {

87
iguana/exchanges/LP_prices.c

@ -35,7 +35,7 @@ struct LP_priceinfo
int32_t ind,pad; int32_t ind,pad;
double diagval,high[2],low[2],last[2],bid[2],ask[2]; double diagval,high[2],low[2],last[2],bid[2],ask[2];
double relvals[LP_MAXPRICEINFOS]; double relvals[LP_MAXPRICEINFOS];
double myprices[LP_MAXPRICEINFOS]; double myprices[2][LP_MAXPRICEINFOS];
double minprices[LP_MAXPRICEINFOS]; // autoprice double minprices[LP_MAXPRICEINFOS]; // autoprice
double fixedprices[LP_MAXPRICEINFOS]; // fixedprices double fixedprices[LP_MAXPRICEINFOS]; // fixedprices
double buymargins[LP_MAXPRICEINFOS]; double buymargins[LP_MAXPRICEINFOS];
@ -451,16 +451,16 @@ void LP_priceinfoupdate(char *base,char *rel,double price)
} }
} }
double LP_myprice(double *bidp,double *askp,char *base,char *rel) double LP_myprice(int32_t iambob,double *bidp,double *askp,char *base,char *rel)
{ {
struct LP_priceinfo *basepp,*relpp; double val; struct LP_priceinfo *basepp,*relpp; double val;
*bidp = *askp = 0.; *bidp = *askp = 0.;
if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{ {
*askp = basepp->myprices[relpp->ind]; *askp = basepp->myprices[iambob][relpp->ind];
if ( LP_pricevalid(*askp) > 0 ) if ( LP_pricevalid(*askp) > 0 )
{ {
val = relpp->myprices[basepp->ind]; val = relpp->myprices[iambob][basepp->ind];
if ( LP_pricevalid(val) > 0 ) if ( LP_pricevalid(val) > 0 )
{ {
*bidp = 1. / val; *bidp = 1. / val;
@ -474,7 +474,7 @@ double LP_myprice(double *bidp,double *askp,char *base,char *rel)
} }
else else
{ {
val = relpp->myprices[basepp->ind]; val = relpp->myprices[iambob][basepp->ind];
if ( LP_pricevalid(val) > 0 ) if ( LP_pricevalid(val) > 0 )
{ {
*bidp = 1. / val; *bidp = 1. / val;
@ -486,7 +486,7 @@ double LP_myprice(double *bidp,double *askp,char *base,char *rel)
return(0.); return(0.);
} }
char *LP_myprices() char *LP_myprices(int32_t iambob)
{ {
int32_t baseid,relid; double bid,ask; char *base,*rel; cJSON *item,*array; int32_t baseid,relid; double bid,ask; char *base,*rel; cJSON *item,*array;
array = cJSON_CreateArray(); array = cJSON_CreateArray();
@ -496,7 +496,7 @@ char *LP_myprices()
for (relid=0; relid<LP_numpriceinfos; relid++) for (relid=0; relid<LP_numpriceinfos; relid++)
{ {
rel = LP_priceinfos[relid].symbol; rel = LP_priceinfos[relid].symbol;
if ( LP_myprice(&bid,&ask,base,rel) > SMALLVAL ) if ( LP_myprice(iambob,&bid,&ask,base,rel) > SMALLVAL )
{ {
item = cJSON_CreateObject(); item = cJSON_CreateObject();
jaddstr(item,"base",base); jaddstr(item,"base",base);
@ -510,7 +510,7 @@ char *LP_myprices()
return(jprint(array,1)); return(jprint(array,1));
} }
int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) int32_t LP_mypriceset(int32_t iambob,int32_t *changedp,char *base,char *rel,double price)
{ {
struct LP_priceinfo *basepp=0,*relpp=0; struct LP_pubkey_info *pubp; double minprice,maxprice,margin,buymargin,sellmargin; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_pubkey_info *pubp; double minprice,maxprice,margin,buymargin,sellmargin;
*changedp = 0; *changedp = 0;
@ -519,43 +519,46 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price)
if ( base != 0 && rel != 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) if ( base != 0 && rel != 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{ {
if ( price == 0. || fabs(basepp->myprices[relpp->ind] - price)/price > 0.001 ) if ( price == 0. || fabs(basepp->myprices[iambob][relpp->ind] - price)/price > 0.001 )
*changedp = 1; *changedp = 1;
sellmargin = relpp->sellmargins[basepp->ind]; if ( iambob != 0 )
buymargin = relpp->buymargins[basepp->ind];
margin = (sellmargin + buymargin) * 0.5;
if ( price == 0. )
{ {
relpp->minprices[basepp->ind] = 0.; sellmargin = relpp->sellmargins[basepp->ind];
relpp->fixedprices[basepp->ind] = 0.; buymargin = relpp->buymargins[basepp->ind];
relpp->buymargins[basepp->ind] = 0.; margin = (sellmargin + buymargin) * 0.5;
relpp->sellmargins[basepp->ind] = 0.; if ( price == 0. )
relpp->offsets[basepp->ind] = 0.; {
relpp->factors[basepp->ind] = 0.; relpp->minprices[basepp->ind] = 0.;
LP_autoref_clear(base,rel); relpp->fixedprices[basepp->ind] = 0.;
margin = 0.; relpp->buymargins[basepp->ind] = 0.;
} relpp->sellmargins[basepp->ind] = 0.;
else if ( (minprice= basepp->minprices[relpp->ind]) > SMALLVAL && price < minprice ) relpp->offsets[basepp->ind] = 0.;
{ relpp->factors[basepp->ind] = 0.;
//printf("%s/%s price %.8f less than minprice %.8f\n",base,rel,price,minprice); LP_autoref_clear(base,rel);
price = minprice * (1. - margin); margin = 0.;
} }
else if ( (maxprice= relpp->minprices[basepp->ind]) > SMALLVAL ) else if ( (minprice= basepp->minprices[relpp->ind]) > SMALLVAL && price < minprice )
{ {
if ( price > (1. / maxprice) ) //printf("%s/%s price %.8f less than minprice %.8f\n",base,rel,price,minprice);
price = minprice * (1. - margin);
}
else if ( (maxprice= relpp->minprices[basepp->ind]) > SMALLVAL )
{ {
//printf("%s/%s price %.8f less than maxprice %.8f, more than %.8f\n",base,rel,price,maxprice,1./maxprice); if ( price > (1. / maxprice) )
price = (1. / maxprice) * (1. + margin); {
//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 ) /*else if ( basepp->myprices[relpp->ind] > SMALLVAL )
{ {
price = (basepp->myprices[relpp->ind] * 0.9) + (0.1 * price); price = (basepp->myprices[relpp->ind] * 0.9) + (0.1 * price);
}*/ }*/
basepp->myprices[relpp->ind] = price; // ask basepp->myprices[iambob][relpp->ind] = price; // ask
//printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); //printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price);
//relpp->myprices[basepp->ind] = (1. / price); // bid, but best to do one dir at a time //relpp->myprices[basepp->ind] = (1. / price); // bid, but best to do one dir at a time
if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 ) if ( iambob != 0 && (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 )
{ {
pubp->timestamp = (uint32_t)time(NULL); pubp->timestamp = (uint32_t)time(NULL);
LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,0,0,0,0,0); LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,0,0,0,0,0);
@ -569,12 +572,12 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price)
return(-1); return(-1);
} }
double LP_price(char *base,char *rel) double LP_price(int32_t iambob,char *base,char *rel)
{ {
struct LP_priceinfo *basepp; int32_t relind; double price = 0.; struct LP_priceinfo *basepp; int32_t relind; double price = 0.;
if ( (basepp= LP_priceinfoptr(&relind,base,rel)) != 0 ) if ( (basepp= LP_priceinfoptr(&relind,base,rel)) != 0 )
{ {
if ( (price= basepp->myprices[relind]) == 0. ) if ( (price= basepp->myprices[iambob][relind]) == 0. )
{ {
price = basepp->relvals[relind]; price = basepp->relvals[relind];
} }
@ -582,19 +585,19 @@ double LP_price(char *base,char *rel)
return(price); return(price);
} }
double LP_getmyprice(char *base,char *rel) double LP_getmyprice(int32_t iambob,char *base,char *rel)
{ {
struct LP_priceinfo *basepp; int32_t relind; double price = 0.; struct LP_priceinfo *basepp; int32_t relind; double price = 0.;
if ( (basepp= LP_priceinfoptr(&relind,base,rel)) != 0 ) if ( (basepp= LP_priceinfoptr(&relind,base,rel)) != 0 )
{ {
if ( (price= basepp->myprices[relind]) == 0. ) if ( (price= basepp->myprices[iambob][relind]) == 0. )
{ {
} }
} }
return(price); return(price);
} }
cJSON *LP_priceinfomatrix(int32_t usemyprices) cJSON *LP_priceinfomatrix(int32_t iambob,int32_t usemyprices)
{ {
int32_t i,j,n,m; double total,sum,val; struct LP_priceinfo *pp; uint32_t now; struct LP_cacheinfo *ptr,*tmp; cJSON *vectorjson = cJSON_CreateObject(); int32_t i,j,n,m; double total,sum,val; struct LP_priceinfo *pp; uint32_t now; struct LP_cacheinfo *ptr,*tmp; cJSON *vectorjson = cJSON_CreateObject();
now = (uint32_t)time(NULL); now = (uint32_t)time(NULL);
@ -611,7 +614,7 @@ cJSON *LP_priceinfomatrix(int32_t usemyprices)
pp->diagval = sum = n = 0; pp->diagval = sum = n = 0;
for (j=0; j<LP_numpriceinfos; j++) for (j=0; j<LP_numpriceinfos; j++)
{ {
if ( usemyprices == 0 || (val= pp->myprices[j]) == 0. ) if ( usemyprices == 0 || (val= pp->myprices[iambob][j]) == 0. )
val = pp->relvals[j]; val = pp->relvals[j];
if ( val > SMALLVAL ) if ( val > SMALLVAL )
{ {
@ -661,7 +664,7 @@ struct LP_priceinfo *LP_priceinfoadd(char *symbol)
pp->coinbits = stringbits(symbol); pp->coinbits = stringbits(symbol);
pp->ind = LP_numpriceinfos++; pp->ind = LP_numpriceinfos++;
//LP_numpriceinfos++; //LP_numpriceinfos++;
if ( (retjson= LP_priceinfomatrix(0)) != 0 ) if ( (retjson= LP_priceinfomatrix(1,0)) != 0 )
free_json(retjson); free_json(retjson);
return(pp); return(pp);
} }
@ -1016,7 +1019,7 @@ int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance)
KMDvalue = balance; KMDvalue = balance;
else else
{ {
if ( (price= LP_price(coin->symbol,"KMD")) > SMALLVAL ) if ( (price= LP_price(1,coin->symbol,"KMD")) > SMALLVAL )
KMDvalue = price * balance; KMDvalue = price * balance;
} }
} }

278
iguana/exchanges/LP_privkey.c

@ -202,6 +202,66 @@ char *LP_secretaddresses(void *ctx,char *prefix,char *passphrase,int32_t n,uint8
return(jprint(retjson,1)); return(jprint(retjson,1));
} }
uint32_t komodo_segid32(char *coinaddr)
{
bits256 addrhash;
vcalc_sha256(0,(uint8_t *)&addrhash,(uint8_t *)coinaddr,(int32_t)strlen(coinaddr));
return(addrhash.uints[0]);
}
char *LP_gen64addrs(void *ctx,char *passphrase,uint8_t taddr,uint8_t pubtype)
{
int32_t i,segid,n=64; uint8_t tmptype,pubkey33[33],rmd160[20]; char str[65],str2[65],buf[8192],wifstr[64],coinaddr[64],coinaddrs[64][64],wifstrs[64][64]; uint64_t mask = 0; bits256 checkprivkey,privkey,pubkey; cJSON *retjson,*addrs,*array;
if ( passphrase == 0 || passphrase[0] == 0 )
passphrase = "password";
memset(coinaddrs,0,sizeof(coinaddrs));
memset(wifstrs,0,sizeof(wifstrs));
conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
bitcoin_priv2pub(ctx,"KMD",pubkey33,coinaddr,privkey,taddr,pubtype);
//sprintf(output,"\"addresses\":[");
for (i=0; bitweight(mask)<64; i++)
{
sprintf(buf,"%s %03d",passphrase,i);
conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)buf,(int32_t)strlen(buf));
bitcoin_priv2pub(ctx,"KMD",pubkey33,coinaddr,privkey,taddr,pubtype);
bitcoin_priv2wif("KMD",0,wifstr,privkey,188);
bitcoin_wif2priv("KMD",0,&tmptype,&checkprivkey,wifstr);
bitcoin_addr2rmd160("KMD",taddr,&tmptype,rmd160,coinaddr);
if ( bits256_cmp(checkprivkey,privkey) != 0 )
{
printf("WIF.(%s) error -> %s vs %s?\n",wifstr,bits256_str(str,privkey),bits256_str(str2,checkprivkey));
free_json(retjson);
return(clonestr("{\"error\":\"couldnt validate wifstr\"}"));
}
else if ( tmptype != pubtype )
{
printf("checktype.%d != pubtype.%d\n",tmptype,pubtype);
free_json(retjson);
return(clonestr("{\"error\":\"couldnt validate pubtype\"}"));
}
segid = komodo_segid32(coinaddr) & 0x3f;
if ( (mask & (1LL << segid)) == 0 )
{
mask |= (1LL << segid);
strcpy(coinaddrs[segid],coinaddr);
strcpy(wifstrs[segid],wifstr);
printf("./komodo-cli -ac_name=POSTEST64 importprivkey %s "" %s\n",wifstr,bitweight(mask)<64?"false":"true");
}
//sprintf(output+strlen(output),"\\\"%s\\\"%c ",coinaddr,i<n-1?',':' ');
}
retjson = cJSON_CreateObject();
addrs = cJSON_CreateObject();
array = cJSON_CreateArray();
for (i=0; i<n; i++)
jaddstr(addrs,coinaddrs[i],wifstrs[i]);
jadd(retjson,"addrpairs",addrs);
for (i=0; i<n; i++)
jaddistr(array,coinaddrs[i]);
jadd(retjson,"addresses",array);
//printf("%s]\n",output);
return(jprint(retjson,1));
}
static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
int32_t LP_wifstr_valid(char *symbol,char *wifstr) int32_t LP_wifstr_valid(char *symbol,char *wifstr)
@ -227,7 +287,7 @@ int32_t LP_wifstr_valid(char *symbol,char *wifstr)
} }
if ( n == 0 || A == 0 || a == 0 ) if ( n == 0 || A == 0 || a == 0 )
return(0); return(0);
if ( A > 5*a || a > 5*A || a > n*20 || A > n*20 ) // unlikely it is a real wif if ( A > 5*a || a > 5*A || a > n*26 || A > n*26 ) // unlikely it is a real wif
{ {
printf("reject wif %s due to n.%d a.%d A.%d (%d %d %d %d)\n",wifstr,n,a,A,A > 5*a,a < 5*A,a > n*20,A > n*20); 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); return(0);
@ -292,6 +352,7 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
{ {
//static uint32_t counter; //static uint32_t counter;
bits256 privkey,userpub,zero,userpass,checkkey,tmpkey; char str[65],str2[65],tmpstr[128]; cJSON *retjson; uint8_t tmptype,sig[128]; int32_t notarized,siglen; uint64_t nxtaddr; bits256 privkey,userpub,zero,userpass,checkkey,tmpkey; char str[65],str2[65],tmpstr[128]; cJSON *retjson; uint8_t tmptype,sig[128]; int32_t notarized,siglen; uint64_t nxtaddr;
uint8_t rmd160[20];
if ( (wifstr == 0 || wifstr[0] == 0) && LP_wifstr_valid(coin->symbol,passphrase) > 0 ) if ( (wifstr == 0 || wifstr[0] == 0) && LP_wifstr_valid(coin->symbol,passphrase) > 0 )
{ {
wifstr = passphrase; wifstr = passphrase;
@ -339,7 +400,7 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
#ifndef NOTETOMIC #ifndef NOTETOMIC
if ( coin->etomic[0] != 0 ) if ( coin->etomic[0] != 0 )
{ {
uint8_t check64[64],checktype,checkrmd160[20],rmd160[20]; char checkaddr[64],checkaddr2[64]; uint8_t check64[64],checktype,checkrmd160[20]; char checkaddr[64],checkaddr2[64];
if ( LP_etomic_priv2pub(check64,privkey) == 0 ) if ( LP_etomic_priv2pub(check64,privkey) == 0 )
{ {
if ( memcmp(check64,coin->pubkey33+1,32) == 0 ) if ( memcmp(check64,coin->pubkey33+1,32) == 0 )
@ -374,8 +435,8 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
coin->counter++; coin->counter++;
memcpy(G.LP_pubsecp,coin->pubkey33,33); memcpy(G.LP_pubsecp,coin->pubkey33,33);
bitcoin_priv2wif(coin->symbol,coin->wiftaddr,tmpstr,privkey,coin->wiftype); bitcoin_priv2wif(coin->symbol,coin->wiftaddr,tmpstr,privkey,coin->wiftype);
bitcoin_addr2rmd160(coin->symbol,coin->taddr,&tmptype,G.LP_myrmd160,coin->smartaddr); bitcoin_addr2rmd160(coin->symbol,coin->taddr,&tmptype,rmd160,coin->smartaddr);
LP_privkeyadd(privkey,G.LP_myrmd160); LP_privkeyadd(privkey,rmd160);
G.LP_privkey = privkey; G.LP_privkey = privkey;
if ( G.counter++ == 0 ) if ( G.counter++ == 0 )
{ {
@ -415,6 +476,209 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
return(privkey); return(privkey);
} }
void verus_utxos(struct iguana_info *coin,char *coinaddr)
{
cJSON *array,*item; char buf[64],str[65]; int32_t i,m,vout,n=0; bits256 txid;
sprintf(buf,"[%d, 99999999, [\"%s\"]]",1,coinaddr);
array = bitcoin_json(coin,"listunspent",buf);
if ( array != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=m=0; i<n; i++)
{
item = jitem(array,i);
if ( fabs(jdouble(item,"amount") - 64.) < 0.00011 )
{
txid = jbits256(item,"txid");
vout = jint(item,"vout");
printf("%d: %s/v%d\n",m,bits256_str(str,txid),vout);
m++;
}
}
}
free_json(array);
}
printf("scanned %d utxos m.%d\n",n,m);
}
char *verusblocks()
{
bits256 hash,txid; uint8_t script[44]; double value,avestakedsize,stakedval,RTu3sum,powsum,supply,possum,histo[1280],myhisto[1280]; int32_t num10,num17,num20,num16,num23000,numpow,numpos,num,locked,height,i,m,n,z,gotblock,numstaked,posflag,npos,npow; char hashstr[64],firstaddr[64],stakingaddr[64],*addr0,*lastaddr,*hexstr; cJSON *blockjson,*txobj,*vouts,*vout,*vout1,*sobj,*addresses,*txs;
struct iguana_info *coin = LP_coinfind("VRSC");
if ( coin == 0 )
return(clonestr("{\"error\":\"VRSC not active\"}"));
char *coinaddr = "RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj";
if ( strcmp(coinaddr,coin->smartaddr) != 0 )
return(clonestr("{\"error\":\"mismatched smartaddr\"}"));
//verus_utxos(coin,coin->smartaddr);
hash = LP_getbestblockhash(coin);
memset(histo,0,sizeof(histo));
memset(myhisto,0,sizeof(myhisto));
num23000 = num16 = num17 = num10 = num20 = numstaked = 0;
avestakedsize = possum = powsum = supply = RTu3sum = 0.;
numpow = numpos = num = npos = npow = 0;
if ( bits256_nonz(hash) != 0 )
{
bits256_str(hashstr,hash);
height = -1;
while ( (blockjson= LP_blockjson(&height,coin->symbol,hashstr,0)) != 0 )
{
num++;
stakedval = 0.;
height = juint(blockjson,"height");
if ( (txs= jarray(&n,blockjson,"tx")) != 0 )
{
txid = jbits256i(txs,0);
value = 0;
posflag = 0;
locked = 0;
gotblock = 0;
lastaddr = addr0 = "";
memset(script,0,sizeof(script));
memset(firstaddr,0,sizeof(firstaddr));
memset(stakingaddr,0,sizeof(stakingaddr));
if ( (txobj= LP_gettx("verus",coin->symbol,txid,0)) != 0 )
{
//printf("TX.(%s)\n",jprint(txobj,0));
if ( (vouts= jarray(&m,txobj,"vout")) != 0 )
{
if ( (vout= jitem(vouts,0)) != 0 )
{
value = jdouble(vout,"value");
supply += value;
hexstr = 0;
if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 )
{
if ( strcmp(hexstr,"2102ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92ac") == 0 || strcmp(hexstr,"2102aef0f54a967031f4c63b36d12741fbb9ca39713baedfff7f8c0d0d8ee14ee0ebac") == 0 || strcmp(hexstr,"76a914cc39e9e699f86b03a5cf1d7f2a0b411cf652641788ac") == 0 || strcmp(hexstr,"76a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688ac") == 0 )
{
gotblock = 1;
}
}
if ( m == 2 && (vout1= jitem(vouts,1)) != 0 )
{
// 6a2001039bbc0bb17576a9149a3af738444dd86b55c86752247aec2e7deb842688ac
if ( jdouble(vout1,"value") == 0. && (sobj= jobj(vout1,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && strlen(hexstr) <= 88 )
{
if ( strlen(hexstr) == 68 )
{
decode_hex(script,34,hexstr);
bitcoin_address(coin->symbol,firstaddr,coin->taddr,coin->pubtype,&script[12],20);
//printf("%s\n",&hexstr[24]);
}
else
{
decode_hex(script,44,hexstr);
bitcoin_address(coin->symbol,firstaddr,coin->taddr,coin->pubtype,&script[10],33);
}
locked = ((int32_t)script[6] << 16) + ((int32_t)script[5] << 8) + script[4];
addr0 = firstaddr;
} else printf("unexpected vout1.(%s) (%s).%d %.8f\n",jprint(vout1,0),hexstr!=0?hexstr:"",(int32_t)strlen(hexstr),jdouble(vout1,"value"));
} //else printf("coinbase without opret (%s)\n",jprint(vouts,0));
}
}
free_json(txobj);
}
if ( n > 1 && (txobj= LP_gettx("verus",coin->symbol,jbits256i(txs,n-1),0)) != 0 )
{
if ( (vouts= jarray(&m,txobj,"vout")) != 0 )
{
if ( (vout= jitem(vouts,0)) != 0 && m == 1 )
{
if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (addresses= jarray(&z,sobj,"addresses")) != 0 )
{
lastaddr = jstri(addresses,0);
if ( lastaddr == 0 )
lastaddr = "";
else
{
strcpy(stakingaddr,lastaddr);
stakedval = jdouble(vout,"value");
avestakedsize += stakedval;
numstaked++;
//printf("stakedval %f\n",stakedval);
posflag = 1;
//printf("ht.%d found staking address.(%s) %.8f (%s)\n",height,stakingaddr,stakedval,jprint(vout,0));
}
} else printf("no addresses[0] in (%s) %s\n",jprint(vout,0),sobj!=0?jprint(sobj,0):"");
} //else printf("n.%d m.%d no first out in lastvout.(%s)\n",n,m,jprint(txobj,0));
} // else printf("cant find vout.(%s)\n",jprint(txobj,0));
free_json(txobj);
}
if ( posflag != 0 )
{
numpos++;
if ( strcmp(coinaddr,stakingaddr) == 0 || strcmp("RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC",stakingaddr) == 0 )
{
if (strcmp("RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC",stakingaddr) == 0 )
RTu3sum += value;
possum += value, npos++;
if ( num < 1500 )
printf("ht.%-5d lock.%-7d PoS cb.(%s) stake.(%s) %.8f %.8f\n",height,locked,addr0,stakingaddr,value,stakedval);
if ( height > 23000 )
{
char strbuf[64];
sprintf(strbuf,"%.0f",stakedval);
if ( strcmp(strbuf,"20") == 0 )
num20++;
else if ( strcmp(strbuf,"17") == 0 )
num17++;
else if ( strcmp(strbuf,"16") == 0 )
num16++;
else if ( strcmp(strbuf,"10") == 0 )
num10++;
else printf("got strbuf.(%s)\n",strbuf);
}
}
else if ( 0 && num < 100 )
printf("ht.%-5d lock.%-7d PoS cb.(%s) stake.(%s) %.8f %.8f\n",height,locked,addr0,stakingaddr,value,stakedval);
}
else
{
numpow++;
if ( num < 100 && strcmp(coinaddr,addr0) == 0 )
printf("ht.%-5d lock.%-7d PoW coinbase.(%s) %.8f\n",height,locked,addr0,value);
if ( strcmp(coinaddr,addr0) == 0 || gotblock != 0 )
powsum += value, npow++;
}
histo[locked/1000] += value;
if ( strcmp(coinaddr,addr0) == 0 || strcmp("RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC",addr0) == 0 )
myhisto[locked/1000] += value;
}
bits256_str(hashstr,jbits256(blockjson,"previousblockhash"));
free_json(blockjson);
if ( height == 5040 )
break;
else if ( height == 23000 )
{
num23000 = num;
printf("num10.%d num16.%d num17.%d num20.%d / num23000.%d -> %.2f%% %.2f%% %.2f%% %.2f%% [%.3f %.3f %.3f %.3f] %.3f ave %.8f\n",num10,num16,num17,num20,num23000,100.*(double)num10/num23000,100.*(double)num16/num23000,100.*(double)num17/num23000,100.*(double)num20/num23000,(100.*(double)num10/num23000)/2.87,(100.*(double)num16/num23000)/10.5,(100.*(double)num17/num23000)/4.88,(100.*(double)num20/num23000)/5.74,(100.*(double)(num10+num16+num17+num20)/num23000)/24,avestakedsize/numstaked);
}
else if ( (num % 1000) == 0 || (num < 1000 && (num % 100) == 0) )
{
printf("num.%d PoW %.2f%% %.0f %d v %d PoS %.2f%% %.0f -> %.0f supply %.0f PoW %.1f%% PoS %.1f%% both %.1f%% RTu3 %.8f %.1f%%\n",num,100.*(double)numpow/num,powsum,npow,npos,100.*(double)numpos/num,possum,powsum+possum,supply,100.*powsum/supply,100.*possum/supply,100.*(powsum+possum)/supply,RTu3sum,100.*RTu3sum/supply);
}
}
}
if ( num > 0 )
{
if ( 0 )
{
for (i=0; i<sizeof(histo)/sizeof(*histo); i++)
if ( histo[i] != 0 )
printf("%d %.8f, ",i*1000,histo[i]);
printf("timelocked\n");
for (i=0; i<sizeof(myhisto)/sizeof(*myhisto); i++)
if ( myhisto[i] != 0 )
printf("%d %.8f, ",i*1000,myhisto[i]);
printf("mytimelocked\n");
}
printf("num.%d PoW %.2f%% %.8f %d v %d PoS %.2f%% %.8f -> %.8f supply %.8f PoW %.1f%% PoS %.1f%% both %.1f%% RTu3sum %.8f %.1f%%\n",num,100.*(double)numpow/num,powsum,npow,npos,100.*(double)numpos/num,possum,powsum+possum,supply,100.*powsum/supply,100.*possum/supply,100.*(powsum+possum)/supply,RTu3sum,100.*RTu3sum/supply);
printf("num10.%d num16.%d num17.%d num20.%d / num23000.%d -> %.2f%% %.2f%% %.2f%% %.2f%% [%.3f %.3f %.3f %.3f] %.3f ave %.8f\n",num10,num16,num17,num20,num23000,100.*(double)num10/num23000,100.*(double)num16/num23000,100.*(double)num17/num23000,100.*(double)num20/num23000,(100.*(double)num10/num23000)/2.87,(100.*(double)num16/num23000)/10.5,(100.*(double)num17/num23000)/4.88,(100.*(double)num20/num23000)/5.74,(100.*(double)(num10+num16+num17+num20)/num23000)/24,avestakedsize/numstaked);
}
return(clonestr("{\"result\":\"success\"}"));
}
void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase) void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase)
{ {
struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33]; int32_t initonly; struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33]; int32_t initonly;
@ -431,7 +695,9 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase)
coin->counter = 0; coin->counter = 0;
memset(coin->smartaddr,0,sizeof(coin->smartaddr)); memset(coin->smartaddr,0,sizeof(coin->smartaddr));
if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 ) if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 )
{
privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,""); privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,"");
}
} }
//printf("i.%d of %d\n",i,LP_numcoins); //printf("i.%d of %d\n",i,LP_numcoins);
else if ( IAMLP == 0 || coin->inactive == 0 ) else if ( IAMLP == 0 || coin->inactive == 0 )
@ -448,6 +714,7 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase)
int32_t LP_passphrase_init(char *passphrase,char *gui,uint16_t netid,char *seednode) int32_t LP_passphrase_init(char *passphrase,char *gui,uint16_t netid,char *seednode)
{ {
static void *ctx; struct iguana_info *coin,*tmp; int32_t counter; static void *ctx; struct iguana_info *coin,*tmp; int32_t counter;
uint8_t pubkey33[100];
if ( ctx == 0 ) if ( ctx == 0 )
ctx = bitcoin_ctx(); ctx = bitcoin_ctx();
if ( G.LP_pendingswaps != 0 ) if ( G.LP_pendingswaps != 0 )
@ -482,8 +749,11 @@ int32_t LP_passphrase_init(char *passphrase,char *gui,uint16_t netid,char *seedn
memset(&G,0,sizeof(G)); memset(&G,0,sizeof(G));
G.netid = netid; G.netid = netid;
safecopy(G.seednode,seednode,sizeof(G.seednode)); safecopy(G.seednode,seednode,sizeof(G.seednode));
vcalc_sha256(0,G.LP_passhash.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); vcalc_sha256(0,G.LP_passhash.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
LP_privkey_updates(ctx,LP_mypubsock,passphrase); LP_privkey_updates(ctx,LP_mypubsock,passphrase);
bitcoin_pubkey33(ctx, pubkey33, G.LP_privkey);
calc_rmd160_sha256(G.LP_myrmd160, pubkey33, 33);
init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20); init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20);
G.LP_sessionid = (uint32_t)time(NULL); G.LP_sessionid = (uint32_t)time(NULL);
safecopy(G.gui,gui,sizeof(G.gui)); safecopy(G.gui,gui,sizeof(G.gui));

116
iguana/exchanges/LP_remember.c

@ -13,10 +13,33 @@
* Removal or modification of this copyright notice is prohibited. * * Removal or modification of this copyright notice is prohibited. *
* * * *
******************************************************************************/ ******************************************************************************/
#include "LP_include.h"
#include "../../includes/cJSON.h"
// //
// LP_remember.c // LP_remember.c
// marketmaker // marketmaker
// //
char *coin_name_by_tx_index(struct LP_swap_remember *rswap, int32_t tx_index)
{
switch (tx_index) {
case BASILISK_MYFEE:
case BASILISK_OTHERFEE:
case BASILISK_ALICEPAYMENT:
case BASILISK_ALICERECLAIM:
case BASILISK_BOBSPEND:
return rswap->dest;
case BASILISK_BOBDEPOSIT:
case BASILISK_BOBPAYMENT:
case BASILISK_BOBRECLAIM:
case BASILISK_BOBREFUND:
case BASILISK_ALICESPEND:
case BASILISK_ALICECLAIM:
return rswap->src;
default:
return 0;
}
}
void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,int32_t scriptlen) void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,int32_t scriptlen)
{ {
int32_t i; char scriptstr[513]; int32_t i; char scriptstr[513];
@ -70,6 +93,13 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx
fprintf(fp,",\"bobtomic\":\"%s\"",swap->I.bobtomic); fprintf(fp,",\"bobtomic\":\"%s\"",swap->I.bobtomic);
if ( swap->I.etomicsrc[0] != 0 ) if ( swap->I.etomicsrc[0] != 0 )
fprintf(fp,",\"etomicsrc\":\"%s\"",swap->I.etomicsrc); fprintf(fp,",\"etomicsrc\":\"%s\"",swap->I.etomicsrc);
#ifndef NOTETOMIC
if (swap->myfee.I.ethTxid[0] != 0) {
fprintf(fp,",\"aliceFeeEthTx\":\"%s\"", swap->myfee.I.ethTxid);
}
if (swap->otherfee.I.ethTxid[0] != 0) {
fprintf(fp,",\"aliceFeeEthTx\":\"%s\"", swap->otherfee.I.ethTxid);
}
if (swap->bobdeposit.I.ethTxid[0] != 0) { if (swap->bobdeposit.I.ethTxid[0] != 0) {
fprintf(fp,",\"bobDepositEthTx\":\"%s\"", swap->bobdeposit.I.ethTxid); fprintf(fp,",\"bobDepositEthTx\":\"%s\"", swap->bobdeposit.I.ethTxid);
} }
@ -80,6 +110,9 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx
fprintf(fp,",\"alicePaymentEthTx\":\"%s\"", swap->alicepayment.I.ethTxid); fprintf(fp,",\"alicePaymentEthTx\":\"%s\"", swap->alicepayment.I.ethTxid);
} }
fprintf(fp,",\"aliceRealSat\":\"%" PRId64 "\"", swap->I.alicerealsat);
fprintf(fp,",\"bobRealSat\":\"%" PRId64 "\"", swap->I.bobrealsat);
#endif
fprintf(fp,",\"alicecoin\":\"%s\"",swap->I.alicestr); fprintf(fp,",\"alicecoin\":\"%s\"",swap->I.alicestr);
if ( swap->I.alicetomic[0] != 0 ) if ( swap->I.alicetomic[0] != 0 )
fprintf(fp,",\"alicetomic\":\"%s\"",swap->I.alicetomic); fprintf(fp,",\"alicetomic\":\"%s\"",swap->I.alicetomic);
@ -250,6 +283,22 @@ void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx
{ {
if ( (reqjson= cJSON_Parse(fstr)) != 0 ) if ( (reqjson= cJSON_Parse(fstr)) != 0 )
{ {
#ifndef NOTETOMIC
if (strcmp(rawtx->symbol,"ETOMIC") == 0) {
jdelete(reqjson,"txid");
jdelete(reqjson,"amount");
jaddstr(reqjson,"txid", rawtx->I.ethTxid);
jaddnum(reqjson,"amount", dstr(rawtx->I.eth_amount));
jdelete(reqjson, "coin");
if (rawtx == &swap->myfee || rawtx == &swap->otherfee || rawtx == &swap->alicepayment || rawtx == &swap->bobspend || rawtx == &swap->alicereclaim) {
jaddstr(reqjson,"coin", swap->I.alicestr);
}
if (rawtx == &swap->bobdeposit || rawtx == &swap->bobrefund || rawtx == &swap->aliceclaim || rawtx == &swap->bobpayment || rawtx == &swap->bobreclaim || rawtx == &swap->alicespend) {
jaddstr(reqjson,"coin", swap->I.bobstr);
}
}
#endif
if ( jobj(reqjson,"method") != 0 ) if ( jobj(reqjson,"method") != 0 )
jdelete(reqjson,"method"); jdelete(reqjson,"method");
jaddstr(reqjson,"method","update"); jaddstr(reqjson,"method","update");
@ -429,9 +478,9 @@ int32_t basilisk_isbobcoin(int32_t iambob,int32_t ind)
case BASILISK_OTHERFEE: return(!iambob); break; case BASILISK_OTHERFEE: return(!iambob); break;
case BASILISK_BOBSPEND: case BASILISK_BOBSPEND:
case BASILISK_ALICEPAYMENT: case BASILISK_ALICEPAYMENT:
case BASILISK_ALICERECLAIM: case BASILISK_ALICERECLAIM: return(0);
case BASILISK_ALICECLAIM: return(0);
break; break;
case BASILISK_ALICECLAIM:
case BASILISK_BOBDEPOSIT: case BASILISK_BOBDEPOSIT:
case BASILISK_ALICESPEND: case BASILISK_ALICESPEND:
case BASILISK_BOBPAYMENT: case BASILISK_BOBPAYMENT:
@ -656,13 +705,31 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap)
jaddnum(item,"alicetxfee",dstr(rswap->Atxfee)); jaddnum(item,"alicetxfee",dstr(rswap->Atxfee));
jadd64bits(item,"aliceid",rswap->aliceid); jadd64bits(item,"aliceid",rswap->aliceid);
array = cJSON_CreateArray(); array = cJSON_CreateArray();
cJSON *tx_chain = cJSON_CreateArray();
for (i=0; i<sizeof(txnames)/sizeof(*txnames); i++) for (i=0; i<sizeof(txnames)/sizeof(*txnames); i++)
{ {
if ( rswap->sentflags[i] != 0 ) if ( rswap->sentflags[i] != 0 ) {
jaddistr(array,txnames[i]); jaddistr(array, txnames[i]);
cJSON *tx = cJSON_CreateObject();
jaddstr(tx, "stage", txnames[i]);
jaddstr(tx, "coin", coin_name_by_tx_index(rswap, i));
#ifndef NOTETOMIC
if (LP_etomic_is_empty_tx_id(rswap->eth_tx_ids[i]) == 0) {
jaddstr(tx, "txid", rswap->eth_tx_ids[i]);
jaddnum(tx, "amount", dstr(rswap->eth_values[i]));
} else {
#endif
jaddbits256(tx, "txid", rswap->txids[i]);
jaddnum(tx, "amount", dstr(rswap->values[i]));
#ifndef NOTETOMIC
}
#endif
jaddi(tx_chain, tx);
}
if ( rswap->txbytes[i] != 0 ) if ( rswap->txbytes[i] != 0 )
free(rswap->txbytes[i]), rswap->txbytes[i] = 0; free(rswap->txbytes[i]), rswap->txbytes[i] = 0;
} }
jadd(item, "txChain", tx_chain);
jadd(item,"sentflags",array); jadd(item,"sentflags",array);
array = cJSON_CreateArray(); array = cJSON_CreateArray();
for (i=0; i<sizeof(txnames)/sizeof(*txnames); i++) for (i=0; i<sizeof(txnames)/sizeof(*txnames); i++)
@ -681,6 +748,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap)
jaddbits256(item,"paymentspent",rswap->paymentspent); jaddbits256(item,"paymentspent",rswap->paymentspent);
jaddbits256(item,"Apaymentspent",rswap->Apaymentspent); jaddbits256(item,"Apaymentspent",rswap->Apaymentspent);
jaddbits256(item,"depositspent",rswap->depositspent); jaddbits256(item,"depositspent",rswap->depositspent);
jaddbits256(item,"alicedexfee",rswap->iambob == 0 ? rswap->txids[BASILISK_MYFEE] : rswap->txids[BASILISK_OTHERFEE]);
return(item); return(item);
} }
@ -901,16 +969,32 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag)
strcpy(rswap->etomicdest,jstr(txobj,"etomicdest")); strcpy(rswap->etomicdest,jstr(txobj,"etomicdest"));
} }
rswap->bobrealsat = jint(txobj, "bobRealSat");
rswap->alicerealsat = jint(txobj, "aliceRealSat");
if (jstr(txobj,"aliceFeeEthTx") != 0) {
if (rswap->iambob == 0) {
strcpy(rswap->eth_tx_ids[BASILISK_MYFEE], jstr(txobj, "aliceFeeEthTx"));
rswap->eth_values[BASILISK_MYFEE] = LP_DEXFEE(rswap->alicerealsat);
} else {
strcpy(rswap->eth_tx_ids[BASILISK_OTHERFEE], jstr(txobj, "aliceFeeEthTx"));
rswap->eth_values[BASILISK_OTHERFEE] = LP_DEXFEE(rswap->alicerealsat);
}
}
if (jstr(txobj,"bobDepositEthTx") != 0) { if (jstr(txobj,"bobDepositEthTx") != 0) {
strcpy(rswap->bobDepositEthTx, jstr(txobj,"bobDepositEthTx")); strcpy(rswap->eth_tx_ids[BASILISK_BOBDEPOSIT], jstr(txobj,"bobDepositEthTx"));
rswap->eth_values[BASILISK_BOBDEPOSIT] = LP_DEPOSITSATOSHIS(rswap->bobrealsat);
} }
if (jstr(txobj,"bobPaymentEthTx") != 0) { if (jstr(txobj,"bobPaymentEthTx") != 0) {
strcpy(rswap->bobPaymentEthTx, jstr(txobj,"bobPaymentEthTx")); strcpy(rswap->eth_tx_ids[BASILISK_BOBPAYMENT], jstr(txobj,"bobPaymentEthTx"));
rswap->eth_values[BASILISK_BOBPAYMENT] = rswap->bobrealsat;
} }
if (jstr(txobj,"alicePaymentEthTx") != 0) { if (jstr(txobj,"alicePaymentEthTx") != 0) {
strcpy(rswap->alicePaymentEthTx, jstr(txobj,"alicePaymentEthTx")); strcpy(rswap->eth_tx_ids[BASILISK_ALICEPAYMENT], jstr(txobj,"alicePaymentEthTx"));
rswap->eth_values[BASILISK_ALICEPAYMENT] = rswap->alicerealsat;
} }
if (jstr(txobj,"bobtomic") != 0) { if (jstr(txobj,"bobtomic") != 0) {
@ -1275,6 +1359,8 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals,
{ {
char *aliceSpendEthTxId = LP_etomicalice_spends_bob_payment(&rswap); char *aliceSpendEthTxId = LP_etomicalice_spends_bob_payment(&rswap);
if (aliceSpendEthTxId != NULL) { if (aliceSpendEthTxId != NULL) {
strcpy(rswap.eth_tx_ids[BASILISK_ALICESPEND], aliceSpendEthTxId);
rswap.eth_values[BASILISK_ALICESPEND] = rswap.bobrealsat;
free(aliceSpendEthTxId); free(aliceSpendEthTxId);
} else { } else {
printf("Alice spend ETH tx send failed!\n"); printf("Alice spend ETH tx send failed!\n");
@ -1324,6 +1410,8 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals,
{ {
char *aliceClaimsEthTxId = LP_etomicalice_claims_bob_deposit(&rswap); char *aliceClaimsEthTxId = LP_etomicalice_claims_bob_deposit(&rswap);
if (aliceClaimsEthTxId != NULL) { if (aliceClaimsEthTxId != NULL) {
strcpy(rswap.eth_tx_ids[BASILISK_ALICECLAIM], aliceClaimsEthTxId);
rswap.eth_values[BASILISK_ALICECLAIM] = LP_DEPOSITSATOSHIS(rswap.bobrealsat);
free(aliceClaimsEthTxId); free(aliceClaimsEthTxId);
} else { } else {
printf("Alice Bob deposit claim ETH tx failed!\n"); printf("Alice Bob deposit claim ETH tx failed!\n");
@ -1356,7 +1444,13 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals,
if ( rswap.alicetomic[0] != 0 ) if ( rswap.alicetomic[0] != 0 )
{ {
char *aliceReclaimEthTx = LP_etomicalice_reclaims_payment(&rswap); char *aliceReclaimEthTx = LP_etomicalice_reclaims_payment(&rswap);
free(aliceReclaimEthTx); if (aliceReclaimEthTx != NULL) {
strcpy(rswap.eth_tx_ids[BASILISK_ALICERECLAIM], aliceReclaimEthTx);
rswap.eth_values[BASILISK_ALICERECLAIM] = rswap.alicerealsat;
free(aliceReclaimEthTx);
} else {
printf("Alice could not reclaim ETH/ERC20 payment!\n");
}
} }
#endif #endif
} }
@ -1400,6 +1494,8 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals,
{ {
char *bobSpendEthTx = LP_etomicbob_spends_alice_payment(&rswap); char *bobSpendEthTx = LP_etomicbob_spends_alice_payment(&rswap);
if (bobSpendEthTx != NULL) { if (bobSpendEthTx != NULL) {
strcpy(rswap.eth_tx_ids[BASILISK_BOBSPEND], bobSpendEthTx);
rswap.eth_values[BASILISK_BOBSPEND] = rswap.alicerealsat;
free(bobSpendEthTx); free(bobSpendEthTx);
} else { } else {
printf("Bob spends Alice payment ETH tx send failed!\n"); printf("Bob spends Alice payment ETH tx send failed!\n");
@ -1437,6 +1533,8 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals,
{ {
char *bobReclaimEthTx = LP_etomicbob_reclaims_payment(&rswap); char *bobReclaimEthTx = LP_etomicbob_reclaims_payment(&rswap);
if (bobReclaimEthTx != NULL) { if (bobReclaimEthTx != NULL) {
strcpy(rswap.eth_tx_ids[BASILISK_BOBRECLAIM], bobReclaimEthTx);
rswap.eth_values[BASILISK_BOBRECLAIM] = rswap.bobrealsat;
free(bobReclaimEthTx); free(bobReclaimEthTx);
} else { } else {
printf("Bob reclaims payment ETH tx send failed!\n"); printf("Bob reclaims payment ETH tx send failed!\n");
@ -1490,6 +1588,8 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals,
{ {
char *bobRefundsEthTx = LP_etomicbob_refunds_deposit(&rswap); char *bobRefundsEthTx = LP_etomicbob_refunds_deposit(&rswap);
if (bobRefundsEthTx != NULL) { if (bobRefundsEthTx != NULL) {
strcpy(rswap.eth_tx_ids[BASILISK_BOBREFUND], bobRefundsEthTx);
rswap.eth_values[BASILISK_BOBREFUND] = LP_DEPOSITSATOSHIS(rswap.bobrealsat);
free(bobRefundsEthTx); free(bobRefundsEthTx);
} else { } else {
printf("Bob refunds deposit ETH tx send failed!\n"); printf("Bob refunds deposit ETH tx send failed!\n");

35
iguana/exchanges/LP_rpc.c

@ -137,6 +137,12 @@ int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin)
uint64_t LP_RTsmartbalance(struct iguana_info *coin) uint64_t LP_RTsmartbalance(struct iguana_info *coin)
{ {
#ifndef NOTETOMIC
if (coin->etomic[0] != 0) {
int error = 0;
return LP_etomic_get_balance(coin, coin->smartaddr, &error);
}
#endif
cJSON *array,*item; char buf[512],*retstr; int32_t i,n; uint64_t valuesum,value; bits256 zero; cJSON *array,*item; char buf[512],*retstr; int32_t i,n; uint64_t valuesum,value; bits256 zero;
valuesum = 0; valuesum = 0;
memset(zero.bytes,0,sizeof(zero)); memset(zero.bytes,0,sizeof(zero));
@ -249,18 +255,21 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
if ( bits256_nonz(txid) == 0 ) if ( bits256_nonz(txid) == 0 )
return(cJSON_Parse("{\"error\":\"null txid\"}")); return(cJSON_Parse("{\"error\":\"null txid\"}"));
if ( coin->electrum == 0 ) if ( coin->electrum == 0 )
{
sprintf(buf,"[\"%s\", %d, true]",bits256_str(str,txid),vout);
return(bitcoin_json(coin,"gettxout",buf));
}
else
{ {
if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts ) if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts )
{ {
if ( tx->outpoints[vout].spendheight > 0 ) if ( tx->outpoints[vout].spendheight > 0 )
{
//fprintf(stderr,"LP_gettxout (%s) tx->outpoints[vout].spendheight > 0\n",coinaddr);
return(0); return(0);
}
//return(LP_gettxout_json(txid,vout,tx->height,tx->outpoints[vout].coinaddr,tx->outpoints[vout].value)); //return(LP_gettxout_json(txid,vout,tx->height,tx->outpoints[vout].coinaddr,tx->outpoints[vout].value));
} }
sprintf(buf,"[\"%s\", %d, true]",bits256_str(str,txid),vout);
return(bitcoin_json(coin,"gettxout",buf));
}
else
{
if ( coinaddr[0] == 0 ) if ( coinaddr[0] == 0 )
{ {
if ( (txobj= electrum_transaction(&height,symbol,coin->electrum,&txobj,txid,0)) != 0 ) if ( (txobj= electrum_transaction(&height,symbol,coin->electrum,&txobj,txid,0)) != 0 )
@ -275,7 +284,10 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 ) if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 )
{ {
if ( up->spendheight > 0 ) if ( up->spendheight > 0 )
{
//fprintf(stderr,"LP_gettxout (%s) up->spendheight > 0\n",coinaddr);
return(0); return(0);
}
//return(LP_gettxout_json(txid,vout,up->U.height,coinaddr,up->U.value)); //return(LP_gettxout_json(txid,vout,up->U.height,coinaddr,up->U.value));
} }
memset(zero.bytes,0,sizeof(zero)); memset(zero.bytes,0,sizeof(zero));
@ -401,6 +413,8 @@ int32_t LP_address_isvalid(char *symbol,char *address)
int32_t isvalid = 0; cJSON *retjson; int32_t isvalid = 0; cJSON *retjson;
if ( symbol == 0 || symbol[0] == 0 ) if ( symbol == 0 || symbol[0] == 0 )
return(0); return(0);
if ( strcmp(symbol,"BCH") == 0 && (address[0] == '1' || address[0] == '3') )
return(-1);
if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) if ( (retjson= LP_validateaddress(symbol,address)) != 0 )
{ {
if ( jobj(retjson,"isvalid") != 0 && is_cJSON_True(jobj(retjson,"isvalid")) != 0 ) if ( jobj(retjson,"isvalid") != 0 && is_cJSON_True(jobj(retjson,"isvalid")) != 0 )
@ -750,7 +764,9 @@ again:
} }
if ( strcmp(coin->estimatefeestr,"estimatesmartfee") == 0 && (rate= jdouble(errjson,"feerate")) != 0 ) if ( strcmp(coin->estimatefeestr,"estimatesmartfee") == 0 && (rate= jdouble(errjson,"feerate")) != 0 )
{ {
printf("extracted feerate %.8f from estimatesmartfee\n",rate); static uint32_t counter;
if ( counter++ < 10 )
printf("extracted feerate %.8f from estimatesmartfee\n",rate);
rate /= 1024.; rate /= 1024.;
} }
free_json(errjson); free_json(errjson);
@ -1030,12 +1046,13 @@ uint32_t LP_heighttime(char *symbol,int32_t height)
cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t height) cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t height)
{ {
cJSON *json = 0; int32_t flag = 0; struct iguana_info *coin; cJSON *json = 0; int32_t flag = 0; struct iguana_info *coin;
*heightp = 0;
if ( symbol == 0 || symbol[0] == 0 ) if ( symbol == 0 || symbol[0] == 0 )
return(cJSON_Parse("{\"error\":\"null symbol\"}")); return(cJSON_Parse("{\"error\":\"null symbol\"}"));
coin = LP_coinfind(symbol); coin = LP_coinfind(symbol);
if ( coin == 0 || coin->electrum != 0 ) if ( coin == 0 || coin->electrum != 0 )
{ {
printf("unexpected electrum path for %s\n",symbol); //printf("unexpected electrum path for %s\n",symbol);
return(0); return(0);
} }
if ( blockhashstr == 0 ) if ( blockhashstr == 0 )
@ -1134,7 +1151,7 @@ int32_t LP_txhasnotarization(bits256 *notarizedhashp,struct iguana_info *coin,bi
{ {
cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[1024]; bits256 spenttxid; uint64_t notarymask; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0; 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)); memset(notarizedhashp,0,sizeof(*notarizedhashp));
if ( (txobj= LP_gettx("LP_txhasnotarization",coin->symbol,txid,0)) != 0 ) if ( (txobj= LP_gettx("LP_txhasnotarization",coin->symbol,txid,1)) != 0 )
{ {
if ( (vins= jarray(&numvins,txobj,"vin")) != 0 ) if ( (vins= jarray(&numvins,txobj,"vin")) != 0 )
{ {
@ -1146,7 +1163,7 @@ int32_t LP_txhasnotarization(bits256 *notarizedhashp,struct iguana_info *coin,bi
vin = jitem(vins,i); vin = jitem(vins,i);
spenttxid = jbits256(vin,"txid"); spenttxid = jbits256(vin,"txid");
spentvout = jint(vin,"vout"); spentvout = jint(vin,"vout");
if ( (spentobj= LP_gettx("LP_txhasnotarization",coin->symbol,spenttxid,0)) != 0 ) if ( (spentobj= LP_gettx("LP_txhasnotarization",coin->symbol,spenttxid,1)) != 0 )
{ {
if ( (vouts= jarray(&numvouts,spentobj,"vout")) != 0 ) if ( (vouts= jarray(&numvouts,spentobj,"vout")) != 0 )
{ {

7
iguana/exchanges/LP_scan.c

@ -23,7 +23,7 @@ int32_t LP_blockinit(struct iguana_info *coin,int32_t height)
{ {
int32_t i,iter,numtx,checkht=-1; cJSON *blockobj,*txs,*txobj; bits256 txid; struct LP_transaction *tx; int32_t i,iter,numtx,checkht=-1; cJSON *blockobj,*txs,*txobj; bits256 txid; struct LP_transaction *tx;
portable_mutex_lock(&LP_blockinit_mutex); portable_mutex_lock(&LP_blockinit_mutex);
if ( (blockobj= LP_blockjson(&checkht,coin->symbol,0,height)) != 0 && checkht == height ) if ( (blockobj= LP_blockjson(&checkht,coin->symbol,0,height)) != 0 && (checkht == 0 || checkht == height) )
{ {
if ( (txs= jarray(&numtx,blockobj,"tx")) != 0 ) if ( (txs= jarray(&numtx,blockobj,"tx")) != 0 )
{ {
@ -54,9 +54,10 @@ int32_t LP_blockinit(struct iguana_info *coin,int32_t height)
free_json(blockobj); free_json(blockobj);
} }
portable_mutex_unlock(&LP_blockinit_mutex); portable_mutex_unlock(&LP_blockinit_mutex);
if ( checkht == height ) if ( checkht == 0 || checkht == height )
return(0); return(0);
else return(-1); printf("%s blockinit error checkht.%d vs height.%d\n",ASSETCHAINS_SYMBOL,checkht,height);
return(-1);
} }
int32_t LP_scanblockchain(struct iguana_info *coin,int32_t startheight,int32_t endheight) int32_t LP_scanblockchain(struct iguana_info *coin,int32_t startheight,int32_t endheight)

2
iguana/exchanges/LP_secp.c

@ -97,7 +97,7 @@ int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256
printf("bitcoin_sign illegal privkey\n"); printf("bitcoin_sign illegal privkey\n");
return(-1); return(-1);
} }
if ( strcmp(symbol,"BCH") == 0 || strcmp(symbol,"BTG") == 0 ) if ( strcmp(symbol,"BCH") == 0 || strcmp(symbol,"BTG") == 0 || strcmp(symbol,"CMM") == 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; funcp = 0;

58
iguana/exchanges/LP_signatures.c

@ -19,7 +19,7 @@
// marketmaker // marketmaker
// //
struct basilisk_request *LP_requestinit(struct basilisk_request *rp,bits256 srchash,bits256 desthash,char *src,uint64_t srcsatoshis,char *dest,uint64_t destsatoshis,uint32_t timestamp,uint32_t quotetime,int32_t DEXselector) struct basilisk_request *LP_requestinit(struct basilisk_request *rp,bits256 srchash,bits256 desthash,char *src,uint64_t srcsatoshis,char *dest,uint64_t destsatoshis,uint32_t timestamp,uint32_t quotetime,int32_t DEXselector,int32_t fillflag,int32_t gtcflag)
{ {
struct basilisk_request R; struct basilisk_request R;
memset(rp,0,sizeof(*rp)); memset(rp,0,sizeof(*rp));
@ -45,6 +45,14 @@ cJSON *LP_quotejson(struct LP_quoteinfo *qp)
if ( jobj(retjson,"gui") == 0 ) if ( jobj(retjson,"gui") == 0 )
jaddstr(retjson,"gui",qp->gui[0] != 0 ? qp->gui : LP_gui); jaddstr(retjson,"gui",qp->gui[0] != 0 ? qp->gui : LP_gui);
jaddstr(retjson,"uuid",qp->uuidstr); jaddstr(retjson,"uuid",qp->uuidstr);
if ( qp->maxprice != 0 )
jaddnum(retjson,"maxprice",qp->maxprice);
if ( qp->mpnet != 0 )
jaddnum(retjson,"mpnet",qp->mpnet);
if ( qp->gtc != 0 )
jaddnum(retjson,"gtc",qp->gtc);
if ( qp->fill != 0 )
jaddnum(retjson,"fill",qp->fill);
jadd64bits(retjson,"aliceid",qp->aliceid); jadd64bits(retjson,"aliceid",qp->aliceid);
jaddnum(retjson,"tradeid",qp->tradeid); jaddnum(retjson,"tradeid",qp->tradeid);
jaddstr(retjson,"base",qp->srccoin); jaddstr(retjson,"base",qp->srccoin);
@ -113,28 +121,36 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson)
{ {
uint32_t rid,qid; char etomic[64],activesymbol[65],*etomicstr; uint32_t rid,qid; char etomic[64],activesymbol[65],*etomicstr;
memset(qp,0,sizeof(*qp)); memset(qp,0,sizeof(*qp));
qp->maxprice = jdouble(argjson,"maxprice");
qp->mpnet = juint(argjson,"mpnet");
qp->gtc = juint(argjson,"gtc");
qp->fill = juint(argjson,"fill");
safecopy(qp->gui,LP_gui,sizeof(qp->gui)); safecopy(qp->gui,LP_gui,sizeof(qp->gui));
safecopy(qp->srccoin,jstr(argjson,"base"),sizeof(qp->srccoin)); safecopy(qp->srccoin,jstr(argjson,"base"),sizeof(qp->srccoin));
safecopy(qp->uuidstr,jstr(argjson,"uuid"),sizeof(qp->uuidstr)); safecopy(qp->uuidstr,jstr(argjson,"uuid"),sizeof(qp->uuidstr));
#ifndef NOTETOMIC
if ( LP_etomicsymbol(activesymbol,etomic,qp->srccoin) != 0 ) if ( LP_etomicsymbol(activesymbol,etomic,qp->srccoin) != 0 )
{ {
if ( (etomicstr= jstr(argjson,"bobtomic")) == 0 || strcmp(etomicstr,etomic) != 0 ) if ( (etomicstr= jstr(argjson,"bobtomic")) == 0 || compareAddresses(etomicstr,etomic) == 0 )
{ {
printf("etomic src mismatch (%s) vs (%s)\n",etomicstr!=0?etomicstr:"",etomic); printf("etomic src mismatch (%s) vs (%s)\n",etomicstr!=0?etomicstr:"",etomic);
return(-1); return(-1);
} }
} }
#endif
safecopy(qp->coinaddr,jstr(argjson,"address"),sizeof(qp->coinaddr)); safecopy(qp->coinaddr,jstr(argjson,"address"),sizeof(qp->coinaddr));
safecopy(qp->etomicsrc,jstr(argjson,"etomicsrc"),sizeof(qp->etomicsrc)); safecopy(qp->etomicsrc,jstr(argjson,"etomicsrc"),sizeof(qp->etomicsrc));
safecopy(qp->destcoin,jstr(argjson,"rel"),sizeof(qp->destcoin)); safecopy(qp->destcoin,jstr(argjson,"rel"),sizeof(qp->destcoin));
#ifndef NOTETOMIC
if ( LP_etomicsymbol(activesymbol,etomic,qp->destcoin) != 0 ) if ( LP_etomicsymbol(activesymbol,etomic,qp->destcoin) != 0 )
{ {
if ( (etomicstr= jstr(argjson,"alicetomic")) == 0 || strcmp(etomicstr,etomic) != 0 ) if ( (etomicstr= jstr(argjson,"alicetomic")) == 0 || compareAddresses(etomicstr,etomic) == 0 )
{ {
printf("etomic dest mismatch (%s) vs (%s)\n",etomicstr!=0?etomicstr:"",etomic); printf("etomic dest mismatch (%s) vs (%s)\n",etomicstr!=0?etomicstr:"",etomic);
return(-1); return(-1);
} }
} }
#endif
safecopy(qp->destaddr,jstr(argjson,"destaddr"),sizeof(qp->destaddr)); safecopy(qp->destaddr,jstr(argjson,"destaddr"),sizeof(qp->destaddr));
safecopy(qp->etomicdest,jstr(argjson,"etomicdest"),sizeof(qp->etomicdest)); safecopy(qp->etomicdest,jstr(argjson,"etomicdest"),sizeof(qp->etomicdest));
qp->aliceid = j64bits(argjson,"aliceid"); qp->aliceid = j64bits(argjson,"aliceid");
@ -152,9 +168,9 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson)
qp->destvout = jint(argjson,"destvout"); qp->destvout = jint(argjson,"destvout");
qp->desthash = jbits256(argjson,"desthash"); qp->desthash = jbits256(argjson,"desthash");
qp->txfee = j64bits(argjson,"txfee"); qp->txfee = j64bits(argjson,"txfee");
if ( (qp->satoshis= j64bits(argjson,"satoshis")) > qp->txfee ) if ( (qp->satoshis= j64bits(argjson,"satoshis")) > qp->txfee && fabs(qp->maxprice) < SMALLVAL )
{ {
//qp->price = (double)qp->destsatoshis / (qp->satoshis = qp->txfee); qp->maxprice = (double)qp->destsatoshis / (qp->satoshis - qp->txfee);
} }
qp->destsatoshis = j64bits(argjson,"destsatoshis"); qp->destsatoshis = j64bits(argjson,"destsatoshis");
qp->desttxfee = j64bits(argjson,"desttxfee"); qp->desttxfee = j64bits(argjson,"desttxfee");
@ -442,6 +458,17 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re
jaddstr(reqjson,"pubsecp",pubsecpstr); jaddstr(reqjson,"pubsecp",pubsecpstr);
if ( (kmd= LP_coinfind("KMD")) != 0 && (ap= LP_address(kmd,kmd->smartaddr)) != 0 && ap->instantdex_credits != 0 ) if ( (kmd= LP_coinfind("KMD")) != 0 && (ap= LP_address(kmd,kmd->smartaddr)) != 0 && ap->instantdex_credits != 0 )
jaddnum(reqjson,"credits",dstr(ap->instantdex_credits)); jaddnum(reqjson,"credits",dstr(ap->instantdex_credits));
#ifndef NOTETOMIC
if (basecoin->etomic[0] != 0) {
int error = 0;
uint64_t etomic_coin_balance = LP_etomic_get_balance(basecoin, basecoin->smartaddr, &error);
jaddstr(reqjson,"utxocoin","ETH_OR_ERC20");
jaddnum(reqjson,"bal",dstr(etomic_coin_balance));
jaddnum(reqjson,"min",dstr(etomic_coin_balance));
jaddnum(reqjson,"max",dstr(etomic_coin_balance));
jaddnum(reqjson,"n",1);
} else
#endif
if ( (numutxos= LP_address_minmax(1,&median,&minsize,&maxsize,basecoin,basecoin->smartaddr)) != 0 ) if ( (numutxos= LP_address_minmax(1,&median,&minsize,&maxsize,basecoin,basecoin->smartaddr)) != 0 )
{ {
//printf("send %s numutxos.%d median %.8f min %.8f max %.8f\n",base,numutxos,dstr(median),dstr(minsize),dstr(maxsize)); //printf("send %s numutxos.%d median %.8f min %.8f max %.8f\n",base,numutxos,dstr(median),dstr(minsize),dstr(maxsize));
@ -717,13 +744,20 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_
jadd(reqjson,"proof",LP_instantdex_txids(0,coin->smartaddr)); jadd(reqjson,"proof",LP_instantdex_txids(0,coin->smartaddr));
} }
msg = jprint(reqjson,1); msg = jprint(reqjson,1);
//printf("QUERY.(%s)\n",msg); {
if ( IPC_ENDPOINT >= 0 ) //printf("QUERY.(%s)\n",msg);
LP_queuecommand(0,msg,IPC_ENDPOINT,-1,0); if ( IPC_ENDPOINT >= 0 )
memset(&zero,0,sizeof(zero)); LP_queuecommand(0,msg,IPC_ENDPOINT,-1,0);
if ( bits256_nonz(qp->srchash) != 0 ) memset(&zero,0,sizeof(zero));
LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->srchash,clonestr(msg)); LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg));
LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); //if ( bits256_nonz(qp->srchash) != 0 )
{
sleep(1);
LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->srchash,clonestr(msg));
}
}
if ( strcmp(method,"connect") == 0 && qp->mpnet != 0 && qp->gtc == 0 )
LP_mpnet_send(0,msg,1,qp->coinaddr);
free(msg); free(msg);
} }

136
iguana/exchanges/LP_socket.c

@ -25,6 +25,83 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <WinSock2.h> #include <WinSock2.h>
#endif #endif
#ifdef _WIN32
#include <WinSock2.h>
#endif
int32_t set_blocking_mode(int32_t sock,int32_t is_blocking) // from https://stackoverflow.com/questions/2149798/how-to-reset-a-socket-back-to-blocking-mode-after-i-set-it-to-nonblocking-mode?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
{
int32_t ret;
#ifdef _WIN32
/// @note windows sockets are created in blocking mode by default
// currently on windows, there is no easy way to obtain the socket's current blocking mode since WSAIsBlocking was deprecated
u_long non_blocking = is_blocking ? 0 : 1;
ret = (NO_ERROR == ioctlsocket(sock,FIONBIO,&non_blocking));
#else
const int flags = fcntl(sock, F_GETFL, 0);
if ((flags & O_NONBLOCK) && !is_blocking) { fprintf(stderr,"set_blocking_mode(): socket was already in non-blocking mode\n"); return ret; }
if (!(flags & O_NONBLOCK) && is_blocking) { fprintf(stderr,"set_blocking_mode(): socket was already in blocking mode\n"); return ret; }
ret = (0 == fcntl(sock, F_SETFL, is_blocking ? (flags ^ O_NONBLOCK) : (flags | O_NONBLOCK)));
#endif
if ( ret == 0 )
return(-1);
else return(0);
}
int32_t komodo_connect(int32_t sock,struct sockaddr *saddr,socklen_t addrlen)
{
struct timeval tv; fd_set wfd,efd; int32_t res,so_error; socklen_t len;
#ifdef _WIN32
set_blocking_mode(sock, 0);
#else
fcntl(sock, F_SETFL, O_NONBLOCK);
#endif // _WIN32
res = connect(sock,saddr,addrlen);
if ( res == -1 )
{
#ifdef _WIN32
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms737625%28v=vs.85%29.aspx - read about WSAEWOULDBLOCK return
errno = WSAGetLastError();
printf("[Decker] errno.%d --> ", errno);
if ( errno != EINPROGRESS && errno != WSAEWOULDBLOCK ) // connect failed, do something...
#else
if ( errno != EINPROGRESS ) // connect failed, do something...
#endif
{
printf("close socket ...\n");
closesocket(sock);
return(-1);
}
//printf("continue with select ...\n");
FD_ZERO(&wfd);
FD_SET(sock,&wfd);
FD_ZERO(&efd);
FD_SET(sock,&efd);
tv.tv_sec = 10;
tv.tv_usec = 0;
res = select(sock+1,NULL,&wfd,&efd,&tv);
if ( res == -1 ) // select failed, do something...
{
closesocket(sock);
return(-1);
}
if ( res == 0 ) // connect timed out...
{
closesocket(sock);
return(-1);
}
if ( FD_ISSET(sock,&efd) )
{
// connect failed, do something...
getsockopt(sock,SOL_SOCKET,SO_ERROR,&so_error,&len);
closesocket(sock);
return(-1);
}
}
set_blocking_mode(sock,1);
return(0);
}
int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port) int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port)
{ {
@ -124,25 +201,35 @@ int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port)
#endif #endif
if ( bindflag == 0 ) if ( bindflag == 0 )
{ {
//printf("call connect sock.%d\n",sock); //#ifdef _WIN32
result = connect(sock,(struct sockaddr *)&saddr,addrlen); if ( 1 ) // connect using async to allow timeout, then switch to sync
//printf("called connect result.%d\n",result);
timeout.tv_sec = 2;
timeout.tv_usec = 0;
setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout));
if ( result != 0 )
{ {
if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) uint32_t starttime = (uint32_t)time(NULL);
//printf("call connect sock.%d\n",sock);
result = komodo_connect(sock,(struct sockaddr *)&saddr,addrlen);
//printf("called connect result.%d lag.%d\n",result,(int32_t)(time(NULL) - starttime));
if ( result < 0 )
return(-1);
timeout.tv_sec = 10;
timeout.tv_usec = 0;
setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout));
}
//#else
else
{
result = connect(sock,(struct sockaddr *)&saddr,addrlen);
if ( result != 0 )
{ {
//printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH )
{
//printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno);
}
if ( sock >= 0 )
closesocket(sock);
return(-1);
} }
if ( sock >= 0 )
closesocket(sock);
return(-1);
} }
timeout.tv_sec = 10; //#endif
timeout.tv_usec = 0;
setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout));
} }
else else
{ {
@ -422,7 +509,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch
{ {
*retjsonp = 0; *retjsonp = 0;
sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params);
//printf("%s %s",symbol,stratumreq); //printf("timeout.%d exp.%d %s %s",timeout,(int32_t)(expiration-time(NULL)),symbol,stratumreq);
memset(ep->buf,0,ep->bufsize); memset(ep->buf,0,ep->bufsize);
sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp);
portable_mutex_lock(&ep->mutex); // this helps performance! portable_mutex_lock(&ep->mutex); // this helps performance!
@ -1112,7 +1199,8 @@ void LP_dedicatedloop(void *arg)
cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port)
{ {
struct electrum_info *ep,*prev; int32_t kickval,already; cJSON *retjson,*array,*item; struct electrum_info *ep,*prev,*cur; int32_t kickval,already; cJSON *retjson,*array,*item;
cur = coin->electrum;
if ( ipaddr == 0 || ipaddr[0] == 0 || port == 0 ) if ( ipaddr == 0 || ipaddr[0] == 0 || port == 0 )
{ {
ep = coin->electrum; ep = coin->electrum;
@ -1190,7 +1278,19 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port)
jaddnum(retjson,"restart",kickval); jaddnum(retjson,"restart",kickval);
} }
} }
#ifndef NOTETOMIC
if (coin->electrum != 0 && cur == 0 && strcmp(coin->symbol, "ETOMIC") == 0) {
cJSON *balance = cJSON_CreateObject();
electrum_address_getbalance(coin->symbol, coin->electrum, &balance, coin->smartaddr);
int64_t confirmed = get_cJSON_int(balance, "confirmed");
int64_t unconfirmed = get_cJSON_int(balance, "unconfirmed");
if ((confirmed + unconfirmed) < 20 * SATOSHIDEN && get_etomic_from_faucet(coin->smartaddr) != 1) {
cJSON_Delete(balance);
return(cJSON_Parse("{\"error\":\"Could not get ETOMIC from faucet!\"}"));
}
cJSON_Delete(balance);
}
#endif
//printf("(%s)\n",jprint(retjson,0)); //printf("(%s)\n",jprint(retjson,0));
return(retjson); return(retjson);
} }

2
iguana/exchanges/LP_statemachine.c

@ -3645,7 +3645,7 @@ if ( LP_pricevalid(price) > 0 )
{ {
LP_query(ctx,myipaddr,mypubsock,"connect",qp); LP_query(ctx,myipaddr,mypubsock,"connect",qp);
//price = LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout); //price = LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout);
LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-2*qp->txfee,qp->destcoin,qp->destsatoshis-2*qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-2*qp->txfee,qp->destcoin,qp->destsatoshis-2*qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector,qp->fill,qp->gtc);
while ( time(NULL) < expiration ) while ( time(NULL) < expiration )
{ {
if ( aliceutxo->S.swap != 0 ) if ( aliceutxo->S.swap != 0 )

86
iguana/exchanges/LP_swap.c

@ -854,7 +854,17 @@ void LP_bobloop(void *_swap)
expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT;
bobwaittimeout = LP_calc_waittimeout(bobstr); bobwaittimeout = LP_calc_waittimeout(bobstr);
alicewaittimeout = LP_calc_waittimeout(alicestr); alicewaittimeout = LP_calc_waittimeout(alicestr);
if ( swap != 0 ) #ifndef NOTETOMIC
if (swap->I.bobtomic[0] != 0 || swap->I.alicetomic[0] != 0) {
int error = 0;
uint64_t eth_balance = getEthBalance(swap->I.etomicsrc, &error);
if (eth_balance < 500000) {
err = -5000, printf("Bob ETH balance too low, aborting swap!\n");
}
}
#endif
if ( swap != 0 && err == 0)
{ {
if ( LP_waitsend("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) if ( LP_waitsend("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 )
err = -2000, printf("error waitsend pubkeys\n"); err = -2000, printf("error waitsend pubkeys\n");
@ -866,7 +876,6 @@ void LP_bobloop(void *_swap)
err = -2003, printf("error bobscripts deposit\n"); err = -2003, printf("error bobscripts deposit\n");
else else
{ {
uint8_t error = 0;
swap->bobrefund.utxovout = 0; swap->bobrefund.utxovout = 0;
swap->bobrefund.utxotxid = swap->bobdeposit.I.signedtxid; swap->bobrefund.utxotxid = swap->bobdeposit.I.signedtxid;
basilisk_bobdeposit_refund(swap,swap->I.putduration); basilisk_bobdeposit_refund(swap,swap->I.putduration);
@ -876,24 +885,32 @@ void LP_bobloop(void *_swap)
LP_unavailableset(swap->bobdeposit.utxotxid,swap->bobdeposit.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash); 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 ) if ( LP_waitfor(swap->N.pair,swap,bobwaittimeout,LP_verify_otherfee) < 0 )
{ {
error = 1;
err = -2004, printf("error waiting for alicefee\n"); err = -2004, printf("error waiting for alicefee\n");
} }
if ( error == 0 ) if ( err == 0 )
{ {
if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0) == 0 ) 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"); err = -2005, printf("error sending bobdeposit\n");
} }
} }
LP_unavailableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash); if (err == 0) {
if ( error == 0 && LP_waitfor(swap->N.pair,swap,alicewaittimeout,LP_verify_alicepayment) < 0 ) LP_unavailableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash);
{ m = swap->I.bobconfirms;
error = 1; while ((n = LP_numconfirms(bobstr, swap->bobdeposit.I.destaddr, swap->bobdeposit.I.signedtxid, 0, 1)) < m) {
err = -2006, printf("error waiting for alicepayment\n"); LP_swap_critical = (uint32_t) time(NULL);
LP_unavailableset(swap->bobpayment.utxotxid, swap->bobpayment.utxovout, (uint32_t) time(NULL) + 60, swap->I.otherhash);
char str[65];
printf("%d wait for bobdeposit %s numconfs.%d %s %s\n", n, swap->bobdeposit.I.destaddr, m, bobstr, bits256_str(str, swap->bobdeposit.I.signedtxid));
sleep(10);
}
printf("wait for alicepayment\n");
if (LP_waitfor(swap->N.pair, swap, bobwaittimeout + alicewaittimeout, LP_verify_alicepayment) < 0) {
err = -2006, printf("error waiting for alicepayment\n");
}
} }
if (error == 0) if (err == 0)
{ {
LP_swap_critical = (uint32_t)time(NULL); LP_swap_critical = (uint32_t)time(NULL);
if ( basilisk_bobscripts_set(swap,0,1) < 0 ) if ( basilisk_bobscripts_set(swap,0,1) < 0 )
@ -901,6 +918,7 @@ void LP_bobloop(void *_swap)
else else
{ {
m = swap->I.aliceconfirms; m = swap->I.aliceconfirms;
LP_unavailableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash);
while ( (n= LP_numconfirms(alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) // sync with alice 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_unavailableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash);
@ -927,7 +945,8 @@ void LP_bobloop(void *_swap)
LP_swap_endcritical = (uint32_t)time(NULL); LP_swap_endcritical = (uint32_t)time(NULL);
if ( err < 0 ) if ( err < 0 )
LP_failedmsg(swap->I.req.requestid,swap->I.req.quoteid,err,swap->uuidstr); LP_failedmsg(swap->I.req.requestid,swap->I.req.quoteid,err,swap->uuidstr);
sleep(13); if ( swap->I.aliceconfirms > 0 )
sleep(13);
LP_pendswap_add(swap->I.expiration,swap->I.req.requestid,swap->I.req.quoteid); 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); //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); basilisk_swap_finished(swap);
@ -939,6 +958,7 @@ void LP_bobloop(void *_swap)
void LP_aliceloop(void *_swap) void LP_aliceloop(void *_swap)
{ {
uint8_t *data; char bobstr[65],alicestr[65]; int32_t bobwaittimeout,alicewaittimeout,maxlen,n,m,err=0; uint32_t expiration; struct basilisk_swap *swap = _swap; uint8_t *data; char bobstr[65],alicestr[65]; int32_t bobwaittimeout,alicewaittimeout,maxlen,n,m,err=0; uint32_t expiration; struct basilisk_swap *swap = _swap;
LP_alicequery_clear();
G.LP_pendingswaps++; G.LP_pendingswaps++;
LP_etomicsymbol(bobstr,swap->I.bobtomic,swap->I.bobstr); LP_etomicsymbol(bobstr,swap->I.bobtomic,swap->I.bobstr);
LP_etomicsymbol(alicestr,swap->I.alicetomic,swap->I.alicestr); LP_etomicsymbol(alicestr,swap->I.alicetomic,swap->I.alicestr);
@ -947,7 +967,18 @@ void LP_aliceloop(void *_swap)
expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT;
bobwaittimeout = LP_calc_waittimeout(bobstr); bobwaittimeout = LP_calc_waittimeout(bobstr);
alicewaittimeout = LP_calc_waittimeout(alicestr); alicewaittimeout = LP_calc_waittimeout(alicestr);
if ( swap != 0 )
#ifndef NOTETOMIC
if (swap->I.bobtomic[0] != 0 || swap->I.alicetomic[0] != 0) {
int error = 0;
uint64_t eth_balance = getEthBalance(swap->I.etomicdest, &error);
if (eth_balance < 500000) {
err = -5001, printf("Alice ETH balance too low, aborting swap!\n");
}
}
#endif
if ( swap != 0 && err == 0)
{ {
printf("start swap iamalice pair.%d\n",swap->N.pair); 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 ) if ( LP_sendwait("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 )
@ -973,6 +1004,7 @@ void LP_aliceloop(void *_swap)
while ( (n= LP_numconfirms(bobstr,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,1)) < m ) while ( (n= LP_numconfirms(bobstr,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,1)) < m )
{ {
LP_swap_critical = (uint32_t)time(NULL); LP_swap_critical = (uint32_t)time(NULL);
LP_unavailableset(swap->alicepayment.utxotxid,swap->alicepayment.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash);
char str[65];printf("%d wait for bobdeposit %s numconfs.%d %s %s\n",n,swap->bobdeposit.I.destaddr,m,bobstr,bits256_str(str,swap->bobdeposit.I.signedtxid)); 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); sleep(10);
} }
@ -999,6 +1031,7 @@ void LP_aliceloop(void *_swap)
char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,bobstr,bits256_str(str,swap->bobpayment.I.signedtxid)); 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); sleep(10);
} }
char str[65];printf("%d waited for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,bobstr,bits256_str(str,swap->bobpayment.I.signedtxid));
if ( swap->N.pair >= 0 ) if ( swap->N.pair >= 0 )
nn_close(swap->N.pair), swap->N.pair = -1; nn_close(swap->N.pair), swap->N.pair = -1;
} }
@ -1009,7 +1042,8 @@ void LP_aliceloop(void *_swap)
LP_swap_endcritical = (uint32_t)time(NULL); LP_swap_endcritical = (uint32_t)time(NULL);
if ( err < 0 ) if ( err < 0 )
LP_failedmsg(swap->I.req.requestid,swap->I.req.quoteid,err,swap->uuidstr); LP_failedmsg(swap->I.req.requestid,swap->I.req.quoteid,err,swap->uuidstr);
sleep(13); if ( swap->I.bobconfirms > 0 )
sleep(13);
LP_pendswap_add(swap->I.expiration,swap->I.req.requestid,swap->I.req.quoteid); 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); //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); basilisk_swap_finished(swap);
@ -1178,6 +1212,16 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
free(swap); free(swap);
return(0); return(0);
} }
#ifndef NOTETOMIC
if (strcmp(alicestr, "ETOMIC") == 0) {
swap->I.alicerealsat = swap->I.alicesatoshis;
swap->I.alicesatoshis = 100000000;
}
if (strcmp(bobstr, "ETOMIC") == 0) {
swap->I.bobrealsat = swap->I.bobsatoshis;
swap->I.bobsatoshis = 100000000;
}
#endif
if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE ) if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE )
swap->I.bobinsurance = LP_MIN_TXFEE; swap->I.bobinsurance = LP_MIN_TXFEE;
if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE ) if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE )
@ -1298,6 +1342,20 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
swap->bobpayment.utxotxid = qp->txid, swap->bobpayment.utxovout = qp->vout; swap->bobpayment.utxotxid = qp->txid, swap->bobpayment.utxovout = qp->vout;
swap->bobdeposit.utxotxid = qp->txid2, swap->bobdeposit.utxovout = qp->vout2; swap->bobdeposit.utxotxid = qp->txid2, swap->bobdeposit.utxovout = qp->vout2;
swap->alicepayment.utxotxid = qp->desttxid, swap->alicepayment.utxovout = qp->destvout; swap->alicepayment.utxotxid = qp->desttxid, swap->alicepayment.utxovout = qp->destvout;
#ifndef NOTETOMIC
if (strcmp(alicestr, "ETOMIC") == 0) {
swap->alicepayment.I.eth_amount = swap->I.alicerealsat;
if (swap->I.iambob == 1) {
swap->otherfee.I.eth_amount = LP_DEXFEE(swap->I.alicerealsat);
} else {
swap->myfee.I.eth_amount = LP_DEXFEE(swap->I.alicerealsat);
}
}
if (strcmp(bobstr, "ETOMIC") == 0) {
swap->bobpayment.I.eth_amount = swap->I.bobrealsat;
swap->bobdeposit.I.eth_amount = LP_DEPOSITSATOSHIS(swap->I.bobrealsat);
}
#endif
LP_mark_spent(bobstr,qp->txid,qp->vout); LP_mark_spent(bobstr,qp->txid,qp->vout);
LP_mark_spent(bobstr,qp->txid2,qp->vout2); LP_mark_spent(bobstr,qp->txid2,qp->vout2);
LP_mark_spent(alicestr,qp->desttxid,qp->destvout); LP_mark_spent(alicestr,qp->desttxid,qp->destvout);

2
iguana/exchanges/LP_tradebots.c

@ -338,7 +338,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot)
{ {
if ( remaining < 0.001 ) if ( remaining < 0.001 )
break; break;
if ( (retstr= LP_autobuy(ctx,0,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining/i,0,0,G.gui,0,destpubkey,tradeid,0)) != 0 ) if ( (retstr= LP_autobuy(ctx,0,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining/i,0,0,G.gui,0,destpubkey,tradeid,0,0,0)) != 0 )
{ {
if ( (retjson2= cJSON_Parse(retstr)) != 0 ) if ( (retjson2= cJSON_Parse(retstr)) != 0 )
{ {

307
iguana/exchanges/LP_transaction.c

@ -427,7 +427,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype,
vpnstr[0] = 0; vpnstr[0] = 0;
*signedtx = 0; *signedtx = 0;
memset(signedtxidp,0,sizeof(*signedtxidp)); memset(signedtxidp,0,sizeof(*signedtxidp));
//printf("bitcoin_verifyvins numvins.%d numvouts.%d signtx.%d privkey.%d M.%d N.%d\n",msgtx->tx_in,numvouts,signtx,bits256_nonz(V[0].signers[0].privkey),V[0].M,V[0].N); //printf("bitcoin_verifyvins suppress.%d numvins.%d numvouts.%d signtx.%d privkey.%d M.%d N.%d\n",suppress_pubkeys,msgtx->tx_in,numvouts,signtx,bits256_nonz(V[0].signers[0].privkey),V[0].M,V[0].N);
for (vini=0; vini<msgtx->tx_in; vini++) for (vini=0; vini<msgtx->tx_in; vini++)
{ {
if ( V->p2shscript[0] != 0 && V->p2shlen != 0 ) if ( V->p2shscript[0] != 0 && V->p2shlen != 0 )
@ -999,11 +999,13 @@ int32_t LP_vin_select(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t
//return(abovei >= 0 && above < (below>>1) ? abovei : belowi); //return(abovei >= 0 && above < (below>>1) ? abovei : belowi);
} }
cJSON *LP_inputjson(bits256 txid,int32_t vout,char *spendscriptstr) cJSON *LP_inputjson(bits256 txid,int32_t vout,char *spendscriptstr,int32_t suppress)
{ {
cJSON *sobj,*item = cJSON_CreateObject(); cJSON *sobj,*item = cJSON_CreateObject();
jaddbits256(item,"txid",txid); jaddbits256(item,"txid",txid);
jaddnum(item,"vout",vout); jaddnum(item,"vout",vout);
if ( suppress != 0 )
jaddnum(item,"suppress",1);
sobj = cJSON_CreateObject(); sobj = cJSON_CreateObject();
jaddstr(sobj,"hex",spendscriptstr); jaddstr(sobj,"hex",spendscriptstr);
jadd(item,"scriptPubKey",sobj); jadd(item,"scriptPubKey",sobj);
@ -1059,7 +1061,7 @@ int64_t LP_komodo_interest(bits256 txid,int64_t value)
int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_t amount,struct vin_info *V,struct LP_address_utxo **utxos,int32_t numunspents,int32_t suppress_pubkeys,int32_t ignore_cltverr,bits256 privkey,cJSON *privkeys,cJSON *vins,uint8_t *script,int32_t scriptlen,bits256 utxotxid,int32_t utxovout,int32_t dustcombine) int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_t amount,struct vin_info *V,struct LP_address_utxo **utxos,int32_t numunspents,int32_t suppress_pubkeys,int32_t ignore_cltverr,bits256 privkey,cJSON *privkeys,cJSON *vins,uint8_t *script,int32_t scriptlen,bits256 utxotxid,int32_t utxovout,int32_t dustcombine)
{ {
char wifstr[128],spendscriptstr[128],str[65]; int32_t i,j,maxiters,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; int64_t value,interest,interestsum,above,below,remains = amount,total = 0; char wifstr[128],spendscriptstr[128],str[65]; int32_t i,j,maxiters,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj,*sobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; int64_t value,interest,interestsum,above,below,remains = amount,total = 0;
*totalp = 0; *totalp = 0;
interestsum = 0; interestsum = 0;
init_hexbytes_noT(spendscriptstr,script,scriptlen); init_hexbytes_noT(spendscriptstr,script,scriptlen);
@ -1073,7 +1075,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
if ( utxovout == up->U.vout && bits256_cmp(utxotxid,up->U.txid) == 0 ) if ( utxovout == up->U.vout && bits256_cmp(utxotxid,up->U.txid) == 0 )
{ {
preselected[numpre++] = up; preselected[numpre++] = up;
printf("found utxotxid in slot.%d\n",j); //printf("found utxotxid in slot.%d\n",j);
utxos[j] = 0; utxos[j] = 0;
continue; continue;
} }
@ -1083,6 +1085,8 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
{ {
up->spendheight = 1; up->spendheight = 1;
utxos[j] = 0; utxos[j] = 0;
if ( (sobj= jobj(txobj,"scriptPubKey")) != 0 && jstr(sobj,"hex") != 0 && strlen(jstr(sobj,"hex")) == 35*2 )
up->U.suppress = 1;
} }
else else
{ {
@ -1117,13 +1121,13 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
preselected[numpre++] = up; preselected[numpre++] = up;
else else
{ {
printf("couldnt add address_utxo after not finding\n"); //printf("couldnt add address_utxo %s/v%d after not finding\n",bits256_str(str,utxotxid),utxovout);
sleep(1); sleep(1);
value = LP_txvalue(0,coin->symbol,utxotxid,utxovout); 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); 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 ) if ( (up= LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout)) != 0 )
preselected[numpre++] = up; preselected[numpre++] = up;
else printf("second couldnt add address_utxo after not finding\n"); else printf("second couldnt add address_utxo %s/v%d after not finding\n",bits256_str(str,utxotxid),utxovout);
//return(0); //return(0);
} }
} }
@ -1205,15 +1209,15 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
char str[65]; printf("%s/%d %.8f hodl interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum)); char str[65]; printf("%s/%d %.8f hodl interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum));
} }
} }
printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f %s/v%d\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum),bits256_str(str,up->U.txid),up->U.vout); //printf("suppress.%d numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f %s/v%d\n",suppress_pubkeys,numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum),bits256_str(str,up->U.txid),up->U.vout);
vp = &V[n++]; vp = &V[n++];
vp->N = vp->M = 1; vp->N = vp->M = 1;
vp->signers[0].privkey = privkey; vp->signers[0].privkey = privkey;
jaddistr(privkeys,wifstr); jaddistr(privkeys,wifstr);
bitcoin_pubkey33(ctx,vp->signers[0].pubkey,privkey); bitcoin_pubkey33(ctx,vp->signers[0].pubkey,privkey);
vp->suppress_pubkeys = suppress_pubkeys; vp->suppress_pubkeys = up->U.suppress;
vp->ignore_cltverr = ignore_cltverr; vp->ignore_cltverr = ignore_cltverr;
jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr)); jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr,up->U.suppress));
LP_unavailableset(up->U.txid,up->U.vout,(uint32_t)time(NULL)+LP_RESERVETIME*2,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 ) if ( remains <= 0 && i >= numpre-1 )
break; break;
@ -1227,7 +1231,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
return(n); 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 *opretstr,char *passphrase) 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,int32_t onevin,uint32_t locktime,char *opretstr,char *passphrase)
{ {
static void *ctx; static void *ctx;
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; 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;
@ -1284,18 +1288,38 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
return(0); return(0);
} }
memset(utxos,0,sizeof(utxos)); memset(utxos,0,sizeof(utxos));
if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,(int32_t)(sizeof(utxos)/sizeof(*utxos)),ap,coin->smartaddr)) <= 0 ) //char str[65];
if ( onevin != 0 )
{ {
if ( bits256_nonz(utxotxid) == 0 ) if ( (txobj= LP_gettxout(coin->symbol,coin->smartaddr,utxotxid,utxovout)) != 0 )
{ {
printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos); struct LP_address_utxo U;
memset(&U,0,sizeof(U));
utxos[0] = &U;
utxos[0]->U.txid = utxotxid;
utxos[0]->U.vout = utxovout;
utxos[0]->U.value = LP_value_extract(txobj,0,utxotxid);
free_json(txobj);
//char str[65]; printf("add onevin %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(utxos[0]->U.value));
numutxos = 1;
}
else
{
printf("LP_createrawtransaction: onevin spent already\n");
return(0); return(0);
} }
} }
//char str[65]; else
//for (i=0; i<numutxos; i++) {
// printf("utxo.%d %s/v%d %.8f\n",i,bits256_str(str,utxos[i]->U.txid),utxos[i]->U.vout,dstr(utxos[i]->U.value)); if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,(int32_t)(sizeof(utxos)/sizeof(*utxos)),ap,coin->smartaddr)) <= 0 )
{
if ( bits256_nonz(utxotxid) == 0 )
{
printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos);
return(0);
}
}
}
ignore_cltverr = 0; ignore_cltverr = 0;
suppress_pubkeys = 1; suppress_pubkeys = 1;
scriptlen = bitcoin_standardspend(script,0,G.LP_myrmd160); scriptlen = bitcoin_standardspend(script,0,G.LP_myrmd160);
@ -1427,6 +1451,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
return(0); return(0);
} }
} }
//printf("suppress.%d\n",V->suppress_pubkeys);
if ( (rawtxbytes= bitcoin_json2hex(coin->symbol,coin->isPoS,&txid,txobj,V)) != 0 ) if ( (rawtxbytes= bitcoin_json2hex(coin->symbol,coin->isPoS,&txid,txobj,V)) != 0 )
{ {
} else printf("error making rawtx suppress.%d\n",suppress_pubkeys); } else printf("error making rawtx suppress.%d\n",suppress_pubkeys);
@ -1576,7 +1601,7 @@ char *LP_createblasttransaction(uint64_t *changep,int32_t *changeoutp,cJSON **tx
scriptlen = bitcoin_standardspend(script,0,rmd160); scriptlen = bitcoin_standardspend(script,0,rmd160);
init_hexbytes_noT(spendscriptstr,script,scriptlen); init_hexbytes_noT(spendscriptstr,script,scriptlen);
vins = cJSON_CreateArray(); vins = cJSON_CreateArray();
jaddi(vins,LP_inputjson(utxotxid,utxovout,spendscriptstr)); jaddi(vins,LP_inputjson(utxotxid,utxovout,spendscriptstr,suppress_pubkeys));
jdelete(txobj,"vin"); jdelete(txobj,"vin");
jadd(txobj,"vin",jduplicate(vins)); jadd(txobj,"vin",jduplicate(vins));
*vinsp = vins; *vinsp = vins;
@ -1779,7 +1804,7 @@ char *LP_txblast(struct iguana_info *coin,cJSON *argjson)
char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
{ {
static void *ctx; static void *ctx;
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; 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],wifstr[64],*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)); //printf("withdraw.%s %s\n",coin->symbol,jprint(argjson,0));
if ( coin->etomic[0] != 0 ) if ( coin->etomic[0] != 0 )
{ {
@ -1811,6 +1836,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
locktime = juint(argjson,"locktime"); locktime = juint(argjson,"locktime");
txfee = juint(argjson,"txfee"); txfee = juint(argjson,"txfee");
autofee = (strcmp(coin->symbol,"BTC") == 0); autofee = (strcmp(coin->symbol,"BTC") == 0);
//printf("LP_withdraw: %s/v%d %s\n",bits256_str(str,utxotxid),utxovout,jprint(outputs,0));
if ( txfee == 0 ) if ( txfee == 0 )
{ {
autofee = 1; autofee = 1;
@ -1832,18 +1858,33 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
vins = cJSON_CreateArray(); vins = cJSON_CreateArray();
memset(V,0,sizeof(*V) * maxV); memset(V,0,sizeof(*V) * maxV);
numvins = 0; numvins = 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 ) if ( (rawtx= LP_createrawtransaction(&txobj,&numvins,coin,V,maxV,privkey,outputs,vins,privkeys,iter == 0 ? txfee : newtxfee,utxotxid,utxovout,jint(argjson,"onevin"),locktime,jstr(argjson,"opreturn"),jstr(argjson,"passphrase"))) != 0 )
{ {
completed = 0; completed = 0;
memset(&msgtx,0,sizeof(msgtx)); memset(&msgtx,0,sizeof(msgtx));
memset(signedtxid.bytes,0,sizeof(signedtxid)); memset(signedtxid.bytes,0,sizeof(signedtxid));
if ( (completed= iguana_signrawtransaction(ctx,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&msgtx,&signedtx,&signedtxid,V,numvins,rawtx,vins,privkeys,coin->zcash)) < 0 ) if ( jint(argjson,"onevin") != 0 )
printf("couldnt sign withdraw %s\n",bits256_str(str,signedtxid));
else if ( completed == 0 )
{ {
printf("incomplete signing withdraw (%s)\n",jprint(vins,0)); V[0].suppress_pubkeys = 1;
if ( signedtx != 0 ) bitcoin_priv2wif(coin->symbol,coin->wiftaddr,wifstr,privkey,coin->wiftype);
free(signedtx), signedtx = 0; if ( (signedtx= bitcoin_signrawtransaction(&completed,&signedtxid,coin,rawtx,wifstr)) != 0 && completed == 0 )
{
printf("incomplete signing\n");
free(signedtx);
signedtx = 0;
}
}
else
{
//printf("created V[0].suppress %d\n",V[0].suppress_pubkeys);
if ( (completed= iguana_signrawtransaction(ctx,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&msgtx,&signedtx,&signedtxid,V,numvins,rawtx,vins,privkeys,coin->zcash)) < 0 )
printf("couldnt sign withdraw %s\n",bits256_str(str,signedtxid));
else if ( completed == 0 )
{
printf("incomplete signing withdraw (%s)\n",jprint(vins,0));
if ( signedtx != 0 )
free(signedtx), signedtx = 0;
}
} }
if ( signedtx == 0 ) if ( signedtx == 0 )
break; break;
@ -1851,7 +1892,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
if ( autofee != 0 && iter == 0 && strcmp(coin->symbol,"BTC") == 0 ) if ( autofee != 0 && iter == 0 && strcmp(coin->symbol,"BTC") == 0 )
{ {
txfee = 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); printf("txfee %.8f -> newtxfee %.8f, numvins.%d datalen.%d\n",dstr(txfee),dstr(newtxfee),numvins,datalen);
for (i=0; i<numvins; i++) for (i=0; i<numvins; i++)
{ {
item = jitem(vins,i); item = jitem(vins,i);
@ -1914,7 +1955,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
char *LP_autosplit(struct iguana_info *coin) char *LP_autosplit(struct iguana_info *coin)
{ {
char *retstr; cJSON *argjson,*withdrawjson,*outputs,*item; int64_t total,balance,halfval,txfee; char *retstr; cJSON *argjson,*withdrawjson,*outputs,*item; int64_t total,balance,txfee;
if ( coin->etomic[0] == 0 ) if ( coin->etomic[0] == 0 )
{ {
if ( coin->electrum != 0 ) if ( coin->electrum != 0 )
@ -1926,17 +1967,21 @@ char *LP_autosplit(struct iguana_info *coin)
//printf("balance %.8f, txfee %.8f, threshold %.8f\n",dstr(balance),dstr(txfee),dstr((1000000 - (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)) ) if ( balance > txfee && balance >= (1000000 - (txfee + 100000)) )
{ {
halfval = (balance / 100) * 45; // .95 / .02 / .02 / 0.005
//halfval = (balance / 100) * 45;
argjson = cJSON_CreateObject(); argjson = cJSON_CreateObject();
outputs = cJSON_CreateArray(); outputs = cJSON_CreateArray();
item = cJSON_CreateObject(); item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,dstr(halfval)); jaddnum(item,coin->smartaddr,dstr(balance/100) * 95);
jaddi(outputs,item);
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,dstr(balance/50));
jaddi(outputs,item); jaddi(outputs,item);
item = cJSON_CreateObject(); item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,dstr(halfval)); jaddnum(item,coin->smartaddr,dstr(balance/50));
jaddi(outputs,item); jaddi(outputs,item);
item = cJSON_CreateObject(); item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,dstr(balance - 2*halfval)); jaddnum(item,coin->smartaddr,0.0001);
jaddi(outputs,item); jaddi(outputs,item);
jadd(argjson,"outputs",outputs); jadd(argjson,"outputs",outputs);
jaddnum(argjson,"broadcast",1); jaddnum(argjson,"broadcast",1);
@ -1950,33 +1995,209 @@ char *LP_autosplit(struct iguana_info *coin)
return(clonestr("{\"error\":\"couldnt autosplit\"}")); return(clonestr("{\"error\":\"couldnt autosplit\"}"));
} }
char *LP_autofillbob(struct iguana_info *coin,uint64_t satoshis)
{
char *retstr; cJSON *argjson,*withdrawjson,*outputs,*item; int64_t total,balance,txfee;
if ( coin->etomic[0] == 0 )
{
if ( coin->electrum != 0 )
balance = LP_unspents_load(coin->symbol,coin->smartaddr);
else balance = LP_RTsmartbalance(coin);
if ( strcmp("BTC",coin->symbol) == 0 )
txfee = LP_txfeecalc(coin,0,1000);
balance -= (txfee + 1000000);
if ( balance < (satoshis<<2) )
return(clonestr("{\"error\":\"couldnt autofill balance too small\"}"));
if ( balance > satoshis+3*txfee && balance >= (txfee + 1000000) )
{
argjson = cJSON_CreateObject();
outputs = cJSON_CreateArray();
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,dstr(satoshis + 3000000));
jaddi(outputs,item);
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,dstr(LP_DEPOSITSATOSHIS(satoshis) + 3000000));
jaddi(outputs,item);
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,0.0001);
jaddi(outputs,item);
jadd(argjson,"outputs",outputs);
jaddnum(argjson,"broadcast",0);
jaddstr(argjson,"coin",coin->symbol);
retstr = LP_withdraw(coin,argjson);
free_json(argjson);
return(retstr);
} else return(clonestr("{\"error\":\"balance too small to autosplit, please make more deposits\"}"));
}
return(clonestr("{\"error\":\"couldnt autofill etomic needs separate support\"}"));
}
char *LP_movecoinbases(char *symbol)
{
static bits256 zero; bits256 utxotxid,txid; struct iguana_info *coin; cJSON *retjson,*outputs,*argjson,*txids,*unspents,*item,*gen,*output; int32_t i,n,utxovout; char *retstr,*hexstr;
if ( (coin= LP_coinfind(symbol)) != 0 )
{
if ( coin->electrum == 0 )
{
txids = cJSON_CreateArray();
if ( (unspents= LP_listunspent(symbol,coin->smartaddr,zero,zero)) != 0 )
{
if ( (n= cJSON_GetArraySize(unspents)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(unspents,i);
if ( is_cJSON_True(jobj(item,"generated")) != 0 )
{
utxotxid = jbits256(item,"txid");
utxovout = jint(item,"vout");
argjson = cJSON_CreateObject();
outputs = cJSON_CreateArray();
output = cJSON_CreateObject();
jaddnum(output,coin->smartaddr,0.0001);
jaddi(outputs,output);
jadd(argjson,"outputs",outputs);
jaddnum(argjson,"broadcast",1);
jaddstr(argjson,"coin",coin->symbol);
jaddbits256(argjson,"utxotxid",utxotxid);
jaddnum(argjson,"utxovout",utxovout);
jaddnum(argjson,"onevin",1);
if ( (retstr= LP_withdraw(coin,argjson)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
txid = jbits256(retjson,"txid");
hexstr = jstr(retjson,"hex");
if ( bits256_nonz(txid) != 0 && hexstr != 0 )
{
printf("%s -> %s\n",jprint(item,0),hexstr);
jaddibits256(txids,txid);
}
free_json(retjson);
}
free(retstr);
}
free_json(argjson);
}
}
}
free_json(unspents);
}
return(jprint(txids,1));
}
return(clonestr("{\"error\":\"LP_movecoinbases cant be electrum\"}"));
}
return(clonestr("{\"error\":\"LP_movecoinbases couldnt find coin\"}"));
}
#ifndef NOTETOMIC #ifndef NOTETOMIC
char *LP_eth_tx_fee(struct iguana_info *coin, char *dest_addr, char *amount, int64_t gas, int64_t gas_price)
{
bits256 privkey;
cJSON *retjson = cJSON_CreateObject();
int64_t actual_gas_price = 0, actual_gas = 0;
char privkey_str[70];
if (gas_price > 0) {
actual_gas_price = gas_price;
} else {
actual_gas_price = getGasPriceFromStation(0);
if (actual_gas_price == 0) {
return (clonestr("{\"error\":\"Couldn't get gas price from station!\"}"));
}
}
cJSON_AddNumberToObject(retjson, "gas_price", actual_gas_price);
if (gas > 0) {
actual_gas = gas;
} else if (strcmp(coin->symbol, "ETH") == 0) {
actual_gas = 21000;
} else {
privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr);
uint8arrayToHex(privkey_str, privkey.bytes, 32);
actual_gas = estimate_erc20_gas(coin->etomic, dest_addr, amount, privkey_str, coin->decimals);
if (actual_gas == 0) {
return (clonestr("{\"error\":\"Couldn't estimate erc20 transfer gas usage!\"}"));
}
}
cJSON_AddNumberToObject(retjson, "gas", actual_gas);
double_t eth_fee = (actual_gas_price * actual_gas) / 1000000000.0;
cJSON_AddNumberToObject(retjson, "eth_fee", eth_fee);
return(jprint(retjson,1));
}
char *LP_eth_withdraw(struct iguana_info *coin,cJSON *argjson) char *LP_eth_withdraw(struct iguana_info *coin,cJSON *argjson)
{ {
cJSON *retjson = cJSON_CreateObject(); cJSON *retjson = cJSON_CreateObject();
cJSON *gas_json = cJSON_GetObjectItem(argjson, "gas");
cJSON *gas_price_json = cJSON_GetObjectItem(argjson, "gas_price");
char *dest_addr, *tx_id, privkey_str[70], amount_str[100]; char *dest_addr, *tx_id, privkey_str[70], amount_str[100];
int64_t amount; int64_t amount = 0, gas = 0, gas_price = 0, broadcast = 0;
bits256 privkey; bits256 privkey;
dest_addr = jstr(argjson, "to"); dest_addr = jstr(argjson, "to");
if (dest_addr == NULL) {
return(clonestr("{\"error\":\"param 'to' is required!\"}"));
}
if (isValidAddress(dest_addr) == 0) {
return(clonestr("{\"error\":\"'to' address is not valid!\"}"));
}
amount = jdouble(argjson, "amount") * 100000000; amount = jdouble(argjson, "amount") * 100000000;
privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr); if (amount == 0) {
uint8arrayToHex(privkey_str, privkey.bytes, 32); return(clonestr("{\"error\":\"'amount' is not set or equal to zero!\"}"));
}
if (gas_json != NULL && is_cJSON_Number(gas_json)) {
gas = gas_json->valueint;
if (gas < 21000) {
return (clonestr("{\"error\":\"'gas' can't be lower than 21000!\"}"));
}
}
if (gas_price_json != NULL && is_cJSON_Number(gas_price_json)) {
gas_price = gas_price_json->valueint;
if (gas_price < 1) {
return (clonestr("{\"error\":\"'gas_price' can't be lower than 1!\"}"));
}
}
broadcast = jint(argjson, "broadcast");
satoshisToWei(amount_str, amount); satoshisToWei(amount_str, amount);
if (strcmp(coin->symbol, "ETH") == 0) { if (broadcast == 1) {
tx_id = sendEth(dest_addr, amount_str, privkey_str, 0); privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr);
uint8arrayToHex(privkey_str, privkey.bytes, 32);
if (strcmp(coin->symbol, "ETH") == 0) {
tx_id = sendEth(dest_addr, amount_str, privkey_str, 0, gas, gas_price, 0);
} else {
tx_id = sendErc20(coin->etomic, dest_addr, amount_str, privkey_str, 0, gas, gas_price, 0, coin->decimals);
}
if (tx_id != NULL) {
jaddstr(retjson, "tx_id", tx_id);
free(tx_id);
} else {
jaddstr(retjson, "error", "Error sending transaction");
}
return (jprint(retjson, 1));
} else { } else {
tx_id = sendErc20(coin->etomic, dest_addr, amount_str, privkey_str, 0); return LP_eth_tx_fee(coin, dest_addr, amount_str, gas, gas_price);
} }
jaddstr(retjson, "tx_id", tx_id);
return(jprint(retjson,1));
} }
char *LP_eth_gas_price()
{
cJSON *retjson = cJSON_CreateObject();
uint64_t gas_price = getGasPriceFromStation(0);
if (gas_price > 0) {
cJSON_AddNumberToObject(retjson, "gas_price", gas_price);
} else {
cJSON_AddStringToObject(retjson, "error", "Could not get gas price from station!");
}
return(jprint(retjson,1));
}
#endif #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) 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; struct iguana_info *coin; int32_t len,retval=-1; char *retstr,*hexstr; cJSON *argjson,*outputs,*item,*retjson,*obj;
@ -2103,7 +2324,7 @@ int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vou
{ {
cJSON *retjson; cJSON *retjson;
coinaddr[0] = 0; coinaddr[0] = 0;
if ( (retjson= LP_gettx("LP_swap_getcoinaddr",symbol,txid,0)) != 0 ) if ( (retjson= LP_gettx("LP_swap_getcoinaddr",symbol,txid,1)) != 0 )
{ {
LP_txdestaddr(coinaddr,txid,vout,retjson); LP_txdestaddr(coinaddr,txid,vout,retjson);
free_json(retjson); free_json(retjson);

61
iguana/exchanges/LP_utxo.c

@ -357,7 +357,7 @@ int32_t LP_address_minmax(int32_t iambob,uint64_t *medianp,uint64_t *minp,uint64
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) 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 i,n = 0; struct LP_address_utxo *up,*tmp; struct LP_transaction *tx; cJSON *txout,*sobj; int32_t i,n = 0;
if ( strcmp(ap->coinaddr,coinaddr) != 0 ) if ( strcmp(ap->coinaddr,coinaddr) != 0 )
printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr); printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr);
//portable_mutex_lock(&LP_utxomutex); //portable_mutex_lock(&LP_utxomutex);
@ -370,6 +370,12 @@ 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 ( (txout= LP_gettxout(coin->symbol,coinaddr,up->U.txid,up->U.vout)) != 0 )
{ {
//printf("check sobj.hex %s\n",jprint(txout,0));
if ( (sobj= jobj(txout,"scriptPubKey")) != 0 && jstr(sobj,"hex") != 0 && strlen(jstr(sobj,"hex")) == 35*2 )
{
up->U.suppress = 1;
//printf("suppress %s\n",jprint(sobj,0));
}
if ( LP_value_extract(txout,0,up->U.txid) == 0 ) if ( LP_value_extract(txout,0,up->U.txid) == 0 )
{ {
//char str[65]; 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);
@ -464,7 +470,7 @@ int32_t LP_address_utxoadd(int32_t skipsearch,uint32_t timestamp,char *debug,str
if ( spendheight > 0 ) // dont autocreate entries for spends we dont care about if ( spendheight > 0 ) // dont autocreate entries for spends we dont care about
ap = LP_addressfind(coin,coinaddr); ap = LP_addressfind(coin,coinaddr);
else ap = LP_address(coin,coinaddr); else ap = LP_address(coin,coinaddr);
//printf("%s add addr.%s ht.%d ap.%p\n",coin->symbol,coinaddr,height,ap); //printf("skipflag.%d %s add addr.%s ht.%d ap.%p\n",skipsearchcoin->symbol,coinaddr,height,ap);
if ( ap != 0 ) if ( ap != 0 )
{ {
flag = 0; flag = 0;
@ -500,7 +506,7 @@ int32_t LP_address_utxoadd(int32_t skipsearch,uint32_t timestamp,char *debug,str
{ {
if ( (hexstr= jstr(sobj,"hex")) != 0 ) if ( (hexstr= jstr(sobj,"hex")) != 0 )
{ {
if ( strlen(hexstr) != 25*2 ) if ( strlen(hexstr) != 25*2 && strlen(hexstr) != 35*2 )
{ {
//printf("skip non-standard utxo.(%s)\n",hexstr); //printf("skip non-standard utxo.(%s)\n",hexstr);
free_json(txobj); free_json(txobj);
@ -699,7 +705,8 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
//printf("address balance call LP_listunspent %s electrum.%p etomic.%d\n",coin->symbol,coin->electrum,coin->etomic[0]); //printf("address balance call LP_listunspent %s electrum.%p etomic.%d\n",coin->symbol,coin->electrum,coin->etomic[0]);
#ifndef NOTETOMIC #ifndef NOTETOMIC
if (coin->etomic[0] != 0) { if (coin->etomic[0] != 0) {
balance = LP_etomic_get_balance(coin, coinaddr); int error = 0;
balance = LP_etomic_get_balance(coin, coinaddr, &error);
} else } else
#endif #endif
if ( coin->electrum == 0 ) if ( coin->electrum == 0 )
@ -724,7 +731,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
} }
else else
{ {
if ( strcmp(coin->smartaddr,coinaddr) != 0 ) //if ( strcmp(coin->smartaddr,coinaddr) != 0 )
{ {
if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,coinaddr,2,zero,zero)) != 0 ) if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,coinaddr,2,zero,zero)) != 0 )
free_json(retjson); free_json(retjson);
@ -787,7 +794,14 @@ cJSON *LP_balances(char *coinaddr)
} }
else else
{ {
if ( (balance= LP_RTsmartbalance(coin)) != 0 ) #ifndef NOTETOMIC
if (coin->etomic[0] == 0 || coin->inactive == 0) {
#endif
balance = LP_RTsmartbalance(coin);
#ifndef NOTETOMIC
}
#endif
if ( balance != 0 )
{ {
item = cJSON_CreateObject(); item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol); jaddstr(item,"coin",coin->symbol);
@ -898,7 +912,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]; 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 ) if ( coin->inactive != 0 )
return(0); return(0);
if ( txobj != 0 || (txobj= LP_gettx("LP_transactioninit",coin->symbol,txid,0)) != 0 ) if ( txobj != 0 || (txobj= LP_gettx("LP_transactioninit",coin->symbol,txid,1)) != 0 )
{ {
if ( coin->electrum == 0 ) if ( coin->electrum == 0 )
height = LP_txheight(coin,txid); height = LP_txheight(coin,txid);
@ -964,7 +978,7 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid)
return(height); return(height);
if ( coin->electrum == 0 ) if ( coin->electrum == 0 )
{ {
if ( (txobj= LP_gettx("LP_txheight",coin->symbol,txid,0)) != 0 ) if ( (txobj= LP_gettx("LP_txheight",coin->symbol,txid,1)) != 0 )
{ {
//*timestampp = juint(txobj,"locktime"); //*timestampp = juint(txobj,"locktime");
//*blocktimep = juint(txobj,"blocktime"); //*blocktimep = juint(txobj,"blocktime");
@ -1067,7 +1081,7 @@ uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_inf
{ {
if ( (value= LP_value_extract(txobj,0,txid)) == 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); // char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",coin->symbol,bits256_str(str,txid),jprint(txobj,0),vout);
} }
else if ( strcmp(coin->symbol,"KMD") == 0 ) else if ( strcmp(coin->symbol,"KMD") == 0 )
{ {
@ -1185,7 +1199,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
return(-1); return(-1);
} }
destaddr[0] = destaddr2[0] = 0; destaddr[0] = destaddr2[0] = 0;
if ( coin != 0 && IAMLP != 0 && coin->inactive != 0 ) if ( coin != 0 && (strcmp(coin->symbol, "ETOMIC") == 0 || (coin->inactive != 0 && IAMLP != 0)))
bypass = 1; bypass = 1;
if ( bypass != 0 ) if ( bypass != 0 )
val = satoshis; val = satoshis;
@ -1209,16 +1223,27 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
strcpy(destaddr,destaddr2); strcpy(destaddr,destaddr2);
if ( coin != 0 ) if ( coin != 0 )
{ {
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 ) char txid_str[100], txid2_str[100];
return(0); bits256_str(txid_str, txid);
bits256_str(txid2_str, txid2);
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 ) {
printf("Could not find tx out: %s %d\n", txid_str, vout);
return (0);
}
else free_json(txobj); else free_json(txobj);
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 ) if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 ) {
return(0); printf("Could not find tx out2: %s %d\n", txid_str, vout2);
return (0);
}
else free_json(txobj); else free_json(txobj);
if ( LP_numconfirms(coin->symbol,destaddr,txid,vout,0) <= 0 ) if ( LP_numconfirms(coin->symbol,destaddr,txid,vout,0) <= 0 ) {
return(0); printf("Txid numconfirms is less or equal to zero: %s %d\n", txid_str, vout);
if ( LP_numconfirms(coin->symbol,destaddr,txid2,vout2,0) <= 0 ) return (0);
return(0); }
if ( LP_numconfirms(coin->symbol,destaddr,txid2,vout2,0) <= 0 ) {
printf("Txid numconfirms is less or equal to zero: %s %d\n", txid2_str, vout2);
return (0);
}
} }
return(1); return(1);
} }

2
iguana/exchanges/auto_chipsbtc

@ -1,2 +1,2 @@
source userpass source userpass
curl --url "http://127.0.0.1:7783" --data "{\"minprice\":0.00006,\"maxprice\":0.0002,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"BTC\",\"margin\":0.05,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}" curl --url "http://127.0.0.1:7783" --data "{\"minprice\":0.00002,\"maxprice\":0.0002,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"BTC\",\"margin\":0.05,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}"

2
iguana/exchanges/auto_chipskmd

@ -1,2 +1,2 @@
source userpass source userpass
curl --url "http://127.0.0.1:7783" --data "{\"minprice\":0.15,\"maxprice\":0.4,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"KMD\",\"margin\":0.05,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}" curl --url "http://127.0.0.1:7783" --data "{\"minprice\":0.05,\"maxprice\":0.4,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"KMD\",\"margin\":0.05,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}"

2
iguana/exchanges/autoprice

@ -39,7 +39,7 @@ sharkholdings="{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"komodo\",\"b
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 "{\"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\":\"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\":486}, {\"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}" 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}"

81
iguana/exchanges/bitcoin.c

@ -22,6 +22,51 @@ char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *meth
return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,0)); return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,0));
} }
int32_t bitcoin_addr2rmd160_ex(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)
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);
}
offset = 1 + (taddr != 0);
memset(rmd160, 0, 20);
*addrtypep = 0;
buf = _buf;
if ((len = bitcoin_base58decode(buf, coinaddr)) >= 4)
{
// validate with trailing hash, then remove hash
hash = bits256_doublesha256(0, buf, 20 + offset);
*addrtypep = (taddr == 0) ? *buf : buf[1];
memcpy(rmd160, buf + offset, 20);
if ((buf[20 + offset] & 0xff) == hash.bytes[31] && (buf[21 + offset] & 0xff) == hash.bytes[30] && (buf[22 + offset] & 0xff) == hash.bytes[29] && (buf[23 + offset] & 0xff) == hash.bytes[28])
{
//printf("coinaddr.(%s) valid checksum addrtype.%02x\n",coinaddr,*addrtypep);
return(20);
}
else 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 if (strcmp(symbol, "BTC") != 0 || *addrtypep == 0 || *addrtypep == 5)
{
int32_t i;
//if ( len > 20 )
// hash = bits256_calcaddrhash(symbol,buf,len);
for (i = 0; i<len; i++)
printf("%02x ", hash.bytes[i]);
char str[65]; printf("\n%s addrtype.%d taddr.%02x checkhash.(%s) len.%d mismatch %02x %02x %02x %02x vs %02x %02x %02x %02x (%s)\n", symbol, *addrtypep, taddr, coinaddr, len, buf[len - 1] & 0xff, buf[len - 2] & 0xff, buf[len - 3] & 0xff, buf[len - 4] & 0xff, hash.bytes[31], hash.bytes[30], hash.bytes[29], hash.bytes[28], bits256_str(str, hash));
}
}
return(0);
}
int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr) int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr)
{ {
bits256 hash; uint8_t *buf,_buf[25]; int32_t len; bits256 hash; uint8_t *buf,_buf[25]; int32_t len;
@ -75,6 +120,42 @@ char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,
return(coinaddr); return(coinaddr);
} }
char *bitcoin_address_ex(char *symbol, char *coinaddr, uint8_t taddr, uint8_t addrtype, uint8_t *pubkey_or_rmd160, int32_t len)
{
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;
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 (taddr != 0)
{
data[0] = taddr;
data[1] = addrtype;
}
else data[0] = addrtype;
hash = bits256_doublesha256(0, data, 20 + offset);
for (i = 0; i<4; i++)
data[20 + offset + i] = hash.bytes[31 - i];
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);
}
int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr) int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr)
{ {
uint8_t rmd160[20],addrtype; char checkaddr[128]; uint8_t rmd160[20],addrtype; char checkaddr[128];

1
iguana/exchanges/bitcoin.h

@ -46,6 +46,7 @@
int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr); int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr);
int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *otheraddr,uint8_t secret160[20],uint32_t locktime); int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *otheraddr,uint8_t secret160[20],uint32_t locktime);
int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr);
int32_t bitcoin_addr2rmd160_ex(char *symbol, uint8_t taddr, uint8_t *addrtypep, uint8_t rmd160[20], char *coinaddr);
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); 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);
int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp); int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp);

4
iguana/exchanges/coins

File diff suppressed because one or more lines are too long

89
iguana/exchanges/etomicswap/etomiccurl.c

@ -1,7 +1,6 @@
#include "etomiccurl.h" #include "etomiccurl.h"
#include <curl/curl.h> #include <curl/curl.h>
static char *ethRpcUrl = ETOMIC_URL;
pthread_mutex_t sendTxMutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t sendTxMutex = PTHREAD_MUTEX_INITIALIZER;
struct string { struct string {
@ -36,16 +35,15 @@ size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s)
cJSON *parseEthRpcResponse(char *requestResult) cJSON *parseEthRpcResponse(char *requestResult)
{ {
printf("Trying to parse ETH RPC response: %s\n", requestResult);
cJSON *json = cJSON_Parse(requestResult); cJSON *json = cJSON_Parse(requestResult);
if (json == NULL) { if (json == NULL) {
printf("ETH RPC response parse failed!\n"); printf("ETH RPC response parse failed: %s!\n", requestResult);
return NULL; return NULL;
} }
cJSON *tmp = cJSON_GetObjectItem(json, "result"); cJSON *tmp = cJSON_GetObjectItem(json, "result");
cJSON *error = cJSON_GetObjectItem(json, "error"); cJSON *error = cJSON_GetObjectItem(json, "error");
cJSON *result = NULL; cJSON *result = NULL;
if (!is_cJSON_Null(tmp)) { if (tmp != NULL && !is_cJSON_Null(tmp)) {
result = cJSON_Duplicate(tmp, 1); result = cJSON_Duplicate(tmp, 1);
} else if (error != NULL && !is_cJSON_Null(error)) { } else if (error != NULL && !is_cJSON_Null(error)) {
char *errorString = cJSON_PrintUnformatted(error); char *errorString = cJSON_PrintUnformatted(error);
@ -56,7 +54,7 @@ cJSON *parseEthRpcResponse(char *requestResult)
return result; return result;
} }
char* sendRequest(char* request) char* sendRequest(char *request, char *url)
{ {
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
@ -72,13 +70,15 @@ char* sendRequest(char* request)
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
curl_easy_setopt(curl, CURLOPT_URL, ethRpcUrl); curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request);
/* Perform the request, res will get the return code */ /* Perform the request, res will get the return code */
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
/* Check for errors */ /* Check for errors */
if (res != CURLE_OK) { if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
curl_easy_cleanup(curl);
return NULL;
} }
/* always cleanup */ /* always cleanup */
@ -98,7 +98,7 @@ cJSON *sendRpcRequest(char *method, cJSON *params)
cJSON_AddItemToObject(request, "params", cJSON_Duplicate(params, 1)); cJSON_AddItemToObject(request, "params", cJSON_Duplicate(params, 1));
cJSON_AddNumberToObject(request, "id", 1); cJSON_AddNumberToObject(request, "id", 1);
string = cJSON_PrintUnformatted(request); string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string); char* requestResult = sendRequest(string, ETOMIC_URL);
free(string); free(string);
cJSON_Delete(request); cJSON_Delete(request);
cJSON *result = parseEthRpcResponse(requestResult); cJSON *result = parseEthRpcResponse(requestResult);
@ -151,8 +151,8 @@ char* sendRawTx(char* rawTx)
int64_t getNonce(char* address) int64_t getNonce(char* address)
{ {
// we should lock this mutex and unlock it only when transaction was already sent. // we should lock this mutex and unlock it only when transaction was already sent or failed.
// make sure that sendRawTx is called after getting a nonce! // make sure that sendRawTx or unlock_send_tx_mutex is called after getting a nonce!
if (pthread_mutex_lock(&sendTxMutex) != 0) { if (pthread_mutex_lock(&sendTxMutex) != 0) {
printf("Nonce mutex lock failed\n"); printf("Nonce mutex lock failed\n");
}; };
@ -186,7 +186,7 @@ char* getEthBalanceRequest(char* address)
return balance; return balance;
} }
char* ethCall(char* to, const char* data) char *ethCall(char *to, const char *data)
{ {
cJSON *params = cJSON_CreateArray(); cJSON *params = cJSON_CreateArray();
cJSON *txObject = cJSON_CreateObject(); cJSON *txObject = cJSON_CreateObject();
@ -196,7 +196,7 @@ char* ethCall(char* to, const char* data)
cJSON_AddItemToArray(params, cJSON_CreateString("latest")); cJSON_AddItemToArray(params, cJSON_CreateString("latest"));
cJSON *resultJson = sendRpcRequest("eth_call", params); cJSON *resultJson = sendRpcRequest("eth_call", params);
cJSON_Delete(params); cJSON_Delete(params);
char* result = NULL; char *result = NULL;
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) { if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
result = (char *) malloc(strlen(resultJson->valuestring) + 1); result = (char *) malloc(strlen(resultJson->valuestring) + 1);
strcpy(result, resultJson->valuestring); strcpy(result, resultJson->valuestring);
@ -205,6 +205,26 @@ char* ethCall(char* to, const char* data)
return result; return result;
} }
uint64_t estimateGas(char *from, char *to, const char *data)
{
cJSON *params = cJSON_CreateArray();
cJSON *txObject = cJSON_CreateObject();
cJSON_AddStringToObject(txObject, "from", from);
cJSON_AddStringToObject(txObject, "to", to);
cJSON_AddStringToObject(txObject, "data", data);
cJSON_AddItemToArray(params, txObject);
cJSON_AddItemToArray(params, cJSON_CreateString("latest"));
cJSON *resultJson = sendRpcRequest("eth_estimateGas", params);
cJSON_Delete(params);
uint64_t result = 0;
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
result = (uint64_t)strtoul(resultJson->valuestring, NULL, 0);
result = (result / 100) * 120; // add 20% because real gas usage might differ from estimate
}
cJSON_Delete(resultJson);
return result;
}
EthTxReceipt getEthTxReceipt(char *txId) EthTxReceipt getEthTxReceipt(char *txId)
{ {
EthTxReceipt result; EthTxReceipt result;
@ -265,7 +285,7 @@ EthTxData getEthTxData(char *txId)
return result; return result;
} }
uint64_t getGasPriceFromStation() uint64_t getGasPriceFromStation(uint8_t defaultOnErr)
{ {
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
@ -283,6 +303,12 @@ uint64_t getGasPriceFromStation()
curl_easy_setopt(curl, CURLOPT_URL, "https://ethgasstation.info/json/ethgasAPI.json"); curl_easy_setopt(curl, CURLOPT_URL, "https://ethgasstation.info/json/ethgasAPI.json");
/* Perform the request, res will get the return code */ /* Perform the request, res will get the return code */
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
uint64_t result;
if (defaultOnErr == 1) {
result = DEFAULT_GAS_PRICE;
} else {
result = 0;
}
/* Check for errors */ /* Check for errors */
if (res != CURLE_OK) { if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
@ -292,9 +318,9 @@ uint64_t getGasPriceFromStation()
/* always cleanup */ /* always cleanup */
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
cJSON *resultJson = cJSON_Parse(s.ptr); cJSON *resultJson = cJSON_Parse(s.ptr);
uint64_t result = DEFAULT_GAS_PRICE;
free(s.ptr); free(s.ptr);
if (resultJson == NULL) { if (resultJson == NULL) {
printf("Could not parse gas station response!\n");
return result; return result;
} }
@ -342,3 +368,40 @@ int32_t waitForConfirmation(char *txId)
return((int32_t)receipt.confirmations); return((int32_t)receipt.confirmations);
} }
void unlock_send_tx_mutex()
{
pthread_mutex_unlock(&sendTxMutex);
}
uint8_t get_etomic_from_faucet(char *etomic_addr)
{
char* string;
cJSON *request = cJSON_CreateObject();
cJSON_AddStringToObject(request, "etomicAddress", etomic_addr);
string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string, FAUCET_URL);
free(string);
cJSON_Delete(request);
if (requestResult == NULL) {
return 0;
}
cJSON *json = cJSON_Parse(requestResult);
if (json == NULL) {
printf("ETOMIC faucet response parse failed!\n");
return 0;
}
cJSON *error = cJSON_GetObjectItem(json, "error");
uint8_t result = 0;
if (error != NULL && !is_cJSON_Null(error)) {
char *errorString = cJSON_PrintUnformatted(error);
printf("Got ETOMIC faucet error: %s\n", errorString);
free(errorString);
} else {
result = 1;
}
cJSON_Delete(json);
return result;
}

9
iguana/exchanges/etomicswap/etomiccurl.h

@ -16,9 +16,11 @@ extern "C"{
#define DEFAULT_GAS_PRICE 100 #define DEFAULT_GAS_PRICE 100
#else #else
#define ETOMIC_URL "http://195.201.0.6:8555" #define ETOMIC_URL "http://195.201.0.6:8555"
#define DEFAULT_GAS_PRICE 4 #define DEFAULT_GAS_PRICE 10
#endif #endif
#define FAUCET_URL "http://195.201.116.176:8000/getEtomic"
typedef struct typedef struct
{ {
uint64_t blockNumber; uint64_t blockNumber;
@ -39,13 +41,16 @@ typedef struct
char* sendRawTx(char* rawTx); char* sendRawTx(char* rawTx);
char* sendRawTxWaitConfirm(char* rawTx); char* sendRawTxWaitConfirm(char* rawTx);
char* ethCall(char* to, const char* data); char* ethCall(char* to, const char* data);
uint64_t estimateGas(char *from, char *to, const char *data);
int64_t getNonce(char* address); int64_t getNonce(char* address);
char* getEthBalanceRequest(char* address); char* getEthBalanceRequest(char* address);
EthTxReceipt getEthTxReceipt(char *txId); EthTxReceipt getEthTxReceipt(char *txId);
EthTxData getEthTxData(char *txId); EthTxData getEthTxData(char *txId);
uint64_t getEthBlockNumber(); uint64_t getEthBlockNumber();
uint64_t getGasPriceFromStation(); uint64_t getGasPriceFromStation(uint8_t defaultOnErr);
int32_t waitForConfirmation(char *txId); int32_t waitForConfirmation(char *txId);
void unlock_send_tx_mutex();
uint8_t get_etomic_from_faucet(char *etomic_addr);
#ifdef __cplusplus #ifdef __cplusplus
} }

302
iguana/exchanges/etomicswap/etomiclib.cpp

@ -4,6 +4,7 @@
#include "etomiclib.h" #include "etomiclib.h"
#include "etomiccurl.h" #include "etomiccurl.h"
#include <iostream> #include <iostream>
#include <regex>
#include <cpp-ethereum/libethcore/Common.h> #include <cpp-ethereum/libethcore/Common.h>
#include <cpp-ethereum/libethcore/CommonJS.h> #include <cpp-ethereum/libethcore/CommonJS.h>
#include <cpp-ethereum/libethcore/TransactionBase.h> #include <cpp-ethereum/libethcore/TransactionBase.h>
@ -27,18 +28,18 @@ TransactionSkeleton txDataToSkeleton(BasicTxData txData)
tx.to = jsToAddress(txData.to); tx.to = jsToAddress(txData.to);
tx.value = jsToU256(txData.amount); tx.value = jsToU256(txData.amount);
tx.gas = 200000; tx.gas = 200000;
tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9); tx.gasPrice = getGasPriceFromStation(1) * boost::multiprecision::pow(u256(10), 9);
tx.nonce = getNonce(txData.from); tx.nonce = getNonce(txData.from);
return tx; return tx;
} }
char *signTx(TransactionSkeleton& tx, char* secret) char *signTx(TransactionSkeleton& tx, char* secret)
{ {
Secret& secretKey = *(new Secret(secret)); Secret secretKey(secret);
auto baseTx = new TransactionBase(tx, secretKey); TransactionBase baseTx(tx, secretKey);
RLPStream& rlpStream = *(new RLPStream()); RLPStream rlpStream;
baseTx->streamRLP(rlpStream); baseTx.streamRLP(rlpStream);
std::stringstream& ss = *(new std::stringstream); std::stringstream ss;
ss << rlpStream.out(); ss << rlpStream.out();
return stringStreamToChar(ss); return stringStreamToChar(ss);
} }
@ -50,7 +51,7 @@ char *approveErc20(ApproveErc20Input input)
tx.to = jsToAddress(input.tokenAddress); tx.to = jsToAddress(input.tokenAddress);
tx.value = 0; tx.value = 0;
tx.gas = 300000; tx.gas = 300000;
tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9); tx.gasPrice = getGasPriceFromStation(1) * boost::multiprecision::pow(u256(10), 9);
tx.nonce = getNonce(input.owner); tx.nonce = getNonce(input.owner);
std::stringstream ss; std::stringstream ss;
ss << "0x095ea7b3" ss << "0x095ea7b3"
@ -101,7 +102,12 @@ uint8_t verifyAliceEthPaymentData(AliceSendsEthPaymentInput input, char *data)
std::stringstream aliceSendsErc20PaymentData(AliceSendsErc20PaymentInput input) std::stringstream aliceSendsErc20PaymentData(AliceSendsErc20PaymentInput input)
{ {
uint8_t decimals = getErc20Decimals(input.tokenAddress); uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
u256 amount = jsToU256(input.amount); u256 amount = jsToU256(input.amount);
if (decimals < 18) { if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals); amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
@ -148,12 +154,20 @@ char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxDat
std::stringstream ss; std::stringstream ss;
u256 amount = jsToU256(input.amount); u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress); dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) { if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress); uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) { if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals); amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
} }
} }
ss << "0x8b9a167a" ss << "0x8b9a167a"
<< toHex(jsToBytes(input.dealId)) << toHex(jsToBytes(input.dealId))
<< toHex(toBigEndian(amount)) << toHex(toBigEndian(amount))
@ -179,12 +193,20 @@ char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData
std::stringstream ss; std::stringstream ss;
u256 amount = jsToU256(input.amount); u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress); dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) { if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress); uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) { if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals); amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
} }
} }
ss << "0x392ec66b" ss << "0x392ec66b"
<< toHex(jsToBytes(input.dealId)) << toHex(jsToBytes(input.dealId))
<< toHex(toBigEndian(amount)) << toHex(toBigEndian(amount))
@ -241,7 +263,13 @@ uint8_t verifyBobEthDepositData(BobSendsEthDepositInput input, char *data)
std::stringstream bobSendsErc20DepositData(BobSendsErc20DepositInput input) std::stringstream bobSendsErc20DepositData(BobSendsErc20DepositInput input)
{ {
uint8_t decimals = getErc20Decimals(input.tokenAddress); uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
u256 amount = jsToU256(input.amount); u256 amount = jsToU256(input.amount);
u256 lockTime = input.lockTime; u256 lockTime = input.lockTime;
if (decimals < 18) { if (decimals < 18) {
@ -289,7 +317,13 @@ char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData)
u256 amount = jsToU256(input.amount); u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress); dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) { if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress); uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) { if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals); amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
} }
@ -316,7 +350,13 @@ char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData
u256 amount = jsToU256(input.amount); u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress); dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) { if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress); uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) { if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals); amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
} }
@ -374,9 +414,15 @@ uint8_t verifyBobEthPaymentData(BobSendsEthPaymentInput input, char *data)
std::stringstream bobSendsErc20PaymentData(BobSendsErc20PaymentInput input) std::stringstream bobSendsErc20PaymentData(BobSendsErc20PaymentInput input)
{ {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
u256 amount = jsToU256(input.amount); u256 amount = jsToU256(input.amount);
u256 lockTime = input.lockTime; u256 lockTime = input.lockTime;
uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) { if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals); amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
} }
@ -422,7 +468,13 @@ char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData
u256 amount = jsToU256(input.amount); u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress); dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) { if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress); uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) { if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals); amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
} }
@ -450,7 +502,13 @@ char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData
u256 amount = jsToU256(input.amount); u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress); dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) { if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress); uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) { if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals); amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
} }
@ -472,54 +530,69 @@ char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData
char* privKey2Addr(char* privKey) char* privKey2Addr(char* privKey)
{ {
Secret& secretKey = *(new Secret(privKey)); Secret secretKey(privKey);
std::stringstream& ss = *(new std::stringstream); std::stringstream ss;
ss << "0x" << toAddress(secretKey); ss << "0x" << toAddress(secretKey);
return stringStreamToChar(ss); return stringStreamToChar(ss);
}; };
char* pubKey2Addr(char* pubKey) char* pubKey2Addr(char* pubKey)
{ {
Public& publicKey = *(new Public(pubKey)); Public publicKey(pubKey);
std::stringstream& ss = *(new std::stringstream); std::stringstream ss;
ss << "0x" << toAddress(publicKey); ss << "0x" << toAddress(publicKey);
return stringStreamToChar(ss); return stringStreamToChar(ss);
}; };
char* getPubKeyFromPriv(char* privKey) char* getPubKeyFromPriv(char *privKey)
{ {
Public publicKey = toPublic(*(new Secret(privKey))); Public publicKey = toPublic(Secret(privKey));
std::stringstream& ss = *(new std::stringstream); std::stringstream ss;
ss << "0x" << publicKey; ss << "0x" << publicKey;
return stringStreamToChar(ss); return stringStreamToChar(ss);
} }
uint64_t getEthBalance(char* address) uint64_t getEthBalance(char *address, int *error)
{ {
char* hexBalance = getEthBalanceRequest(address); char* hexBalance = getEthBalanceRequest(address);
// convert wei to satoshi if (hexBalance != NULL) {
u256 balance = jsToU256(hexBalance) / boost::multiprecision::pow(u256(10), 10); // convert wei to satoshi
free(hexBalance); u256 balance = jsToU256(hexBalance) / boost::multiprecision::pow(u256(10), 10);
return static_cast<uint64_t>(balance); free(hexBalance);
return static_cast<uint64_t>(balance);
} else {
*error = 1;
return 0;
}
} }
uint64_t getErc20BalanceSatoshi(char *address, char *tokenAddress) uint64_t getErc20BalanceSatoshi(char *address, char *tokenAddress, uint8_t setDecimals, int *error)
{ {
std::stringstream ss; std::stringstream ss;
ss << "0x70a08231" ss << "0x70a08231"
<< "000000000000000000000000" << "000000000000000000000000"
<< toHex(jsToAddress(address)); << toHex(jsToAddress(address));
std::stringstream& resultStream = *(new std::stringstream);
char* hexBalance = ethCall(tokenAddress, ss.str().c_str()); char* hexBalance = ethCall(tokenAddress, ss.str().c_str());
// convert wei to satoshi // convert wei to satoshi
uint8_t decimals = getErc20Decimals(tokenAddress); uint8_t decimals;
u256 balance = jsToU256(hexBalance); if (hexBalance != NULL) {
if (decimals < 18) { if (setDecimals > 0) {
balance *= boost::multiprecision::pow(u256(10), 18 - decimals); decimals = setDecimals;
} else {
decimals = getErc20Decimals(tokenAddress);
}
u256 balance = jsToU256(hexBalance);
if (decimals < 18) {
balance *= boost::multiprecision::pow(u256(10), 18 - decimals);
}
balance /= boost::multiprecision::pow(u256(10), 10);
free(hexBalance);
return static_cast<uint64_t>(balance);
} else {
*error = 1;
return 0;
} }
balance /= boost::multiprecision::pow(u256(10), 10);
free(hexBalance);
return static_cast<uint64_t>(balance);
} }
char *getErc20BalanceHexWei(char *address, char *tokenAddress) char *getErc20BalanceHexWei(char *address, char *tokenAddress)
@ -532,7 +605,7 @@ char *getErc20BalanceHexWei(char *address, char *tokenAddress)
return hexBalance; return hexBalance;
} }
uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress) uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress, uint8_t set_decimals)
{ {
std::stringstream ss; std::stringstream ss;
ss << "0xdd62ed3e" ss << "0xdd62ed3e"
@ -541,7 +614,12 @@ uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress)
<< "000000000000000000000000" << "000000000000000000000000"
<< toHex(jsToAddress(spender)); << toHex(jsToAddress(spender));
char* hexAllowance = ethCall(tokenAddress, ss.str().c_str()); char* hexAllowance = ethCall(tokenAddress, ss.str().c_str());
uint8_t decimals = getErc20Decimals(tokenAddress); uint8_t decimals;
if (set_decimals > 0) {
decimals = set_decimals;
} else {
decimals = getErc20Decimals(tokenAddress);
}
u256 allowance = jsToU256(hexAllowance); u256 allowance = jsToU256(hexAllowance);
if (decimals < 18) { if (decimals < 18) {
allowance *= boost::multiprecision::pow(u256(10), 18 - decimals); allowance *= boost::multiprecision::pow(u256(10), 18 - decimals);
@ -560,6 +638,18 @@ uint8_t getErc20Decimals(char *tokenAddress)
return decimals; return decimals;
} }
uint8_t getErc20DecimalsZeroOnError(char *tokenAddress)
{
char* hexDecimals = ethCall(tokenAddress, "0x313ce567");
if (hexDecimals != NULL) {
auto decimals = (uint8_t) strtol(hexDecimals, NULL, 0);
free(hexDecimals);
return decimals;
} else {
return 0;
}
}
void uint8arrayToHex(char *dest, uint8_t *input, int len) void uint8arrayToHex(char *dest, uint8_t *input, int len)
{ {
strcpy(dest, "0x"); strcpy(dest, "0x");
@ -582,17 +672,30 @@ uint64_t weiToSatoshi(char *wei)
return static_cast<uint64_t>(satoshi); return static_cast<uint64_t>(satoshi);
} }
char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm) char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm, int64_t gas, int64_t gasPrice, uint8_t defaultGasOnErr)
{ {
TransactionSkeleton tx; TransactionSkeleton tx;
char *from = privKey2Addr(privKey), *result; char *from = privKey2Addr(privKey), *result;
tx.from = jsToAddress(from); tx.from = jsToAddress(from);
tx.to = jsToAddress(to); tx.to = jsToAddress(to);
tx.value = jsToU256(amount); tx.value = jsToU256(amount);
tx.gas = 21000;
tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9);
tx.nonce = getNonce(from); tx.nonce = getNonce(from);
free(from); free(from);
if (gas > 0) {
tx.gas = gas;
} else {
tx.gas = 21000;
}
if (gasPrice > 0) {
tx.gasPrice = gasPrice * boost::multiprecision::pow(u256(10), 9);
} else {
tx.gasPrice = getGasPriceFromStation(defaultGasOnErr) * boost::multiprecision::pow(u256(10), 9);
if (tx.gasPrice == 0 && !defaultGasOnErr) {
printf("Could not get gas price from station!\n");
unlock_send_tx_mutex();
return NULL;
}
}
char *rawTx = signTx(tx, privKey); char *rawTx = signTx(tx, privKey);
if (waitConfirm == 0) { if (waitConfirm == 0) {
@ -604,10 +707,15 @@ char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm)
return result; return result;
} }
std::stringstream getErc20TransferData(char *tokenAddress, char *to, char *amount) std::stringstream getErc20TransferData(char *tokenAddress, char *to, char *amount, uint8_t setDecimals)
{ {
u256 amountWei = jsToU256(amount); u256 amountWei = jsToU256(amount);
uint8_t decimals = getErc20Decimals(tokenAddress); uint8_t decimals;
if (setDecimals > 0) {
decimals = setDecimals;
} else {
decimals = getErc20Decimals(tokenAddress);
}
if (decimals < 18) { if (decimals < 18) {
amountWei /= boost::multiprecision::pow(u256(10), 18 - decimals); amountWei /= boost::multiprecision::pow(u256(10), 18 - decimals);
} }
@ -620,19 +728,64 @@ std::stringstream getErc20TransferData(char *tokenAddress, char *to, char *amoun
return ss; return ss;
} }
char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8_t waitConfirm) uint64_t estimate_erc20_gas(
char *tokenAddress,
char *to,
char *amount,
char *privKey,
uint8_t decimals
)
{
std::stringstream ss = getErc20TransferData(tokenAddress, to, amount, decimals);
char *from = privKey2Addr(privKey);
uint64_t result = estimateGas(from, tokenAddress, ss.str().c_str());
free(from);
return result;
}
char *sendErc20(
char *tokenAddress,
char *to,
char *amount,
char *privKey,
uint8_t waitConfirm,
int64_t gas,
int64_t gasPrice,
uint8_t defaultGasOnErr,
uint8_t decimals
)
{ {
TransactionSkeleton tx; TransactionSkeleton tx;
char *from = privKey2Addr(privKey), *result; char *from = privKey2Addr(privKey), *result;
std::stringstream ss = getErc20TransferData(tokenAddress, to, amount, decimals);
tx.from = jsToAddress(from); tx.from = jsToAddress(from);
tx.to = jsToAddress(tokenAddress); tx.to = jsToAddress(tokenAddress);
tx.value = 0; tx.value = 0;
tx.gas = 60000;
tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9);
tx.nonce = getNonce(from); tx.nonce = getNonce(from);
if (gas > 0) {
tx.gas = gas;
} else {
uint64_t gasEstimation = estimateGas(from, tokenAddress, ss.str().c_str());
if (gasEstimation > 0) {
tx.gas = gasEstimation;
} else {
tx.gas = 150000;
}
}
free(from); free(from);
if (gasPrice > 0) {
tx.gasPrice = gasPrice * boost::multiprecision::pow(u256(10), 9);
} else {
tx.gasPrice = getGasPriceFromStation(defaultGasOnErr) * boost::multiprecision::pow(u256(10), 9);
if (tx.gasPrice == 0 && !defaultGasOnErr) {
printf("Could not get gas price from station!\n");
unlock_send_tx_mutex();
return NULL;
}
}
std::stringstream ss = getErc20TransferData(tokenAddress, to, amount);
tx.data = jsToBytes(ss.str()); tx.data = jsToBytes(ss.str());
char *rawTx = signTx(tx, privKey); char *rawTx = signTx(tx, privKey);
@ -645,12 +798,61 @@ char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8
return result; return result;
} }
uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data) uint8_t verifyAliceErc20FeeData(char *tokenAddress, char *to, char *amount, char *data, uint8_t decimals)
{ {
std::stringstream ss = getErc20TransferData(tokenAddress, to, amount); std::stringstream ss = getErc20TransferData(tokenAddress, to, amount, decimals);
if (strcmp(ss.str().c_str(), data) != 0) { 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()); printf("Alice ERC20 fee data %s is not equal to expected %s\n", data, ss.str().c_str());
return 0; return 0;
} }
return 1; return 1;
} }
uint8_t alicePaymentStatus(char *paymentId)
{
char buffer[100];
memset(buffer, 0, sizeof(buffer));
strcpy(buffer, "0x81cd872a");
strcat(buffer, paymentId);
char *hexStatus = ethCall(ETOMIC_ALICECONTRACT, buffer);
auto status = (uint8_t) strtol(hexStatus + 66, NULL, 0);
free(hexStatus);
return status;
}
uint8_t bobDepositStatus(char *depositId)
{
char buffer[100];
memset(buffer, 0, sizeof(buffer));
strcpy(buffer, "0x3d4dff7b");
strcat(buffer, depositId);
char *hexStatus = ethCall(ETOMIC_BOBCONTRACT, buffer);
auto status = (uint8_t) strtol(hexStatus + 130, NULL, 0);
free(hexStatus);
return status;
}
uint8_t bobPaymentStatus(char *paymentId)
{
char buffer[100];
memset(buffer, 0, sizeof(buffer));
strcpy(buffer, "0x0716326d");
strcat(buffer, paymentId);
char *hexStatus = ethCall(ETOMIC_BOBCONTRACT, buffer);
auto status = (uint8_t) strtol(hexStatus + 130, NULL, 0);
free(hexStatus);
return status;
}
uint8_t compareAddresses(char *address1, char *address2)
{
auto addr_bytes_1 = jsToAddress(address1);
auto addr_bytes_2 = jsToAddress(address2);
return static_cast<uint8_t>(addr_bytes_1 == addr_bytes_2);
}
uint8_t isValidAddress(char *address)
{
std::regex r("^(0x|0X)?[a-fA-F0-9]{40}$");
return static_cast<uint8_t>(std::regex_match(address, r));
}

49
iguana/exchanges/etomicswap/etomiclib.h

@ -38,6 +38,7 @@ typedef struct {
char bobAddress[65]; char bobAddress[65];
char aliceHash[65]; char aliceHash[65];
char bobHash[65]; char bobHash[65];
uint8_t decimals;
} AliceSendsErc20PaymentInput; } AliceSendsErc20PaymentInput;
typedef struct { typedef struct {
@ -47,6 +48,7 @@ typedef struct {
char bobAddress[65]; char bobAddress[65];
char aliceHash[65]; char aliceHash[65];
char bobSecret[70]; char bobSecret[70];
uint8_t decimals;
} AliceReclaimsAlicePaymentInput; } AliceReclaimsAlicePaymentInput;
typedef struct { typedef struct {
@ -56,6 +58,7 @@ typedef struct {
char aliceAddress[65]; char aliceAddress[65];
char aliceSecret[70]; char aliceSecret[70];
char bobHash[65]; char bobHash[65];
uint8_t decimals;
} BobSpendsAlicePaymentInput; } BobSpendsAlicePaymentInput;
typedef struct { typedef struct {
@ -72,6 +75,7 @@ typedef struct {
char aliceAddress[65]; char aliceAddress[65];
char bobHash[65]; char bobHash[65];
uint64_t lockTime; uint64_t lockTime;
uint8_t decimals;
} BobSendsErc20DepositInput; } BobSendsErc20DepositInput;
typedef struct { typedef struct {
@ -80,6 +84,7 @@ typedef struct {
char tokenAddress[65]; char tokenAddress[65];
char aliceAddress[65]; char aliceAddress[65];
char bobSecret[70]; char bobSecret[70];
uint8_t decimals;
} BobRefundsDepositInput; } BobRefundsDepositInput;
typedef struct { typedef struct {
@ -88,6 +93,7 @@ typedef struct {
char tokenAddress[65]; char tokenAddress[65];
char bobAddress[65]; char bobAddress[65];
char bobHash[65]; char bobHash[65];
uint8_t decimals;
} AliceClaimsBobDepositInput; } AliceClaimsBobDepositInput;
typedef struct { typedef struct {
@ -104,6 +110,7 @@ typedef struct {
char aliceAddress[65]; char aliceAddress[65];
char aliceHash[65]; char aliceHash[65];
uint64_t lockTime; uint64_t lockTime;
uint8_t decimals;
} BobSendsErc20PaymentInput; } BobSendsErc20PaymentInput;
typedef struct { typedef struct {
@ -112,6 +119,7 @@ typedef struct {
char tokenAddress[65]; char tokenAddress[65];
char aliceAddress[65]; char aliceAddress[65];
char aliceHash[65]; char aliceHash[65];
uint8_t decimals;
} BobReclaimsBobPaymentInput; } BobReclaimsBobPaymentInput;
typedef struct { typedef struct {
@ -120,6 +128,7 @@ typedef struct {
char tokenAddress[65]; char tokenAddress[65];
char aliceSecret[70]; char aliceSecret[70];
char bobAddress[65]; char bobAddress[65];
uint8_t decimals;
} AliceSpendsBobPaymentInput; } AliceSpendsBobPaymentInput;
typedef struct { typedef struct {
@ -164,24 +173,50 @@ char* pubKey2Addr(char* pubKey);
char* getPubKeyFromPriv(char* privKey); char* getPubKeyFromPriv(char* privKey);
// returns satoshis, not wei! // returns satoshis, not wei!
uint64_t getEthBalance(char* address); uint64_t getEthBalance(char* address, int *error);
uint64_t getErc20BalanceSatoshi(char* address, char tokenAddress[65]); uint64_t getErc20BalanceSatoshi(char *address, char *tokenAddress, uint8_t setDecimals, int *error);
char *getErc20BalanceHexWei(char* address, char tokenAddress[65]); char *getErc20BalanceHexWei(char* address, char tokenAddress[65]);
uint8_t getErc20Decimals(char *tokenAddress); uint8_t getErc20Decimals(char *tokenAddress);
// returns satoshis, not wei! // returns satoshis, not wei!
uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress); uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress, uint8_t set_decimals);
void uint8arrayToHex(char *dest, uint8_t *input, int len); void uint8arrayToHex(char *dest, uint8_t *input, int len);
void satoshisToWei(char *dest, uint64_t input); void satoshisToWei(char *dest, uint64_t input);
uint64_t weiToSatoshi(char *wei); uint64_t weiToSatoshi(char *wei);
char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm); char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm, int64_t gas, int64_t gasPrice, uint8_t defaultGasOnErr);
char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8_t waitConfirm); char *sendErc20(
char *tokenAddress,
char *to,
char *amount,
char *privKey,
uint8_t waitConfirm,
int64_t gas,
int64_t gasPrice,
uint8_t defaultGasOnErr,
uint8_t decimals
);
uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data, uint8_t decimals);
uint8_t alicePaymentStatus(char *paymentId);
uint8_t bobDepositStatus(char *depositId);
uint8_t bobPaymentStatus(char *paymentId);
uint64_t estimate_erc20_gas(
char *tokenAddress,
char *to,
char *amount,
char *privKey,
uint8_t decimals
);
uint8_t compareAddresses(char *address1, char *address2);
uint8_t isValidAddress(char *address);
uint8_t getErc20DecimalsZeroOnError(char *tokenAddress);
uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data);
// Your prototype or Definition
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

2
iguana/exchanges/fundvalue

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
source userpass source userpass
# this will only work for watchonly addresses that have been rescanned and with active coins # 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\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"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\":650000}" curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":600000}, {\"coin\":\"bitcoin\",\"balance\":486}, {\"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\":650000}"

3
iguana/exchanges/gen64addrs

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"gen64addrs\",\"passphrase\":\"default\"}"

7
iguana/exchanges/mm.c

@ -164,6 +164,7 @@ int main(int argc, const char * argv[])
{ {
char dirname[512]; double incr; cJSON *retjson; char dirname[512]; double incr; cJSON *retjson;
OS_init(); OS_init();
printf("BarterDEX Marketmaker %s \n",MM_VERSION);
if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 ) if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 )
{ {
bits256 privkey,checkkey; uint8_t tmptype; char kmdwif[64],str[65],str2[65],*retstr; bits256 privkey,checkkey; uint8_t tmptype; char kmdwif[64],str[65],str2[65],*retstr;
@ -346,6 +347,12 @@ int main(int argc, const char * argv[])
printf("couldnt write to (%s)\n",dirname); printf("couldnt write to (%s)\n",dirname);
exit(0); exit(0);
} }
sprintf(dirname,"%s/GTC",GLOBAL_DBDIR), OS_ensure_directory(dirname);
if ( ensure_writable(dirname) < 0 )
{
printf("couldnt write to (%s)\n",dirname);
exit(0);
}
sprintf(dirname,"%s/PRICES",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/PRICES",GLOBAL_DBDIR), OS_ensure_directory(dirname);
if ( ensure_writable(dirname) < 0 ) if ( ensure_writable(dirname) < 0 )
{ {

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save