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. 37
      .travis.yml
  5. 5
      CMakeLists.txt
  6. 10
      Dockerfile.clientnode
  7. 10
      Dockerfile.seednode
  8. 33
      Jenkinsfile
  9. 5
      OSlibs/win/mingw.h
  10. 30
      appveyor.yml
  11. 19
      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. 181
      crypto777/bitcoind_RPC.c
  17. 4
      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. 57
      iguana/dpow/dpow_fsm.c
  57. 193
      iguana/dpow/dpow_network.c
  58. 87
      iguana/dpow/dpow_rpc.c
  59. 81
      iguana/dpow/dpow_tx.c
  60. 49
      iguana/dpowassets
  61. 8
      iguana/exchanges/CMakeLists.txt
  62. 360
      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. 4
      iguana/exchanges/LP_mmjson.c
  70. 254
      iguana/exchanges/LP_mpnet.c
  71. 94
      iguana/exchanges/LP_nativeDEX.c
  72. 13
      iguana/exchanges/LP_network.c
  73. 271
      iguana/exchanges/LP_ordermatch.c
  74. 32
      iguana/exchanges/LP_portfolio.c
  75. 41
      iguana/exchanges/LP_prices.c
  76. 278
      iguana/exchanges/LP_privkey.c
  77. 112
      iguana/exchanges/LP_remember.c
  78. 33
      iguana/exchanges/LP_rpc.c
  79. 7
      iguana/exchanges/LP_scan.c
  80. 2
      iguana/exchanges/LP_secp.c
  81. 48
      iguana/exchanges/LP_signatures.c
  82. 118
      iguana/exchanges/LP_socket.c
  83. 2
      iguana/exchanges/LP_statemachine.c
  84. 78
      iguana/exchanges/LP_swap.c
  85. 2
      iguana/exchanges/LP_tradebots.c
  86. 281
      iguana/exchanges/LP_transaction.c
  87. 53
      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. 85
      iguana/exchanges/etomicswap/etomiccurl.c
  95. 9
      iguana/exchanges/etomicswap/etomiccurl.h
  96. 280
      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/*
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

37
.travis.yml

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

5
CMakeLists.txt

@ -13,6 +13,9 @@ set(CMAKE_CXX_EXTENSIONS Off)
include(cmake/DownloadProject.cmake)
hunter_add_package(libsodium)
find_package(libsodium CONFIG REQUIRED)
# Download and install nanomsg at CMake configure time
download_project(PROJ nanomsg
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)
include_directories("${CMAKE_SOURCE_DIR}")
include_directories("${CMAKE_SOURCE_DIR}" ${LIBSODIUM_ROOT})
add_subdirectory(cpp-ethereum)
add_subdirectory(iguana/exchanges)
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

33
Jenkinsfile

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

5
OSlibs/win/mingw.h

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

30
appveyor.yml

@ -1,6 +1,30 @@
version: 1.0.{build}
branches:
only:
- etomic
build_script:
- 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

19
basilisk/basilisk_bitcoin.c

@ -584,18 +584,31 @@ char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coi
*completedp = 0;
if ( signedtxidp != 0 )
memset(signedtxidp,0,sizeof(*signedtxidp));
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);
if ( strcmp(coin->symbol,"GAME") == 0 )
printf("GAME txfee %.8f\n",dstr(txfee));
if ( (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,0,1,0)) != 0 )
if (strcmp(coin->symbol, "GAME") == 0 || strcmp(coin->symbol, "EMC2") == 0)
printf("%s txfee %.8f\n", coin->symbol, dstr(txfee));
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 )
duplicates = 1;
spendlen = bitcoin_pubkeyspend(script,0,pubkey33);
for (i=0; i<duplicates; i++)
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);
//printf("JSON: %s\n", cJSON_Print(txobj));
if ( strcmp(coin->chain->symbol,"BTC") == 0 && cJSON_GetArraySize(vins) > duplicates/2 )
{
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(-DIGUANA_LOG2PACKETSIZE=20)
add_definitions(-DIGUANA_MAXPACKETSIZE=1572864)
add_definitions(-DMM_WIN_BUILD)
include_directories("${CMAKE_SOURCE_DIR}/includes")
endif()

8
crypto777/OS_nonportable.c

@ -26,10 +26,10 @@
* not from the mingw header, so we need to include the windows header
* if we are compiling in windows 64bit
*/
//#if defined(_M_X64)
//#define WIN32_LEAN_AND_MEAN
//#include <WinSock2.h>
//#endif
#if defined(_M_X64)
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#endif
#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_sha256(uint8_t rmd160[20],bits256 data);
double get_theoretical(double *avebidp,double *aveaskp,double *highbidp,double *lowaskp,double *CMC_averagep,double changes[3],char *name,char *base,char *rel,double *USD_averagep);
char *bitcoind_RPCnew(void *curl_handle,char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout);
extern char *Iguana_validcommands[];
extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY;

181
crypto777/bitcoind_RPC.c

