jl777
7 years ago
committed by
GitHub
503 changed files with 16506 additions and 4050 deletions
Binary file not shown.
Binary file not shown.
@ -0,0 +1,25 @@ |
|||||
|
## What's this? |
||||
|
|
||||
|
This is a first build of **MarketMaker** app from barterDEX for Windows (64-bit) platform. This branch includes all that you need to build marketmaker for Windows. 64-bit build uses MSVC 2015 as a default C/C++ compiler, to build - simply open *marketmaker.sln* project file via File -> Open -> Project/Solution ... next choose Release / x64 configuration and build solution. Your binaries will be placed x64\Release folder. To run marketmaker you also need following dll libraries: |
||||
|
|
||||
|
- libcurl.dll |
||||
|
- nanomsg.dll |
||||
|
- curl.exe (win64 curl binary, used is scripts) |
||||
|
|
||||
|
It already included in this branch. |
||||
|
|
||||
|
## How to use? |
||||
|
|
||||
|
Please, refer to original barterDEX documentation and Komodo Platform + SuperNET resources to learn how to work this it. Later i will add some examples and useful links here. |
||||
|
|
||||
|
Important, coins.json on Windows shouldn't contain coins which haven't running daemons. Add to coins.json only coins that you plan to use, in other case starting marketmaker will too long: about 4 seconds on each not-running coin. |
||||
|
|
||||
|
Get the latest binary release from release section and step-by-step run cmd files: |
||||
|
|
||||
|
- 1-client.cmd - this runs marketmaker with passphrase taken from a passphrase file. |
||||
|
- 2-getuserpass.cmd - this will save and output your userpass in userpass file for future use. |
||||
|
- 3-orderbook.cmd - to get an orderbook (if u downloaded binary release from release section - it's have only REVS in coins.json and orderbook will be shown at KMD/REVS coins pair). |
||||
|
|
||||
|
Other scripts will be post later ... this is just for example that it works. |
||||
|
|
||||
|
|
@ -0,0 +1,2 @@ |
|||||
|
curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"MNZ.conf\",\"path\":\"${HOME#"/"}/.komodo/MNZ\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MNZ\",\"name\":\"MNZ\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"53d06fde\",\"p2p\":14336,\"rpc\":14337,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" |
||||
|
|
@ -0,0 +1,2 @@ |
|||||
|
#!/bin/bash |
||||
|
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"chips.conf\",\"path\":\"${HOME#"/"}/.chips\",\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"CHIPS\",\"startpend\":64,\"endpend\":64,\"services\":0,\"maxpeers\":512,\"RELAY\":-1,\"VALIDATE\":0,\"portp2p\":57777,\"minconfirms\":1,\"pubval\":60,\"p2shval\":85,\"wifval\":188}" |
@ -0,0 +1,2 @@ |
|||||
|
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MNZ.conf\",\"path\":\"${HOME#"/"}/.komodo/MNZ\",\"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\":\"MNZ\",\"name\":\"MNZ\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"53d06fde\",\"p2p\":14336,\"rpc\":14337,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" |
||||
|
|
@ -0,0 +1,16 @@ |
|||||
|
@echo off |
||||
|
set USERHOME=%APPDATA:\=\\% |
||||
|
rem [!] Coins config now taked from coins.json file, no need to put in environment variable |
||||
|
rem --------------------------------------------------------------------------------------- |
||||
|
rem set COINS=[{\"coin\":\"REVS\",\"active\":1,\"asset\":\"REVS\",\"rpcport\":10196}] |
||||
|
rem marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\", \"passphrase\":\"mypassphrase\", \"coins\":%COINS%}" |
||||
|
|
||||
|
set COINS=\"\" |
||||
|
set /p PASSPHRASE=<passphrase |
||||
|
rem , \"canbind\":1 |
||||
|
rem marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\", \"passphrase\":\"%PASSPHRASE%\"}" 1> marketmaker.log 2>&1 |
||||
|
marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\", \"passphrase\":\"%PASSPHRASE%\"}" |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,7 @@ |
|||||
|
@echo off |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":null,\"method\":\"enable\",\"coin\":\" \"}" -s > userpass.json |
||||
|
for /f "tokens=2 delims=:," %%a in (' find "userpass" "userpass.json" ') do ( |
||||
|
echo UserPass: %%~a |
||||
|
echo %%~a > userpass |
||||
|
) |
||||
|
del userpass.json |
@ -0,0 +1,4 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"balance\",\"coin\":\"KMD\",\"address\":\"RSpP2Nffy379SwF1cAkooNg6vwPHpakCpC\"}" |
@ -0,0 +1,7 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
set /p PASSPHRASE=<passphrase |
||||
|
echo passphrase: "%PASSPHRASE%" |
||||
|
echo userpass: "%USERPASS%" |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"bot_buy\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"maxprice\":0.20,\"relvolume\":10.0}" |
@ -0,0 +1,7 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
set /p PASSPHRASE=<passphrase |
||||
|
rem echo passphrase: "%PASSPHRASE%" |
||||
|
rem echo userpass: "%USERPASS%" |
||||
|
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"bot_list\"}" |
@ -0,0 +1,7 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
set /p PASSPHRASE=<passphrase |
||||
|
rem echo passphrase: "%PASSPHRASE%" |
||||
|
rem echo userpass: "%USERPASS%" |
||||
|
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"bot_statuslist\"}" |
@ -0,0 +1,7 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
set /p PASSPHRASE=<passphrase |
||||
|
rem echo passphrase: "%PASSPHRASE%" |
||||
|
rem echo userpass: "%USERPASS%" |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"bot_stop\",\"botid\":1376557535}" |
Binary file not shown.
@ -0,0 +1,9 @@ |
|||||
|
@echo off |
||||
|
rem http://pad.supernet.org/electrum-servers |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
set /p PASSPHRASE=<passphrase |
||||
|
echo passphrase: "%PASSPHRASE%" |
||||
|
echo userpass: "%USERPASS%" |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"electrum\",\"coin\":\"KMD\",\"ipaddr\":\"electrum.cipig.net\",\"port\":10001}" |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"electrum\",\"coin\":\"MNZ\",\"ipaddr\":\"electrum.cipig.net\",\"port\":10002}" |
@ -0,0 +1,4 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"enable\",\"coin\":\"REVS\"}" |
@ -0,0 +1,4 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"getcoin\",\"coin\":\"KMD\"}" |
@ -0,0 +1,4 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"getutxos\",\"coin\":\"KMD\"}" |
@ -0,0 +1,2 @@ |
|||||
|
@echo off |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"method\":\"help\"}" |
@ -0,0 +1,100 @@ |
|||||
|
## DexScripts for Windows. How to use? ## |
||||
|
|
||||
|
**1.** Before start you should put scripts and following binaries into one folder: |
||||
|
|
||||
|
- curl.exe (required for all scripts) |
||||
|
- marketmaker.exe |
||||
|
- libcurl.dll (required to run marketmaker) |
||||
|
- nanomsg.dll (required to run marketmaker) |
||||
|
|
||||
|
**2.** Don't forget to put `coins.json` file into a same folder. This file is available it this repo. |
||||
|
|
||||
|
**3.** Type your passphrase into passphrase file in this folder (you should create file with name `passphrase` and without extension) and run `1-client.cmd`. This will run marketmaker. Next step is to obtain userpass needed for other scripts, you can simply copy and paste it from marketmaker output on startup into userpass file. |
||||
|
|
||||
|
![](./images/userpass.png) |
||||
|
|
||||
|
Or run `2-getuserpass.cmd` to fill userpass file automatically.** NB!** To get userpass you shouldn't run any scripts between 1-client.cmd and 2-getuserpass.cmd launching. |
||||
|
|
||||
|
Sample output of correct `2-getuserpass.cmd` usage is: |
||||
|
|
||||
|
![](./images/userpass_usage.png) |
||||
|
|
||||
|
You should see your userpass on screen, and after it will automatically copied in userpass file. It's important to all other scripts to have this password in userpass file. If output of `2-getuserpass.cmd` is not same as showed on screen above - wait some seconds and run `2-getuserpass.cmd` again. Also make sure that you have allowed marketmaker to accept incoming connections in your Windows Firewall (first time launched system should automatically asked for it). |
||||
|
|
||||
|
**4.** For using other scripts please refer to barterDEX API. Or **barterDEX API Summary by Category** document by *shossain*. |
||||
|
|
||||
|
## Scripts List ## |
||||
|
|
||||
|
**NB!** Before you use any script that do some actions with your coins (for example, withdraw and others) **edit it** and make sure that it have correct addresses, coin name and volumes inside. Don't run any scripts without looking on it's source and clearly understanding what it does. |
||||
|
|
||||
|
* **1-client.cmd** - used to start Marketmaker. Make sure you already have filled a strong passphrase into `passphrase` file as described above. |
||||
|
* **2-getuserpass.cmd** - fills userpass in `userpass` file. this step needed to use any other scripts. |
||||
|
* **balance.cmd** - displays current balance of selected coin. |
||||
|
* **enable.cmd** - enables a selected coin for trading. |
||||
|
* **getcoin.cmd** - prints information about a selecting coin: |
||||
|
|
||||
|
|
||||
|
{"result":"success","enabled":2,"disabled":70,"coin":{"coin":"KMD","installed":true,"height":580716,"balance":72.68774305,"KMDvalue":72.68774305,"status":"active","electrum":"electrum.cipig.net:10001","smartaddress":"RTCVGuoSNehKG8YYxcoskC7LK1yZhgvQRV","rpc":"127.0.0.1:7771","pubtype":60,"p2shtype":85,"wiftype":188,"txfee":10000}} |
||||
|
|
||||
|
|
||||
|
* **getutxos.cmd** - seems alredy deprecated. |
||||
|
* **inventory.cmd** - prints your inventory. |
||||
|
* **listunspent.cmd** - prints your utxos. |
||||
|
* **orderbook.cmd** - prints base/rel orderbook. |
||||
|
* **portfolio.cmd** - prints porfolio information. |
||||
|
* **snapshot.cmd** - ... |
||||
|
* **electrum.cmd** - allows you to run coins in electum mode (!), example includes two coins - KMD and MNZ. if you need to run more coins in electrum mode, add needed electrum servers from here - [http://pad.supernet.org/electrum-servers](http://pad.supernet.org/electrum-servers). |
||||
|
* **help.cmd** - displays help about all available API commands. |
||||
|
* **bot_buy.cmd** - launches bot for buying. you'll need to set base and rel coin in script, and also maxprice and relvolume. |
||||
|
* **bot_list.cmd** - lists id of all running bots. |
||||
|
* **bot_statuslist.cmd** - list statuses of all running bots. |
||||
|
* **bot_stop.cmd** - stopt the bot with given bot_id. |
||||
|
* **withdraw.cmd** - example of withdraw method. you can send coins from your smartaddress to any other address using widthraw. as a result method generates signed raw tx in hex, which you can use with sendrawtransaction.cmd . remember, that withdraw only *prepares* transaction, but it doesn't broadcast (send) it to network. after tx is prepared we need to send it using sendrawtransaction method. |
||||
|
* **sendrawtransaction.cmd** - sends raw transaction. you'll need a signedtx in hex. |
||||
|
* **withdraw_send.cmd** - combines withdraw and send raw tx scripts. you can call it `send`, just specify coin, volume and addresses to which you wan send coins and it will prepare and broadcast transaction automatically. |
||||
|
* **withdraw_10_send.cmd** - example of inventory split: this split 10 KMD from your balance to Alice inventory in 10 utxos pairs (1.002, 0.00386871). Strongly recommended to read [http://pad.supernet.org/barterdex-readme](http://pad.supernet.org/barterdex-readme) -> UTXO PAIRS to understand the basics. This script is just for example how you can split your coins in (X, X/777) to start trading them. |
||||
|
|
||||
|
## F.A.Q. ## |
||||
|
|
||||
|
**Q.** Is any simple way how i can display JSON results returned by all scripts, like orderbook and others, in human readable form? |
||||
|
|
||||
|
**A.** Yes, you can use this service [JSON Editor Online](http://jsoneditoronline.org/), just copy and paste output of script in left column and see structured output in right. |
||||
|
|
||||
|
**Q.** I see an output like this when i'm start `1-client.cmd` : |
||||
|
|
||||
|
bind(0.0.0.0) port.7783 failed: No error sock.1468. errno.0 |
||||
|
bind(0.0.0.0) port.7783 failed: No error sock.1516. errno.0 |
||||
|
bind(0.0.0.0) port.7783 failed: No error sock.1444. errno.0 |
||||
|
bind(0.0.0.0) port.7783 failed: No error sock.1484. errno.0 |
||||
|
bind(0.0.0.0) port.7783 failed: No error sock.1412. errno.0 |
||||
|
bind(0.0.0.0) port.7783 failed: No error sock.1524. errno.0 |
||||
|
bind(0.0.0.0) port.7783 failed: No error sock.1008. errno.0 |
||||
|
|
||||
|
And nothing works. |
||||
|
|
||||
|
**A.** Before run `1-client.cmd` make sure in Task Manager that you haven't already running `marketmaker.exe`. If have - kill this process via Task Manager or via command line command `taskkill /f /im taskkill.exe` . |
||||
|
|
||||
|
**Q.** How can i pretty print JSON answers of marketmaker? |
||||
|
|
||||
|
**A.** You can get best results with 2 tools - [conemu](https://conemu.github.io/) and [jq](https://stedolan.github.io/jq/), conemu supports ANSI X3.64 and Xterm 256 colors and jq allow you to pretty-print json output with colors, like this: |
||||
|
|
||||
|
![](./images/conemu_jq.png) |
||||
|
|
||||
|
Also i'm always recommend to install [Far Manager](https://www.farmanager.com/index.php?l=en) - this is powerful console file manager for Windows, like Midnight Commander in *nix. |
||||
|
|
||||
|
**Q.** What additional dependencies required by marketmaker? |
||||
|
|
||||
|
**A.** Currently marketmaker (Windows) used the following DLLs: |
||||
|
|
||||
|
*32 bit:* |
||||
|
- libcrypto-1_1.dll |
||||
|
- libcurl.dll |
||||
|
- libssl-1_1.dll |
||||
|
- nanomsg.dll |
||||
|
- pthreadvc2.dll |
||||
|
|
||||
|
*64-bit:* |
||||
|
- libcurl.dll |
||||
|
- nanomsg.dll |
||||
|
|
||||
|
It already included in repo and in archive with release. |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,4 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"inventory\",\"coin\":\"KMD\"}" |
@ -0,0 +1,4 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"listunspent\",\"coin\":\"KMD\",\"address\":\"RSpP2Nffy379SwF1cAkooNg6vwPHpakCpC\"}" |
@ -0,0 +1,4 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"orderbook\",\"base\":\"KMD\",\"rel\":\"REVS\"}" |
@ -0,0 +1 @@ |
|||||
|
your_very_strong_secret_passphrase |
@ -0,0 +1,4 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"portfolio\"}" |
@ -0,0 +1,5 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
set HEX=your_signed_raw_tx |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"sendrawtransaction\",\"coin\":\"KMD\",\"signedtx\":%HEX%"\"}" |
@ -0,0 +1,5 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"snapshot\",\"coin\":\"KMD\",\"height\":%1}" |
||||
|
|
@ -0,0 +1,8 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
rem *** Change coin and outputs before use (!) *** |
||||
|
set COIN=KMD |
||||
|
set OUTPUTS=[{\"RDecker69MM5dhDBosUXPNTzfoGqxPQqHu\":0.00007777}] |
||||
|
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"withdraw\",\"coin\":\"%COIN%\",\"outputs\":%OUTPUTS%}" > withdraw.txt |
||||
|
type withdraw.txt |
@ -0,0 +1,14 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
rem *** Change coin and outputs before use (!) *** |
||||
|
set COIN=KMD |
||||
|
set SMARTADDRESS=RDecker69MM5dhDBosUXPNTzfoGqxPQqHu |
||||
|
set OUTPUTS=[{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871}] |
||||
|
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"withdraw\",\"coin\":\"%COIN%\",\"outputs\":%OUTPUTS%}" > withdraw.txt |
||||
|
type withdraw.txt |
||||
|
timeout /t 5 /nobreak |
||||
|
for /f "tokens=4 delims=:," %%a in (' find "hex" "withdraw.txt" ') do ( |
||||
|
rem echo [%%~a] |
||||
|
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"sendrawtransaction\",\"coin\":\"%COIN%\",\"signedtx\":\"%%~a\"}" |
||||
|
) |
@ -0,0 +1,14 @@ |
|||||
|
@echo off |
||||
|
set /p TMPUSERPASS=<userpass |
||||
|
set USERPASS=%TMPUSERPASS: =% |
||||
|
rem *** Change coin and outputs before use (!) *** |
||||
|
set COIN=KMD |
||||
|
set OUTPUTS=[{\"RDecker69MM5dhDBosUXPNTzfoGqxPQqHu\":0.00007777}] |
||||
|
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"withdraw\",\"coin\":\"%COIN%\",\"outputs\":%OUTPUTS%}" > withdraw.txt |
||||
|
type withdraw.txt |
||||
|
timeout /t 5 /nobreak |
||||
|
for /f "tokens=4 delims=:," %%a in (' find "hex" "withdraw.txt" ') do ( |
||||
|
rem echo [%%~a] |
||||
|
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"sendrawtransaction\",\"coin\":\"%COIN%\",\"signedtx\":\"%%~a\"}" |
||||
|
) |
||||
|
|
@ -0,0 +1,291 @@ |
|||||
|
|
||||
|
/******************************************************************************
|
||||
|
* Copyright © 2014-2017 The SuperNET Developers. * |
||||
|
* * |
||||
|
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * |
||||
|
* the top-level directory of this distribution for the individual copyright * |
||||
|
* holder information and the developer policies on copyright and licensing. * |
||||
|
* * |
||||
|
* Unless otherwise agreed in a custom licensing agreement, no part of the * |
||||
|
* SuperNET software, including this file may be copied, modified, propagated * |
||||
|
* or distributed except according to the terms contained in the LICENSE file * |
||||
|
* * |
||||
|
* Removal or modification of this copyright notice is prohibited. * |
||||
|
* * |
||||
|
******************************************************************************/ |
||||
|
//
|
||||
|
// LP_RTmetrics.c
|
||||
|
// marketmaker
|
||||
|
//
|
||||
|
|
||||
|
struct LP_metricinfo |
||||
|
{ |
||||
|
double metric; |
||||
|
double price,balance,minvol; |
||||
|
bits256 pubkey; |
||||
|
double maxvol; |
||||
|
int32_t ind,numutxos,age,pendingswaps; |
||||
|
}; |
||||
|
|
||||
|
struct LP_RTmetrics_pendings |
||||
|
{ |
||||
|
char refbase[65],refrel[65]; |
||||
|
int32_t numswaps,numavoidtxids,numwhitelist,numblacklist,numpendings,pending_swaps[1024]; |
||||
|
bits256 avoidtxids[8192],whitelist[1024],blacklist[1024],pending_pubkeys[1024]; |
||||
|
} LP_RTmetrics; |
||||
|
|
||||
|
int32_t LP_bits256_find(bits256 *list,int32_t num,bits256 val) |
||||
|
{ |
||||
|
int32_t i; |
||||
|
if ( bits256_nonz(val) != 0 ) |
||||
|
{ |
||||
|
for (i=0; i<num; i++) |
||||
|
if ( bits256_cmp(list[i],val) == 0 ) |
||||
|
return(i); |
||||
|
} |
||||
|
return(-1); |
||||
|
} |
||||
|
|
||||
|
int32_t LP_bits256_add(char *debugstr,bits256 *list,int32_t *nump,int32_t maxnum,bits256 val) |
||||
|
{ |
||||
|
if ( bits256_nonz(val) != 0 && *nump < maxnum ) |
||||
|
{ |
||||
|
if ( LP_bits256_find(list,*nump,val) < 0 ) |
||||
|
list[(*nump)++] = val; |
||||
|
return(*nump); |
||||
|
} else printf("%s[%d] overflow\n",debugstr,*nump); |
||||
|
return(-1); |
||||
|
} |
||||
|
|
||||
|
int32_t LP_RTmetrics_avoidadd(bits256 txid) |
||||
|
{ |
||||
|
return(LP_bits256_add("LP_RTmetrics_avoidadd avoidtxids",LP_RTmetrics.avoidtxids,&LP_RTmetrics.numavoidtxids,(int32_t)(sizeof(LP_RTmetrics.avoidtxids)/sizeof(*LP_RTmetrics.avoidtxids)),txid)); |
||||
|
} |
||||
|
|
||||
|
int32_t LP_RTmetrics_whitelistadd(bits256 pubkey) |
||||
|
{ |
||||
|
return(LP_bits256_add("LP_RTmetrics_whitelistadd whitelist",LP_RTmetrics.whitelist,&LP_RTmetrics.numwhitelist,(int32_t)(sizeof(LP_RTmetrics.whitelist)/sizeof(*LP_RTmetrics.whitelist)),pubkey)); |
||||
|
} |
||||
|
|
||||
|
int32_t LP_RTmetrics_blacklistadd(bits256 pubkey) |
||||
|
{ |
||||
|
return(LP_bits256_add("LP_RTmetrics_blacklistadd blacklist",LP_RTmetrics.blacklist,&LP_RTmetrics.numblacklist,(int32_t)(sizeof(LP_RTmetrics.blacklist)/sizeof(*LP_RTmetrics.blacklist)),pubkey)); |
||||
|
} |
||||
|
|
||||
|
int32_t LP_RTmetrics_pendingswap(bits256 pubkey) |
||||
|
{ |
||||
|
int32_t ind; |
||||
|
if ( (ind= LP_bits256_add("LP_RTmetrics_pendingswap",LP_RTmetrics.pending_pubkeys,&LP_RTmetrics.numpendings,(int32_t)(sizeof(LP_RTmetrics.pending_pubkeys)/sizeof(*LP_RTmetrics.pending_pubkeys)),pubkey)) >= 0 ) |
||||
|
LP_RTmetrics.pending_swaps[ind]++; |
||||
|
return(ind); |
||||
|
} |
||||
|
|
||||
|
int32_t LP_RTmetrics_pendingswaps(bits256 pubkey) |
||||
|
{ |
||||
|
int32_t ind; |
||||
|
if ( (ind= LP_bits256_find(LP_RTmetrics.pending_pubkeys,LP_RTmetrics.numpendings,pubkey)) >= 0 ) |
||||
|
return(LP_RTmetrics.pending_swaps[ind]); |
||||
|
else return(0); |
||||
|
} |
||||
|
|
||||
|
int32_t LP_RTmetrics_avoidtxid(bits256 txid) |
||||
|
{ |
||||
|
return(LP_bits256_find(LP_RTmetrics.avoidtxids,LP_RTmetrics.numavoidtxids,txid)); |
||||
|
} |
||||
|
|
||||
|
int32_t LP_RTmetrics_whitelisted(bits256 pubkey) |
||||
|
{ |
||||
|
return(LP_bits256_find(LP_RTmetrics.whitelist,LP_RTmetrics.numwhitelist,pubkey)); |
||||
|
} |
||||
|
|
||||
|
int32_t LP_RTmetrics_blacklisted(bits256 pubkey) |
||||
|
{ |
||||
|
return(LP_bits256_find(LP_RTmetrics.blacklist,LP_RTmetrics.numblacklist,pubkey)); |
||||
|
} |
||||
|
|
||||
|
void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t numswaps) |
||||
|
{ |
||||
|
int32_t i; char *base,*rel,*retstr; cJSON *item,*swapjson; bits256 srcpub,destpub; uint64_t aliceid,basesatoshis,relsatoshis; uint32_t requestid,quoteid; double price; |
||||
|
for (i=0; i<numswaps; i++) |
||||
|
{ |
||||
|
item = jitem(swaps,i); |
||||
|
if ( (base= jstr(item,"base")) == 0 ) |
||||
|
base = ""; |
||||
|
if ( (rel= jstr(item,"rel")) == 0 ) |
||||
|
rel = ""; |
||||
|
if ( strcmp(base,refbase) != 0 && strcmp(base,refrel) != 0 && strcmp(rel,refbase) != 0 && strcmp(rel,refrel) != 0 ) |
||||
|
continue; |
||||
|
aliceid = j64bits(item,"aliceid"); |
||||
|
basesatoshis = SATOSHIDEN * jdouble(item,"basevol"); |
||||
|
srcpub = jbits256(item,"src"); |
||||
|
relsatoshis = SATOSHIDEN * jdouble(item,"relvol"); |
||||
|
destpub = jbits256(item,"dest"); |
||||
|
price = jdouble(item,"price"); |
||||
|
requestid = juint(item,"requestid"); |
||||
|
quoteid = juint(item,"quoteid"); |
||||
|
LP_RTmetrics_pendingswap(srcpub); |
||||
|
LP_RTmetrics_pendingswap(destpub); |
||||
|
if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid)) != 0 ) // no need for this
|
||||
|
{ |
||||
|
if ( (swapjson= cJSON_Parse(retstr)) != 0 ) |
||||
|
{ |
||||
|
LP_RTmetrics_avoidadd(jbits256(swapjson,"bobdeposit")); |
||||
|
LP_RTmetrics_avoidadd(jbits256(swapjson,"alicepayment")); |
||||
|
LP_RTmetrics_avoidadd(jbits256(swapjson,"bobpayment")); |
||||
|
LP_RTmetrics_avoidadd(jbits256(swapjson,"paymentspent")); |
||||
|
LP_RTmetrics_avoidadd(jbits256(swapjson,"Apaymentspent")); |
||||
|
LP_RTmetrics_avoidadd(jbits256(swapjson,"depositspent")); |
||||
|
free_json(swapjson); |
||||
|
} |
||||
|
free(retstr); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void LP_RTmetrics_update(char *base,char *rel) |
||||
|
{ |
||||
|
struct LP_pubkeyinfo *pubp,*tmp; uint32_t futuretime; int32_t i,numswaps; bits256 zero; char *retstr; cJSON *statsjson,*swaps; |
||||
|
memset(&LP_RTmetrics,0,sizeof(LP_RTmetrics)); |
||||
|
HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) |
||||
|
{ |
||||
|
if ( pubp->istrusted > 0 ) |
||||
|
LP_RTmetrics_whitelistadd(pubp->pubkey); |
||||
|
else if ( pubp->istrusted < 0 ) |
||||
|
LP_RTmetrics_blacklistadd(pubp->pubkey); |
||||
|
} |
||||
|
futuretime = (uint32_t)time(NULL) + 3600*100; |
||||
|
memset(zero.bytes,0,sizeof(zero)); |
||||
|
if ( (retstr= LP_statslog_disp(100,futuretime,futuretime,"",zero)) != 0 ) |
||||
|
{ |
||||
|
if ( (statsjson= cJSON_Parse(retstr)) != 0 ) |
||||
|
{ |
||||
|
if ( (swaps= jarray(&numswaps,statsjson,"swaps")) != 0 ) |
||||
|
{ |
||||
|
//printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0));
|
||||
|
if ( numswaps > 0 ) |
||||
|
LP_RTmetrics_swapsinfo(base,rel,swaps,numswaps); |
||||
|
} |
||||
|
free_json(statsjson); |
||||
|
} |
||||
|
free(retstr); |
||||
|
} |
||||
|
for (i=0; i<LP_RTmetrics.numpendings; i++) |
||||
|
if ( LP_RTmetrics.pending_swaps[i] > LP_MAXPENDING_SWAPS ) |
||||
|
{ |
||||
|
char str[65]; printf("%s has %d pending swaps! which is more than %d\n",bits256_str(str,LP_RTmetrics.pending_pubkeys[i]),LP_RTmetrics.pending_swaps[i],LP_MAXPENDING_SWAPS); |
||||
|
LP_RTmetrics_blacklistadd(LP_RTmetrics.pending_pubkeys[i]); |
||||
|
} |
||||
|
//printf("%d pubkeys have pending swaps, whitelist.%d blacklist.%d avoidtxids.%d\n",LP_RTmetrics.numpendings,LP_RTmetrics.numwhitelist,LP_RTmetrics.numblacklist,LP_RTmetrics.numavoidtxids);
|
||||
|
} |
||||
|
|
||||
|
double _LP_RTmetric_calc(struct LP_metricinfo *mp,double bestprice,double maxprice,double relvolume) |
||||
|
{ |
||||
|
int32_t n; double metric,origmetric = (mp->price / bestprice); |
||||
|
metric = origmetric; |
||||
|
if ( mp->numutxos == 0 || relvolume == 0. || mp->maxvol == 0. || mp->balance == 0. ) |
||||
|
{ |
||||
|
//printf("skip i.%d as no info\n",mp->ind);
|
||||
|
return(metric * 100.); |
||||
|
} |
||||
|
if ( relvolume < mp->minvol ) |
||||
|
{ |
||||
|
metric *= (mp->minvol / relvolume); |
||||
|
//printf("relvolume < minvol %.8f\n",(mp->minvol / relvolume));
|
||||
|
} |
||||
|
else if ( relvolume > mp->maxvol ) |
||||
|
{ |
||||
|
metric *= (relvolume / mp->maxvol); |
||||
|
//printf("relvolume > minvol %.8f\n",(relvolume / mp->maxvol));
|
||||
|
} |
||||
|
if ( relvolume < mp->balance/LP_MINVOL ) |
||||
|
{ |
||||
|
metric *= (mp->balance / relvolume); |
||||
|
//printf("relvolume < balance %.8f\n",(mp->balance / relvolume));
|
||||
|
} |
||||
|
else if ( relvolume > mp->balance/mp->numutxos ) |
||||
|
{ |
||||
|
metric *= (relvolume / (mp->balance/mp->numutxos)); |
||||
|
//printf("relvolume < ave %.8f\n",(relvolume / (mp->balance/mp->numutxos)));
|
||||
|
} |
||||
|
if ( mp->age > LP_ORDERBOOK_DURATION*0.8 ) |
||||
|
metric *= 2; |
||||
|
else if ( mp->age > 60 ) |
||||
|
metric *= 1.03; |
||||
|
if ( (n= mp->pendingswaps) > 0 ) |
||||
|
while ( n-- > 0 ) |
||||
|
metric *= 1.1; |
||||
|
//if ( metric != origmetric )
|
||||
|
printf("i.%d price %.8f orig %.8f -> %.8f relvol %.8f min %.8f max %.8f bal %.8f age.%d pend.%d\n",mp->ind,mp->price,origmetric,metric,relvolume,mp->minvol,mp->maxvol,mp->balance,mp->age,mp->pendingswaps); |
||||
|
return(metric); |
||||
|
} |
||||
|
|
||||
|
void LP_RTmetric_calc(struct LP_metricinfo *sortbuf,int32_t ind,cJSON *item,double bestprice,double maxprice,double relvolume,double prevdepth) |
||||
|
{ |
||||
|
sortbuf[ind].pubkey = jbits256(item,"pubkey"); |
||||
|
sortbuf[ind].price = jdouble(item,"price"); |
||||
|
sortbuf[ind].maxvol = jdouble(item,"maxvolume"); |
||||
|
sortbuf[ind].minvol = jdouble(item,"minvolume"); |
||||
|
sortbuf[ind].balance = jdouble(item,"depth") - prevdepth; |
||||
|
sortbuf[ind].numutxos = juint(item,"numutxos"); |
||||
|
sortbuf[ind].age = juint(item,"age"); |
||||
|
sortbuf[ind].ind = ind; |
||||
|
sortbuf[ind].pendingswaps = LP_RTmetrics_pendingswaps(sortbuf[ind].pubkey); |
||||
|
sortbuf[ind].metric = _LP_RTmetric_calc(&sortbuf[ind],bestprice,maxprice,relvolume); |
||||
|
} |
||||
|
|
||||
|
int _increasing_metrics(const void *a,const void *b) |
||||
|
{ |
||||
|
#define ptr_a ((struct LP_metricinfo *)a) |
||||
|
#define ptr_b ((struct LP_metricinfo *)b) |
||||
|
if ( ptr_b->metric > ptr_a->metric ) |
||||
|
return(-1); |
||||
|
else if ( ptr_b->metric < ptr_a->metric ) |
||||
|
return(1); |
||||
|
return(0); |
||||
|
#undef ptr_a |
||||
|
#undef ptr_b |
||||
|
} |
||||
|
|
||||
|
cJSON *LP_RTmetrics_sort(char *base,char *rel,cJSON *rawasks,int32_t numasks,double maxprice,double relvolume) |
||||
|
{ |
||||
|
cJSON *array=rawasks,*item; int32_t i,num,groupi; double price,prevdepth,bestprice; struct LP_metricinfo *sortbuf; |
||||
|
groupi = -1; |
||||
|
bestprice = 0.; |
||||
|
for (num=i=0; i<numasks; i++) |
||||
|
{ |
||||
|
item = jitem(rawasks,i); |
||||
|
price = jdouble(item,"price"); |
||||
|
if ( price > maxprice ) |
||||
|
break; |
||||
|
if ( i == 0 ) |
||||
|
bestprice = price; |
||||
|
else if ( price < bestprice*LP_RTMETRICS_TOPGROUP ) |
||||
|
groupi = i; |
||||
|
num++; |
||||
|
} |
||||
|
if ( groupi > 0 ) |
||||
|
{ |
||||
|
sortbuf = calloc(groupi+1,sizeof(*sortbuf)); |
||||
|
prevdepth = 0.; |
||||
|
for (i=0; i<=groupi; i++) |
||||
|
{ |
||||
|
item = jitem(rawasks,i); |
||||
|
LP_RTmetric_calc(sortbuf,i,item,bestprice,maxprice,relvolume,prevdepth); |
||||
|
prevdepth = jdouble(item,"depth"); |
||||
|
//printf("%.8f ",sortbuf[i].metric);
|
||||
|
} |
||||
|
qsort(&sortbuf[0].metric,groupi+1,sizeof(*sortbuf),_increasing_metrics); |
||||
|
array = cJSON_CreateArray(); |
||||
|
for (i=0; i<=groupi; i++) |
||||
|
{ |
||||
|
printf("(%d <- %d %.3f) ",i,sortbuf[i].ind,sortbuf[i].metric); |
||||
|
item = jitem(rawasks,sortbuf[i].ind); |
||||
|
jaddi(array,jduplicate(item)); |
||||
|
} |
||||
|
for (; i<numasks; i++) |
||||
|
jaddi(array,jduplicate(jitem(rawasks,i))); |
||||
|
printf("new ask order for %d of %d, capped at num.%d\n",groupi,numasks,num); |
||||
|
free(sortbuf); |
||||
|
} |
||||
|
return(array); |
||||
|
} |
@ -0,0 +1,343 @@ |
|||||
|
|
||||
|
/******************************************************************************
|
||||
|
* Copyright © 2014-2017 The SuperNET Developers. * |
||||
|
* * |
||||
|
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * |
||||
|
* the top-level directory of this distribution for the individual copyright * |
||||
|
* holder information and the developer policies on copyright and licensing. * |
||||
|
* * |
||||
|
* Unless otherwise agreed in a custom licensing agreement, no part of the * |
||||
|
* SuperNET software, including this file may be copied, modified, propagated * |
||||
|
* or distributed except according to the terms contained in the LICENSE file * |
||||
|
* * |
||||
|
* Removal or modification of this copyright notice is prohibited. * |
||||
|
* * |
||||
|
******************************************************************************/ |
||||
|
//
|
||||
|
// LP_cache.c
|
||||
|
// marketmaker
|
||||
|
//
|
||||
|
|
||||
|
cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len) |
||||
|
{ |
||||
|
uint8_t *extraspace; cJSON *txobj; char str[65],str2[65]; struct iguana_msgtx msgtx; bits256 checktxid; |
||||
|
extraspace = calloc(1,4000000); |
||||
|
memset(&msgtx,0,sizeof(msgtx)); |
||||
|
txobj = bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->height,&checktxid,&msgtx,extraspace,4000000,serialized,len,0,0,coin->zcash); |
||||
|
//printf("TX.(%s) match.%d\n",jprint(txobj,0),bits256_cmp(txid,checktxid));
|
||||
|
free(extraspace); |
||||
|
if ( bits256_cmp(txid,checktxid) != 0 ) |
||||
|
{ |
||||
|
printf("%s LP_transaction_fromdata mismatched txid %s vs %s\n",coin->symbol,bits256_str(str,txid),bits256_str(str2,checktxid)); |
||||
|
free_json(txobj); |
||||
|
txobj = 0; |
||||
|
} |
||||
|
return(txobj); |
||||
|
} |
||||
|
|
||||
|
struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len,int32_t height,long fpos) |
||||
|
{ |
||||
|
cJSON *txobj; bits256 spenttxid; int32_t i,spentvout,numvins,numvouts; cJSON *vout,*vin,*vins,*vouts; struct LP_transaction *tx; char str[65]; |
||||
|
if ( (tx= LP_transactionfind(coin,txid)) != 0 ) |
||||
|
return(tx); |
||||
|
if ( (txobj= LP_transaction_fromdata(coin,txid,serialized,len)) != 0 ) |
||||
|
{ |
||||
|
vins = jarray(&numvins,txobj,"vin"); |
||||
|
vouts = jarray(&numvouts,txobj,"vout"); |
||||
|
tx = LP_transactionadd(coin,txid,height,numvouts,numvins); |
||||
|
tx->serialized = 0;//serialized;
|
||||
|
free(serialized); |
||||
|
tx->fpos = fpos; |
||||
|
tx->len = 0;//tx->len;
|
||||
|
tx->SPV = tx->height = height; |
||||
|
//printf("tx.%s numvins.%d numvouts.%d\n",bits256_str(str,txid),numvins,numvouts);
|
||||
|
for (i=0; i<numvouts; i++) |
||||
|
{ |
||||
|
vout = jitem(vouts,i); |
||||
|
tx->outpoints[i].value = LP_value_extract(vout,0); |
||||
|
tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest"); |
||||
|
LP_destaddr(tx->outpoints[i].coinaddr,vout); |
||||
|
//printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value));
|
||||
|
LP_address_utxoadd((uint32_t)time(NULL),"LP_create_transaction",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); |
||||
|
} |
||||
|
for (i=0; i<numvins; i++) |
||||
|
{ |
||||
|
vin = jitem(vins,i); |
||||
|
spenttxid = jbits256(vin,"txid"); |
||||
|
spentvout = jint(vin,"vout"); |
||||
|
if ( i == 0 && bits256_nonz(spenttxid) == 0 ) |
||||
|
continue; |
||||
|
if ( (tx= LP_transactionfind(coin,spenttxid)) != 0 ) |
||||
|
{ |
||||
|
if ( spentvout < tx->numvouts ) |
||||
|
{ |
||||
|
if ( tx->outpoints[spentvout].spendheight <= 0 ) |
||||
|
{ |
||||
|
tx->outpoints[spentvout].spendtxid = txid; |
||||
|
tx->outpoints[spentvout].spendvini = i; |
||||
|
tx->outpoints[spentvout].spendheight = height > 0 ? height : 1; |
||||
|
LP_address_utxoadd((uint32_t)time(NULL),"LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1); |
||||
|
if ( 0 && strcmp(coin->symbol,"REVS") == 0 ) |
||||
|
printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height); |
||||
|
} |
||||
|
} else printf("LP_transactioninit: %s spentvout.%d < numvouts.%d spendheight.%d\n",bits256_str(str,spenttxid),spentvout,tx->numvouts,tx->outpoints[spentvout].spendheight); |
||||
|
} //else printf("LP_transactioninit: couldnt find (%s) ht.%d %s\n",bits256_str(str,spenttxid),height,jprint(vin,0));
|
||||
|
if ( bits256_cmp(spenttxid,txid) == 0 ) |
||||
|
printf("spending same tx's %p vout ht.%d %s.[%d] s%d\n",tx,height,bits256_str(str,txid),tx!=0?tx->numvouts:0,spentvout); |
||||
|
} |
||||
|
free_json(txobj); |
||||
|
} |
||||
|
return(tx); |
||||
|
} |
||||
|
|
||||
|
void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) |
||||
|
{ |
||||
|
FILE *fp; char fname[512]; struct LP_transaction *tx = 0; |
||||
|
if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 && tx->fpos == 0 ) |
||||
|
{ |
||||
|
sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); |
||||
|
if ( (fp= OS_appendfile(fname)) != 0 ) |
||||
|
{ |
||||
|
fwrite(&tx->txid,1,sizeof(tx->txid),fp); |
||||
|
fwrite(&tx->len,1,sizeof(tx->len),fp); |
||||
|
fwrite(&tx->height,1,sizeof(tx->height),fp); |
||||
|
tx->fpos = ftell(fp); |
||||
|
fwrite(tx->serialized,1,tx->len,fp); |
||||
|
fclose(fp); |
||||
|
} |
||||
|
} //else printf("cant store %s %s tx.%p [%d] fpos.%ld SPV.%d\n",coin->symbol,bits256_str(str,txid),tx,tx!=0?tx->len:-1,tx!=0?tx->fpos:-1,tx!=0?tx->SPV:-1);
|
||||
|
} |
||||
|
|
||||
|
int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) |
||||
|
{ |
||||
|
bits256 txid,hash; long fpos; int32_t offset,retval,height,len; uint8_t *serialized; char str[65],str2[65]; |
||||
|
fpos = ftell(fp); |
||||
|
if ( fread(&txid,1,sizeof(txid),fp) == sizeof(txid) && fread(&len,1,sizeof(len),fp) == sizeof(len) && fread(&height,1,sizeof(height),fp) == sizeof(height) && len < 100000 ) |
||||
|
{ |
||||
|
offset = (int32_t)(sizeof(txid) + sizeof(len) + sizeof(height)); |
||||
|
serialized = malloc(len); |
||||
|
if ( (retval= (int32_t)fread(serialized,1,len,fp)) == len ) |
||||
|
{ |
||||
|
hash = bits256_doublesha256(0,serialized,len); |
||||
|
if ( bits256_cmp(hash,txid) == 0 ) |
||||
|
{ |
||||
|
//printf("%s validated in cache\n",bits256_str(str,hash));
|
||||
|
LP_create_transaction(coin,txid,serialized,len,height,fpos+offset); |
||||
|
return((int32_t)(ftell(fp) - fpos)); |
||||
|
} |
||||
|
printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,txid)); |
||||
|
} else printf("retval.%d vs len.%d\n",retval,len); |
||||
|
} else printf("fread error\n"); |
||||
|
return(-1); |
||||
|
} |
||||
|
|
||||
|
void LP_cacheptrs_init(struct iguana_info *coin) |
||||
|
{ |
||||
|
char fname[1024]; FILE *fp; int32_t count,tflag=0; long n,fsize=0,len = 0; |
||||
|
sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); |
||||
|
fp = fopen(fname,"rb"); |
||||
|
count = 0; |
||||
|
if ( fp != 0 ) |
||||
|
{ |
||||
|
fseek(fp,0,SEEK_END); |
||||
|
fsize = ftell(fp); |
||||
|
rewind(fp); |
||||
|
while ( len < fsize ) |
||||
|
{ |
||||
|
if ( (n= LP_cacheitem(coin,fp)) < 0 ) |
||||
|
{ |
||||
|
printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize); |
||||
|
tflag = 1; |
||||
|
break; |
||||
|
} |
||||
|
count++; |
||||
|
len += n; |
||||
|
} |
||||
|
printf("loaded %s %d entries total len.%ld\n",fname,count,len); |
||||
|
fclose(fp); |
||||
|
} //else printf("couldnt find.(%s)\n",fname);
|
||||
|
if ( tflag != 0 ) |
||||
|
OS_truncate(fname,len); |
||||
|
} |
||||
|
|
||||
|
bits256 iguana_merkle(bits256 *tree,int32_t txn_count) |
||||
|
{ |
||||
|
int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; |
||||
|
if ( txn_count == 1 ) |
||||
|
return(tree[0]); |
||||
|
prev = 0; |
||||
|
while ( txn_count > 1 ) |
||||
|
{ |
||||
|
if ( (txn_count & 1) != 0 ) |
||||
|
tree[prev + txn_count] = tree[prev + txn_count-1], txn_count++; |
||||
|
n += txn_count; |
||||
|
for (i=0; i<txn_count; i+=2) |
||||
|
{ |
||||
|
iguana_rwbignum(1,serialized,sizeof(*tree),tree[prev + i].bytes); |
||||
|
iguana_rwbignum(1,&serialized[sizeof(*tree)],sizeof(*tree),tree[prev + i + 1].bytes); |
||||
|
tree[n + (i >> 1)] = bits256_doublesha256(0,serialized,sizeof(serialized)); |
||||
|
} |
||||
|
prev = n; |
||||
|
txn_count >>= 1; |
||||
|
} |
||||
|
return(tree[n]); |
||||
|
} |
||||
|
|
||||
|
bits256 validate_merkle(int32_t pos,bits256 txid,cJSON *proofarray,int32_t proofsize) |
||||
|
{ |
||||
|
int32_t i; uint8_t serialized[sizeof(bits256) * 2]; bits256 hash,proof; |
||||
|
hash = txid; |
||||
|
for (i=0; i<proofsize; i++) |
||||
|
{ |
||||
|
proof = jbits256i(proofarray,i); |
||||
|
if ( (pos & 1) == 0 ) |
||||
|
{ |
||||
|
iguana_rwbignum(1,&serialized[0],sizeof(hash),hash.bytes); |
||||
|
iguana_rwbignum(1,&serialized[sizeof(hash)],sizeof(proof),proof.bytes); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
iguana_rwbignum(1,&serialized[0],sizeof(proof),proof.bytes); |
||||
|
iguana_rwbignum(1,&serialized[sizeof(hash)],sizeof(hash),hash.bytes); |
||||
|
} |
||||
|
hash = bits256_doublesha256(0,serialized,sizeof(serialized)); |
||||
|
pos >>= 1; |
||||
|
} |
||||
|
return(hash); |
||||
|
} |
||||
|
|
||||
|
bits256 LP_merkleroot(struct iguana_info *coin,struct electrum_info *ep,int32_t height) |
||||
|
{ |
||||
|
cJSON *hdrobj; bits256 merkleroot; |
||||
|
memset(merkleroot.bytes,0,sizeof(merkleroot)); |
||||
|
if ( coin->cachedmerkleheight == height ) |
||||
|
return(coin->cachedmerkle); |
||||
|
if ( (hdrobj= electrum_getheader(coin->symbol,ep,&hdrobj,height)) != 0 ) |
||||
|
{ |
||||
|
if ( jobj(hdrobj,"merkle_root") != 0 ) |
||||
|
{ |
||||
|
merkleroot = jbits256(hdrobj,"merkle_root"); |
||||
|
if ( bits256_nonz(merkleroot) != 0 ) |
||||
|
{ |
||||
|
coin->cachedmerkle = merkleroot; |
||||
|
coin->cachedmerkleheight = height; |
||||
|
} |
||||
|
} |
||||
|
free_json(hdrobj); |
||||
|
} else printf("couldnt get header for ht.%d\n",height); |
||||
|
return(merkleroot); |
||||
|
} |
||||
|
|
||||
|
int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height) |
||||
|
{ |
||||
|
struct LP_transaction *tx=0; cJSON *merkobj,*merkles,*retjson; bits256 roothash,merkleroot; int32_t m,SPV = 0; |
||||
|
if ( height <= 0 ) |
||||
|
return(0); |
||||
|
if ( (tx= LP_transactionfind(coin,txid)) == 0 && strcmp(coinaddr,coin->smartaddr) == 0 ) |
||||
|
{ |
||||
|
if ( (retjson= electrum_transaction(coin->symbol,ep,&retjson,txid,0)) != 0 ) |
||||
|
free_json(retjson); |
||||
|
} |
||||
|
if ( tx != 0 ) |
||||
|
{ |
||||
|
tx->height = height; |
||||
|
if ( tx->SPV > 0 ) |
||||
|
return(tx->SPV); |
||||
|
} |
||||
|
if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 ) |
||||
|
{ |
||||
|
char str[65],str2[65],str3[65]; |
||||
|
SPV = 0; |
||||
|
memset(roothash.bytes,0,sizeof(roothash)); |
||||
|
if ( (merkles= jarray(&m,merkobj,"merkle")) != 0 ) |
||||
|
{ |
||||
|
roothash = validate_merkle(jint(merkobj,"pos"),txid,merkles,m); |
||||
|
merkleroot = LP_merkleroot(coin,ep,height); |
||||
|
if ( bits256_nonz(merkleroot) != 0 ) |
||||
|
{ |
||||
|
if ( bits256_cmp(merkleroot,roothash) == 0 ) |
||||
|
{ |
||||
|
SPV = height; |
||||
|
LP_SPV_store(coin,txid,height); |
||||
|
if ( tx != 0 ) |
||||
|
{ |
||||
|
tx->SPV = height; |
||||
|
if ( tx->serialized != 0 ) |
||||
|
{ |
||||
|
free(tx->serialized); |
||||
|
tx->serialized = 0; |
||||
|
tx->len = 0; |
||||
|
} |
||||
|
} |
||||
|
//printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash));
|
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
SPV = -1; |
||||
|
printf("ERROR MERK %s ht.%d -> %s root.(%s) vs %s\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash),bits256_str(str3,merkleroot)); |
||||
|
} |
||||
|
} else SPV = 0; |
||||
|
} |
||||
|
if ( SPV < 0 ) |
||||
|
{ |
||||
|
printf("MERKLE DIDNT VERIFY.%s %s ht.%d (%s)\n",coin->symbol,bits256_str(str,txid),height,jprint(merkobj,0)); |
||||
|
if ( jobj(merkobj,"error") != 0 ) |
||||
|
SPV = 0; // try again later
|
||||
|
} |
||||
|
free_json(merkobj); |
||||
|
} |
||||
|
return(SPV); |
||||
|
} |
||||
|
|
||||
|
char *LP_unspents_filestr(char *symbol,char *addr) |
||||
|
{ |
||||
|
char fname[1024]; long fsize; |
||||
|
sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); |
||||
|
return(OS_filestr(&fsize,fname)); |
||||
|
} |
||||
|
|
||||
|
void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag) |
||||
|
{ |
||||
|
char fname[1024]; FILE *fp=0; |
||||
|
sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); |
||||
|
//printf("unspents cache.(%s) for %s %s, updated.%d\n",fname,symbol,addr,updatedflag);
|
||||
|
if ( updatedflag == 0 && (fp= fopen(fname,"rb")) == 0 ) |
||||
|
updatedflag = 1; |
||||
|
else if ( fp != 0 ) |
||||
|
fclose(fp); |
||||
|
if ( updatedflag != 0 && (fp= fopen(fname,"wb")) != 0 ) |
||||
|
{ |
||||
|
fwrite(arraystr,1,strlen(arraystr),fp); |
||||
|
fclose(fp); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
uint64_t LP_unspents_load(char *symbol,char *addr) |
||||
|
{ |
||||
|
char *arraystr; uint64_t balance = 0; int32_t i,n; cJSON *retjson,*item; struct iguana_info *coin; |
||||
|
if ( (coin= LP_coinfind(symbol)) != 0 ) |
||||
|
{ |
||||
|
if ( (arraystr= LP_unspents_filestr(symbol,addr)) != 0 ) |
||||
|
{ |
||||
|
if ( (retjson= cJSON_Parse(arraystr)) != 0 ) |
||||
|
{ |
||||
|
//printf("PROCESS UNSPENTS %s\n",arraystr);
|
||||
|
if ( (n= cJSON_GetArraySize(retjson)) > 0 ) |
||||
|
{ |
||||
|
for (i=0; i<n; i++) |
||||
|
{ |
||||
|
item = jitem(retjson,i); |
||||
|
balance += j64bits(item,"value"); |
||||
|
} |
||||
|
} |
||||
|
electrum_process_array(coin,coin->electrum,coin->smartaddr,retjson,1); |
||||
|
free_json(retjson); |
||||
|
} |
||||
|
free(arraystr); |
||||
|
} |
||||
|
} |
||||
|
return(balance); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
File diff suppressed because it is too large
File diff suppressed because it is too large
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue