Browse Source

Merge pull request #930 from jl777/dev

sync branches
patch-6
jl777 6 years ago
committed by GitHub
parent
commit
f54411c10b
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. 9
      Dockerfile.clientnode
  6. 9
      Dockerfile.seednode
  7. 33
      Jenkinsfile
  8. 30
      appveyor.yml
  9. 2
      cpp-ethereum
  10. 4
      crypto777/cJSON.c
  11. 41
      docker-compose.yml
  12. 5
      etomic_build/client
  13. 4
      etomic_build/client/buy_BEER_OTHER
  14. 4
      etomic_build/client/client
  15. 7
      etomic_build/client/enable
  16. 1
      etomic_build/client/myipaddr
  17. 1
      etomic_build/client/passphrase
  18. 4
      etomic_build/client/setpassphrase
  19. 2
      etomic_build/client/userpass
  20. 2
      etomic_build/coins
  21. 3
      etomic_build/enable
  22. 1
      etomic_build/passphrase
  23. 5
      etomic_build/run
  24. 7
      etomic_build/seed/enable
  25. 1
      etomic_build/seed/myipaddr
  26. 1
      etomic_build/seed/passphrase
  27. 4
      etomic_build/seed/run
  28. 4
      etomic_build/seed/sell_BEER_OTHER
  29. 4
      etomic_build/seed/setpassphrase
  30. 2
      etomic_build/seed/userpass
  31. 2
      etomic_build/userpass
  32. 2
      iguana/coins/sec_7776
  33. 4
      iguana/dpow/dpow_network.c
  34. 2
      iguana/dpow/dpow_tx.c
  35. 5
      iguana/exchanges/CMakeLists.txt
  36. 19
      iguana/exchanges/LP_coins.c
  37. 64
      iguana/exchanges/LP_commands.c
  38. 214
      iguana/exchanges/LP_etomic.c
  39. 2
      iguana/exchanges/LP_etomic.h
  40. 26
      iguana/exchanges/LP_include.h
  41. 6
      iguana/exchanges/LP_mmjson.c
  42. 19
      iguana/exchanges/LP_nativeDEX.c
  43. 24
      iguana/exchanges/LP_ordermatch.c
  44. 12
      iguana/exchanges/LP_portfolio.c
  45. 85
      iguana/exchanges/LP_privkey.c
  46. 114
      iguana/exchanges/LP_remember.c
  47. 8
      iguana/exchanges/LP_rpc.c
  48. 19
      iguana/exchanges/LP_signatures.c
  49. 16
      iguana/exchanges/LP_socket.c
  50. 73
      iguana/exchanges/LP_swap.c
  51. 99
      iguana/exchanges/LP_transaction.c
  52. 41
      iguana/exchanges/LP_utxo.c
  53. 2
      iguana/exchanges/auto_chipsbtc
  54. 2
      iguana/exchanges/auto_chipskmd
  55. 2
      iguana/exchanges/coins
  56. 89
      iguana/exchanges/etomicswap/etomiccurl.c
  57. 9
      iguana/exchanges/etomicswap/etomiccurl.h
  58. 282
      iguana/exchanges/etomicswap/etomiclib.cpp
  59. 49
      iguana/exchanges/etomicswap/etomiclib.h
  60. 3
      iguana/exchanges/gen64addrs
  61. 1
      iguana/exchanges/mm.c
  62. 102
      iguana/exchanges/mm2.md
  63. 2
      iguana/exchanges/mshark
  64. 6
      iguana/exchanges/prices/autoprice
  65. 2
      iguana/exchanges/supernet
  66. 2
      iguana/iguana_notary.c
  67. 2
      iguana/m_notary
  68. 6
      iguana/m_notary_run
  69. 2
      iguana/m_splitfund
  70. 60
      marketmaker_build_depends.cmd
  71. 5
      marketmaker_build_etomic.cmd
  72. 8
      start_BEER_OTHER_trade.sh
  73. 8
      start_BEER_OTHER_trade_inverted.sh
  74. 5
      travis_cmake_linux.sh
  75. 6
      travis_cmake_mac.sh

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

9
Dockerfile.clientnode

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