@ -14,6 +14,7 @@
******************************************************************************/
//#define KEEPALIVE breaks marketmaker api
#ifndef FROM_JS
#include "OS_portable.h"
@ -74,7 +75,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
char *retstr = 0;
cJSON *json,*result,*error;
#ifndef FROM_MARKETMAKER
usleep(1000);
//usleep(1000);
#endif
//printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr);
if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 )
@ -131,7 +132,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
*
************************************************************************/
static int32_t USE_JAY;
//static int32_t USE_JAY;
char *Jay_NXTrequest(char *command,char *params)
{
@ -141,23 +142,28 @@ char *Jay_NXTrequest(char *command,char *params)
return(retstr);
}
char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout)
static void bitcoind_init()
{
CURL *curl_handle; static int didinit,count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY;
struct MemoryStruct chunk;
struct curl_slist *headers = NULL; struct return_string s; CURLcode res;
char *bracket0,*bracket1,*retstr,*databuf = 0; long len; int32_t specialcase,numretries; double starttime;
static int32_t didinit;
if ( didinit == 0 )
{
didinit = 1;
curl_global_init(CURL_GLOBAL_ALL); //init the curl session
//curl_handle = curl_easy_init();
}
if ( (0) && (USE_JAY != 0 && (strncmp(url,"http://127.0.0.1:7876/nxt",strlen("http://127.0.0.1:7876/nxt")) == 0 || strncmp(url,"https://127.0.0.1:7876/nxt",strlen("https://127.0.0.1:7876/nxt")) == 0)) )
{
if ( (databuf= Jay_NXTrequest(command,params)) != 0 )
return(databuf);
}
char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout)
{
#ifdef KEEPALIVE
static
#endif
CURL *curl_handle = 0;
static int count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY;
struct MemoryStruct chunk;
struct curl_slist *headers = NULL; struct return_string s; CURLcode res;
char *bracket0,*bracket1,*retstr,*databuf = 0; long len; int32_t specialcase,numretries; double starttime;
bitcoind_init();
numretries = 0;
if ( debugstr != 0 && strcmp(debugstr,"BTCD") == 0 && command != 0 && strcmp(command,"SuperNET") == 0 )
specialcase = 1;
@ -174,6 +180,7 @@ try_again:
if ( retstrp != 0 )
*retstrp = 0;
starttime = OS_milliseconds();
if ( curl_handle == 0 )
curl_handle = curl_easy_init();
headers = curl_slist_append(0,"Expect:");
@ -244,7 +251,10 @@ try_again:
//laststart = milliseconds();
res = curl_easy_perform(curl_handle);
curl_slist_free_all(headers);
#ifndef KEEPALIVE
curl_easy_cleanup(curl_handle);
curl_handle = 0;
#endif
if ( databuf != 0 ) // clean up temporary buffer
{
free(databuf);
@ -275,6 +285,153 @@ try_again:
else
{
if ( command != 0 && specialcase == 0 )
{
count++;
elapsedsum += (OS_milliseconds() - starttime);
if ( (count % 100000) == 0)
printf("%d: %s ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,debugstr,elapsedsum/count,(OS_milliseconds() - starttime),command,url);
if ( retstrp != 0 )
{
*retstrp = retstr;
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);
}
}
}
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);

4
crypto777/cJSON.c

@ -902,10 +902,10 @@ char *get_cJSON_fieldname(cJSON *obj)
{
if ( obj != 0 )
{
if ( obj->string != 0 )
return(obj->string);
if ( obj->child != 0 && obj->child->string != 0 )
return(obj->child->string);
else if ( obj->string != 0 )
return(obj->string);
}
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
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETH\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETOMIC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETH\"}"

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="c3d8c2a364b7d18c1f9d7321d017b92e9f9c791e4f5c741214fefdea8a071256"
export userpass="$USERPASS"

8
iguana.vcxproj

@ -113,14 +113,14 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<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>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<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>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -151,7 +151,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<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>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
@ -160,7 +160,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<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>
</Link>
</ItemDefinitionGroup>

1
iguana/client

@ -17,6 +17,7 @@ git pull;
{\"coin\":\"ANC\", \"name\":\"anoncoin\", \"pubtype\":23, \"p2shtype\":5, \"wiftype\":151, \"txfee\":2000000},
{\"coin\":\"FRK\", \"name\":\"franko\", \"pubtype\":35, \"p2shtype\":5, \"wiftype\":163, \"txfee\":0},
{\"coin\":\"GAME\", \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000},
{\"coin\":\"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\":\"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\"}" &

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_UTXOSIZE dpow_utxosize(coin->symbol) //10000
#define DPOW_MINOUTPUT 6000
#define DPOW_DURATION 1200
#define DPOW_DURATION 300
#define DPOW_RATIFYDURATION (3600 * 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
{
bits256 hashmsg,desttxid,srctxid,beacon,commit,MoM;
bits256 hashmsg,desttxid,srctxid,beacon,commit,MoM,mysrcutxo,mydestutxo;
struct iguana_info *srccoin,*destcoin; char *opret_symbol;
uint64_t destsigsmasks[DPOW_MAXRELAYS],srcsigsmasks[DPOW_MAXRELAYS];
uint64_t recvmask,bestmask,ratifybestmask,ratifyrecvmask,pendingbestmask,pendingratifybestmask,ratifysigmasks[2];
@ -119,6 +119,7 @@ struct dpow_block
int32_t rawratifiedlens[2],height,numnotaries,numerrors,completed,minsigs,duration,numratified,isratify,require0,scores[DPOW_MAXRELAYS];
int8_t myind,bestk,ratifybestk,pendingbestk,pendingratifybestk,matches,bestmatches;
cJSON *ratified;
uint16_t CCid;
uint8_t ratified_pubkeys[DPOW_MAXRELAYS][33],ratifysigs[2][DPOW_MAXSIGLEN],ratifysiglens[2];
char handles[DPOW_MAXRELAYS][32];
char signedtx[32768]; uint8_t ratifyrawtx[2][32768]; uint32_t pendingcrcs[2];
@ -134,6 +135,8 @@ struct pax_transaction
char symbol[16],coinaddr[64]; uint8_t rmd160[20],shortflag;
};
#define DPOW_MAXIPBITS 512
struct dpow_info
{
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;
int32_t lastheight,maxblocks,SRCHEIGHT,DESTHEIGHT,prevDESTHEIGHT,SHORTFLAG,ratifying,minsigs,freq;
struct pax_transaction *PAX;
uint32_t fullCCid;
portable_mutex_t paxmutex,dexmutex;
uint32_t ipbits[128],numipbits;
uint32_t ipbits[DPOW_MAXIPBITS],numipbits;
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);
int32_t dpow_paxpending(uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,int32_t src_or_dest,struct dpow_block *bp);
int32_t dpow_paxpending(struct supernet_info *myinfo,uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,uint16_t CCid,int32_t src_or_dest,struct dpow_block *bp);
void dex_updateclient(struct supernet_info *myinfo);
char *dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *data,int32_t datalen,int32_t M,char *field);
char *basilisk_respond_addmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen,uint8_t *data,int32_t datalen,int32_t sendping,uint32_t duration);

57
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();
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 )
{
@ -235,7 +235,7 @@ bits256 dpow_calcMoM(uint32_t *MoMdepthp,struct supernet_info *myinfo,struct igu
bits256 MoM; cJSON *MoMjson,*infojson; int32_t prevMoMheight;
*MoMdepthp = 0;
memset(MoM.bytes,0,sizeof(MoM));
if ( strcmp(coin->symbol,"GAME") == 0 ) // 80 byte OP_RETURN limit
if ( strcmp(coin->symbol,"GAME") == 0 || strcmp(coin->symbol,"HUSH") == 0 || strcmp(coin->symbol,"EMC2") == 0 ) // 80 byte OP_RETURN limit
return(MoM);
if ( (infojson= dpow_getinfo(myinfo,coin)) != 0 )
{
@ -265,6 +265,7 @@ void dpow_statemachinestart(void *ptr)
void **ptrs = ptr;
struct supernet_info *myinfo; struct dpow_info *dp; struct dpow_checkpoint checkpoint;
int32_t i,j,ht,extralen,destprevvout0,srcprevvout0,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));
MoM = zero;
srcprevtxid0 = destprevtxid0 = zero;
@ -302,6 +303,7 @@ void dpow_statemachinestart(void *ptr)
Numallocated++;
bp->MoM = MoM;
bp->MoMdepth = MoMdepth;
bp->CCid = dp->fullCCid & 0xffff;
bp->minsigs = minsigs;
bp->duration = duration;
bp->srccoin = src;
@ -383,7 +385,12 @@ void dpow_statemachinestart(void *ptr)
return;
}
dp->ratifying += bp->isratify;
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 )
{
@ -438,7 +445,7 @@ void dpow_statemachinestart(void *ptr)
return;
}
bp->myind = myind;
printf("[%d] notarize %s->%s %s ht.%d minsigs.%d duration.%d start.%u MoM[%d] %s\n",bp->myind,dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height,minsigs,duration,checkpoint.timestamp,bp->MoMdepth,bits256_str(str2,bp->MoM));
printf("[%d] notarize %s->%s %s ht.%d minsigs.%d duration.%d start.%u MoM[%d] %s CCid.%u\n",bp->myind,dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height,minsigs,duration,checkpoint.timestamp,bp->MoMdepth,bits256_str(str2,bp->MoM),bp->CCid);
if ( bp->isratify != 0 && memcmp(bp->notaries[0].pubkey,bp->ratified_pubkeys[0],33) != 0 )
{
for (i=0; i<33; i++)
@ -487,6 +494,11 @@ void dpow_statemachinestart(void *ptr)
bp->notaries[myind].ratifydestutxo = ep->dest.prev_hash;
bp->notaries[myind].ratifydestvout = ep->dest.prev_vout;
}
else
{
bp->mysrcutxo = ep->src.prev_hash;
bp->mydestutxo = ep->dest.prev_hash;
}
}
/*if ( strcmp(dp->symbol,"CHIPS") == 0 && myind == 0 )
{
@ -495,6 +507,25 @@ void dpow_statemachinestart(void *ptr)
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);
}*/
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->notaries[myind].othermask |= (1LL << myind);
dp->checkpoint = checkpoint;
@ -520,7 +551,7 @@ void dpow_statemachinestart(void *ptr)
if ( strcmp(bp->destcoin->symbol,"KMD") == 0 )
src_or_dest = 0;
else src_or_dest = 1;
extralen = dpow_paxpending(extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp);
extralen = dpow_paxpending(myinfo,extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp);
bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc;
}
printf("PAXWDCRC.%x myind.%d isratify.%d DPOW.%s statemachine checkpoint.%d %s start.%u+dur.%d vs %ld MoM[%d] %s\n",bp->paxwdcrc,bp->myind,bp->isratify,src->symbol,checkpoint.blockhash.height,bits256_str(str,checkpoint.blockhash.hash),starttime,bp->duration,time(NULL),bp->MoMdepth,bits256_str(str2,bp->MoM));
@ -541,7 +572,7 @@ void dpow_statemachinestart(void *ptr)
if ( strcmp(bp->destcoin->symbol,"KMD") == 0 )
src_or_dest = 0;
else src_or_dest = 1;
extralen = dpow_paxpending(extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp);
extralen = dpow_paxpending(myinfo,extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp);
bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc;
}
if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) //(checkpoint.blockhash.height % 100) != 0 &&
@ -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);
dp->lastrecvmask = bp->recvmask;
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;
bp->state = 0xffffffff;
free(ptr);
}

193
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++)
if ( ipbits == myinfo->dexipbits[i] )
break;
if ( i == n && n < 64 )
if ( i == n && n < DPOW_MAXIPBITS )
{
myinfo->dexipbits[n++] = ipbits;
qsort(myinfo->dexipbits,n,sizeof(uint32_t),_increasing_ipbits);
@ -1292,7 +1292,7 @@ struct dpow_nanomsghdr
{
bits256 srchash,desthash;
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];
uint8_t senderind,version0,version1,packet[];
} 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);
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)
{
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 )
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);
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++)
if ( ipbits == ptr[i] )
break;
if ( i == n && n < 64 )
if ( i == n && n < DPOW_MAXIPBITS )
{
ptr[n] = ipbits;
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);
}
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)
{
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(owts,0,sizeof(owts));
for (i=0; i<bp->numnotaries; i++)
@ -1518,11 +1641,14 @@ void dpow_bestconsensus(struct dpow_info *dp,struct dpow_block *bp)
{
//printf("(%d %llx).%d ",bestks[i],(long long)masks[i],counts[i]);
if ( counts[i] > matches && bitweight(masks[i]) == bp->minsigs )
{
if ( dpow_crossconnected(&badmask,bp,masks[i]) == bp->minsigs )
{
matches = counts[i];
besti = i;
}
}
}
for (i=0; i<bp->numnotaries; i++)
{
if ( ((1LL << i) & masks[besti]) != 0 )
@ -1537,7 +1663,9 @@ void dpow_bestconsensus(struct dpow_info *dp,struct dpow_block *bp)
bp->bestmatches = bestmatches;
bp->notaries[bp->myind].bestmask = bp->bestmask = masks[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++)
printf("%d:%d%s ",wts[i],owts[i],wts[i]*owts[i]>median?"*":"");
@ -1837,6 +1965,8 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru
if ( bp->myind < 0 )
return;
if ( bp->isratify == 0 && bp->state != 0xffffffff && senderind >= 0 && senderind < bp->numnotaries && bits256_nonz(srcutxo) != 0 && bits256_nonz(destutxo) != 0 )
{
if ( bp->myind != senderind )
{
if ( bits256_nonz(srcutxo) != 0 )
{
@ -1849,6 +1979,12 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru
bp->notaries[senderind].dest.prev_hash = destutxo;
bp->notaries[senderind].dest.prev_vout = destvout;
}
}
else
{
bp->notaries[bp->myind].src.prev_hash = bp->mysrcutxo;
bp->notaries[bp->myind].dest.prev_hash = bp->mydestutxo;
}
if ( bestmask != 0 )
bp->notaries[senderind].bestmask = bestmask;
if ( recvmask != 0 )
@ -1857,17 +1993,32 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru
{
//fprintf(stderr,"{%d %x} ",senderind,paxwdcrc);
}
bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc;
if ( bp->bestmask == 0 )
{
bp->recvmask |= (1LL << senderind) | (1LL << bp->myind);
bp->bestmask = dpow_maskmin(bp->recvmask,bp,&bp->bestk);
}
dpow_bestconsensus(dp,bp);
if ( bp->bestk >= 0 )
bp->notaries[bp->myind].bestk = bp->bestk;
if ( bp->bestmask != 0 )
bp->notaries[bp->myind].bestmask = bp->bestmask;
if ( bp->recvmask != 0 )
bp->notaries[bp->myind].recvmask = bp->recvmask;
if ( bestk >= 0 || bp->notaries[senderind].bestk < 0 )
{
bp->notaries[senderind].bestk = bestk;
if ( (bp->notaries[senderind].src.siglens[bestk]= siglens[0]) != 0 )
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]= siglens[1]) != 0 )
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 )
@ -1875,19 +2026,7 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru
else bp->destsigsmasks[bestk] &= ~(1LL << senderind);
}
}
bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc;
if ( bp->bestmask == 0 )
{
bp->recvmask |= (1LL << senderind) | (1LL << bp->myind);
bp->bestmask = dpow_maskmin(bp->recvmask,bp,&bp->bestk);
}
dpow_bestconsensus(dp,bp);
if ( bp->bestk >= 0 )
bp->notaries[bp->myind].bestk = bp->bestk;
if ( bp->bestmask != 0 )
bp->notaries[bp->myind].bestmask = bp->bestmask;
if ( bp->recvmask != 0 )
bp->notaries[bp->myind].recvmask = bp->recvmask;
if ( bp->bestk >= 0 )
{
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);
bp->lastnanosend = now;
}
if ( 0 && strcmp("CHIPS",dp->symbol) == 0 && bp->myind == 0 )
printf("%s recv.%llx best.(%d %llx) m.%d p.%d:%d b.%d state.%d minsigs.%d\n",dp->symbol,(long long)bp->recvmask,bp->bestk,(long long)bp->bestmask,matches,paxmatches,paxbestmatches,bestmatches,bp->state,bp->minsigs);
if ( 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 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 ( 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 )
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 )
} // 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 || strcmp(dp->symbol,"EMC2") == 0 )
//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);
}
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);
}
}
@ -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]);
}
@ -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 )
src_or_dest = 0;
else src_or_dest = 1;
extralen = dpow_paxpending(extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp);
extralen = dpow_paxpending(myinfo,extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp);
bp->paxwdcrc = bp->notaries[bp->myind].paxwdcrc = np->notarize.paxwdcrc = paxwdcrc;
//dpow_bestconsensus(dp,bp);
dpow_nanoutxoset(myinfo,dp,&np->notarize,bp,0);
@ -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);
//portable_mutex_unlock(&myinfo->dpowmutex);
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);
}

87
iguana/dpow/dpow_rpc.c

@ -17,7 +17,7 @@
uint64_t dpow_utxosize(char *symbol)
{
if ( strcmp(symbol,"GAME") == 0 )
if ( strcmp(symbol,"GAME") == 0 || strcmp(symbol,"EMC2") == 0)
return(100000);
else return(10000);
}
@ -78,6 +78,17 @@ cJSON *dpow_getinfo(struct supernet_info *myinfo,struct iguana_info *coin)
return(json);
}
uint32_t dpow_CCid(struct supernet_info *myinfo,struct iguana_info *coin)
{
uint32_t CCid = 0; cJSON *retjson;
if ( (retjson= dpow_getinfo(myinfo,coin)) != 0 )
{
CCid = juint(retjson,"CCid");
free_json(retjson);
}
return(CCid);
}
char *Notaries_elected[65][2];
//char *seeds[] = { "78.47.196.146", "5.9.102.210", "149.56.29.163", "191.235.80.138", "88.198.65.74", "94.102.63.226", "129.232.225.202", "104.255.64.3", "52.72.135.200", "149.56.28.84", "103.18.58.150", "221.121.144.140", "123.249.79.12", "103.18.58.146", "27.50.93.252", "176.9.0.233", "94.102.63.227", "167.114.227.223", "27.50.68.219", "192.99.233.217", "94.102.63.217", "45.64.168.216" };
int32_t Notaries_numseeds;// = (int32_t)(sizeof(seeds)/sizeof(*seeds))
@ -99,8 +110,7 @@ int32_t komodo_initjson(char *fname)
Notaries_port = port;
if ( (num= juint(argjson,"BTCminsigs")) > Notaries_BTCminsigs )
Notaries_BTCminsigs = num;
if ( (num= juint(argjson,"minsigs")) > Notaries_minsigs )
Notaries_minsigs = num;
Notaries_minsigs = juint(argjson,"minsigs");
if ( (array= jarray(&n,argjson,"seeds")) != 0 && n <= 64 )
{
for (i=0; i<n&&i<64; i++)
@ -252,16 +262,16 @@ cJSON *issue_calcMoM(struct iguana_info *coin,int32_t height,int32_t MoMdepth)
return(retjson);
}
cJSON *dpow_MoMoMdata(struct iguana_info *coin,char *symbol,int32_t kmdheight)
cJSON *dpow_MoMoMdata(struct iguana_info *coin,char *symbol,int32_t kmdheight,uint16_t CCid)
{
char buf[128],*retstr=0; cJSON *retjson = 0; struct iguana_info *src;
if ( coin->FULLNODE < 0 && strcmp(coin->symbol,"KMD") == 0 && (src= iguana_coinfind(symbol)) != 0 )
{
sprintf(buf,"[\"%s\", \"%d\", \"%d\"]",symbol,kmdheight,src->MoMoMheight);
sprintf(buf,"[\"%s\", \"%d\", \"%d\"]",symbol,kmdheight,CCid);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"MoMoMdata",buf)) != 0 )
{
retjson = cJSON_Parse(retstr);
printf("MoMoM.%s -> %s\n",buf,retstr);
printf("%s kmdheight.%d CCid.%u MoMoM.%s -> %s\n",symbol,kmdheight,CCid,buf,retstr);
free(retstr);
}
usleep(10000);
@ -269,22 +279,29 @@ cJSON *dpow_MoMoMdata(struct iguana_info *coin,char *symbol,int32_t kmdheight)
return(retjson);
}
int32_t dpow_paxpending(uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,int32_t src_or_dest,struct dpow_block *bp)
int32_t dpow_paxpending(struct supernet_info *myinfo,uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,uint16_t CCid,int32_t src_or_dest,struct dpow_block *bp)
{
struct iguana_info *coin,*kmdcoin=0; char *retstr,*hexstr; cJSON *retjson; int32_t hexlen=0,n=0; uint32_t paxwdcrc;
struct iguana_info *coin,*kmdcoin=0; char *retstr,*hexstr; cJSON *retjson,*infojson; int32_t kmdheight=0,hexlen=0,n=0; uint32_t paxwdcrc;
paxwdcrc = 0;
if ( strcmp(bp->srccoin->symbol,"GAME") != 0 || src_or_dest != 0 )
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);
MoMdepth = (MoMdepth & 0xffff) | ((uint32_t)CCid<<16);
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;
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 )
{
hexlen >>= 1;
printf("add MoMoMdata.(%s)\n",hexstr);
decode_hex(&hex[n],hexlen,hexstr), n += hexlen;
}
free_json(retjson);
@ -353,6 +370,39 @@ bits256 dpow_getblockhash(struct supernet_info *myinfo,struct iguana_info *coin,
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)
{
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);
}
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 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");
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);
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);
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");
free(retstr);
@ -590,6 +647,9 @@ char *dpow_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *c
free_json(retjson);
}
//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);
usleep(10000);
return(retstr);
@ -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);
return(height);
}