9
Dockerfile.seednode

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

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'''
}
}
}

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

2
cpp-ethereum

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

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

41
docker-compose.yml

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

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

7
etomic_build/client/enable

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

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}" &

7
etomic_build/seed/enable

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

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"

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

4
iguana/dpow/dpow_network.c

@ -1308,8 +1308,8 @@ int32_t dpow_addnotary(struct supernet_info *myinfo,struct dpow_info *dp,char *i
char str[512]; uint32_t ipbits,*ptr; int32_t i,iter,n,retval = -1;
if ( myinfo->IAMNOTARY == 0 )
return(-1);
if ( strcmp(ipaddr,"88.99.251.101") == 0 || strcmp(ipaddr,"82.202.193.100") == 0 )
return(-1);
//if ( strcmp(ipaddr,"88.99.251.101") == 0 || strcmp(ipaddr,"82.202.193.100") == 0 )
// return(-1);
portable_mutex_lock(&myinfo->notarymutex);
if ( myinfo->dpowsock >= 0 )//&& myinfo->dexsock >= 0 )
{

2
iguana/dpow/dpow_tx.c

@ -329,7 +329,7 @@ bits256 dpow_notarytx(struct supernet_info *myinfo,char *signedtx,int32_t *numsi
memcpy(&serialized[len],sig,siglen);
len += siglen;
numsigs++;
} 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 printf("%s -> %s src_or_dest.%d Missing sig from k.%d\n",bp->srccoin->symbol,bp->destcoin->symbol,src_or_dest,k);
} else serialized[len++] = 0;
len += iguana_rwnum(1,&serialized[len],sizeof(sequenceid),&sequenceid);
//printf("height.%d mod.%d VINI.%d <- i.%d j.%d\n",height,height % numnotaries,m,i,j);

5
iguana/exchanges/CMakeLists.txt

@ -32,3 +32,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}")

19
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
@ -374,7 +378,7 @@ struct iguana_info *LP_coinadd(struct iguana_info *cdata)
}
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)
uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetname,int32_t isPoS,uint16_t port,uint8_t pubtype,uint8_t p2shtype,uint8_t wiftype,uint64_t txfee,double estimatedrate,int32_t longestchain,uint8_t wiftaddr,uint8_t taddr,uint16_t busport,char *confpath,uint8_t decimals)
{
static void *ctx;
char *name2; uint16_t origport = port;
@ -437,6 +441,7 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse
}
coin->curl_handle = curl_easy_init();
portable_mutex_init(&coin->curl_mutex);
coin->decimals = decimals;
return(port);
}
@ -480,7 +485,7 @@ struct iguana_info *LP_coinfind(char *symbol)
else if ( strcmp(symbol,"KMD") == 0 )
name = "komodo";
else return(0);
port = LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0,0,busport,0);
port = LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0,0,busport,0,0);
if ( port == 0 )
isinactive = 1;
else isinactive = 0;
@ -522,7 +527,9 @@ struct iguana_info *LP_coincreate(cJSON *item)
}
else if ( (name= jstr(item,"name")) == 0 )
name = symbol;
if ( LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,juint(item,"wiftaddr"),juint(item,"taddr"),LP_busport(port),jstr(item,"confpath")) < 0 )
uint8_t decimals = juint(item,"decimals");
if ( LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,juint(item,"wiftaddr"),juint(item,"taddr"),LP_busport(port),jstr(item,"confpath"),decimals) < 0 )
{
coin = LP_coinadd(&cdata);
coin->inactive = (uint32_t)time(NULL);

64
iguana/exchanges/LP_commands.c

@ -120,6 +120,7 @@ cancel(uuid)\n\
buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce)\n\
sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)\n\
withdraw(coin, outputs[], broadcast=0)\n\
eth_withdraw(coin, to, amount, gas, gas_price, broadcast=0)\n\
txblast(coin, utxotxid, utxovout, utxovalue, txfee, passphrase, outputs[], broadcast=0)\n\
sendrawtransaction(coin, signedtx)\n\
swapstatus(pending=0, fast=0)\n\
@ -151,6 +152,7 @@ getprice(base, rel)\n\
//getmessages(firsti=0, num=100)\n\
//deletemessages(firsti=0, num=100)\n\
secretaddresses(prefix='secretaddress', passphrase, num=10, pubtype=60, taddr=0)\n\
gen64addrs(passphrase, taddr=0, pubtype=60)\n\
electrum(coin, ipaddr, port)\n\
snapshot(coin, height)\n\
snapshot_balance(coin, height, addresses[])\n\
@ -177,7 +179,13 @@ 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 = "";
@ -233,9 +241,14 @@ 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\"}"));
}
@ -403,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\"}"));
}
@ -419,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;
@ -463,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 )
@ -591,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);

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

26
iguana/exchanges/LP_include.h

@ -206,7 +206,7 @@ struct basilisk_rawtxinfo
{
char destaddr[64],ethTxid[75];
bits256 txid,signedtxid,actualtxid;
int64_t amount,change,inputsum;
int64_t amount,change,inputsum,eth_amount;
int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys;
uint32_t locktime,crcs[2];
uint8_t addrtype,pubkey33[33],rmd160[20];
@ -241,7 +241,7 @@ struct basilisk_swapinfo
bits256 myhash,otherhash,orderhash;
uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration;
int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad,aliceistrusted,bobistrusted,otheristrusted,otherstrust,alicemaxconfirms,bobmaxconfirms;
int64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee;
int64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee,alicerealsat,bobrealsat;
bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn;
uint32_t crcs_mypub[2],crcs_mychoosei[2],crcs_myprivs[2],crcs_mypriv[2];
@ -256,29 +256,31 @@ struct basilisk_swapinfo
uint8_t userdata_bobrefund[256],userdata_bobrefundlen;
};
#define BASILISK_ALICESPEND 0
#define BASILISK_BOBSPEND 1
#define BASILISK_BOBPAYMENT 2
#define BASILISK_MYFEE 0
#define BASILISK_OTHERFEE 1
#define BASILISK_BOBDEPOSIT 2
#define BASILISK_ALICEPAYMENT 3
#define BASILISK_BOBDEPOSIT 4
#define BASILISK_OTHERFEE 5
#define BASILISK_MYFEE 6
#define BASILISK_BOBPAYMENT 4
#define BASILISK_ALICESPEND 5
#define BASILISK_BOBSPEND 6
#define BASILISK_BOBREFUND 7
#define BASILISK_BOBRECLAIM 8
#define BASILISK_ALICERECLAIM 9
#define BASILISK_ALICECLAIM 10
//0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0
static char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" };
static char *txnames[] = { "myfee", "otherfee", "bobdeposit", "alicepayment", "bobpayment", "alicespend", "bobspend", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" };
struct LP_swap_remember
{
bits256 pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)];
uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid;
uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid,alicerealsat,bobrealsat;
int64_t values[sizeof(txnames)/sizeof(*txnames)];
uint32_t finishtime,tradeid,requestid,quoteid,plocktime,dlocktime,expiration,state,otherstate;
int32_t iambob,finishedflag,origfinishedflag,Predeemlen,Dredeemlen,sentflags[sizeof(txnames)/sizeof(*txnames)];
uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],Predeemscript[1024],Dredeemscript[1024],pubkey33[33],other33[33];
char uuidstr[65],Agui[65],Bgui[65],gui[65],src[65],dest[65],bobtomic[128],alicetomic[128],etomicsrc[65],etomicdest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)],bobDepositEthTx[75],bobPaymentEthTx[75],alicePaymentEthTx[75];
char uuidstr[65],Agui[65],Bgui[65],gui[65],src[65],dest[65],bobtomic[128],alicetomic[128],etomicsrc[65],etomicdest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)];
char eth_tx_ids[sizeof(txnames)/sizeof(*txnames)][75];
int64_t eth_values[sizeof(txnames)/sizeof(*txnames)];
};
struct LP_outpoint
@ -312,7 +314,7 @@ struct iguana_info
double price_kmd,force,perc,goal,goalperc,relvolume,rate;
void *electrum; void *ctx;
uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB,fillsatoshis;
uint8_t pubkey33[33],zcash;
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;

6
iguana/exchanges/LP_mmjson.c

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

19
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;
@ -117,7 +120,7 @@ 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,mpnet;
@ -1126,6 +1129,7 @@ void LP_swapsloop(void *ctx)
if ( (sp->finished= LP_swapwait(0,sp->requestid,sp->quoteid,-1,0)) != 0 )
{
}
sleep(3);
}
}
if ( nonz == 0 )
@ -1136,7 +1140,7 @@ 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);
}
}
@ -1222,7 +1226,7 @@ void queue_loop(void *ctx)
}
if ( (json= cJSON_Parse((char *)ptr->msg)) != 0 )
{
if ( 1 && ptr->msglen < sizeof(linebuf) )
if ( ptr->msglen < sizeof(linebuf) )
{
if ( (k= MMJSON_encode(linebuf,(char *)ptr->msg)) > 0 )
{
@ -1421,8 +1425,7 @@ extern int32_t bitcoind_RPC_inittime;
void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybusport,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson)
{
char *myipaddr=0,version[64]; long filesize,n; int32_t valid,timeout; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128],*coins_str=0; cJSON *coinsjson=0; void *ctx = bitcoin_ctx();
sprintf(version,"Marketmaker %s.%s %s rsize.%ld",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER,sizeof(struct basilisk_request));
char *myipaddr=0; long filesize,n; int32_t valid,timeout; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128],*coins_str=0; cJSON *coinsjson=0; void *ctx = bitcoin_ctx();
bitcoind_RPC_inittime = 1;
if ( LP_MAXPRICEINFOS > 256 )
{
@ -1430,7 +1433,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
exit(-1);
}
LP_showwif = juint(argjson,"wif");
printf("showwif.%d %s %u\n",LP_showwif,version,calc_crc32(0,version,(int32_t)strlen(version)));
printf("showwif.%d version: %s %u\n",LP_showwif,MM_VERSION,calc_crc32(0,MM_VERSION,(int32_t)strlen(MM_VERSION)));
if ( passphrase == 0 || passphrase[0] == 0 )
{
printf("jeezy says we cant use the nullstring as passphrase and I agree\n");
@ -1505,10 +1508,10 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
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);

24
iguana/exchanges/LP_ordermatch.c

@ -198,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);
@ -221,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 )
{
@ -421,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;
@ -1023,7 +1031,7 @@ double LP_trades_pricevalidate(struct LP_quoteinfo *qp,struct iguana_info *coin,
printf("quote %s/%s validate error %.0f\n",qp->srccoin,qp->destcoin,qprice);
return(-3);
}
if ( qprice < (price - 0.00000001) * 0.998 )
if ( qprice < (price - 0.00000001) * 0.998)
{
printf(" quote price %.8f (%llu/%llu %.8f) too low vs %.8f for %s/%s price %.8f %.8f\n",qprice,(long long)qp->destsatoshis,(long long)(qp->satoshis-qp->txfee),(double)qp->destsatoshis/(qp->satoshis-qp->txfee),price,qp->srccoin,qp->destcoin,price,(price - 0.00000001) * 0.998);
return(-77);
@ -1130,7 +1138,11 @@ printf("bob %s received REQUEST.(%s) mpnet.%d fill.%d gtc.%d\n",bits256_str(str,
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;
}
@ -1771,13 +1783,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\"}"));

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

85
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)
@ -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 )
{
@ -443,7 +504,7 @@ void verus_utxos(struct iguana_info *coin,char *coinaddr)
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,numstaked,posflag,npos,npow; char hashstr[64],firstaddr[64],stakingaddr[64],*addr0,*lastaddr,*hexstr; cJSON *blockjson,*txobj,*vouts,*vout,*vout1,*sobj,*addresses,*txs;
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\"}"));
@ -472,6 +533,7 @@ char *verusblocks()
value = 0;
posflag = 0;
locked = 0;
gotblock = 0;
lastaddr = addr0 = "";
memset(script,0,sizeof(script));
memset(firstaddr,0,sizeof(firstaddr));
@ -486,6 +548,13 @@ char *verusblocks()
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
@ -505,7 +574,7 @@ char *verusblocks()
locked = ((int32_t)script[6] << 16) + ((int32_t)script[5] << 8) + script[4];
addr0 = firstaddr;
} else printf("unexpected vout1.(%s) (%s).%d %.8f\n",jprint(vout1,0),hexstr!=0?hexstr:"",(int32_t)strlen(hexstr),jdouble(vout1,"value"));
} else printf("coinbase without opret (%s)\n",jprint(vouts,0));
} //else printf("coinbase without opret (%s)\n",jprint(vouts,0));
}
}
free_json(txobj);
@ -569,7 +638,7 @@ char *verusblocks()
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 )
if ( strcmp(coinaddr,addr0) == 0 || gotblock != 0 )
powsum += value, npow++;
}
histo[locked/1000] += value;
@ -645,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 )
@ -679,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));

114
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 )
jaddistr(array,txnames[i]);
if ( rswap->sentflags[i] != 0 ) {
jaddistr(array, txnames[i]);
cJSON *tx = cJSON_CreateObject();
jaddstr(tx, "stage", txnames[i]);
jaddstr(tx, "coin", coin_name_by_tx_index(rswap, i));
#ifndef NOTETOMIC
if (LP_etomic_is_empty_tx_id(rswap->eth_tx_ids[i]) == 0) {
jaddstr(tx, "txid", rswap->eth_tx_ids[i]);
jaddnum(tx, "amount", dstr(rswap->eth_values[i]));
} else {
#endif
jaddbits256(tx, "txid", rswap->txids[i]);
jaddnum(tx, "amount", dstr(rswap->values[i]));
#ifndef NOTETOMIC
}
#endif
jaddi(tx_chain, tx);
}
if ( rswap->txbytes[i] != 0 )
free(rswap->txbytes[i]), rswap->txbytes[i] = 0;
}
jadd(item, "txChain", tx_chain);
jadd(item,"sentflags",array);
array = cJSON_CreateArray();
for (i=0; 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");

8
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));
@ -401,6 +407,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 )

19
iguana/exchanges/LP_signatures.c

@ -128,25 +128,29 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson)
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");
@ -454,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));

16
iguana/exchanges/LP_socket.c

@ -1277,7 +1277,21 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port)
jaddnum(retjson,"restart",kickval);
}
}
#ifndef NOTETOMIC
if (strcmp(coin->symbol, "ETOMIC") == 0) {
cJSON *balance = cJSON_CreateObject();
electrum_address_getbalance(coin->symbol, ep, &balance, coin->smartaddr);
int64_t confirmed = get_cJSON_int(balance, "confirmed");
int64_t unconfirmed = get_cJSON_int(balance, "unconfirmed");
if ((confirmed + unconfirmed) < 20 * SATOSHIDEN && get_etomic_from_faucet(coin->smartaddr) != 1) {
coin->inactive = (uint32_t)time(NULL);
coin->electrum = ep->prev;
cJSON_Delete(balance);
return(cJSON_Parse("{\"error\":\"Could not get ETOMIC from faucet!\"}"));
}
cJSON_Delete(balance);
}
#endif
//printf("(%s)\n",jprint(retjson,0));
return(retjson);
}

73
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,33 +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);
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));
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 ( error == 0 && LP_waitfor(swap->N.pair,swap,bobwaittimeout + alicewaittimeout,LP_verify_alicepayment) < 0 )
{
error = 1;
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 )
@ -958,7 +966,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 )
@ -1191,6 +1210,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 )
@ -1311,6 +1340,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);

99
iguana/exchanges/LP_transaction.c

@ -1117,13 +1117,13 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
preselected[numpre++] = up;
else
{
printf("couldnt add address_utxo %s/v%d after not finding\n",bits256_str(str,utxotxid),utxovout);
//printf("couldnt add address_utxo %s/v%d after not finding\n",bits256_str(str,utxotxid),utxovout);
sleep(1);
value = LP_txvalue(0,coin->symbol,utxotxid,utxovout);
LP_address_utxoadd(0,(uint32_t)time(NULL),"withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1);
if ( (up= LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout)) != 0 )
preselected[numpre++] = up;
else printf("second couldnt add address_utxo after not finding\n");
else printf("second couldnt add address_utxo %s/v%d after not finding\n",bits256_str(str,utxotxid),utxovout);
//return(0);
}
}
@ -2087,31 +2087,112 @@ char *LP_movecoinbases(char *symbol)
#ifndef NOTETOMIC
char *LP_eth_tx_fee(struct iguana_info *coin, char *dest_addr, char *amount, int64_t gas, int64_t gas_price)
{
bits256 privkey;
cJSON *retjson = cJSON_CreateObject();
int64_t actual_gas_price = 0, actual_gas = 0;
char privkey_str[70];
if (gas_price > 0) {
actual_gas_price = gas_price;
} else {
actual_gas_price = getGasPriceFromStation(0);
if (actual_gas_price == 0) {
return (clonestr("{\"error\":\"Couldn't get gas price from station!\"}"));
}
}
cJSON_AddNumberToObject(retjson, "gas_price", actual_gas_price);
if (gas > 0) {
actual_gas = gas;
} else if (strcmp(coin->symbol, "ETH") == 0) {
actual_gas = 21000;
} else {
privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr);
uint8arrayToHex(privkey_str, privkey.bytes, 32);
actual_gas = estimate_erc20_gas(coin->etomic, dest_addr, amount, privkey_str, coin->decimals);
if (actual_gas == 0) {
return (clonestr("{\"error\":\"Couldn't estimate erc20 transfer gas usage!\"}"));
}
}
cJSON_AddNumberToObject(retjson, "gas", actual_gas);
double_t eth_fee = (actual_gas_price * actual_gas) / 1000000000.0;
cJSON_AddNumberToObject(retjson, "eth_fee", eth_fee);
return(jprint(retjson,1));
}
char *LP_eth_withdraw(struct iguana_info *coin,cJSON *argjson)
{
cJSON *retjson = cJSON_CreateObject();
cJSON *gas_json = cJSON_GetObjectItem(argjson, "gas");
cJSON *gas_price_json = cJSON_GetObjectItem(argjson, "gas_price");
char *dest_addr, *tx_id, privkey_str[70], amount_str[100];
int64_t amount;
int64_t amount = 0, gas = 0, gas_price = 0, broadcast = 0;
bits256 privkey;
dest_addr = jstr(argjson, "to");
if (dest_addr == NULL) {
return(clonestr("{\"error\":\"param 'to' is required!\"}"));
}
if (isValidAddress(dest_addr) == 0) {
return(clonestr("{\"error\":\"'to' address is not valid!\"}"));
}
amount = jdouble(argjson, "amount") * 100000000;
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);
return(jprint(retjson,1));
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;

41
iguana/exchanges/LP_utxo.c

@ -699,7 +699,8 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
//printf("address balance call LP_listunspent %s electrum.%p etomic.%d\n",coin->symbol,coin->electrum,coin->etomic[0]);
#ifndef NOTETOMIC
if (coin->etomic[0] != 0) {
balance = LP_etomic_get_balance(coin, coinaddr);
int error = 0;
balance = LP_etomic_get_balance(coin, coinaddr, &error);
} else
#endif
if ( coin->electrum == 0 )
@ -787,7 +788,14 @@ cJSON *LP_balances(char *coinaddr)
}
else
{
if ( (balance= LP_RTsmartbalance(coin)) != 0 )
#ifndef NOTETOMIC
if (coin->etomic[0] == 0 || coin->inactive == 0) {
#endif
balance = LP_RTsmartbalance(coin);
#ifndef NOTETOMIC
}
#endif
if ( balance != 0 )
{
item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol);
@ -1185,7 +1193,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
return(-1);
}
destaddr[0] = destaddr2[0] = 0;
if ( coin != 0 && IAMLP != 0 && coin->inactive != 0 )
if ( coin != 0 && (strcmp(coin->symbol, "ETOMIC") == 0 || (coin->inactive != 0 && IAMLP != 0)))
bypass = 1;
if ( bypass != 0 )
val = satoshis;
@ -1209,16 +1217,27 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
strcpy(destaddr,destaddr2);
if ( coin != 0 )
{
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 )
return(0);
char txid_str[100], txid2_str[100];
bits256_str(txid_str, txid);
bits256_str(txid2_str, txid2);
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 ) {
printf("Could not find tx out: %s %d\n", txid_str, vout);
return (0);
}
else free_json(txobj);
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 )
return(0);
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 ) {
printf("Could not find tx out: %s %d\n", txid_str, vout2);
return (0);
}
else free_json(txobj);
if ( LP_numconfirms(coin->symbol,destaddr,txid,vout,0) <= 0 )
return(0);
if ( LP_numconfirms(coin->symbol,destaddr,txid2,vout2,0) <= 0 )
return(0);
if ( LP_numconfirms(coin->symbol,destaddr,txid,vout,0) <= 0 ) {
printf("Txid numconfirms is less or equal to zero: %s %d\n", txid_str, vout);
return (0);
}
if ( LP_numconfirms(coin->symbol,destaddr,txid2,vout2,0) <= 0 ) {
printf("Txid numconfirms is less or equal to zero: %s %d\n", txid2_str, vout2);
return (0);
}
}
return(1);
}

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/coins

File diff suppressed because one or more lines are too long

89
iguana/exchanges/etomicswap/etomiccurl.c

@ -1,7 +1,6 @@
#include "etomiccurl.h"
#include <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");
};
@ -186,7 +186,7 @@ char* getEthBalanceRequest(char* address)
return balance;
}
char* ethCall(char* to, const char* data)
char *ethCall(char *to, const char *data)
{
cJSON *params = cJSON_CreateArray();
cJSON *txObject = cJSON_CreateObject();
@ -196,7 +196,7 @@ char* ethCall(char* to, const char* data)
cJSON_AddItemToArray(params, cJSON_CreateString("latest"));
cJSON *resultJson = sendRpcRequest("eth_call", params);
cJSON_Delete(params);
char* result = NULL;
char *result = NULL;
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
result = (char *) malloc(strlen(resultJson->valuestring) + 1);
strcpy(result, resultJson->valuestring);
@ -205,6 +205,26 @@ char* ethCall(char* to, const char* data)
return result;
}
uint64_t estimateGas(char *from, char *to, const char *data)
{
cJSON *params = cJSON_CreateArray();
cJSON *txObject = cJSON_CreateObject();
cJSON_AddStringToObject(txObject, "from", from);
cJSON_AddStringToObject(txObject, "to", to);
cJSON_AddStringToObject(txObject, "data", data);
cJSON_AddItemToArray(params, txObject);
cJSON_AddItemToArray(params, cJSON_CreateString("latest"));
cJSON *resultJson = sendRpcRequest("eth_estimateGas", params);
cJSON_Delete(params);
uint64_t result = 0;
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
result = (uint64_t)strtoul(resultJson->valuestring, NULL, 0);
result = (result / 100) * 120; // add 20% because real gas usage might differ from estimate
}
cJSON_Delete(resultJson);
return result;
}
EthTxReceipt getEthTxReceipt(char *txId)
{
EthTxReceipt result;
@ -265,7 +285,7 @@ EthTxData getEthTxData(char *txId)
return result;
}
uint64_t getGasPriceFromStation()
uint64_t getGasPriceFromStation(uint8_t defaultOnErr)
{
CURL *curl;
CURLcode res;
@ -283,6 +303,12 @@ uint64_t getGasPriceFromStation()
curl_easy_setopt(curl, CURLOPT_URL, "https://ethgasstation.info/json/ethgasAPI.json");
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
uint64_t result;
if (defaultOnErr == 1) {
result = DEFAULT_GAS_PRICE;
} else {
result = 0;
}
/* Check for errors */
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
@ -292,9 +318,9 @@ uint64_t getGasPriceFromStation()
/* always cleanup */
curl_easy_cleanup(curl);
cJSON *resultJson = cJSON_Parse(s.ptr);
uint64_t result = DEFAULT_GAS_PRICE;
free(s.ptr);
if (resultJson == NULL) {
printf("Could not parse gas station response!\n");
return result;
}
@ -342,3 +368,40 @@ int32_t waitForConfirmation(char *txId)
return((int32_t)receipt.confirmations);
}
void unlock_send_tx_mutex()
{
pthread_mutex_unlock(&sendTxMutex);
}
uint8_t get_etomic_from_faucet(char *etomic_addr)
{
char* string;
cJSON *request = cJSON_CreateObject();
cJSON_AddStringToObject(request, "etomicAddress", etomic_addr);
string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string, FAUCET_URL);
free(string);
cJSON_Delete(request);
if (requestResult == NULL) {
return 0;
}
cJSON *json = cJSON_Parse(requestResult);
if (json == NULL) {
printf("ETOMIC faucet response parse failed!\n");
return 0;
}
cJSON *error = cJSON_GetObjectItem(json, "error");
uint8_t result = 0;
if (error != NULL && !is_cJSON_Null(error)) {
char *errorString = cJSON_PrintUnformatted(error);
printf("Got ETOMIC faucet error: %s\n", errorString);
free(errorString);
} else {
result = 1;
}
cJSON_Delete(json);
return result;
}

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
}

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

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

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

102
iguana/exchanges/mm2.md

@ -0,0 +1,102 @@
# Market Maker 2
This document will help us track the information related to the MarketMaker Rust rewrite.
## Rewrite goals
Rewrites and ports
[are costly](http://nibblestew.blogspot.com/2017/04/why-dont-you-just-rewrite-it-in-x.html).
We tend to think that porting is simple, and on some level this intuition is true
because we can skip some high-level design decisions and focus on translating the existing logic,
but it still takes a lot of time
and though we don't need to make some of the new design decisions,
we might spend no less effort to reverse-engineer and understand the old ones.
So why the rewrite then?
Carol, in her talk about rewrites, offers some possible reasons:
"*If* you have some code in C or another language, and need to change it, or it’s slow, or it crashes a
lot, or no one understands it anymore, THEN maybe a rewrite in Rust would be a good fit.
I would also posit that more people are *able* to write production Rust than production C, so if your
team *is* willing to learn Rust, it might actually expand the number of
maintainers." - https://github.com/carols10cents/rust-out-your-c-talk, https://www.youtube.com/watch?v=SKGVItFlK3w.
And we have some of these:
* We *need to change* the MarketMaker:
A more approachable and reliable API.
Ability to embed the MarketMaker in the GUI applications.
Ways to more easily deploy it at home by running it from small computers like on a spare mobile phone or on a Raspberry Pi 3.
Ability to process multiple API calls in parallel.
A faster version of the `swapstatus` API call.
* The MarketMaker *crashes a lot*,
to quote hyperDEX: "The biggest issue with the MM right now, is bobs crash or does not have the orders in users orderbook, or when users try to do a order it doesnt work or goes unmatched or other random stuff"
and lukechilds: "We've frequently experienced crashes while querying all swaps with swapstatus".
We want it to be stable and reliable instead.
## Purely functional core
One of our goals is to make the MarketMaker 2 more
[stable and reliable](https://softwareengineering.stackexchange.com/questions/158054/stability-vs-reliability).
We want it to crash less often.
If there was a failure, we want to simplify and preferably automate recovery.
And we want to reduce the time between a failure and a fix.
We'll make a big step towards these goals if the core of the MarketMaker is purely functional.
That is, if we can untangle the *state* of the MarketMaker from the code operating on that state.
The benefits we want to reap from this are:
* Transparency. Some bugs are hard to fix because we don't have enough information about them. We might be lucky to have been running the program in a debugger or finding the necessary bits it verbose logs, but more often than not this is not the case: we know that a failure has happened, but have no idea where and on what input. Separating the state from the code allows the state to be easily shared with a developer, which means much faster roundtrips between discovering a failure and fixing it.
* Replayability. Having a separate state allows us to easily replay any operation. If a failure occured in the middle of a transaction, it should be possible to try a new version of the code without manually repeating all the steps that were necessary to initiate the transaction. And the updated code will run exactly on the failing transaction, not on some other transaction initiated at a later time, which means that users will benefit from less friction and developers will have a better chance to fix the hard-to-reproduce bugs.
* Testability. Stateless code is much easier to test and according to Kent Beck is often a natural result of a Test-Driven development process.
* Portability. Separating the state from the code allows us to more easily use the stateless parts from the sandboxed environments, such as when running under the Web Assembly (WASM). We only need to port the state-managing layer, fully reusing the stateless code.
* Hot reloading. When the code is separated from state, it's trivial to reload it, both with the shared libraries in CPU-native environments (dlopen) and with WASM in GUI environments. This might positively affect the development cycle, reducing the round-trip time from a failure to a fix.
* Concurrency. MarketMaker can currently only perform a single API operation at the time. The more stateless code we have the easier it should be to introduce the parallel execution of API requests in the future.
Implementation might consist of two layers.
A layer that is ported to the host environment (native, JS, Java, Objective-C, cross-compiled Raspberry Pi 3, etc) and implements the TCP/IP communication, state management, hot reloading, all things that won't fit into the WASM sandbox.
And a layer that implements the core logic in a stateless manner and which is compiled into a native shared library or, in the future, to WASM.
Parts of the state might be marked as sensitive.
This will give the users an option to share only the information that can be freely shared,
without a risk of loosing money that is.
Even without the sensitive information a state snapshot might provide the developer with enough data to quickly triage and/or fix the failure, therefore improving the roundtrip time before a failure and a fix.
Plus users will more easily share their problems when it's quick, automatic and doesn't pose a monetary risk.
The feasibility of this approach is yet to be evaluated, but we can move gradually towards it
by separating the code into the stateful and stateless layers while working on the basic Rust port.
During the initial Rust port we're going to
a) Mark the ported functions as purely functional or stateful, allowing us to more easily focus on the state management code in the future.
b) Where possible, take a low-hanging fruit and try to refactor the functions towards being stateless.
c) Probably mark as stateful the `sleep`ing functions, because `sleep` can be seen as changing the global state (moving the time forwards) and might negatively affect Transparency (we have no idea what's going on while a function is sleeping), Testability (sleeping tests might kill the TDD development cycle), Portability (sleeps are not compatible with WASM), Hot reloading and Concurrency (let's say we want to load new version of the code, but the old version is still sleeping somewhere).
## Gradual rewrite
Above in the [Rewrite goals](#rewrite-goals) section we have identified some of the goals that we pursue with this rewrite.
These goals constitute the Value (in the Lean Production terms) that we are going to create.
For a project to suceed it is usually important to make shorter the path the Value takes to the users.
(Inventory is waste. If we have created the Value but the users can't get their hands on it, we're wasting that Value).
Hence we're going to start with a gradual rewrite. Keeping the version under rewrite immediately avaliable to the users willing to experiment with it.
Let's list the good things that should come out of the gradual rewrite:
* Transparency. With the second version of the MarketMaker being immediately available we can always check the Value we're getting. Is it more stable? Does it have new functions? Or did we hit the wall? What's going on with the code and how can we help? Gradual rewrite is critical for transparency because the change is available in small increments. We can more easily see what function has changed or what new functionality was added when we aren't being uprooted from the familiar context.
* Risk reduction. It comes with transparency, as we can now more easily measure the progress, identify the roadblocks as they occur, see certain problems when they occur and not months after. Plus a gradual rewrite will by default follow the outline of the original project. We have a working system and we're improving it piece by piece, having the original design to fall back to. This makes it less likely for the rewrite to suffer from far-reaching redesign flaws (cf. [Second-system effect](https://en.wikipedia.org/wiki/Second-system_effect)) and creative blocks (cf. [Pantsing](https://www.wikiwrimo.org/wiki/Pantsing)).
* Feedback. Incorporating user feedback is critical for most projects out there, allowing us to iteratively improve the functionality in the right direction (cf. [Fail faster](https://www.youtube.com/watch?v=rDjrOaoHz9s), [PDIA](https://www.youtube.com/watch?v=ZKdjBbiGjao)). The more early we get the feedback, the more time we have to react, and at a lesser cost.
* Motivation. Feedback is not only important to guide us, but also to show us that our work is meaningful and changes lives to the better. It is the cornerstone of Agile (["Build projects around motivated individuals"](https://www.agilealliance.org/agile101/12-principles-behind-the-agile-manifesto/)) and affects our performance on all levels, down to the physical health.
The plan so far is to by default use the C functions as the atomic units of rewrite.
Rust FFI allows us to swap any C function with a similar Rust function.
Porting on this level we
* reuse the function-level modularity of the C language;
* preserve the code meta-data (Git history will show a nice diff between the C and Rust functions, we'll be able to easily investigate the evolution of the code back to its roots);
* avoid the complexity and slow-downs associated with adding RPC/networking layers or drawing new lines of abstraction;
* have a good indicator of the porting progress (how many functions were ported, how many remains).
Focusing on the function call chains that are a common part of a failure/crash or touch on the new functionality
will allow us to leverage the [Pareto principle](https://en.wikipedia.org/wiki/Pareto_principle),
advancing on 80% of desired Value (stability, functionality) with 20% of initial effort.

2
iguana/exchanges/mshark

@ -1,4 +1,4 @@
#!/bin/bash
source userpass
# this will only work for watchonly addresses that have been rescanned and with active coins
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC\",\"holdings\":[{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"bitcoin-cash\",\"balance\":1200}, {\"coin\":\"bitcoin\",\"balance\":100}, {\"coin\":\"komodo\",\"balance\":100000}, {\"coin\":\"chips\",\"balance\":100000}],\"divisor\":1400000}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC\",\"holdings\":[{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"bitcoin-cash\",\"balance\":1200}, {\"coin\":\"bitcoin\",\"balance\":25}],\"divisor\":1400000}"

6
iguana/exchanges/prices/autoprice

@ -35,15 +35,15 @@ source trackbtc
#source revs
#source trackbtc
sharkholdings="{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"komodo\",\"balance\":120000}, {\"coin\":\"bitcoin-cash\",\"balance\":1200}, {\"coin\":\"bitcoin\",\"balance\":100}"
sharkholdings="{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"bitcoin-cash\",\"balance\":1200}, {\"coin\":\"bitcoin\",\"balance\":25}"
curl --url "http://127.0.0.1:7783" --data "{\"base\":\"MSHARK\",\"rel\":\"KMD\",\"fundvalue_bid\":\"NAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"margin\":$margin,\"address\":\"RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC\",\"holdings\":[$sharkholdings],\"divisor\":1400000}"
curl --url "http://127.0.0.1:7783" --data "{\"margin\":$margin,\"base\":\"SUPERNET\",\"rel\":\"KMD\",\"fundvalue_bid\":\"NAV_KMD\",\"fundvalue_ask\":\"NAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":0.10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":570}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":0.20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":0.150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":0.375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }, {\"coin\":\"utrum\",\"balance\":2100000}, {\"coin\":\"verus\",\"balance\":65000}],\"divisor\":612529}"
curl --url "http://127.0.0.1:7783" --data "{\"margin\":$margin,\"base\":\"SUPERNET\",\"rel\":\"KMD\",\"fundvalue_bid\":\"NAV_KMD\",\"fundvalue_ask\":\"NAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":0.10000}, {\"coin\":\"syscoin\",\"balance\":0.20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":540}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":0.20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":0.150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":0.375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }, {\"coin\":\"utrum\",\"balance\":2100000}, {\"coin\":\"verus\",\"balance\":65000}],\"divisor\":777777}"
curl --url "http://127.0.0.1:7783" --data "{\"margin\":$margin,\"base\":\"HODL\",\"rel\":\"KMD\",\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RNcUaMUEFLxVwtTo7rgruhwYanGk1jTkeU\",\"holdings\":[{\"coin\":\"siacoin\",\"balance\":185000000,\"comment\":\"using siafunds equal to million siacoin\"}],\"divisor\":10000000}"
dexholdings="{\"coin\":\"blocknet\",\"balance\":2500000}"
dexholdings="{\"coin\":\"blocknet\",\"balance\":2000000}"
curl --url "http://127.0.0.1:7783" --data "{\"base\":\"DEX\",\"rel\":\"KMD\",\"margin\":$margin,\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf\",\"holdings\":[$dexholdings],\"divisor\":1000000}"
curl --url "http://127.0.0.1:7783" --data "{\"base\":\"BOTS\",\"rel\":\"KMD\",\"margin\":$margin,\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RNdqHx26GWy9bk8MtmH1UiXjQcXE4RKK2P\",\"holdings\":[$dexholdings],\"divisor\":3333333}"

2
iguana/exchanges/supernet

@ -15,5 +15,5 @@ echo supernet
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}"
echo supernet
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":0.10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":570}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":0.20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":0.150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":0.375000}, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }, {\"coin\":\"utrum\",\"balance\":2350000}, {\"coin\":\"verus\",\"balance\":65000}],\"divisor\":612529}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":0.10000}, {\"coin\":\"syscoin\",\"balance\":0.20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":540}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":0.20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":0.150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":0.375000}, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }, {\"coin\":\"utrum\",\"balance\":2350000}, {\"coin\":\"verus\",\"balance\":65000}],\"divisor\":777777}"

2
iguana/iguana_notary.c

@ -535,7 +535,7 @@ STRING_ARG(iguana,addnotary,ipaddr)
}
char NOTARY_CURRENCIES[][65] = {
"REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "BOTS", "MGW", "COQUI", "WLC", "KV", "CEAL", "MESH", "MNZ", "CHIPS", "MSHARK", "AXO", "ETOMIC", "BTCH", "VOTE2018", "NINJA", "OOT", "CHAIN", "BNTN", "PRLPAY", "DSEC", "GLXT", "EQL" "ZILLA"
"REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "BOTS", "MGW", "COQUI", "WLC", "KV", "CEAL", "MESH", "MNZ", "CHIPS", "MSHARK", "AXO", "ETOMIC", "BTCH", "VOTE2018", "NINJA", "OOT", "CHAIN", "BNTN", "PRLPAY", "DSEC", "GLXT", "EQL", "ZILLA", "RFOX", "SEC"
};
// "LTC", "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK",

2
iguana/m_notary

@ -2,4 +2,4 @@
pkill -15 iguana
rm -f ../agents/iguana *.o
git pull
./m_notary_run $1
./m_notary_run "$1" "$2"

6
iguana/m_notary_run

@ -8,7 +8,8 @@ clang -g -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../b
clang -g -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c
clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm
stdbuf -oL $1 ../agents/iguana notary & #> iguana.log 2> error.log &
iguana_arg=${2:-notary}
stdbuf -oL $1 ../agents/iguana $iguana_arg & #> iguana.log 2> error.log &
myip=`curl -s4 checkip.amazonaws.com`
source pubkey.txt
@ -25,6 +26,8 @@ curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"ad
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"138.121.203.210\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"139.99.149.41\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"209.58.169.65\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"5.189.232.34\"}"
#tests/addnotarys_7776
coins/btc_7776
@ -66,6 +69,7 @@ coins/eql_7776
coins/zilla_7776
coins/vrsc_7776
coins/rfox_7776
coins/sec_7776
#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"passthru\",\"method\":\"paxfiats\",\"timeout\":900000}"

2
iguana/m_splitfund

@ -36,3 +36,5 @@ curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DSEC\",\"agent\":\"iguana
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"GLXT\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"EQL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ZILLA\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RFOX\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SEC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"10000\",\"sendflag\":1,\"duplicates\":50}"

60
marketmaker_build_depends.cmd

@ -36,54 +36,66 @@ exit
rem MSBuild /help
echo.
echo Decker will automatically download and build all needed *.dll and *.lib for you ;)
timeout /t 5 /nobreak
mkdir marketmaker_depends
mkdir x64\Release
rem --- pthreads ---
:compile_pthreads
if not exist marketmaker_depends\pthread-win32\bin\x64_MSVC2015.Release\pthread_lib.lib (
cd marketmaker_depends
git clone https://github.com/DeckerSU/pthread-win32
cd pthread-win32
MSBuild pthread.2015.sln /t:Rebuild /p:Configuration=Release /p:Platform=Win32
MSBuild pthread.2015.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64
cd ../..
)
copy marketmaker_depends\pthread-win32\bin\x64_MSVC2015.Release\pthread_lib.lib OSlibs\win\x64\pthread_lib.lib
rem --- nanomsg ---
:compile_nanomsg
cd marketmaker_depends
git clone https://github.com/nanomsg/nanomsg
cd nanomsg
mkdir build_msvc_2015_win32
mkdir build_msvc_2015_win64
cd build_msvc_2015_win64
cmake -G "Visual Studio 14 2015 Win64" ..
cmake --build . --config Release --target nanomsg
cd ../../..
if not exist marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.lib (
if not exist marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.exp (
if not exist marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.dll (
cd marketmaker_depends
git clone https://github.com/nanomsg/nanomsg
cd nanomsg
mkdir build_msvc_2015_win32
mkdir build_msvc_2015_win64
cd build_msvc_2015_win64
cmake -G "Visual Studio 14 2015 Win64" ..
cmake --build . --config Release --target nanomsg
cd ../../..
)
)
)
copy marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.lib OSlibs\win\x64\release\nanomsg.lib
copy marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.exp OSlibs\win\x64\release\nanomsg.exp
copy marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.dll x64\Release\nanomsg.dll
rem --- curl ---
:compile_curl
cd marketmaker_depends
git clone https://github.com/curl/curl
cd curl
mkdir build_msvc_2015_win32
mkdir build_msvc_2015_win64
cd build_msvc_2015_win64
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_USE_WINSSL:BOOL=ON ..
cmake --build . --config Release --target libcurl
if not exist marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.lib (
if not exist marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.exp (
if not exist marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl.dll (
cd marketmaker_depends
git clone https://github.com/curl/curl
cd curl
mkdir build_msvc_2015_win32
mkdir build_msvc_2015_win64
cd build_msvc_2015_win64
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_USE_WINSSL:BOOL=ON ..
cmake --build . --config Release --target libcurl
rem cmake .. -G"Visual Studio 14 2015 Win64" -DCURL_STATICLIB=ON -DCURL_DISABLE_LDAP=ON -DCURL_STATIC_CRT=ON
rem cmake .. -G"Visual Studio 14 2015 Win64" -DCURL_STATICLIB:BOOL=ON -DCURL_STATIC_CRT:BOOL=ON -DHTTP_ONLY:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=RELEASE ..
rem cmake --build . --config Release
rem cmake --build . --config Release --target libcurl
rem cmake .. -G"Visual Studio 14 2015 Win64" -DCURL_STATICLIB=ON -DCURL_DISABLE_LDAP=ON -DCURL_STATIC_CRT=ON
rem cmake .. -G"Visual Studio 14 2015 Win64" -DCURL_STATICLIB:BOOL=ON -DCURL_STATIC_CRT:BOOL=ON -DHTTP_ONLY:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=RELEASE ..
rem cmake --build . --config Release
rem cmake --build . --config Release --target libcurl
cd ../../..
cd ../../..
)
)
)
copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.lib OSlibs\win\x64\release\libcurl.lib
copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.exp OSlibs\win\x64\release\libcurl.exp
copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl.dll x64\Release\libcurl.dll

5
marketmaker_build_etomic.cmd

@ -7,16 +7,13 @@ copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.lib
copy marketmaker_depends\pthread-win32\bin\x64_MSVC2015.Release\pthread_lib.lib marketmaker_depends\pthread-win32\bin\x64_MSVC2015.Release\pthread.lib
echo [#2] Prepare build etomic needed things ...
git submodule init
git submodule update --init --recursive
cd cpp-ethereum
rem git submodule init
rem git submodule update --init
call scripts\install_deps.bat
cd ..
mkdir build_win64_release
cd build_win64_release
cmake .. -G "Visual Studio 14 2015 Win64"
cmake .. -G "Visual Studio 14 2015 Win64" -DMM_VERSION="%APPVEYOR_BUILD_VERSION%"
rem Steps before build:
rem

8
start_BEER_OTHER_trade.sh

@ -0,0 +1,8 @@
#!/bin/bash
docker-compose exec -T clientnode ./enable
sleep 3
docker-compose exec -T seednode ./enable
sleep 3
docker-compose exec -T seednode ./sell_BEER_OTHER $1
sleep 3
docker-compose exec -T clientnode ./buy_BEER_OTHER $1

8
start_BEER_OTHER_trade_inverted.sh

@ -0,0 +1,8 @@
#!/bin/bash
docker-compose exec -T clientnode ./enable
sleep 3
docker-compose exec -T seednode ./enable
sleep 3
docker-compose exec -T clientnode ./buy_BEER_OTHER $1
sleep 3
docker-compose exec -T seednode ./sell_BEER_OTHER $1

5
travis_cmake_linux.sh

@ -0,0 +1,5 @@
#!/bin/bash
sudo rm -rf /usr/local/cmake-3.9.2 && sudo rm -rf /usr/local/cmake
wget https://cmake.org/files/v3.12/cmake-3.12.0-rc2-Linux-x86_64.sh
chmod +x cmake-3.12.0-rc2-Linux-x86_64.sh
sudo ./cmake-3.12.0-rc2-Linux-x86_64.sh --skip-license --exclude-subdir --prefix=/usr/local

6
travis_cmake_mac.sh

@ -0,0 +1,6 @@
#!/bin/bash
brew uninstall cmake --force
wget https://cmake.org/files/v3.12/cmake-3.12.0-rc2-Darwin-x86_64.tar.gz
tar -xzf cmake-3.12.0-rc2-Darwin-x86_64.tar.gz
cp -r cmake-3.12.0-rc2-Darwin-x86_64/CMake.app/Contents/bin/* /usr/local/bin/
cp -r cmake-3.12.0-rc2-Darwin-x86_64/CMake.app/Contents/share/* /usr/local/share/
Loading…
Cancel
Save