81
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)
{
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;
for (m=j=0; j<bp->numnotaries; j++)
{
@ -110,6 +110,11 @@ uint64_t dpow_notarybestk(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp)
//if ( bp->require0 != 0 && k == 0 )
// 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 )
{
for (z=n=0; z<bp->numnotaries; z++)
if ( (bp->notaries[z].recvmask & (1LL << k)) != 0 )
n++;
if ( n >= bp->numnotaries/2 )
{
mask |= (1LL << k);
if ( ++m == bp->minsigs )//-bp->require0 )
@ -120,6 +125,7 @@ uint64_t dpow_notarybestk(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp)
}
}
}
}
if ( bestk >= 0 )
*lastkp = bestk;
return(bestmask);
@ -193,7 +199,7 @@ struct dpow_block *dpow_heightfind(struct supernet_info *myinfo,struct dpow_info
return(bp);
}
int32_t dpow_voutstandard(struct dpow_block *bp,uint8_t *serialized,int32_t m,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified)
int32_t dpow_voutstandard(struct supernet_info *myinfo,struct dpow_block *bp,uint8_t *serialized,int32_t m,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified)
{
uint32_t paxwdcrc=0,locktime=0,numvouts; struct iguana_info *coin; uint64_t satoshis,satoshisB; int32_t i,n=0,opretlen,len=0; uint8_t opret[16384],data[16384],extras[16384];
numvouts = 2;
@ -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) )
{
n = dpow_paxpending(extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,src_or_dest,bp);
n = dpow_paxpending(myinfo,extras,sizeof(extras),&paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp);
}
satoshis = 0;
len += iguana_rwnum(1,&serialized[len],sizeof(satoshis),&satoshis);
@ -258,27 +264,46 @@ int32_t dpow_voutstandard(struct dpow_block *bp,uint8_t *serialized,int32_t m,in
return(len);
}
bits256 dpow_notarytx(char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t usesigs,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified)
bits256 dpow_notarytx(struct supernet_info *myinfo,char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t usesigs,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified)
{
uint32_t k,m,numsigs,version,vout,crcval,sequenceid = 0xffffffff; bits256 zero; int32_t n,siglen,len; uint8_t serialized[32768],*sig; bits256 txid; struct dpow_entry *ep; struct dpow_coinentry *cp;
// 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;
memset(zero.bytes,0,sizeof(zero));
len = numsigs = 0;
version = 1;
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);
m = bp->minsigs;
len += iguana_rwvarint32(1,&serialized[len],(uint32_t *)&m);
// -- vins --
for (k=m=0; k<bp->numnotaries; k++)
{
siglen = 0;
sig = 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 )
{
txid = bp->notaries[k].ratifydestutxo;
@ -289,15 +314,17 @@ bits256 dpow_notarytx(char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow
txid = bp->notaries[k].ratifysrcutxo;
vout = bp->notaries[k].ratifysrcvout;
}
if ( bestk >= 0 )
if ( bestk >= 0 ) //
{
siglen = bp->notaries[k].ratifysiglens[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);
}
else
else // state [2]
{
//printf("[Decker] dpow_notarytx: state [2]\n");
ep = &bp->notaries[k];
cp = (src_or_dest != 0) ? &bp->notaries[k].dest : &bp->notaries[k].src;
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_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);
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);
len += siglen;
numsigs++;
} else printf("Missing sig from k.%d\n",k);
} else serialized[len++] = 0;
} //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; // usesigs=0 -> insert scriptlen = 0
len += iguana_rwnum(1,&serialized[len],sizeof(sequenceid),&sequenceid);
//printf("height.%d mod.%d VINI.%d <- i.%d j.%d\n",height,height % numnotaries,m,i,j);
m++;
@ -332,13 +361,32 @@ bits256 dpow_notarytx(char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow
break;
}
}
if ( (n= dpow_voutstandard(bp,&serialized[len],m,src_or_dest,pubkeys,numratified)) < 0 )
// -- 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);
return(zero);
}
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);
//printf("[Decker] dpow_notarytx: signedtx.(%s)\n", signedtx);
//printf("notarytx.(%s) opretlen.%d\n",signedtx,opretlen);
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();
jaddbits256(item,"txid",txid);
jaddnum(item,"vout",vout);
jaddnum(item, "amount", dstr(dpow_utxosize(coin->symbol)));
if ( k == 0 && bp->require0 != 0 )
{
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];
if ( (vins= dpow_vins(coin,bp,bestk,bestmask,1,src_or_dest,useratified)) != 0 )
{
txid = dpow_notarytx(rawtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,bp->numratified!=0?bp->ratified_pubkeys:0,useratified*bp->numratified);
txid = dpow_notarytx(myinfo,rawtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,bp->numratified!=0?bp->ratified_pubkeys:0,useratified*bp->numratified);
//char str[65]; printf("%s signedtxgen %s src_or_dest.%d (%d %llx) useratified.%d raw.(%s)\n",dp->symbol,bits256_str(str,txid),src_or_dest,bestk,(long long)bestmask,useratified,rawtx);
if ( bits256_nonz(txid) != 0 && rawtx[0] != 0 ) // send tx to share utxo set
{
@ -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;
if ( bestk >= 0 && bp->state != 0xffffffff && coin != 0 )
{
dpow_notarytx(bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,pubkeys,numratified); // setcrcval
signedtxid = dpow_notarytx(bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,1,src_or_dest,pubkeys,numratified);
if ( strcmp("GAME",coin->symbol) == 0 )
dpow_notarytx(myinfo,bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,pubkeys,numratified); // setcrcval
signedtxid = dpow_notarytx(myinfo,bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,1,src_or_dest,pubkeys,numratified);
if ( strcmp("GAME",coin->symbol) == 0 || 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);
bp->state = 1;
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
{
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);
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\"}"

8
iguana/exchanges/CMakeLists.txt

@ -1,6 +1,6 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
set(MM_SOURCES mm.c ../mini-gmp.c ../groestl.c ../segwit_addr.c ../keccak.c LP_etomic.c)
set(MM_LIBS curl pthread libcrypto777 libjpeg libsecp256k1)
set(MM_LIBS curl pthread libcrypto777 libjpeg libsecp256k1 libsodium::libsodium)
if(WIN32)
link_directories(${CMAKE_SOURCE_DIR}/marketmaker_depends/curl/build_msvc_2015_win64/lib/Release ${CMAKE_SOURCE_DIR}/marketmaker_depends/pthread-win32/bin/x64_MSVC2015.Release ${CMAKE_SOURCE_DIR}/marketmaker_depends/nanomsg/build_msvc_2015_win64/Release)
set(MM_LIBS ${MM_LIBS} nanomsg)
@ -24,6 +24,7 @@ add_definitions(-DNATIVE_WINDOWS)
add_definitions(-DIGUANA_LOG2PACKETSIZE=20)
add_definitions(-DIGUANA_MAXPACKETSIZE=1572864)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_definitions(-DMM_WIN_BUILD)
include_directories("${CMAKE_SOURCE_DIR}/includes")
endif()
target_link_libraries(marketmaker-testnet ${MM_LIBS} etomiclib-testnet)
@ -32,3 +33,8 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
target_link_libraries(marketmaker-mainnet -static-libgcc -static-libstdc++)
target_link_libraries(marketmaker-testnet -static-libgcc -static-libstdc++)
endif()
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}")

360
iguana/exchanges/LP_bitcoin.c

@ -17,6 +17,23 @@
// LP_bitcoin.c
// 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]; };
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);
}
char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params)
char *bitcoind_passthrut(char *coinstr,char *serverport,char *userpass,char *method,char *params,int32_t timeout)
{
if ( userpass[0] == 0 )
return(clonestr("{\"error\":\"no rpcusername rpcpassword in coin.conf\"}"));
return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,4));
/*struct iguana_info *coin; char *retstr;
if ( (coin= LP_coinfind(coinstr)) != 0 )
{
portable_mutex_lock(&coin->curl_mutex);
retstr = bitcoind_RPCnew(coin->curl_handle,0,coinstr,serverport,userpass,method,params,timeout);
portable_mutex_unlock(&coin->curl_mutex);
return(retstr);
}*/
return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,timeout));
}
char *bitcoind_passthrut(char *coinstr,char *serverport,char *userpass,char *method,char *params,int32_t timeout)
char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params)
{
return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,timeout));
if ( userpass[0] == 0 )
return(clonestr("{\"error\":\"no rpcusername rpcpassword in coin.conf\"}"));
return(bitcoind_passthrut(coinstr,serverport,userpass,method,params,4));
//return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,4));
}
bits256 bits256_calcaddrhash(char *symbol,uint8_t *serialized,int32_t len)
@ -2093,7 +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] )
return(20);
else
else if ( strcmp(symbol,"BTC") != 0 || *addrtypep == 0 || *addrtypep == 5 )
{
int32_t i;
//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)
{
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;
#ifndef NOTETOMIC
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();
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 )
locktime = (uint32_t)time(NULL);
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);
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++)
{
@ -3579,7 +3734,7 @@ bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2sht
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;
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[1]),msg->vmacs[1].bytes);
if ( rwflag == 1 )
memcpy(&serialized[len],msg->zkproof,sizeof(msg->zkproof));
else memcpy(msg->zkproof,&serialized[len],sizeof(msg->zkproof));
len += sizeof(msg->zkproof);
memcpy(&serialized[len],msg->zkproof,proof_size);
else memcpy(msg->zkproof,&serialized[len],proof_size);
len += proof_size;
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 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);
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 (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();
voutarray = cJSON_CreateArray();
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);
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);
if ( zcash == LP_IS_ZCASHPROTOCOL && msg->version > 1 )
{
uint32_t numjoinsplits; struct iguana_msgjoinsplit joinsplit; uint8_t joinsplitpubkey[33],joinsplitsig[64];
len += iguana_rwvarint32(rwflag,&serialized[len],&numjoinsplits);
if ( numjoinsplits > 0 )
struct iguana_msgjoinsplit joinsplit; uint8_t joinsplitpubkey[33],joinsplitsig[64];
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->numjoinsplits),&msg->numjoinsplits);
if ( msg->numjoinsplits > 0 )
{
for (i=0; i<numjoinsplits; i++)
len += iguana_rwjoinsplit(rwflag,&serialized[len],&joinsplit);
for (i=0; i<msg->numjoinsplits; i++)
len += iguana_rwjoinsplit(rwflag,&serialized[len],&joinsplit,zksnark_proof_size);
if ( rwflag != 0 )
{
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 )
{
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 )
return(txid);
vpnstr[0] = 0;
if ( (msg->version= juint(txobj,"version")) == 0 )
uint32_t version = juint(txobj,"version");
if (version == 0 ) {
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);
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 ( (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");
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");
*txstartp = 0;
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
else if (coin->etomic[0] != 0) {
//balance = LP_etomic_get_balance(coin, coin->smartaddr);
int error = 0;
if (coin->inactive == 0) {
balance = LP_etomic_get_balance(coin, coin->smartaddr, &error);
} else {
balance = 0;
}
jaddnum(item,"height",-1);
//jaddnum(item,"balance",dstr(balance));
jaddnum(item,"balance",0);
jaddnum(item,"balance",dstr(balance));
}
#endif
else
@ -373,7 +377,8 @@ struct iguana_info *LP_coinadd(struct iguana_info *cdata)
return(coin);
}
uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetname,int32_t isPoS,uint16_t port,uint8_t pubtype,uint8_t p2shtype,uint8_t wiftype,uint64_t txfee,double estimatedrate,int32_t longestchain,uint8_t wiftaddr,uint8_t taddr,uint16_t busport,char *confpath)
void *curl_easy_init();
uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetname,int32_t isPoS,uint16_t port,uint8_t pubtype,uint8_t p2shtype,uint8_t wiftype,uint64_t txfee,double estimatedrate,int32_t longestchain,uint8_t wiftaddr,uint8_t taddr,uint16_t busport,char *confpath,uint8_t decimals,uint32_t txversion)
{
static void *ctx;
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));
if ( strcmp(symbol,"PART") == 0 )
coin->txversion = 160;
else coin->txversion = 1;
else coin->txversion = txversion;
coin->updaterate = (uint32_t)time(NULL);
coin->isPoS = isPoS;
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;
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);
}
@ -472,7 +485,7 @@ struct iguana_info *LP_coinfind(char *symbol)
else if ( strcmp(symbol,"KMD") == 0 )
name = "komodo";
else return(0);
port = LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0,0,busport,0);
port = LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0,0,busport,0,0,0);
if ( port == 0 )
isinactive = 1;
else isinactive = 0;
@ -514,7 +527,13 @@ struct iguana_info *LP_coincreate(cJSON *item)
}
else if ( (name= jstr(item,"name")) == 0 )
name = symbol;
if ( LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,juint(item,"wiftaddr"),juint(item,"taddr"),LP_busport(port),jstr(item,"confpath")) < 0 )
uint8_t decimals = juint(item,"decimals");
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->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\
sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)\n\
withdraw(coin, outputs[], broadcast=0)\n\
eth_withdraw(coin, to, amount, gas, gas_price, broadcast=0)\n\
txblast(coin, utxotxid, utxovout, utxovalue, txfee, passphrase, outputs[], broadcast=0)\n\
sendrawtransaction(coin, signedtx)\n\
swapstatus(pending=0, fast=0)\n\
@ -144,12 +145,14 @@ fundvalue(address="", holdings=[], divisor=0)\n\
orderbook(base, rel, duration=3600)\n\
getprices()\n\
inuse()\n\
movecoinbases(coin)\n\
getmyprice(base, rel)\n\
getprice(base, rel)\n\
//sendmessage(base=coin, rel="", pubkey=zero, <argjson method2>)\n\
//getmessages(firsti=0, num=100)\n\
//deletemessages(firsti=0, num=100)\n\
secretaddresses(prefix='secretaddress', passphrase, num=10, pubtype=60, taddr=0)\n\
gen64addrs(passphrase, taddr=0, pubtype=60)\n\
electrum(coin, ipaddr, port)\n\
snapshot(coin, height)\n\
snapshot_balance(coin, height, addresses[])\n\
@ -172,10 +175,17 @@ unlockedspend(coin, txid)\n\
opreturndecrypt(coin, txid, passphrase)\n\
getendpoint(port=5555)\n\
getfee(coin)\n\
mpnet(onoff)\n\
sleep(seconds=60)\n\
listtransactions(coin, address, count=10, skip=0)\n\
jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
version\n\
\"}"));
if ( strcmp(method,"version") == 0 ) {
retjson = cJSON_CreateObject();
jaddstr(retjson,"result",MM_VERSION);
return(jprint(retjson,1));
}
if ( (base= jstr(argjson,"base")) == 0 )
base = "";
@ -231,12 +241,23 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
{
if ( (ptr= LP_coinsearch("KMD")) != 0 )
{
if ( jint(argjson,"weeks") <= 0 || jdouble(argjson,"amount") < 10. )
return(clonestr("{\"error\":\"instantdex_deposit needs to have weeks and amount\"}"));
else return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jobj(argjson,"broadcast") != 0 ? jint(argjson,"broadcast") : 1));
if ( jint(argjson,"weeks") <= 0 ) {
return(clonestr("{\"error\":\"instantdex_deposit weeks param must be greater than zero\"}"));
}
if ( jdouble(argjson,"amount") < 10. ) {
return(clonestr("{\"error\":\"instantdex_deposit amount param must be equal or greater than 10\"}"));
}
return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jobj(argjson,"broadcast") != 0 ? jint(argjson,"broadcast") : 1));
}
return(clonestr("{\"error\":\"cant find KMD\"}"));
}
else if ( strcmp(method,"mpnet") == 0 )
{
G.mpnet = jint(argjson,"onoff");
printf("MPNET onoff.%d\n",G.mpnet);
return(clonestr("{\"status\":\"success\"}"));
}
else if ( strcmp(method,"getendpoint") == 0 )
{
int32_t err,mode; uint16_t wsport = 5555; char endpoint[64],bindpoint[64];
@ -276,6 +297,10 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
}
return(jprint(retjson,1));
}
else if ( strcmp(method,"verus") == 0 )
{
return(verusblocks());
}
else if ( strcmp(method,"instantdex_claim") == 0 )
{
if ( (ptr= LP_coinsearch("KMD")) != 0 )
@ -391,11 +416,6 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
jaddbits256(retjson,"privkey",privkey);
bitcoin_priv2wif(coin,wiftaddr,wifstr,privkey,wiftype);
jaddstr(retjson,"wif",wifstr);
#ifndef NOTETOMIC
char ethaddr[50];
LP_etomic_pubkeystr_to_addr(pubsecp, ethaddr);
jaddstr(retjson,"ethaddr",ethaddr);
#endif
return(jprint(retjson,1));
} else return(clonestr("{\"error\":\"need to have passphrase\"}"));
}
@ -407,6 +427,13 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
{
return(LP_ticker(jstr(argjson,"base"),jstr(argjson,"rel")));
}
else if ( strcmp(method,"gen64addrs") == 0 )
{
uint8_t taddr,pubtype;
pubtype = (jobj(argjson,"pubtype") == 0) ? 60 : juint(argjson,"pubtype");
taddr = (jobj(argjson,"taddr") == 0) ? 0 : juint(argjson,"taddr");
return(LP_gen64addrs(ctx,jstr(argjson,"passphrase"),taddr,pubtype));
}
else if ( strcmp(method,"secretaddresses") == 0 )
{
uint8_t taddr,pubtype;
@ -451,6 +478,12 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
}
else if ( strcmp(method,"inuse") == 0 )
return(jprint(LP_inuse_json(),1));
#ifndef NOTETOMIC
else if ( strcmp(method,"eth_gas_price") == 0 )
{
return LP_eth_gas_price();
}
#endif
else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 )
return(retstr);
if ( base[0] != 0 && rel[0] != 0 )
@ -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));
}
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 )
return(clonestr("{\"error\":\"at least one of coins disabled\"}"));
price = jdouble(argjson,"price");
if ( strcmp(method,"setprice") == 0 )
{
if ( LP_mypriceset(&changed,base,rel,price) < 0 )
if ( LP_mypriceset(1,&changed,base,rel,price) < 0 )
return(clonestr("{\"error\":\"couldnt set price\"}"));
//else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 )
//else if ( LP_mypriceset(1,&changed,rel,base,1./price) < 0 )
// return(clonestr("{\"error\":\"couldnt set price\"}"));
else if ( price == 0. || jobj(argjson,"broadcast") == 0 || jint(argjson,"broadcast") != 0 )
return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio));
else return(clonestr("{\"result\":\"success\"}"));
}
else if ( strcmp(method,"orderbook") == 0 )
return(LP_orderbook(base,rel,jint(argjson,"duration")));
else if ( strcmp(method,"myprice") == 0 )
{
if ( LP_myprice(&bid,&ask,base,rel) > SMALLVAL )
if ( LP_myprice(1,&bid,&ask,base,rel) > SMALLVAL )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"base",base);
@ -514,7 +573,7 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
} else vol = jdouble(argjson,"relvolume");
if ( price > SMALLVAL )
{
return(LP_autobuy(ctx,fomo,myipaddr,pubsock,base,rel,price,vol,jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0,jstr(argjson,"uuid")));
return(LP_autobuy(ctx,fomo,myipaddr,pubsock,base,rel,price,vol,jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0,jstr(argjson,"uuid"),jint(argjson,"fill"),jint(argjson,"gtc")));
} else return(clonestr("{\"error\":\"no price set\"}"));
}
else if ( strcmp(method,"sell") == 0 )
@ -528,7 +587,7 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
} else vol = jdouble(argjson,"basevolume");
if ( price > SMALLVAL )
{
return(LP_autobuy(ctx,fomo,myipaddr,pubsock,rel,base,1./price,vol,jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0,jstr(argjson,"uuid")));
return(LP_autobuy(ctx,fomo,myipaddr,pubsock,rel,base,1./price,vol,jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0,jstr(argjson,"uuid"),jint(argjson,"fill"),jint(argjson,"gtc")));
} else return(clonestr("{\"error\":\"no price set\"}"));
}
}
@ -553,12 +612,35 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
jaddstr(retjson,"coin",coin);
return(jprint(retjson,1));
}
#ifndef NOTETOMIC
if (strcmp(coin, "ETOMIC") == 0 && LP_RTsmartbalance(ptr) < 20 * SATOSHIDEN) {
if (get_etomic_from_faucet(ptr->smartaddr) != 1) {
return(clonestr("{\"error\":\"Could not get ETOMIC from faucet!\"}"));
}
}
if (ptr->etomic[0] != 0) {
if (isValidAddress(ptr->etomic) == 0) {
return(clonestr("{\"error\":\"'etomic' field is not valid address!\"}"));
}
struct iguana_info *etomic_coin = LP_coinsearch("ETOMIC");
if (etomic_coin->inactive != 0) {
return(clonestr("{\"error\":\"Enable ETOMIC first to use ETH/ERC20!\"}"));
}
if (ptr->decimals == 0 && strcmp(coin, "ETH") != 0) {
ptr->decimals = getErc20DecimalsZeroOnError(ptr->etomic);
if (ptr->decimals == 0) {
return(clonestr("{\"error\":\"Could not get token decimals or token has zero decimals which is not supported!\"}"));
}
}
}
#endif
if ( LP_conflicts_find(ptr) == 0 )
{
cJSON *array;
ptr->inactive = 0;
if ( ptr->smartaddr[0] != 0 )
LP_unspents_load(coin,ptr->smartaddr);
LP_unspents_load(coin,ptr->smartaddr);
if ( strcmp(ptr->symbol,"KMD") == 0 )
LP_importaddress("KMD",BOTS_BONDADDRESS);
@ -664,6 +746,10 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
return(LP_txblast(ptr,argjson));
else return(clonestr("{\"error\":\"cant find coind\"}"));
}
else if ( strcmp(method,"movecoinbases") == 0 )
{
return(LP_movecoinbases(coin));
}
else if ( strcmp(method,"withdraw") == 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));
}
else if ( strcmp(method,"myprices") == 0 )
return(LP_myprices());
return(LP_myprices(1));
else if ( strcmp(method,"trust") == 0 )
return(LP_pubkey_trustset(jbits256(argjson,"pubkey"),jint(argjson,"trust")));
else if ( strcmp(method,"trusted") == 0 )
@ -827,14 +913,14 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
double price,bid,ask;
if ( strcmp(method,"getprice") == 0 )
{
ask = LP_price(base,rel);
if ( (bid= LP_price(rel,base)) > SMALLVAL )
ask = LP_price(1,base,rel);
if ( (bid= LP_price(1,rel,base)) > SMALLVAL )
bid = 1./bid;
}
else
{
ask = LP_getmyprice(base,rel);
if ( (bid= LP_getmyprice(rel,base)) > SMALLVAL )
ask = LP_getmyprice(1,base,rel);
if ( (bid= LP_getmyprice(1,rel,base)) > SMALLVAL )
bid = 1./bid;
}
price = _pairaved(bid,ask);

214
iguana/exchanges/LP_etomic.c

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

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);
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);

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

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("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue));
printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue));
}
if ( 0 && credits != 0 )
printf("%s %s othercredits %.8f debits %.8f + %.8f -> %.8f\n",coin->symbol,coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue),dstr(credits - (swaps_kmdvalue+kmdvalue)));
@ -679,9 +679,9 @@ int64_t LP_instantdex_proofcheck(char *symbol,char *coinaddr,cJSON *proof,int32_
credits = ap->instantdex_credits;
ap->didinstantdex = 1;
ap->instantdextime = (uint32_t)time(NULL);
if ( 0 && ap->instantdex_credits > 0 )
if ( 1 && ap->instantdex_credits > 0 )
printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits));
} //else printf("cant find ap.%p or already did %d %.8f\n",ap,ap!=0?ap->didinstantdex:-1,ap!=0?dstr(ap->instantdex_credits):-1);
} else printf("cant find ap.%p or already did %d %.8f\n",ap,ap!=0?ap->didinstantdex:-1,ap!=0?dstr(ap->instantdex_credits):-1);
}
return(credits);
}

4
iguana/exchanges/LP_mmjson.c

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

94
iguana/exchanges/LP_nativeDEX.c

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

13
iguana/exchanges/LP_network.c

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

271
iguana/exchanges/LP_ordermatch.c

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

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

41
iguana/exchanges/LP_prices.c

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

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));
}
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";
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 )
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);
return(0);
@ -292,6 +352,7 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
{
//static uint32_t counter;
bits256 privkey,userpub,zero,userpass,checkkey,tmpkey; char str[65],str2[65],tmpstr[128]; cJSON *retjson; uint8_t tmptype,sig[128]; int32_t notarized,siglen; uint64_t nxtaddr;
uint8_t rmd160[20];
if ( (wifstr == 0 || wifstr[0] == 0) && LP_wifstr_valid(coin->symbol,passphrase) > 0 )
{
wifstr = passphrase;
@ -339,7 +400,7 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
#ifndef NOTETOMIC
if ( coin->etomic[0] != 0 )
{
uint8_t check64[64],checktype,checkrmd160[20],rmd160[20]; char checkaddr[64],checkaddr2[64];
uint8_t check64[64],checktype,checkrmd160[20]; char checkaddr[64],checkaddr2[64];
if ( LP_etomic_priv2pub(check64,privkey) == 0 )
{
if ( memcmp(check64,coin->pubkey33+1,32) == 0 )
@ -374,8 +435,8 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
coin->counter++;
memcpy(G.LP_pubsecp,coin->pubkey33,33);
bitcoin_priv2wif(coin->symbol,coin->wiftaddr,tmpstr,privkey,coin->wiftype);
bitcoin_addr2rmd160(coin->symbol,coin->taddr,&tmptype,G.LP_myrmd160,coin->smartaddr);
LP_privkeyadd(privkey,G.LP_myrmd160);
bitcoin_addr2rmd160(coin->symbol,coin->taddr,&tmptype,rmd160,coin->smartaddr);
LP_privkeyadd(privkey,rmd160);
G.LP_privkey = privkey;
if ( G.counter++ == 0 )
{
@ -415,6 +476,209 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
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)
{
struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33]; int32_t initonly;
@ -431,8 +695,10 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase)
coin->counter = 0;
memset(coin->smartaddr,0,sizeof(coin->smartaddr));
if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 )
{
privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,"");
}
}
//printf("i.%d of %d\n",i,LP_numcoins);
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)
{
static void *ctx; struct iguana_info *coin,*tmp; int32_t counter;
uint8_t pubkey33[100];
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( G.LP_pendingswaps != 0 )
@ -482,8 +749,11 @@ int32_t LP_passphrase_init(char *passphrase,char *gui,uint16_t netid,char *seedn
memset(&G,0,sizeof(G));
G.netid = netid;
safecopy(G.seednode,seednode,sizeof(G.seednode));
vcalc_sha256(0,G.LP_passhash.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
LP_privkey_updates(ctx,LP_mypubsock,passphrase);
bitcoin_pubkey33(ctx, pubkey33, G.LP_privkey);
calc_rmd160_sha256(G.LP_myrmd160, pubkey33, 33);
init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20);
G.LP_sessionid = (uint32_t)time(NULL);
safecopy(G.gui,gui,sizeof(G.gui));

112
iguana/exchanges/LP_remember.c

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

33
iguana/exchanges/LP_rpc.c

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

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

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");
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));
funcp = 0;

48
iguana/exchanges/LP_signatures.c

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

118
iguana/exchanges/LP_socket.c

@ -25,6 +25,83 @@
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#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)
{
@ -124,12 +201,23 @@ int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port)
#endif
if ( bindflag == 0 )
{
//#ifdef _WIN32
if ( 1 ) // connect using async to allow timeout, then switch to sync
{
uint32_t starttime = (uint32_t)time(NULL);
//printf("call connect sock.%d\n",sock);
result = connect(sock,(struct sockaddr *)&saddr,addrlen);
//printf("called connect result.%d\n",result);
timeout.tv_sec = 2;
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 )
{
if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH )
@ -140,9 +228,8 @@ int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port)
closesocket(sock);
return(-1);
}
timeout.tv_sec = 10;
timeout.tv_usec = 0;
setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout));
}
//#endif
}
else
{
@ -422,7 +509,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch
{
*retjsonp = 0;
sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params);
//printf("%s %s",symbol,stratumreq);
//printf("timeout.%d exp.%d %s %s",timeout,(int32_t)(expiration-time(NULL)),symbol,stratumreq);
memset(ep->buf,0,ep->bufsize);
sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp);
portable_mutex_lock(&ep->mutex); // this helps performance!
@ -1112,7 +1199,8 @@ void LP_dedicatedloop(void *arg)
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 )
{
ep = coin->electrum;
@ -1190,7 +1278,19 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port)
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));
return(retjson);
}

2
iguana/exchanges/LP_statemachine.c

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

78
iguana/exchanges/LP_swap.c

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

2
iguana/exchanges/LP_tradebots.c

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

281
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;
*signedtx = 0;
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++)
{
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);
}
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();
jaddbits256(item,"txid",txid);
jaddnum(item,"vout",vout);
if ( suppress != 0 )
jaddnum(item,"suppress",1);
sobj = cJSON_CreateObject();
jaddstr(sobj,"hex",spendscriptstr);
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)
{
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;
interestsum = 0;
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 )
{
preselected[numpre++] = up;
printf("found utxotxid in slot.%d\n",j);
//printf("found utxotxid in slot.%d\n",j);
utxos[j] = 0;
continue;
}
@ -1083,6 +1085,8 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
{
up->spendheight = 1;
utxos[j] = 0;
if ( (sobj= jobj(txobj,"scriptPubKey")) != 0 && jstr(sobj,"hex") != 0 && strlen(jstr(sobj,"hex")) == 35*2 )
up->U.suppress = 1;
}
else
{
@ -1117,13 +1121,13 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
preselected[numpre++] = up;
else
{
printf("couldnt add address_utxo after not finding\n");
//printf("couldnt add address_utxo %s/v%d after not finding\n",bits256_str(str,utxotxid),utxovout);
sleep(1);
value = LP_txvalue(0,coin->symbol,utxotxid,utxovout);
LP_address_utxoadd(0,(uint32_t)time(NULL),"withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1);
if ( (up= LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout)) != 0 )
preselected[numpre++] = up;
else printf("second couldnt add address_utxo after not finding\n");
else printf("second couldnt add address_utxo %s/v%d after not finding\n",bits256_str(str,utxotxid),utxovout);
//return(0);
}
}
@ -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));
}
}
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->N = vp->M = 1;
vp->signers[0].privkey = privkey;
jaddistr(privkeys,wifstr);
bitcoin_pubkey33(ctx,vp->signers[0].pubkey,privkey);
vp->suppress_pubkeys = suppress_pubkeys;
vp->suppress_pubkeys = up->U.suppress;
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);
if ( remains <= 0 && i >= numpre-1 )
break;
@ -1227,7 +1231,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
return(n);
}
char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_info *coin,struct vin_info *V,int32_t max,bits256 privkey,cJSON *outputs,cJSON *vins,cJSON *privkeys,int64_t txfee,bits256 utxotxid,int32_t utxovout,uint32_t locktime,char *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;
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,6 +1288,29 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
return(0);
}
memset(utxos,0,sizeof(utxos));
//char str[65];
if ( onevin != 0 )
{
if ( (txobj= LP_gettxout(coin->symbol,coin->smartaddr,utxotxid,utxovout)) != 0 )
{
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);
}
}
else
{
if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,(int32_t)(sizeof(utxos)/sizeof(*utxos)),ap,coin->smartaddr)) <= 0 )
{
if ( bits256_nonz(utxotxid) == 0 )
@ -1292,10 +1319,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
return(0);
}
}
//char str[65];
//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));
}
ignore_cltverr = 0;
suppress_pubkeys = 1;
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);
}
}
//printf("suppress.%d\n",V->suppress_pubkeys);
if ( (rawtxbytes= bitcoin_json2hex(coin->symbol,coin->isPoS,&txid,txobj,V)) != 0 )
{
} 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);
init_hexbytes_noT(spendscriptstr,script,scriptlen);
vins = cJSON_CreateArray();
jaddi(vins,LP_inputjson(utxotxid,utxovout,spendscriptstr));
jaddi(vins,LP_inputjson(utxotxid,utxovout,spendscriptstr,suppress_pubkeys));
jdelete(txobj,"vin");
jadd(txobj,"vin",jduplicate(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)
{
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));
if ( coin->etomic[0] != 0 )
{
@ -1811,6 +1836,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
locktime = juint(argjson,"locktime");
txfee = juint(argjson,"txfee");
autofee = (strcmp(coin->symbol,"BTC") == 0);
//printf("LP_withdraw: %s/v%d %s\n",bits256_str(str,utxotxid),utxovout,jprint(outputs,0));
if ( txfee == 0 )
{
autofee = 1;
@ -1832,11 +1858,25 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
vins = cJSON_CreateArray();
memset(V,0,sizeof(*V) * maxV);
numvins = 0;
if ( (rawtx= LP_createrawtransaction(&txobj,&numvins,coin,V,maxV,privkey,outputs,vins,privkeys,iter == 0 ? txfee : newtxfee,utxotxid,utxovout,locktime,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;
memset(&msgtx,0,sizeof(msgtx));
memset(signedtxid.bytes,0,sizeof(signedtxid));
if ( jint(argjson,"onevin") != 0 )
{
V[0].suppress_pubkeys = 1;
bitcoin_priv2wif(coin->symbol,coin->wiftaddr,wifstr,privkey,coin->wiftype);
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 )
@ -1845,13 +1885,14 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
if ( signedtx != 0 )
free(signedtx), signedtx = 0;
}
}
if ( signedtx == 0 )
break;
datalen = (int32_t)strlen(signedtx) / 2;
if ( autofee != 0 && iter == 0 && strcmp(coin->symbol,"BTC") == 0 )
{
txfee = newtxfee = LP_txfeecalc(coin,0,datalen);
printf("txfee %.8f -> newtxfee %.8f, numvins.%d\n",dstr(txfee),dstr(newtxfee),numvins);
printf("txfee %.8f -> newtxfee %.8f, numvins.%d datalen.%d\n",dstr(txfee),dstr(newtxfee),numvins,datalen);
for (i=0; i<numvins; 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 *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->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))));
if ( balance > txfee && balance >= (1000000 - (txfee + 100000)) )
{
halfval = (balance / 100) * 45;
// .95 / .02 / .02 / 0.005
//halfval = (balance / 100) * 45;
argjson = cJSON_CreateObject();
outputs = cJSON_CreateArray();
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,dstr(halfval));
jaddnum(item,coin->smartaddr,dstr(balance/100) * 95);
jaddi(outputs,item);
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,dstr(halfval));
jaddnum(item,coin->smartaddr,dstr(balance/50));
jaddi(outputs,item);
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,dstr(balance - 2*halfval));
jaddnum(item,coin->smartaddr,dstr(balance/50));
jaddi(outputs,item);
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,0.0001);
jaddi(outputs,item);
jadd(argjson,"outputs",outputs);
jaddnum(argjson,"broadcast",1);
@ -1950,33 +1995,209 @@ char *LP_autosplit(struct iguana_info *coin)
return(clonestr("{\"error\":\"couldnt autosplit\"}"));
}
char *LP_autofillbob(struct iguana_info *coin,uint64_t satoshis)
{
char *retstr; cJSON *argjson,*withdrawjson,*outputs,*item; int64_t total,balance,txfee;
if ( coin->etomic[0] == 0 )
{
if ( coin->electrum != 0 )
balance = LP_unspents_load(coin->symbol,coin->smartaddr);
else balance = LP_RTsmartbalance(coin);
if ( strcmp("BTC",coin->symbol) == 0 )
txfee = LP_txfeecalc(coin,0,1000);
balance -= (txfee + 1000000);
if ( balance < (satoshis<<2) )
return(clonestr("{\"error\":\"couldnt autofill balance too small\"}"));
if ( balance > satoshis+3*txfee && balance >= (txfee + 1000000) )
{
argjson = cJSON_CreateObject();
outputs = cJSON_CreateArray();
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,dstr(satoshis + 3000000));
jaddi(outputs,item);
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,dstr(LP_DEPOSITSATOSHIS(satoshis) + 3000000));
jaddi(outputs,item);
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,0.0001);
jaddi(outputs,item);
jadd(argjson,"outputs",outputs);
jaddnum(argjson,"broadcast",0);
jaddstr(argjson,"coin",coin->symbol);
retstr = LP_withdraw(coin,argjson);
free_json(argjson);
return(retstr);
} else return(clonestr("{\"error\":\"balance too small to autosplit, please make more deposits\"}"));
}
return(clonestr("{\"error\":\"couldnt autofill etomic needs separate support\"}"));
}
char *LP_movecoinbases(char *symbol)
{
static bits256 zero; bits256 utxotxid,txid; struct iguana_info *coin; cJSON *retjson,*outputs,*argjson,*txids,*unspents,*item,*gen,*output; int32_t i,n,utxovout; char *retstr,*hexstr;
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
char *LP_eth_tx_fee(struct iguana_info *coin, char *dest_addr, char *amount, int64_t gas, int64_t gas_price)
{
bits256 privkey;
cJSON *retjson = cJSON_CreateObject();
int64_t actual_gas_price = 0, actual_gas = 0;
char privkey_str[70];
if (gas_price > 0) {
actual_gas_price = gas_price;
} else {
actual_gas_price = getGasPriceFromStation(0);
if (actual_gas_price == 0) {
return (clonestr("{\"error\":\"Couldn't get gas price from station!\"}"));
}
}
cJSON_AddNumberToObject(retjson, "gas_price", actual_gas_price);
if (gas > 0) {
actual_gas = gas;
} else if (strcmp(coin->symbol, "ETH") == 0) {
actual_gas = 21000;
} else {
privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr);
uint8arrayToHex(privkey_str, privkey.bytes, 32);
actual_gas = estimate_erc20_gas(coin->etomic, dest_addr, amount, privkey_str, coin->decimals);
if (actual_gas == 0) {
return (clonestr("{\"error\":\"Couldn't estimate erc20 transfer gas usage!\"}"));
}
}
cJSON_AddNumberToObject(retjson, "gas", actual_gas);
double_t eth_fee = (actual_gas_price * actual_gas) / 1000000000.0;
cJSON_AddNumberToObject(retjson, "eth_fee", eth_fee);
return(jprint(retjson,1));
}
char *LP_eth_withdraw(struct iguana_info *coin,cJSON *argjson)
{
cJSON *retjson = cJSON_CreateObject();
cJSON *gas_json = cJSON_GetObjectItem(argjson, "gas");
cJSON *gas_price_json = cJSON_GetObjectItem(argjson, "gas_price");
char *dest_addr, *tx_id, privkey_str[70], amount_str[100];
int64_t amount;
int64_t amount = 0, gas = 0, gas_price = 0, broadcast = 0;
bits256 privkey;
dest_addr = jstr(argjson, "to");
if (dest_addr == NULL) {
return(clonestr("{\"error\":\"param 'to' is required!\"}"));
}
if (isValidAddress(dest_addr) == 0) {
return(clonestr("{\"error\":\"'to' address is not valid!\"}"));
}
amount = jdouble(argjson, "amount") * 100000000;
if (amount == 0) {
return(clonestr("{\"error\":\"'amount' is not set or equal to zero!\"}"));
}
if (gas_json != NULL && is_cJSON_Number(gas_json)) {
gas = gas_json->valueint;
if (gas < 21000) {
return (clonestr("{\"error\":\"'gas' can't be lower than 21000!\"}"));
}
}
if (gas_price_json != NULL && is_cJSON_Number(gas_price_json)) {
gas_price = gas_price_json->valueint;
if (gas_price < 1) {
return (clonestr("{\"error\":\"'gas_price' can't be lower than 1!\"}"));
}
}
broadcast = jint(argjson, "broadcast");
satoshisToWei(amount_str, amount);
if (broadcast == 1) {
privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr);
uint8arrayToHex(privkey_str, privkey.bytes, 32);
satoshisToWei(amount_str, amount);
if (strcmp(coin->symbol, "ETH") == 0) {
tx_id = sendEth(dest_addr, amount_str, privkey_str, 0);
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);
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 {
return LP_eth_tx_fee(coin, dest_addr, amount_str, gas, gas_price);
}
}
char *LP_eth_gas_price()
{
cJSON *retjson = cJSON_CreateObject();
uint64_t gas_price = getGasPriceFromStation(0);
if (gas_price > 0) {
cJSON_AddNumberToObject(retjson, "gas_price", gas_price);
} else {
cJSON_AddStringToObject(retjson, "error", "Could not get gas price from station!");
}
return(jprint(retjson,1));
}
#endif
int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pubkey33,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf,int32_t delay,bits256 privkey,uint8_t *changermd160,char *vinaddr)
{
struct iguana_info *coin; int32_t len,retval=-1; char *retstr,*hexstr; cJSON *argjson,*outputs,*item,*retjson,*obj;
@ -2103,7 +2324,7 @@ int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vou
{
cJSON *retjson;
coinaddr[0] = 0;
if ( (retjson= LP_gettx("LP_swap_getcoinaddr",symbol,txid,0)) != 0 )
if ( (retjson= LP_gettx("LP_swap_getcoinaddr",symbol,txid,1)) != 0 )
{
LP_txdestaddr(coinaddr,txid,vout,retjson);
free_json(retjson);

53
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)
{
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 )
printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr);
//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 )
{
//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 )
{
//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
ap = LP_addressfind(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 )
{
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 ( strlen(hexstr) != 25*2 )
if ( strlen(hexstr) != 25*2 && strlen(hexstr) != 35*2 )
{
//printf("skip non-standard utxo.(%s)\n",hexstr);
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]);
#ifndef NOTETOMIC
if (coin->etomic[0] != 0) {
balance = LP_etomic_get_balance(coin, coinaddr);
int error = 0;
balance = LP_etomic_get_balance(coin, coinaddr, &error);
} else
#endif
if ( coin->electrum == 0 )
@ -724,7 +731,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
}
else
{
if ( strcmp(coin->smartaddr,coinaddr) != 0 )
//if ( strcmp(coin->smartaddr,coinaddr) != 0 )
{
if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,coinaddr,2,zero,zero)) != 0 )
free_json(retjson);
@ -787,7 +794,14 @@ cJSON *LP_balances(char *coinaddr)
}
else
{
if ( (balance= LP_RTsmartbalance(coin)) != 0 )
#ifndef NOTETOMIC
if (coin->etomic[0] == 0 || coin->inactive == 0) {
#endif
balance = LP_RTsmartbalance(coin);
#ifndef NOTETOMIC
}
#endif
if ( balance != 0 )
{
item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol);
@ -898,7 +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];
if ( coin->inactive != 0 )
return(0);
if ( txobj != 0 || (txobj= LP_gettx("LP_transactioninit",coin->symbol,txid,0)) != 0 )
if ( txobj != 0 || (txobj= LP_gettx("LP_transactioninit",coin->symbol,txid,1)) != 0 )
{
if ( coin->electrum == 0 )
height = LP_txheight(coin,txid);
@ -964,7 +978,7 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid)
return(height);
if ( coin->electrum == 0 )
{
if ( (txobj= LP_gettx("LP_txheight",coin->symbol,txid,0)) != 0 )
if ( (txobj= LP_gettx("LP_txheight",coin->symbol,txid,1)) != 0 )
{
//*timestampp = juint(txobj,"locktime");
//*blocktimep = juint(txobj,"blocktime");
@ -1067,7 +1081,7 @@ uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_inf
{
if ( (value= LP_value_extract(txobj,0,txid)) == 0 )
{
char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",coin->symbol,bits256_str(str,txid),jprint(txobj,0),vout);
// char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",coin->symbol,bits256_str(str,txid),jprint(txobj,0),vout);
}
else if ( strcmp(coin->symbol,"KMD") == 0 )
{
@ -1185,7 +1199,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
return(-1);
}
destaddr[0] = destaddr2[0] = 0;
if ( coin != 0 && IAMLP != 0 && coin->inactive != 0 )
if ( coin != 0 && (strcmp(coin->symbol, "ETOMIC") == 0 || (coin->inactive != 0 && IAMLP != 0)))
bypass = 1;
if ( bypass != 0 )
val = satoshis;
@ -1209,17 +1223,28 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
strcpy(destaddr,destaddr2);
if ( coin != 0 )
{
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 )
char txid_str[100], txid2_str[100];
bits256_str(txid_str, txid);
bits256_str(txid2_str, txid2);
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 ) {
printf("Could not find tx out: %s %d\n", txid_str, vout);
return (0);
}
else free_json(txobj);
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 )
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 ) {
printf("Could not find tx out2: %s %d\n", txid_str, vout2);
return (0);
}
else free_json(txobj);
if ( LP_numconfirms(coin->symbol,destaddr,txid,vout,0) <= 0 )
if ( LP_numconfirms(coin->symbol,destaddr,txid,vout,0) <= 0 ) {
printf("Txid numconfirms is less or equal to zero: %s %d\n", txid_str, vout);
return (0);
if ( LP_numconfirms(coin->symbol,destaddr,txid2,vout2,0) <= 0 )
}
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);
}
} else printf("no val2 %.8f < threshold %.8f\n",dstr(val),dstr(threshold));

2
iguana/exchanges/auto_chipsbtc

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

2
iguana/exchanges/auto_chipskmd

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

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 "{\"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}"

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));
}
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)
{
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);
}
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)
{
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_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_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);
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

85
iguana/exchanges/etomicswap/etomiccurl.c

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

9
iguana/exchanges/etomicswap/etomiccurl.h

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

280
iguana/exchanges/etomicswap/etomiclib.cpp

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

2
iguana/exchanges/fundvalue

@ -1,4 +1,4 @@
#!/bin/bash
source userpass
# this will only work for watchonly addresses that have been rescanned and with active coins
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"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;
OS_init();
printf("BarterDEX Marketmaker %s \n",MM_VERSION);
if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 )
{
bits256 privkey,checkkey; uint8_t tmptype; char kmdwif[64],str[65],str2[65],*retstr;
@ -346,6 +347,12 @@ int main(int argc, const char * argv[])
printf("couldnt write to (%s)\n",dirname);
exit(0);
}
sprintf(dirname,"%s/GTC",GLOBAL_DBDIR), OS_ensure_directory(dirname);
if ( ensure_writable(dirname) < 0 )
{
printf("couldnt write to (%s)\n",dirname);
exit(0);
}
sprintf(dirname,"%s/PRICES",GLOBAL_DBDIR), OS_ensure_directory(dirname);
if ( ensure_writable(dirname) < 0 )
{

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

Loading…
Cancel
Save