Browse Source

Merge pull request #342 from jl777/dev

Dev
beta
jl777 8 years ago
committed by GitHub
parent
commit
e972958876
  1. 1
      crypto777/OS_portable.h
  2. 2
      crypto777/bitcoind_RPC.c
  3. 4
      iguana/coins/jumblr
  4. 3
      iguana/coins/jumblr_osx
  5. 2
      iguana/coins/mesh_7776
  6. 3
      iguana/coins/revs
  7. 3
      iguana/coins/revs_osx
  8. 1485
      iguana/exchanges/LP_bitcoin.c
  9. 189
      iguana/exchanges/LP_coins.c
  10. 601
      iguana/exchanges/LP_commands.c
  11. 368
      iguana/exchanges/LP_include.h
  12. 779
      iguana/exchanges/LP_nativeDEX.c
  13. 249
      iguana/exchanges/LP_network.c
  14. 188
      iguana/exchanges/LP_peers.c
  15. 350
      iguana/exchanges/LP_prices.c
  16. 210
      iguana/exchanges/LP_remember.c
  17. 559
      iguana/exchanges/LP_rpc.c
  18. 719
      iguana/exchanges/LP_statemachine.c
  19. 588
      iguana/exchanges/LP_swap.c
  20. 1436
      iguana/exchanges/LP_transaction.c
  21. 366
      iguana/exchanges/LP_utxos.c
  22. 2
      iguana/exchanges/autotrade
  23. 2
      iguana/exchanges/candidates
  24. 2
      iguana/exchanges/client
  25. 2
      iguana/exchanges/getpeers
  26. 10
      iguana/exchanges/getpeersIP
  27. 2
      iguana/exchanges/getprice
  28. 2
      iguana/exchanges/inv
  29. 125
      iguana/exchanges/mm.c
  30. 2
      iguana/exchanges/myprice
  31. 2
      iguana/exchanges/orderbook
  32. 1
      iguana/exchanges/randval
  33. 2
      iguana/exchanges/run
  34. 2
      iguana/exchanges/setprice
  35. 1
      iguana/exchanges/userpass
  36. 2
      iguana/m_mm
  37. 6
      iguana/main.c
  38. 434
      iguana/tests/KMD.batch17
  39. 346
      iguana/tests/KMD.batch17.listunspent
  40. 5
      iguana/tests/REVS.batch17
  41. 2
      iguana/tests/dexgetbalance
  42. 2
      iguana/tests/dexlistunspent

1
crypto777/OS_portable.h

@ -359,6 +359,7 @@ void calc_base64_decodestr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len);
void calc_hexstr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len);
void calc_unhexstr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len);
int32_t safecopy(char *dest,char *src,long len);
double dxblend(double *destp,double val,double decay);
uint64_t calc_ipbits(char *ip_port);
void expand_ipbits(char *ipaddr,uint64_t ipbits);

2
crypto777/bitcoind_RPC.c

@ -137,7 +137,7 @@ char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *
if ( url[0] == 0 )
strcpy(url,"http://127.0.0.1:7776");
if ( specialcase != 0 && (0) )
printf("<<<<<<<<<<< bitcoind_RPC: debug.(%s) url.(%s) command.(%s) params.(%s)\n",debugstr,url,command,params);
printf("<<<<<<<<<<< bitcoind_RPC: userpass.(%s) url.(%s) command.(%s) params.(%s)\n",userpass,url,command,params);
try_again:
if ( retstrp != 0 )
*retstrp = 0;

4
iguana/coins/jumblr

@ -0,0 +1,4 @@
~/komodo/src/komodod -ac_name=JUMBLR -ac_supply=999999 -addnode=78.47.196.146 &
curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"JUMBLR.conf\",\"path\":\"${HOME#"/"}/.komodo/JUMBLR\",\"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\":\"JUMBLR\",\"name\":\"JUMBLR\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7223759e\",\"p2p\":15105,\"rpc\":15106,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}"

3
iguana/coins/jumblr_osx

@ -0,0 +1,3 @@
/Applications/komodoOSX.app/Contents/komodod -ac_name=JUMBLR -ac_supply=999999 -addnode=78.47.196.146 &
curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"JUMBLR.conf\",\"path\":\"/${HOME#"/"}/Library/Application\ Support/Komodo/JUMBLR\",\"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\":\"JUMBLR\",\"name\":\"JUMBLR\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7223759e\",\"p2p\":15105,\"rpc\":15106,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}"

2
iguana/coins/mesh_7776

@ -1 +1 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MESH.conf\",\"path\":\"${HOME#"/"}/.komodo/MESH\",\"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\":\"MESH\",\"name\":\"MESH\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"4d6bbfb6\",\"p2p\":8399,\"rpc\":8400,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}"
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MESH.conf\",\"path\":\"${HOME#"/"}/.komodo/MESH\",\"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\":\"MESH\",\"name\":\"MESH\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"4d6bbfb6\",\"p2p\":9454,\"rpc\":9455,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}"

3
iguana/coins/revs

@ -0,0 +1,3 @@
./komodod -ac_name=REVS -ac_supply=1300000 -addnode=78.47.196.146 &
curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"REVS.conf\",\"path\":\"${HOME#"/"}/.komodo/REVS\",\"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\":\"REVS\",\"name\":\"REVS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"905c3498\",\"p2p\":10195,\"rpc\":10196,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}"

3
iguana/coins/revs_osx

@ -0,0 +1,3 @@
/Applications/komodoOSX.app/Contents/komodod -ac_name=REVS -ac_supply=1300000 -addnode=78.47.196.146 &
curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"REVS.conf\",\"path\":\"/${HOME#"/"}/Library/Application\ Support/Komodo/REVS\",\"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\":\"REVS\",\"name\":\"REVS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"905c3498\",\"p2p\":10195,\"rpc\":10196,\"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\"}"

1485
iguana/exchanges/LP_bitcoin.c

File diff suppressed because it is too large

189
iguana/exchanges/LP_coins.c

@ -0,0 +1,189 @@
/******************************************************************************
* 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_coins.c
// marketmaker
//
char *portstrs[][2] = { { "BTC", "8332" }, { "KMD", "7771" }, { "LTC", "9332" }, { "REVS", "10196" }, { "JUMBLR", "15106" }, };
char *parse_conf_line(char *line,char *field)
{
line += strlen(field);
for (; *line!='='&&*line!=0; line++)
break;
if ( *line == 0 )
return(0);
if ( *line == '=' )
line++;
while ( line[strlen(line)-1] == '\r' || line[strlen(line)-1] == '\n' || line[strlen(line)-1] == ' ' )
line[strlen(line)-1] = 0;
//printf("LINE.(%s)\n",line);
_stripwhite(line,0);
return(clonestr(line));
}
void LP_userpassfp(char *username,char *password,FILE *fp)
{
char *rpcuser,*rpcpassword,*str,line[8192];
rpcuser = rpcpassword = 0;
username[0] = password[0] = 0;
while ( fgets(line,sizeof(line),fp) != 0 )
{
if ( line[0] == '#' )
continue;
//printf("line.(%s) %p %p\n",line,strstr(line,(char *)"rpcuser"),strstr(line,(char *)"rpcpassword"));
if ( (str= strstr(line,(char *)"rpcuser")) != 0 )
rpcuser = parse_conf_line(str,(char *)"rpcuser");
else if ( (str= strstr(line,(char *)"rpcpassword")) != 0 )
rpcpassword = parse_conf_line(str,(char *)"rpcpassword");
}
if ( rpcuser != 0 && rpcpassword != 0 )
{
strcpy(username,rpcuser);
strcpy(password,rpcpassword);
}
//printf("rpcuser.(%s) rpcpassword.(%s) KMDUSERPASS.(%s) %u\n",rpcuser,rpcpassword,KMDUSERPASS,port);
if ( rpcuser != 0 )
free(rpcuser);
if ( rpcpassword != 0 )
free(rpcpassword);
}
void LP_statefname(char *fname,char *symbol,char *assetname,char *str)
{
sprintf(fname,"%s",LP_getdatadir());
#ifdef WIN32
strcat(fname,"\\");
#else
strcat(fname,"/");
#endif
if ( strcmp(symbol,"BTC") == 0 )
{
#ifdef __APPLE__
strcat(fname,"Bitcoin");
#else
strcat(fname,".bitcoin");
#endif
}
else if ( strcmp(symbol,"LTC") == 0 )
{
#ifdef __APPLE__
strcat(fname,"Litecoin");
#else
strcat(fname,".litecoin");
#endif
}
else
{
#ifdef __APPLE__
strcat(fname,"Komodo");
#else
strcat(fname,".komodo");
#endif
if ( strcmp(symbol,"KMD") != 0 )
{
#ifdef WIN32
strcat(fname,"\\");
#else
strcat(fname,"/");
#endif
strcat(fname,assetname);
}
}
#ifdef WIN32
strcat(fname,"\\");
#else
strcat(fname,"/");
#endif
strcat(fname,str);
printf("LP_statefname.(%s) <- %s %s %s\n",fname,symbol,assetname,str);
}
int32_t LP_userpass(char *userpass,char *symbol,char *assetname,char *confroot)
{
FILE *fp; char fname[512],username[512],password[512],confname[16];
userpass[0] = 0;
sprintf(confname,"%s.conf",confroot);
#ifdef __APPLE__
confname[0] = toupper(confname[0]);
#endif
LP_statefname(fname,symbol,assetname,confname);
if ( (fp= fopen(fname,"rb")) != 0 )
{
LP_userpassfp(username,password,fp);
sprintf(userpass,"%s:%s",username,password);
fclose(fp);
return((int32_t)strlen(userpass));
}
return(-1);
}
uint16_t LP_rpcport(char *symbol)
{
int32_t i;
for (i=0; i<sizeof(portstrs)/sizeof(*portstrs); i++)
if ( strcmp(portstrs[i][0],symbol) == 0 )
return(atoi(portstrs[i][1]));
return(0);
}
struct iguana_info *LP_coinfind(char *symbol)
{
static struct iguana_info *LP_coins; static int32_t LP_numcoins;
struct iguana_info *coin,cdata; int32_t i; uint16_t port;
for (i=0; i<LP_numcoins; i++)
if ( strcmp(LP_coins[i].symbol,symbol) == 0 )
return(&LP_coins[i]);
memset(&cdata,0,sizeof(cdata));
coin = &cdata;
safecopy(cdata.symbol,symbol,sizeof(cdata.symbol));
port = LP_rpcport(symbol);
sprintf(cdata.serverport,"127.0.0.1:%u",port);
cdata.longestchain = 100000;
cdata.txfee = 10000;
cdata.estimatedrate = 20;
if ( strcmp(symbol,"BTC") == 0 )
{
cdata.txfee = 50000;
cdata.estimatedrate = 300;
cdata.p2shtype = 5;
cdata.wiftype = 128;
LP_userpass(cdata.userpass,symbol,"","bitcoin");
}
else if ( strcmp(symbol,"LTC") == 0 )
{
cdata.pubtype = 48;
cdata.p2shtype = 5;
cdata.wiftype = 176;
LP_userpass(cdata.userpass,symbol,"","litecoin");
}
else
{
cdata.pubtype = 60;
cdata.p2shtype = 85;
cdata.wiftype = 188;
LP_userpass(cdata.userpass,symbol,symbol,strcmp(symbol,"KMD") == 0 ? "komodo" : symbol);
}
//printf("%s: (%s) (%s)\n",symbol,cdata.serverport,cdata.userpass);
LP_coins = realloc(LP_coins,sizeof(*LP_coins) * (LP_numcoins+1));
coin = &LP_coins[LP_numcoins++];
*coin = cdata;
return(coin);
}

601
iguana/exchanges/LP_commands.c

@ -20,100 +20,464 @@
struct basilisk_request *LP_requestinit(struct basilisk_request *rp,bits256 srchash,bits256 desthash,char *src,uint64_t srcsatoshis,char *dest,uint64_t destsatoshis,uint32_t timestamp,uint32_t quotetime,int32_t DEXselector)
{
struct basilisk_request R;
memset(rp,0,sizeof(*rp));
rp->srchash = srchash;
rp->desthash = desthash;
rp->srcamount = srcsatoshis;
rp->destamount = destsatoshis;
rp->timestamp = timestamp;
rp->quotetime = quotetime;
rp->DEXselector = DEXselector;
safecopy(rp->src,src,sizeof(rp->src));
safecopy(rp->dest,dest,sizeof(rp->dest));
rp->quoteid = basilisk_quoteid(rp);
R = *rp;
rp->requestid = basilisk_requestid(rp);
rp->quotetime = quotetime;
rp->desthash = desthash;
rp->destamount = destsatoshis;
rp->quoteid = basilisk_quoteid(rp);
return(rp);
}
void LP_command(struct LP_peerinfo *mypeer,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen,double profitmargin)
cJSON *LP_quotejson(struct LP_quoteinfo *qp)
{
double price; cJSON *retjson = cJSON_CreateObject();
jaddstr(retjson,"base",qp->srccoin);
jaddstr(retjson,"rel",qp->destcoin);
if ( qp->coinaddr[0] != 0 )
jaddstr(retjson,"address",qp->coinaddr);
if ( qp->timestamp != 0 )
jaddnum(retjson,"timestamp",qp->timestamp);
if ( bits256_nonz(qp->txid) != 0 )
{
jaddbits256(retjson,"txid",qp->txid);
jaddnum(retjson,"vout",qp->vout);
}
if ( bits256_nonz(qp->srchash) != 0 )
jaddbits256(retjson,"srchash",qp->srchash);
if ( qp->txfee != 0 )
jadd64bits(retjson,"txfee",qp->txfee);
if ( qp->quotetime != 0 )
jaddnum(retjson,"quotetime",qp->quotetime);
if ( qp->satoshis != 0 )
{
jadd64bits(retjson,"satoshis",qp->satoshis);
price = (double)(qp->destsatoshis+qp->desttxfee) / qp->satoshis;
jaddnum(retjson,"price",price);
}
if ( bits256_nonz(qp->desthash) != 0 )
jaddbits256(retjson,"desthash",qp->desthash);
if ( bits256_nonz(qp->txid2) != 0 )
{
jaddbits256(retjson,"txid2",qp->txid2);
jaddnum(retjson,"vout2",qp->vout2);
if ( qp->satoshis2 != 0 )
jadd64bits(retjson,"satoshis2",qp->satoshis2);
}
if ( bits256_nonz(qp->desttxid) != 0 )
{
if ( qp->destaddr[0] != 0 )
jaddstr(retjson,"destaddr",qp->destaddr);
jaddbits256(retjson,"desttxid",qp->desttxid);
jaddnum(retjson,"destvout",qp->destvout);
}
if ( bits256_nonz(qp->feetxid) != 0 )
{
jaddbits256(retjson,"feetxid",qp->feetxid);
jaddnum(retjson,"feevout",qp->feevout);
}
if ( qp->destsatoshis != 0 )
jadd64bits(retjson,"destsatoshis",qp->destsatoshis);
if ( qp->desttxfee != 0 )
jadd64bits(retjson,"desttxfee",qp->desttxfee);
if ( qp->change != 0 )
jaddnum(retjson,"change",dstr(qp->change));
return(retjson);
}
int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson)
{
safecopy(qp->srccoin,jstr(argjson,"base"),sizeof(qp->srccoin));
safecopy(qp->coinaddr,jstr(argjson,"address"),sizeof(qp->coinaddr));
safecopy(qp->destcoin,jstr(argjson,"rel"),sizeof(qp->destcoin));
safecopy(qp->destaddr,jstr(argjson,"destaddr"),sizeof(qp->destaddr));
qp->timestamp = juint(argjson,"timestamp");
qp->quotetime = juint(argjson,"quotetime");
qp->txid = jbits256(argjson,"txid");
qp->txid2 = jbits256(argjson,"txid2");
qp->vout = jint(argjson,"vout");
qp->vout2 = jint(argjson,"vout2");
qp->feevout = jint(argjson,"feevout");
qp->srchash = jbits256(argjson,"srchash");
qp->desttxid = jbits256(argjson,"desttxid");
qp->feetxid = jbits256(argjson,"feetxid");
qp->destvout = jint(argjson,"destvout");
qp->desthash = jbits256(argjson,"desthash");
if ( (qp->satoshis= j64bits(argjson,"satoshis")) == 0 )
qp->satoshis = j64bits(argjson,"value");
if ( (qp->satoshis2= j64bits(argjson,"satoshis2")) == 0 )
qp->satoshis2 = j64bits(argjson,"value2");
qp->destsatoshis = j64bits(argjson,"destsatoshis");
qp->change = SATOSHIDEN * jdouble(argjson,"change");
qp->txfee = j64bits(argjson,"txfee");
qp->desttxfee = j64bits(argjson,"desttxfee");
return(0);
}
int32_t LP_quoteinfoinit(struct LP_quoteinfo *qp,struct LP_utxoinfo *utxo,char *destcoin,double price)
{
memset(qp,0,sizeof(*qp));
qp->timestamp = (uint32_t)time(NULL);
safecopy(qp->destcoin,destcoin,sizeof(qp->destcoin));
if ( (qp->txfee= LP_getestimatedrate(utxo->coin)*LP_AVETXSIZE) < 10000 )
qp->txfee = 10000;
if ( qp->txfee >= utxo->satoshis || qp->txfee >= utxo->satoshis2 )
return(-1);
qp->txid = utxo->txid;
qp->vout = utxo->vout;
qp->txid2 = utxo->txid2;
qp->vout2 = utxo->vout2;
qp->satoshis2 = utxo->satoshis2 - qp->txfee;
qp->satoshis = utxo->satoshis - qp->txfee;
qp->destsatoshis = qp->satoshis * price;
if ( (qp->desttxfee= LP_getestimatedrate(qp->destcoin) * LP_AVETXSIZE) < 10000 )
qp->desttxfee = 10000;
if ( qp->desttxfee >= qp->destsatoshis )
return(-2);
qp->destsatoshis -= qp->desttxfee;
safecopy(qp->srccoin,utxo->coin,sizeof(qp->srccoin));
safecopy(qp->coinaddr,utxo->coinaddr,sizeof(qp->coinaddr));
qp->srchash = LP_pubkey(LP_privkey(utxo->coinaddr));
return(0);
}
int32_t LP_quoteinfoset(struct LP_quoteinfo *qp,uint32_t timestamp,uint32_t quotetime,uint64_t value,uint64_t txfee,uint64_t destsatoshis,uint64_t desttxfee,bits256 desttxid,int32_t destvout,bits256 desthash,char *destaddr)
{
if ( txfee != qp->txfee )
{
if ( txfee >= value )
return(-1);
qp->txfee = txfee;
qp->satoshis = value - txfee;
}
qp->timestamp = timestamp;
qp->quotetime = quotetime;
qp->destsatoshis = destsatoshis;
qp->desttxfee = desttxfee;
qp->desttxid = desttxid;
qp->destvout = destvout;
qp->desthash = desthash;
safecopy(qp->destaddr,destaddr,sizeof(qp->destaddr));
return(0);
}
char *LP_quotereceived(cJSON *argjson)
{
struct LP_cacheinfo *ptr; double price; struct LP_quoteinfo Q;
LP_quoteparse(&Q,argjson);
price = (double)(Q.destsatoshis + Q.desttxfee) / (Q.satoshis + Q.txfee);
if ( (ptr= LP_cacheadd(Q.srccoin,Q.destcoin,Q.txid,Q.vout,price,&Q)) != 0 )
{
ptr->Q = Q;
return(clonestr("{\"result\":\"updated\"}"));
} else return(clonestr("{\"error\":\"nullptr\"}"));
}
double LP_query(char *method,struct LP_quoteinfo *qp,char *ipaddr,uint16_t port,char *base,char *rel,bits256 mypub)
{
cJSON *reqjson; struct LP_peerinfo *peer; int32_t i,flag = 0,pushsock = -1; double price = 0.;
if ( ipaddr != 0 && port >= 1000 )
{
if ( (peer= LP_peerfind((uint32_t)calc_ipbits(ipaddr),port)) == 0 )
peer = LP_addpeer(1,0,-1,ipaddr,port,port+1,port+2,0,0,0);
if ( peer != 0 )
{
if ( (pushsock= peer->pushsock) >= 0 )
{
qp->desthash = mypub;
strcpy(qp->srccoin,base);
strcpy(qp->destcoin,rel);
if ( strcmp(method,"request") == 0 )
qp->quotetime = (uint32_t)time(NULL);
reqjson = LP_quotejson(qp);
if ( bits256_nonz(qp->desthash) != 0 )
flag = 1;
jaddstr(reqjson,"method",method);
LP_send(pushsock,jprint(reqjson,1),1);
for (i=0; i<30; i++)
{
if ( (price= LP_pricecache(qp,base,rel,qp->txid,qp->vout)) != 0. )
{
if ( flag == 0 || bits256_nonz(qp->desthash) != 0 )
{
//printf("break out of loop.%d price %.8f\n",i,price);
break;
}
}
usleep(100000);
}
} else printf("no pushsock for peer.%s:%u\n",ipaddr,port);
} else printf("cant find/create peer.%s:%u\n",ipaddr,port);
}
return(price);
}
int32_t LP_sizematch(uint64_t mysatoshis,uint64_t othersatoshis)
{
char *method,*base,*rel,*retstr,*pairstr; cJSON *retjson; double price; bits256 srchash,desthash,pubkey,privkey,txid,desttxid; struct LP_utxoinfo *utxo; uint32_t timestamp,quotetime; int32_t destvout,DEXselector = 0; uint64_t txfee,satoshis,desttxfee,destsatoshis,value; struct basilisk_request R;
if ( (method= jstr(argjson,"method")) != 0 )
if ( mysatoshis >= othersatoshis )
return(0);
else return(-1);
}
cJSON *LP_tradecandidates(struct LP_utxoinfo *myutxo,char *base)
{
struct LP_peerinfo *peer,*tmp; struct LP_quoteinfo Q; char *utxostr,coinstr[16]; cJSON *array,*icopy,*retarray=0,*item; int32_t i,n; double price; int64_t estimatedbase;
if ( (price= LP_price(base,myutxo->coin)) == .0 )
{
printf("no LP_price (%s -> %s)\n",base,myutxo->coin);
return(0);
}
estimatedbase = myutxo->satoshis / price;
printf("%s -> %s price %.8f mysatoshis %llu estimated base %llu\n",base,myutxo->coin,price,(long long)myutxo->satoshis,(long long)estimatedbase);
if ( estimatedbase <= 0 )
return(0);
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( (utxostr= issue_LP_clientgetutxos(peer->ipaddr,peer->port,base,100)) != 0 )
{
//printf("%s:%u %s\n",peer->ipaddr,peer->port,utxostr);
if ( (array= cJSON_Parse(utxostr)) != 0 )
{
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
retarray = cJSON_CreateArray();
for (i=0; i<n; i++)
{
item = jitem(array,i);
//printf("%s\n",jprint(item,0));
safecopy(coinstr,jstr(item,"base"),sizeof(coinstr));
if ( strcmp(coinstr,base) == 0 && LP_sizematch(estimatedbase,j64bits(item,"satoshis")) == 0 )
{
icopy = 0;
if ( (price= LP_pricecache(&Q,base,myutxo->coin,jbits256(item,"txid"),jint(item,"vout"))) != 0. )
{
if ( LP_sizematch(myutxo->satoshis,Q.destsatoshis) == 0 )
icopy = jduplicate(item);
} else icopy = jduplicate(item);
if ( icopy != 0 )
{
if ( price != 0. )
jaddnum(icopy,"price",price);
jaddi(retarray,icopy);
}
} else printf("skip %s estimated %.8f vs %.8f\n",coinstr,dstr(estimatedbase),dstr(j64bits(item,"satoshis")));
}
}
free_json(array);
}
free(utxostr);
}
if ( retarray != 0 )
break;
}
return(retarray);
}
cJSON *LP_autotrade(struct LP_utxoinfo *myutxo,char *base,double maxprice)
{
static bits256 zero;
int32_t i,n,besti,DEXselector=0; cJSON *array,*item,*bestitem=0; struct basilisk_request R; double bestmetric,metric,bestprice=0.,price,prices[100]; struct LP_quoteinfo Q[sizeof(prices)/sizeof(*prices)];
bestprice = 0.;
if ( maxprice == 0. )
maxprice = LP_price(base,myutxo->coin) / 0.975;
if ( (array= LP_tradecandidates(myutxo,base)) != 0 )
{
printf("candidates.(%s)\n",jprint(array,0));
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
memset(prices,0,sizeof(prices));
memset(Q,0,sizeof(Q));
for (i=0; i<n && i<sizeof(prices)/sizeof(*prices); i++)
{
item = jitem(array,i);
LP_quoteparse(&Q[i],item);
if ( (price= jdouble(item,"price")) == 0. )
{
price = LP_query("price",&Q[i],jstr(item,"ipaddr"),jint(item,"port"),base,myutxo->coin,zero);
if ( Q[i].destsatoshis != 0 && (double)j64bits(item,"satoshis")/Q[i].destsatoshis > price )
{
printf("adjustprice %.8f -> %.8f\n",price,(double)j64bits(item,"satoshis")/Q[i].destsatoshis);
price = (double)j64bits(item,"satoshis")/Q[i].destsatoshis;
}
}
if ( (prices[i]= price) != 0. && (bestprice == 0. || price < bestprice) )
bestprice = price;
char str[65]; printf("i.%d of %d: (%s) -> txid.%s price %.8f best %.8f\n",i,n,jprint(item,0),bits256_str(str,Q[i].txid),price,bestprice);
}
if ( bestprice != 0. )
{
bestmetric = 0.;
besti = -1;
for (i=0; i<n && i<sizeof(prices)/sizeof(*prices); i++)
{
if ( (price= prices[i]) != 0. && Q[i].destsatoshis != 0 )
{
metric = price / bestprice;
printf("%f ",metric);
if ( metric > 0.9 )
{
metric = Q[i].destsatoshis / metric * metric * metric;
printf("%f, ",metric);
if ( metric > bestmetric )
{
besti = i;
bestmetric = metric;
}
}
}
}
printf("metrics, best %f\n",bestmetric);
if ( besti >= 0 )//&& bits256_cmp(myutxo->mypub,otherpubs[besti]) == 0 )
{
i = besti;
bestprice = prices[i];
item = jitem(array,i);
bestitem = LP_quotejson(&Q[i]);
printf("bestprice %f vs maxprice %f\n",bestprice,maxprice);
if ( maxprice == 0. || bestprice <= maxprice )
{
Q[i].desttxid = myutxo->txid;
Q[i].destvout = myutxo->vout;
Q[i].feetxid = myutxo->txid2;
Q[i].feevout = myutxo->vout2;
strcpy(Q[i].destaddr,myutxo->coinaddr);
price = LP_query("request",&Q[i],jstr(item,"ipaddr"),jint(item,"port"),base,myutxo->coin,myutxo->mypub);
if ( jobj(bestitem,"price") != 0 )
jdelete(bestitem,"price");
jaddnum(bestitem,"price",prices[i]);
if ( price <= maxprice )
{
Q[i].desttxid = myutxo->txid;
Q[i].destvout = myutxo->vout;
Q[i].feetxid = myutxo->txid2;
Q[i].feevout = myutxo->vout2;
strcpy(Q[i].destaddr,myutxo->coinaddr);
price = LP_query("connect",&Q[i],jstr(item,"ipaddr"),jint(item,"port"),base,myutxo->coin,myutxo->mypub);
LP_requestinit(&R,Q[i].srchash,Q[i].desthash,base,Q[i].satoshis,Q[i].destcoin,Q[i].destsatoshis,Q[i].timestamp,Q[i].quotetime,DEXselector);
jaddstr(bestitem,"status","connected");
jaddnum(bestitem,"requestid",R.requestid);
jaddnum(bestitem,"quoteid",R.quoteid);
printf("Alice r.%u q.%u\n",R.requestid,R.quoteid);
} else jaddstr(bestitem,"status","too expensive");
}
}
}
free_json(array);
}
}
if ( bestitem == 0 )
return(cJSON_Parse("{\"error\":\"no match found\"}"));
return(bestitem);
}
int32_t LP_priceping(int32_t pubsock,struct LP_utxoinfo *utxo,char *rel,double profitmargin)
{
double price; uint32_t now; cJSON *retjson; struct LP_quoteinfo Q; char *retstr;
if ( (now= (uint32_t)time(NULL)) > utxo->swappending )
utxo->swappending = 0;
if ( now > utxo->published+60 && utxo->swappending == 0 && utxo->pair < 0 && utxo->swap == 0 && (price= LP_price(utxo->coin,rel)) != 0. )
{
price *= (1. + profitmargin);
if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
return(-1);
Q.timestamp = (uint32_t)time(NULL);
retjson = LP_quotejson(&Q);
jaddstr(retjson,"method","quote");
retstr = jprint(retjson,1);
LP_send(pubsock,retstr,1);
utxo->published = now;
return(0);
}
return(-1);
}
int32_t LP_command(struct LP_peerinfo *mypeer,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen,double profitmargin)
{
char *method,*base,*rel,*retstr,pairstr[512]; cJSON *retjson; double price; bits256 privkey,txid; struct LP_utxoinfo *utxo; int32_t retval = -1,DEXselector = 0; uint64_t destvalue; struct basilisk_request R; struct LP_quoteinfo Q;
if ( IAMCLIENT == 0 && (method= jstr(argjson,"method")) != 0 )
{
txid = jbits256(argjson,"txid");
if ( (utxo= LP_utxofind(txid,jint(argjson,"vout"))) != 0 && strcmp(utxo->ipaddr,mypeer->ipaddr) == 0 && utxo->port == mypeer->port && (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && strcmp(base,utxo->coin) == 0 )
{
//printf("LP_command.(%s)\n",jprint(argjson,0));
if ( time(NULL) > utxo->swappending )
utxo->swappending = 0;
if ( strcmp(method,"price") == 0 || strcmp(method,"request") == 0 )
{
if ( utxo->swappending == 0 && utxo->pair < 0 )
retval = 1;
if ( utxo->swappending == 0 )
{
if ( utxo->pair >= 0 )
if ( strcmp(method,"request") == 0 && utxo->pair >= 0 )
nn_close(utxo->pair), utxo->pair = -1;
if ( (price= LP_price(base,rel)) != 0. )
{
price *= (1. + profitmargin);
retjson = cJSON_CreateObject();
jaddstr(retjson,"base",base);
jaddstr(retjson,"rel",rel);
jaddnum(retjson,"timestamp",time(NULL));
jaddnum(retjson,"price",price);
jaddbits256(retjson,"txid",txid);
pubkey = LP_pubkey(LP_privkey(utxo->coinaddr));
jaddbits256(retjson,"srchash",pubkey);
txfee = LP_txfee(base);
jadd64bits(retjson,"txfee",txfee);
jadd64bits(retjson,"satoshis",utxo->satoshis - txfee);
jadd64bits(retjson,"destsatoshis",price * (utxo->satoshis-txfee));
if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
return(-1);
if ( strcmp(method,"price") == 0 )
Q.timestamp = (uint32_t)time(NULL);
retjson = LP_quotejson(&Q);
if ( strcmp(method,"request") == 0 )
{
utxo->swappending = (uint32_t)(time(NULL) + 60);
utxo->otherpubkey = jbits256(argjson,"pubkey");
jaddstr(retjson,"result","reserved");
retval |= 2;
utxo->swappending = (uint32_t)(time(NULL) + LP_RESERVETIME);
utxo->otherpubkey = jbits256(argjson,"desthash");
jaddnum(retjson,"quotetime",juint(argjson,"quotetime"));
jaddnum(retjson,"pending",utxo->swappending);
jaddbits256(retjson,"desthash",utxo->otherpubkey);
jaddstr(retjson,"method","reserved");
}
else jaddstr(retjson,"method","quote");
retstr = jprint(retjson,1);
LP_send(pubsock,retstr,1);
}
}
utxo->published = (uint32_t)time(NULL);
} else printf("null price\n");
} else printf("swappending.%u pair.%d\n",utxo->swappending,utxo->pair);
}
else if ( strcmp(method,"connect") == 0 )
{
retval = 4;
if ( utxo->pair < 0 )
{
if ( (price= LP_price(base,rel)) != 0. )
{
price *= (1. + profitmargin);
txfee = LP_txfee(base);
satoshis = j64bits(argjson,"satoshis");
desttxfee = LP_txfee(rel);
desttxid = jbits256(argjson,"desttxid");
destvout = jint(argjson,"destvout");
timestamp = juint(argjson,"timestamp");
quotetime = juint(argjson,"quotetime");
if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 )
return(-1);
if ( LP_quoteparse(&Q,argjson) < 0 )
return(-2);
//printf("connect with.(%s)\n",jprint(argjson,0));
privkey = LP_privkey(utxo->coinaddr);
pubkey = LP_pubkey(privkey);
srchash = jbits256(argjson,"srchash");
value = j64bits(argjson,"destsatoshis");
if ( timestamp == utxo->swappending-60 && quotetime >= timestamp && quotetime < utxo->swappending && bits256_cmp(pubkey,srchash) == 0 && (destsatoshis= LP_txvalue(rel,desttxid,destvout)) > price*(utxo->satoshis-txfee)+desttxfee && value <= destsatoshis-desttxfee )
if ( bits256_nonz(utxo->mypub) == 0 )
utxo->mypub = LP_pubkey(privkey);
if ( bits256_nonz(privkey) != 0 && Q.quotetime >= Q.timestamp-3 && Q.quotetime < utxo->swappending && bits256_cmp(utxo->mypub,Q.srchash) == 0 && (destvalue= LP_txvalue(rel,Q.desttxid,Q.destvout)) >= price*Q.satoshis+Q.desttxfee && destvalue >= Q.destsatoshis+Q.desttxfee )
{
destsatoshis = value;
Q.change = destvalue - (Q.destsatoshis+Q.desttxfee);
nanomsg_tcpname(pairstr,mypeer->ipaddr,10000+(rand() % 10000));
if ( (utxo->pair= nn_socket(AF_SP,NN_PAIR)) < 0 )
printf("error creating utxo->pair\n");
else if ( (pairstr= jstr(argjson,"pair")) != 0 && nn_connect(utxo->pair,pairstr) >= 0 )
else if ( nn_bind(utxo->pair,pairstr) >= 0 )
{
desthash = jbits256(argjson,"desthash");
LP_requestinit(&R,srchash,desthash,base,satoshis,rel,destsatoshis,timestamp,quotetime,DEXselector);
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_bobloop,(void *)utxo) != 0 )
//char str[65]; printf("destsatoshis %.8f %s t%u\n",dstr(Q.destsatoshis),bits256_str(str,Q.desthash),Q.quotetime);
LP_requestinit(&R,Q.srchash,Q.desthash,base,Q.satoshis,rel,Q.destsatoshis,Q.timestamp,Q.quotetime,DEXselector);
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_bobloop,(void *)utxo) == 0 )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","connected");
retjson = LP_quotejson(&Q);
jaddstr(retjson,"method","connected");
jaddstr(retjson,"pair",pairstr);
jaddnum(retjson,"requestid",R.requestid);
jaddnum(retjson,"quoteid",R.quoteid);
retstr = jprint(retjson,1);
LP_send(pubsock,retstr,1);
utxo->swap = LP_swapinit(1,0,privkey,&R);
utxo->swap = LP_swapinit(1,0,privkey,&R,&Q);
}
else
{
@ -126,28 +490,117 @@ void LP_command(struct LP_peerinfo *mypeer,int32_t pubsock,cJSON *argjson,uint8_
}
else
{
if ( pairstr != 0 )
printf("printf error nn_connect to %s\n",pairstr);
else printf("(%s) missing pair\n",jprint(argjson,0));
printf("printf error nn_connect to %s\n",pairstr);
nn_close(utxo->pair);
utxo->pair = -1;
}
} else printf("dest %.8f < required %.8f\n",dstr(value),dstr(price*(utxo->satoshis-txfee)));
} else printf("dest %.8f < required %.8f (%d %d %d %d %d %d) %.8f %.8f\n",dstr(Q.satoshis),dstr(price*(utxo->satoshis-Q.txfee)),bits256_nonz(privkey) != 0 ,Q.timestamp == utxo->swappending-LP_RESERVETIME ,Q.quotetime >= Q.timestamp ,Q.quotetime < utxo->swappending ,bits256_cmp(utxo->mypub,Q.srchash) == 0 , LP_txvalue(rel,Q.desttxid,Q.destvout) >= price*Q.satoshis+Q.desttxfee,dstr(LP_txvalue(rel,Q.desttxid,Q.destvout)),dstr(price*Q.satoshis+Q.desttxfee));
} else printf("no price for %s/%s\n",base,rel);
} else printf("utxo->pair.%d when connect came in (%s)\n",utxo->pair,jprint(argjson,0));
}
}
}
return(retval);
}
char *LP_connected(cJSON *argjson)
{
cJSON *retjson; int32_t pairsock = -1; char *pairstr; struct LP_quoteinfo *qp; int32_t DEXselector = 0;
retjson = cJSON_CreateObject();
if ( IAMCLIENT == 0 )
jaddstr(retjson,"result","update stats");
else
{
if ( (pairstr= jstr(argjson,"pair")) == 0 || (pairsock= nn_socket(AF_SP,NN_PAIR)) < 0 )
jaddstr(retjson,"error","couldnt create pairsock");
else if ( nn_connect(pairsock,pairstr) >= 0 )
{
qp = calloc(1,sizeof(*qp));
LP_quoteparse(qp,argjson);
qp->pair = pairsock;
qp->privkey = LP_privkey(qp->destaddr);
LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis,qp->destcoin,qp->destsatoshis,qp->timestamp,qp->quotetime,DEXselector);
printf("alice pairstr.(%s)\n",pairstr);
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_aliceloop,(void *)qp) == 0 )
{
jaddstr(retjson,"result","success");
jadd(retjson,"trade",LP_quotejson(qp));
} else jaddstr(retjson,"error","couldnt aliceloop");
}
}
return(jprint(retjson,1));
}
// addcoin api
char *stats_JSON(cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port
{
char *method,*ipaddr,*coin,*retstr = 0; uint16_t argport,pushport,subport; int32_t otherpeers,othernumutxos; struct LP_peerinfo *peer; cJSON *retjson;
char *method,*ipaddr,*userpass,*base,*rel,*coin,*retstr = 0; uint16_t argport,pushport,subport; int32_t amclient,otherpeers,othernumutxos; struct LP_peerinfo *peer; cJSON *retjson;
if ( (method= jstr(argjson,"method")) == 0 )
return(clonestr("{\"error\":\"need method in request\"}"));
else
if ( USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 )
{
if ( USERPASS_COUNTER == 0 )
{
USERPASS_COUNTER = 1;
retjson = cJSON_CreateObject();
jaddstr(retjson,"userpass",USERPASS);
jaddstr(retjson,"BTC",BTCADDR);
jaddstr(retjson,"KMD",KMDADDR);
return(jprint(retjson,1));
}
if ( (userpass= jstr(argjson,"userpass")) == 0 || strcmp(userpass,USERPASS) != 0 )
return(clonestr("{\"error\":\"authentication error\"}"));
if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 )
{
if ( strcmp(method,"setprice") == 0 )
{
if ( LP_mypriceset(base,rel,jdouble(argjson,"price")) < 0 )
return(clonestr("{\"error\":\"couldnt set price\"}"));
else return(clonestr("{\"result\":\"success\"}"));
}
else if ( strcmp(method,"myprice") == 0 )
{
double bid,ask;
if ( LP_myprice(&bid,&ask,base,rel) != 0. )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"base",base);
jaddstr(retjson,"rel",rel);
jaddnum(retjson,"bid",bid);
jaddnum(retjson,"ask",ask);
return(jprint(retjson,1));
} else return(clonestr("{\"error\":\"no price set\"}"));
}
}
else if ( (coin= jstr(argjson,"coin")) != 0 )
{
if ( strcmp(method,"inventory") == 0 )
{
LP_privkey_init(0,-1,coin,0,USERPASS_WIFSTR,1);
return(LP_inventory(coin));
}
else if ( IAMCLIENT != 0 && (strcmp(method,"candidates") == 0 || strcmp(method,"autotrade") == 0) )
{
bits256 txid; int32_t vout; struct LP_utxoinfo *utxo;
txid = jbits256(argjson,"txid");
if ( bits256_nonz(txid) == 0 )
return(clonestr("{\"error\":\"invalid or missing txid\"}"));
if ( jobj(argjson,"vout") == 0 )
return(clonestr("{\"error\":\"missing vout\"}"));
vout = jint(argjson,"vout");
if ( (utxo= LP_utxofind(txid,vout)) == 0 )
return(clonestr("{\"error\":\"txid/vout not found\"}"));
if ( strcmp(method,"candidates") == 0 )
return(jprint(LP_tradecandidates(utxo,coin),1));
else return(jprint(LP_autotrade(utxo,coin,jdouble(argjson,"maxprice")),1));
}
}
}
amclient = (LP_mypeer == 0);
if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 )
{
if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 )
if ( strcmp(ipaddr,"127.0.0.1") != 0 && port >= 1000 )
{
if ( (pushport= juint(argjson,"push")) == 0 )
pushport = argport + 1;
@ -155,32 +608,42 @@ char *stats_JSON(cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port
subport = argport + 2;
if ( (peer= LP_peerfind((uint32_t)calc_ipbits(ipaddr),argport)) != 0 )
{
if ( (otherpeers= jint(argjson,"numpeers")) > peer->numpeers )
if ( 0 && (otherpeers= jint(argjson,"numpeers")) > peer->numpeers )
peer->numpeers = otherpeers;
if ( (othernumutxos= jint(argjson,"numutxos")) > peer->numutxos )
if ( 0 && (othernumutxos= jint(argjson,"numutxos")) > peer->numutxos )
{
printf("change.(%s) numutxos.%d -> %d mynumutxos.%d\n",peer->ipaddr,peer->numutxos,othernumutxos,LP_mypeer->numutxos);
printf("change.(%s) numutxos.%d -> %d mynumutxos.%d\n",peer->ipaddr,peer->numutxos,othernumutxos,LP_mypeer != 0 ? LP_mypeer->numutxos:0);
peer->numutxos = othernumutxos;
}
//printf("peer.(%s) found (%d %d) (%d %d) (%s)\n",peer->ipaddr,peer->numpeers,peer->numutxos,otherpeers,othernumutxos,jprint(argjson,0));
} else LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,argport,pushport,subport,jdouble(argjson,"profit"),jint(argjson,"numpeers"),jint(argjson,"numutxos"));
if ( strcmp(method,"getpeers") == 0 )
retstr = LP_peers();
else if ( strcmp(method,"getutxos") == 0 && (coin= jstr(argjson,"coin")) != 0 )
retstr = LP_utxos(LP_mypeer,coin,jint(argjson,"lastn"));
else if ( strcmp(method,"notify") == 0 )
retstr = clonestr("{\"result\":\"success\",\"notify\":\"received\"}");
else if ( strcmp(method,"notifyutxo") == 0 )
{
printf("utxonotify.(%s)\n",jprint(argjson,0));
LP_addutxo(LP_mypeer,LP_mypubsock,jstr(argjson,"coin"),jbits256(argjson,"txid"),jint(argjson,"vout"),SATOSHIDEN * jdouble(argjson,"value"),jbits256(argjson,"deposit"),jint(argjson,"dvout"),SATOSHIDEN * jdouble(argjson,"dvalue"),jstr(argjson,"script"),jstr(argjson,"address"),ipaddr,argport,jdouble(argjson,"profit"));
retstr = clonestr("{\"result\":\"success\",\"notifyutxo\":\"received\"}");
}
} else printf("malformed request.(%s)\n",jprint(argjson,0));
} else LP_addpeer(amclient,LP_mypeer,LP_mypubsock,ipaddr,argport,pushport,subport,jdouble(argjson,"profit"),jint(argjson,"numpeers"),jint(argjson,"numutxos"));
}
}
//printf("CMD.(%s)\n",jprint(argjson,0));
if ( strcmp(method,"quote") == 0 || strcmp(method,"reserved") == 0 )
retstr = LP_quotereceived(argjson);
else if ( strcmp(method,"connected") == 0 )
retstr = LP_connected(argjson);
else if ( strcmp(method,"getprice") == 0 )
retstr = LP_pricestr(jstr(argjson,"base"),jstr(argjson,"rel"));
else if ( strcmp(method,"orderbook") == 0 )
retstr = LP_orderbook(jstr(argjson,"base"),jstr(argjson,"rel"));
else if ( strcmp(method,"getpeers") == 0 )
retstr = LP_peers();
else if ( IAMCLIENT == 0 && strcmp(method,"getutxos") == 0 && (coin= jstr(argjson,"coin")) != 0 )
retstr = LP_utxos(LP_mypeer,coin,jint(argjson,"lastn"));
else if ( IAMCLIENT == 0 && strcmp(method,"notify") == 0 )
retstr = clonestr("{\"result\":\"success\",\"notify\":\"received\"}");
else if ( IAMCLIENT == 0 && strcmp(method,"notifyutxo") == 0 )
{
printf("utxonotify.(%s)\n",jprint(argjson,0));
LP_addutxo(amclient,LP_mypeer,LP_mypubsock,jstr(argjson,"coin"),jbits256(argjson,"txid"),jint(argjson,"vout"),SATOSHIDEN * jdouble(argjson,"value"),jbits256(argjson,"txid2"),jint(argjson,"vout2"),SATOSHIDEN * jdouble(argjson,"value2"),jstr(argjson,"script"),jstr(argjson,"address"),jstr(argjson,"ipaddr"),juint(argjson,"port"),jdouble(argjson,"profit"));
retstr = clonestr("{\"result\":\"success\",\"notifyutxo\":\"received\"}");
}
if ( retstr != 0 )
return(retstr);
retjson = cJSON_CreateObject();
jaddstr(retjson,"error","unrecognized command");
printf("ERROR.(%s)\n",jprint(argjson,0));
return(clonestr(jprint(retjson,1)));
}

368
iguana/exchanges/LP_include.h

@ -21,55 +21,6 @@
#ifndef LP_INCLUDE_H
#define LP_INCLUDE_H
#define BASILISK_DISABLEWAITTX
#define BASILISK_DISABLESENDTX
#define BASILISK_DEFAULT_NUMCONFIRMS 5
#define DEX_SLEEP 3
#define BASILISK_DEXDURATION 300
#define BASILISK_MSGDURATION 30
#define BASILISK_AUCTION_DURATION 5
#define BASILISK_MAXFUTUREBLOCK 60
#define BASILISK_KEYSIZE ((int32_t)(2*sizeof(bits256)+sizeof(uint32_t)*2))
extern char GLOBAL_DBDIR[];
void *bitcoin_ctx();
int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen);
int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig,bits256 messagehash2,uint8_t *pubkey,size_t plen);
int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag);
bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey);
bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even);
char *bitcoin_base58encode(char *coinaddr,uint8_t *data,int32_t datalen);
int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr);
#define IGUANA_MAXSCRIPTSIZE 10001
#define IGUANA_SEQUENCEID_FINAL 0xfffffffe
#define IGUANA_SCRIPT_NULL 0
#define IGUANA_SCRIPT_76AC 1
#define IGUANA_SCRIPT_76A988AC 2
#define IGUANA_SCRIPT_P2SH 3
#define IGUANA_SCRIPT_OPRETURN 4
#define IGUANA_SCRIPT_3of3 5
#define IGUANA_SCRIPT_2of3 6
#define IGUANA_SCRIPT_1of3 7
#define IGUANA_SCRIPT_2of2 8
#define IGUANA_SCRIPT_1of2 9
#define IGUANA_SCRIPT_MSIG 10
#define IGUANA_SCRIPT_DATA 11
#define IGUANA_SCRIPT_AC 12
#define IGUANA_SCRIPT_1of1 13
#define IGUANA_SCRIPT_STRANGE 15
#define BASILISK_TIMEOUT 3000
#define BASILISK_MINFANOUT 8
#define BASILISK_MAXFANOUT 64
#define BASILISK_DEFAULTDIFF 0x1effffff
#define BASILISK_HDROFFSET ((int32_t)(sizeof(bits256)+sizeof(struct iguana_msghdr)+sizeof(uint32_t)))
#define INSTANTDEX_DECKSIZE 1000
#define INSTANTDEX_LOCKTIME (3600*2 + 300*2)
#define INSTANTDEX_INSURANCEDIV 777
@ -80,6 +31,20 @@ int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr);
#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu"
#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf"
#define BASILISK_DISABLEWAITTX
#define BASILISK_DISABLESENDTX
#define LP_PROPAGATION_SLACK 10 // txid ordering is not enforced, so getting extra recent txid
#define LP_RESERVETIME 60
#define LP_AVETXSIZE 200
#define LP_CACHEDURATION 60
#define BASILISK_DEFAULT_NUMCONFIRMS 5
#define DEX_SLEEP 3
#define BASILISK_KEYSIZE ((int32_t)(2*sizeof(bits256)+sizeof(uint32_t)*2))
extern char GLOBAL_DBDIR[],USERPASS[],USERPASS_WIFSTR[];
extern int32_t IAMCLIENT,USERPASS_COUNTER;
struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; };
struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; };
@ -102,7 +67,7 @@ struct vin_info
struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid;
int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,hashtype,userdatalen,suppress_pubkeys,ignore_cltverr;
uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65];
uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE],userdata[IGUANA_MAXSCRIPTSIZE];
uint8_t rmd160[20],spendscript[10000],p2shscript[10000],userdata[10000];
};
struct basilisk_swapmessage
@ -171,10 +136,10 @@ struct basilisk_swapinfo
struct iguana_info
{
uint64_t txfee,estimatedfee;
uint64_t txfee; double estimatedrate;
int32_t longestchain;
uint8_t pubtype,p2shtype,isPoS,wiftype;
char symbol[16],changeaddr[64];
char symbol[16],changeaddr[64],userpass[1024],serverport[128];
};
struct basilisk_swap
@ -190,280 +155,49 @@ struct basilisk_swap
struct basilisk_swapmessage *messages; int32_t nummessages;
char Bdeposit[64],Bpayment[64];
uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2];
uint8_t persistent_pubkey33[33],pad[15],verifybuf[65536];
uint8_t persistent_pubkey33[33],changermd160[20],pad[15],verifybuf[65536];
};
static struct bitcoin_opcode { UT_hash_handle hh; uint8_t opcode,flags,stackitems; int8_t extralen; } *OPTABLE; static char *OPCODES[0x100]; static int32_t OPCODELENS[0x100];
#define SIGHASH_ALL 1
#define SIGHASH_NONE 2
#define SIGHASH_SINGLE 3
#define SIGHASH_ANYONECANPAY 0x80
#define SCRIPT_OP_NOP 0x00
#define SCRIPT_OP_TRUE 0x51
#define SCRIPT_OP_2 0x52
#define SCRIPT_OP_3 0x53
#define SCRIPT_OP_4 0x54
#define SCRIPT_OP_IF 0x63
#define SCRIPT_OP_ELSE 0x67
#define SCRIPT_OP_RETURN 0x6a
#define SCRIPT_OP_DUP 0x76
#define SCRIPT_OP_ENDIF 0x68
#define SCRIPT_OP_DROP 0x75
#define SCRIPT_OP_EQUALVERIFY 0x88
#define SCRIPT_OP_SHA256 0xa8
#define SCRIPT_OP_HASH160 0xa9
#define SCRIPT_OP_EQUAL 0x87
#define SCRIPT_OP_CHECKSIG 0xac
#define SCRIPT_OP_CHECKMULTISIG 0xae
#define SCRIPT_OP_CHECKSEQUENCEVERIFY 0xb2
#define SCRIPT_OP_CHECKLOCKTIMEVERIFY 0xb1
#define IGUANA_OP_0 0x00
#define IGUANA_OP_PUSHDATA1 0x4c
#define IGUANA_OP_PUSHDATA2 0x4d
#define IGUANA_OP_PUSHDATA4 0x4e
#define IGUANA_OP_1NEGATE 0x4f
#define IGUANA_OP_1 0x51
#define IGUANA_OP_16 0x60
#define IGUANA_OP_NOP 0x61
#define IGUANA_OP_IF 0x63
#define IGUANA_OP_NOTIF 0x64
#define IGUANA_OP_ELSE 0x67
#define IGUANA_OP_ENDIF 0x68
#define IGUANA_OP_VERIFY 0x69
#define IGUANA_OP_RETURN 0x6a
#define IGUANA_OP_TOALTSTACK 0x6b
#define IGUANA_OP_FROMALTSTACK 0x6c
#define IGUANA_OP_2DROP 0x6d
#define IGUANA_OP_2DUP 0x6e
#define IGUANA_OP_3DUP 0x6f
#define IGUANA_OP_2OVER 0x70
#define IGUANA_OP_2ROT 0x71
#define IGUANA_OP_2SWAP 0x72
#define IGUANA_OP_IFDUP 0x73
#define IGUANA_OP_DEPTH 0x74
#define IGUANA_OP_DROP 0x75
#define IGUANA_OP_DUP 0x76
#define IGUANA_OP_NIP 0x77
#define IGUANA_OP_OVER 0x78
#define IGUANA_OP_PICK 0x79
#define IGUANA_OP_ROLL 0x7a
#define IGUANA_OP_ROT 0x7b
#define IGUANA_OP_SWAP 0x7c
#define IGUANA_OP_TUCK 0x7d
#define IGUANA_OP_EQUAL 0x87
#define IGUANA_OP_EQUALVERIFY 0x88
#define IGUANA_OP_1ADD 0x8b
#define IGUANA_OP_1SUB 0x8c
#define IGUANA_OP_NEGATE 0x8f
#define IGUANA_OP_ABS 0x90
#define IGUANA_OP_NOT 0x91
#define IGUANA_OP_0NOTEQUAL 0x92
#define IGUANA_OP_ADD 0x93
#define IGUANA_OP_SUB 0x94
#define IGUANA_OP_BOOLAND 0x9a
#define IGUANA_OP_BOOLOR 0x9b
#define IGUANA_OP_NUMEQUAL 0x9c
#define IGUANA_OP_NUMEQUALVERIFY 0x9d
#define IGUANA_OP_NUMNOTEQUAL 0x9e
#define IGUANA_OP_LESSTHAN 0x9f
#define IGUANA_OP_GREATERTHAN 0xa0
#define IGUANA_OP_LESSTHANOREQUAL 0xa1
#define IGUANA_OP_GREATERTHANOREQUAL 0xa2
#define IGUANA_OP_MIN 0xa3
#define IGUANA_OP_MAX 0xa4
#define IGUANA_OP_WITHIN 0xa5
#define IGUANA_OP_RIPEMD160 0xa6
#define IGUANA_OP_SHA1 0xa7
#define IGUANA_OP_SHA256 0xa8
#define IGUANA_OP_HASH160 0xa9
#define IGUANA_OP_HASH256 0xaa
#define IGUANA_OP_CODESEPARATOR 0xab
#define IGUANA_OP_CHECKSIG 0xac
#define IGUANA_OP_CHECKSIGVERIFY 0xad
#define IGUANA_OP_CHECKMULTISIG 0xae
#define IGUANA_OP_CHECKMULTISIGVERIFY 0xaf
#define IGUANA_OP_NOP1 0xb0
#define IGUANA_OP_CHECKLOCKTIMEVERIFY 0xb1
#define IGUANA_OP_CHECKSEQUENCEVERIFY 0xb2
#define IGUANA_OP_NOP10 0xb9
#define IGUANA_OP_COMBINEPUBKEYS 0xc0
#define IGUANA_OP_CHECKSCHNORR 0xc1
#define IGUANA_OP_CHECKSCHNORRVERIFY 0xc2
// https://github.com/TierNolan/bips/blob/cpkv/bip-cprkv.mediawiki
#define IGUANA_OP_CHECKPRIVATEKEY 0xc3
#define IGUANA_OP_CHECKPRIVATEKEYVERIFY 0xc4
struct LP_utxoinfo
{
UT_hash_handle hh;
bits256 txid,txid2,feetxid,otherpubkey,mypub;
void *swap;
uint64_t satoshis,satoshis2;
uint8_t key[sizeof(bits256) + sizeof(int32_t)];
int32_t vout,vout2,pair;
uint32_t lasttime,errors,swappending,published;
double profitmargin;
char ipaddr[64],coinaddr[64],spendscript[256],coin[16];
uint16_t port;
};
#define IGUANA_NOPFLAG 1
#define IGUANA_ALWAYSILLEGAL 2
#define IGUANA_EXECUTIONILLEGAL 4
#define IGUANA_POSTVERIFY 8
#define IGUANA_CRYPTOFLAG 16
#define IGUANA_MATHFLAG 32
#define IGUANA_CONTROLFLAG 64
#define IGUANA_STACKFLAG 128
struct LP_peerinfo
{
UT_hash_handle hh;
uint64_t ip_port;
double profitmargin;
uint32_t ipbits,errortime,errors,numpeers,numutxos,lasttime,connected;
int32_t pushsock,subsock;
uint16_t port;
char ipaddr[64];
};
enum opcodetype
struct LP_quoteinfo
{
// push value
OP_0 = 0x00,
OP_FALSE = OP_0,
OP_PUSHDATA1 = 0x4c,
OP_PUSHDATA2 = 0x4d,
OP_PUSHDATA4 = 0x4e,
OP_1NEGATE = 0x4f,
OP_RESERVED = 0x50,
OP_1 = 0x51,
OP_TRUE=OP_1,
OP_2 = 0x52,
OP_3 = 0x53,
OP_4 = 0x54,
OP_5 = 0x55,
OP_6 = 0x56,
OP_7 = 0x57,
OP_8 = 0x58,
OP_9 = 0x59,
OP_10 = 0x5a,
OP_11 = 0x5b,
OP_12 = 0x5c,
OP_13 = 0x5d,
OP_14 = 0x5e,
OP_15 = 0x5f,
OP_16 = 0x60,
// control
OP_NOP = 0x61,
OP_VER = 0x62,
OP_IF = 0x63,
OP_NOTIF = 0x64,
OP_VERIF = 0x65,
OP_VERNOTIF = 0x66,
OP_ELSE = 0x67,
OP_ENDIF = 0x68,
OP_VERIFY = 0x69,
OP_RETURN = 0x6a,
// stack ops
OP_TOALTSTACK = 0x6b,
OP_FROMALTSTACK = 0x6c,
OP_2DROP = 0x6d,
OP_2DUP = 0x6e,
OP_3DUP = 0x6f,
OP_2OVER = 0x70,
OP_2ROT = 0x71,
OP_2SWAP = 0x72,
OP_IFDUP = 0x73,
OP_DEPTH = 0x74,
OP_DROP = 0x75,
OP_DUP = 0x76,
OP_NIP = 0x77,
OP_OVER = 0x78,
OP_PICK = 0x79,
OP_ROLL = 0x7a,
OP_ROT = 0x7b,
OP_SWAP = 0x7c,
OP_TUCK = 0x7d,
// splice ops
OP_CAT = 0x7e,
OP_SUBSTR = 0x7f,
OP_LEFT = 0x80,
OP_RIGHT = 0x81,
OP_SIZE = 0x82,
// bit logic
OP_INVERT = 0x83,
OP_AND = 0x84,
OP_OR = 0x85,
OP_XOR = 0x86,
OP_EQUAL = 0x87,
OP_EQUALVERIFY = 0x88,
OP_RESERVED1 = 0x89,
OP_RESERVED2 = 0x8a,
// numeric
OP_1ADD = 0x8b,
OP_1SUB = 0x8c,
OP_2MUL = 0x8d,
OP_2DIV = 0x8e,
OP_NEGATE = 0x8f,
OP_ABS = 0x90,
OP_NOT = 0x91,
OP_0NOTEQUAL = 0x92,
OP_ADD = 0x93,
OP_SUB = 0x94,
OP_MUL = 0x95,
OP_DIV = 0x96,
OP_MOD = 0x97,
OP_LSHIFT = 0x98,
OP_RSHIFT = 0x99,
OP_BOOLAND = 0x9a,
OP_BOOLOR = 0x9b,
OP_NUMEQUAL = 0x9c,
OP_NUMEQUALVERIFY = 0x9d,
OP_NUMNOTEQUAL = 0x9e,
OP_LESSTHAN = 0x9f,
OP_GREATERTHAN = 0xa0,
OP_LESSTHANOREQUAL = 0xa1,
OP_GREATERTHANOREQUAL = 0xa2,
OP_MIN = 0xa3,
OP_MAX = 0xa4,
OP_WITHIN = 0xa5,
// crypto
OP_RIPEMD160 = 0xa6,
OP_SHA1 = 0xa7,
OP_SHA256 = 0xa8,
OP_HASH160 = 0xa9,
OP_HASH256 = 0xaa,
OP_CODESEPARATOR = 0xab,
OP_CHECKSIG = 0xac,
OP_CHECKSIGVERIFY = 0xad,
OP_CHECKMULTISIG = 0xae,
OP_CHECKMULTISIGVERIFY = 0xaf,
// expansion
OP_NOP1 = 0xb0,
OP_CHECKLOCKTIMEVERIFY = 0xb1,
OP_CHECKSEQUENCEVERIFY = 0xb2,
OP_NOP4 = 0xb3,
OP_NOP5 = 0xb4,
OP_NOP6 = 0xb5,
OP_NOP7 = 0xb6,
OP_NOP8 = 0xb7,
OP_NOP9 = 0xb8,
OP_NOP10 = 0xb9,
OP_COMBINEPUBKEYS = 0xc0,
OP_CHECKSCHNORR = 0xc1,
OP_CHECKSCHNORRVERIFY = 0xc2,
OP_CHECKPRIVATEKEY = 0xc3,
OP_CHECKPRIVATEKEYVERIFY = 0xc4,
// template matching params
//OP_SMALLINTEGER = 0xfa,
//OP_PUBKEYS = 0xfb,
//OP_PUBKEYHASH = 0xfd,
//OP_PUBKEY = 0xfe,
OP_INVALIDOPCODE = 0xff,
struct basilisk_request R;
bits256 srchash,desthash,txid,txid2,desttxid,feetxid,privkey;
uint64_t satoshis,satoshis2,txfee,destsatoshis,desttxfee,change;
uint32_t timestamp,quotetime; int32_t vout,vout2,destvout,feevout,pair;
char srccoin[16],coinaddr[64],destcoin[16],destaddr[64];
};
void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx);
uint32_t basilisk_requestid(struct basilisk_request *rp);
uint32_t basilisk_quoteid(struct basilisk_request *rp);
struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp);
char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params);
uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend);
#endif

779
iguana/exchanges/LP_nativeDEX.c

@ -17,673 +17,286 @@
// LP_nativeDEX.c
// marketmaker
//
// jl777: fix price calcs based on specific txfees
#include <stdio.h>
#include "LP_include.h"
#include "LP_network.c"
#define LP_PROPAGATION_SLACK 10 // txid ordering is not enforced, so getting extra recent txid
struct LP_utxoinfo *LP_utxoinfos;
struct LP_peerinfo *LP_peerinfos,*LP_mypeer;
char *default_LPnodes[] = { "5.9.253.195", "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", "5.9.253.204" };
portable_mutex_t LP_peermutex,LP_utxomutex,LP_commandmutex;
int32_t LP_mypubsock = -1;
char *activecoins[] = { "BTC", "KMD", "REVS", "JUMBLR" };//"LTC", "USD", };
char GLOBAL_DBDIR[] = { "DB" };
char USERPASS[65],USERPASS_WIFSTR[64],BTCADDR[64],KMDADDR[64],USERHOME[512] = { "/root" };
struct LP_peerinfo
{
UT_hash_handle hh;
uint64_t ip_port;
double profitmargin;
uint32_t ipbits,errortime,errors,numpeers,numutxos,lasttime,connected;
int32_t pushsock,subsock;
uint16_t port;
char ipaddr[64];
} *LP_peerinfos,*LP_mypeer;
char *default_LPnodes[] = { "5.9.253.196", "5.9.253.197", "5.9.253.198", "5.9.253.199", "5.9.253.200", "5.9.253.201", "5.9.253.202", "5.9.253.203", "5.9.253.204" }; //"5.9.253.195",
struct LP_utxoinfo
{
UT_hash_handle hh;
bits256 txid,deposittxid,otherpubkey;
void *swap;
uint64_t satoshis,depositsatoshis;
uint8_t key[sizeof(bits256) + sizeof(int32_t)];
int32_t vout,depositvout,pair; uint32_t lasttime,errors,swappending;
double profitmargin;
char ipaddr[64],coinaddr[64],spendscript[256],coin[16];
uint16_t port;
} *LP_utxoinfos;
portable_mutex_t LP_peermutex,LP_utxomutex,LP_commandmutex,LP_cachemutex;
int32_t LP_mypubsock = -1;
int32_t Client_connections;
int32_t USERPASS_COUNTER,IAMCLIENT = 0;
double LP_profitratio = 1.;
struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port)
// stubs
int32_t basilisk_istrustedbob(struct basilisk_swap *swap)
{
struct LP_peerinfo *peer=0; uint64_t ip_port;
ip_port = ((uint64_t)port << 32) | ipbits;
portable_mutex_lock(&LP_peermutex);
HASH_FIND(hh,LP_peerinfos,&ip_port,sizeof(ip_port),peer);
portable_mutex_unlock(&LP_peermutex);
return(peer);
// for BTC and if trusted LP
return(0);
}
struct LP_utxoinfo *LP_utxofind(bits256 txid,int32_t vout)
void tradebot_swap_balancingtrade(struct basilisk_swap *swap,int32_t iambob)
{
struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)];
memcpy(key,txid.bytes,sizeof(txid));
memcpy(&key[sizeof(txid)],&vout,sizeof(vout));
portable_mutex_lock(&LP_utxomutex);
HASH_FIND(hh,LP_utxoinfos,key,sizeof(key),utxo);
portable_mutex_unlock(&LP_utxomutex);
return(utxo);
}
cJSON *LP_peerjson(struct LP_peerinfo *peer)
void tradebot_pendingadd(cJSON *tradejson,char *base,double basevolume,char *rel,double relvolume)
{
cJSON *item = cJSON_CreateObject();
jaddstr(item,"ipaddr",peer->ipaddr);
jaddnum(item,"port",peer->port);
jaddnum(item,"profit",peer->profitmargin);
return(item);
// add to trades
}
cJSON *LP_utxojson(struct LP_utxoinfo *utxo)
char *LP_getdatadir()
{
cJSON *item = cJSON_CreateObject();
jaddstr(item,"ipaddr",utxo->ipaddr);
jaddnum(item,"port",utxo->port);
jaddnum(item,"profit",utxo->profitmargin);
jaddstr(item,"coin",utxo->coin);
jaddstr(item,"address",utxo->coinaddr);
jaddstr(item,"script",utxo->spendscript);
jaddbits256(item,"txid",utxo->txid);
jaddnum(item,"vout",utxo->vout);
jaddnum(item,"value",dstr(utxo->satoshis));
jaddbits256(item,"deposit",utxo->deposittxid);
jaddnum(item,"dvout",utxo->depositvout);
jaddnum(item,"dvalue",dstr(utxo->depositsatoshis));
return(item);
return(USERHOME);
}
char *LP_peers()
char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_t skip)
{
struct LP_peerinfo *peer,*tmp; cJSON *peersjson = cJSON_CreateArray();
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
jaddi(peersjson,LP_peerjson(peer));
}
return(jprint(peersjson,1));
return(0);
}
char *LP_utxos(struct LP_peerinfo *mypeer,char *coin,int32_t lastn)
#include "LP_secp.c"
#include "LP_bitcoin.c"
#include "LP_coins.c"
#include "LP_rpc.c"
#include "LP_prices.c"
#include "LP_transaction.c"
#include "LP_remember.c"
#include "LP_swap.c"
#include "LP_peers.c"
#include "LP_utxos.c"
#include "LP_commands.c"
void LP_mainloop(struct LP_peerinfo *mypeer,uint16_t mypubport,int32_t pubsock,int32_t pullsock,uint16_t myport,int32_t amclient,char *passphrase,double profitmargin)
{
int32_t i,firsti; struct LP_utxoinfo *utxo,*tmp; cJSON *utxosjson = cJSON_CreateArray();
i = 0;
if ( lastn >= mypeer->numutxos )
firsti = -1;
else firsti = (mypeer->numutxos - lastn);
HASH_ITER(hh,LP_utxoinfos,utxo,tmp)
//static uint16_t tmpport;
char *retstr; uint8_t r; int32_t i,n,j,len,recvsize,counter=0,nonz,lastn; struct LP_peerinfo *peer,*tmp; struct LP_utxoinfo *utxo,*utmp; void *ptr; cJSON *argjson;
if ( amclient == 0 )
{
if ( i++ < firsti )
continue;
if ( coin == 0 || coin[0] == 0 || strcmp(coin,utxo->coin) == 0 )
for (i=0; i<sizeof(default_LPnodes)/sizeof(*default_LPnodes); i++)
{
jaddi(utxosjson,LP_utxojson(utxo));
if ( (rand() % 100) > 25 )
continue;
LP_peersquery(amclient,mypeer,pubsock,default_LPnodes[i],myport,mypeer->ipaddr,myport,profitmargin);
}
}
return(jprint(utxosjson,1));
}
struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,double profitmargin,int32_t numpeers,int32_t numutxos)
{
uint32_t ipbits; int32_t pushsock,subsock,timeout; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0;
ipbits = (uint32_t)calc_ipbits(ipaddr);
expand_ipbits(checkip,ipbits);
if ( strcmp(checkip,ipaddr) == 0 )
else
{
//printf("LPaddpeer %s\n",ipaddr);
if ( (peer= LP_peerfind(ipbits,port)) != 0 )
{
if ( peer->profitmargin == 0. )
peer->profitmargin = profitmargin;
if ( numpeers > peer->numpeers )
peer->numpeers = numpeers;
if ( numutxos > peer->numutxos )
peer->numutxos = numutxos;
}
else
OS_randombytes((void *)&r,sizeof(r));
for (j=0; j<sizeof(default_LPnodes)/sizeof(*default_LPnodes); j++)
{
peer = calloc(1,sizeof(*peer));
peer->pushsock = peer->subsock = pushsock = subsock = -1;
strcpy(peer->ipaddr,ipaddr);
if ( pushport != 0 && subport != 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 )
{
if ( (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 )
{
timeout = 1000;
nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
timeout = 1;
nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0);
peer->pushsock = pushsock;
peer->subsock = subsock;
nanomsg_tcpname(pushaddr,peer->ipaddr,pushport);
nanomsg_tcpname(subaddr,peer->ipaddr,subport);
printf("adding (%s and %s) %d %d\n",pushaddr,subaddr,peer->pushsock,peer->subsock);
if ( nn_connect(peer->pushsock,pushaddr) >= 0 && nn_connect(peer->subsock,subaddr) >= 0 )
peer->connected = (uint32_t)time(NULL);
} else nn_close(pushsock);
}
peer->profitmargin = profitmargin;
peer->ipbits = ipbits;
peer->port = port;
peer->ip_port = ((uint64_t)port << 32) | ipbits;
portable_mutex_lock(&LP_peermutex);
HASH_ADD(hh,LP_peerinfos,ip_port,sizeof(peer->ip_port),peer);
if ( mypeer != 0 )
{
mypeer->numpeers++;
printf("_LPaddpeer %s -> numpeers.%d mypubsock.%d other.(%d %d)\n",ipaddr,mypeer->numpeers,mypubsock,numpeers,numutxos);
} else peer->numpeers = 1; // will become mypeer
portable_mutex_unlock(&LP_peermutex);
if ( mypubsock >= 0 )
LP_send(mypubsock,jprint(LP_peerjson(peer),1),1);
i = (r + j) % (sizeof(default_LPnodes)/sizeof(*default_LPnodes));
LP_peersquery(amclient,mypeer,pubsock,default_LPnodes[i],myport,"127.0.0.1",myport,profitmargin);
}
}
return(peer);
}
struct LP_utxoinfo *LP_addutxo(struct LP_peerinfo *mypeer,int32_t mypubsock,char *coin,bits256 txid,int32_t vout,int64_t satoshis,bits256 deposittxid,int32_t depositvout,int64_t depositsatoshis,char *spendscript,char *coinaddr,char *ipaddr,uint16_t port,double profitmargin)
{
struct LP_utxoinfo *utxo = 0; uint8_t key[sizeof(txid) + sizeof(vout)];
if ( coin == 0 || coin[0] == 0 || spendscript == 0 || spendscript[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(deposittxid) == 0 || vout < 0 || depositvout < 0 || satoshis <= 0 || depositsatoshis <= 0 )
//if ( amclient != 0 )
// tmpport = myport + 10;
//else tmpport = myport;
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 )
{
printf("malformed addutxo %d %d %d %d %d %d %d %d %d %d %d %d\n", coin == 0,coin[0] == 0,spendscript == 0,spendscript[0] == 0,coinaddr == 0,coinaddr[0] == 0,bits256_nonz(txid) == 0,bits256_nonz(deposittxid) == 0,vout < 0,depositvout < 0,satoshis <= 0,depositsatoshis <= 0);
return(0);
printf("error launching stats rpcloop for port.%u\n",myport);
exit(-1);
}
if ( (utxo= LP_utxofind(txid,vout)) != 0 )
for (i=0; i<sizeof(activecoins)/sizeof(*activecoins); i++)
{
if ( bits256_cmp(txid,utxo->txid) != 0 || bits256_cmp(deposittxid,utxo->deposittxid) != 0 || vout != utxo->vout || satoshis != utxo->satoshis || depositvout != utxo->depositvout || depositsatoshis != utxo->depositsatoshis || strcmp(coin,utxo->coin) != 0 || strcmp(spendscript,utxo->spendscript) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || strcmp(ipaddr,utxo->ipaddr) != 0 || port != utxo->port )
{
utxo->errors++;
char str[65]; printf("error on subsequent utxo add.(%s)\n",bits256_str(str,txid));
}
else if ( profitmargin != 0. )
utxo->profitmargin = profitmargin;
LP_coinfind(activecoins[i]);
LP_priceinfoadd(activecoins[i]);
}
else
LP_privkey_updates(mypeer,pubsock,passphrase,amclient);
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
utxo = calloc(1,sizeof(*utxo));
utxo->pair = -1;
utxo->profitmargin = profitmargin;
strcpy(utxo->ipaddr,ipaddr);
utxo->port = port;
safecopy(utxo->coin,coin,sizeof(utxo->coin));
safecopy(utxo->coinaddr,coinaddr,sizeof(utxo->coinaddr));
safecopy(utxo->spendscript,spendscript,sizeof(utxo->spendscript));
utxo->txid = txid;
utxo->vout = vout;
utxo->satoshis = satoshis;
utxo->deposittxid = deposittxid;
utxo->depositvout = depositvout;
utxo->depositsatoshis = depositsatoshis;
memcpy(key,txid.bytes,sizeof(txid));
memcpy(&key[sizeof(txid)],&vout,sizeof(vout));
memcpy(utxo->key,key,sizeof(key));
portable_mutex_lock(&LP_utxomutex);
HASH_ADD(hh,LP_utxoinfos,key,sizeof(key),utxo);
if ( mypeer != 0 )
{
mypeer->numutxos++;
printf("%s:%u LP_addutxo.(%.8f %.8f) numutxos.%d\n",ipaddr,port,dstr(satoshis),dstr(depositsatoshis),mypeer->numutxos);
}
portable_mutex_unlock(&LP_utxomutex);
if ( mypubsock >= 0 )
LP_send(mypubsock,jprint(LP_utxojson(utxo),1),1);
if ( strcmp(peer->ipaddr,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1") != 0 )
LP_utxosquery(0,mypeer,pubsock,peer->ipaddr,peer->port,"",100,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1",myport,profitmargin);
}
return(utxo);
}
int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now)
{
struct LP_peerinfo *peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0;
if ( (array= cJSON_Parse(retstr)) != 0 )
if ( amclient != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
while ( 1 )
{
for (i=0; i<n; i++)
nonz = n = 0;
if ( (++counter % 3600) == 0 )
LP_privkey_updates(mypeer,pubsock,passphrase,amclient);
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
item = jitem(array,i);
if ( (argipaddr= jstr(item,"ipaddr")) != 0 && (argport= juint(item,"port")) != 0 )
n++;
while ( peer->subsock >= 0 && (recvsize= nn_recv(peer->subsock,&ptr,NN_MSG,0)) >= 0 )
{
if ( (pushport= juint(item,"push")) == 0 )
pushport = argport + 1;
if ( (subport= juint(item,"sub")) == 0 )
subport = argport + 2;
argipbits = (uint32_t)calc_ipbits(argipaddr);
if ( (peer= LP_peerfind(argipbits,argport)) == 0 )
peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jdouble(item,"profit"),jint(item,"numpeers"),jint(item,"numutxos"));
if ( peer != 0 )
nonz++;
if ( (argjson= cJSON_Parse((char *)ptr)) != 0 )
{
peer->lasttime = now;
if ( strcmp(argipaddr,destipaddr) == 0 && destport == argport && peer->numpeers < n )
peer->numpeers = n;
}
portable_mutex_lock(&LP_commandmutex);
if ( (retstr= stats_JSON(argjson,"127.0.0.1",0)) != 0 )
{
//printf("%s RECV.[%d] %s\n",peer->ipaddr,recvsize,(char *)ptr);
free(retstr);
}
portable_mutex_unlock(&LP_commandmutex);
//printf("subloop.(%s)\n",jprint(argjson,0));
free_json(argjson);
} else printf("error parsing.(%s)\n",(char *)ptr);
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
}
}
if ( nonz == 0 )
usleep(100000);
}
free_json(array);
}
return(n);
}
int32_t LP_utxosparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now)
{
struct LP_peerinfo *peer,*destpeer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; bits256 txid; struct LP_utxoinfo *utxo;
if ( (array= cJSON_Parse(retstr)) != 0 )
else
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
while ( 1 )
{
for (i=0; i<n; i++)
nonz = 0;
if ( (++counter % 2000) == 0 )
LP_privkey_updates(mypeer,pubsock,passphrase,amclient);
if ( (counter % 500) == 0 )
{
item = jitem(array,i);
if ( (argipaddr= jstr(item,"ipaddr")) != 0 && (argport= juint(item,"port")) != 0 )
HASH_ITER(hh,LP_utxoinfos,utxo,utmp)
{
if ( (pushport= juint(item,"push")) == 0 )
pushport = argport + 1;
if ( (subport= juint(item,"sub")) == 0 )
subport = argport + 2;
argipbits = (uint32_t)calc_ipbits(argipaddr);
if ( (peer= LP_peerfind(argipbits,argport)) == 0 )
peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jdouble(item,"profit"),jint(item,"numpeers"),jint(item,"numutxos"));
if ( jobj(item,"txid") != 0 )
if ( strcmp(utxo->ipaddr,mypeer->ipaddr) == 0 && utxo->port == mypeer->port )
{
txid = jbits256(item,"txid");
utxo = LP_addutxo(mypeer,mypubsock,jstr(item,"coin"),txid,jint(item,"vout"),SATOSHIDEN*jdouble(item,"value"),jbits256(item,"deposit"),jint(item,"dvout"),SATOSHIDEN * jdouble(item,"dvalue"),jstr(item,"script"),jstr(item,"address"),argipaddr,argport,jdouble(item,"profit"));
if ( utxo != 0 )
utxo->lasttime = now;
if ( strcmp(utxo->coin,"KMD") == 0 )
LP_priceping(pubsock,utxo,"BTC",profitmargin);
else LP_priceping(pubsock,utxo,"KMD",profitmargin);
}
}
}
if ( (destpeer= LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport)) != 0 )
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( destpeer->numutxos < n )
if ( peer->numpeers != mypeer->numpeers || (rand() % 10000) == 0 )
{
destpeer->numutxos = n;
printf("got.(%s) from %s numutxos.%d\n",retstr,destpeer->ipaddr,destpeer->numutxos);
if ( peer->numpeers != mypeer->numpeers )
printf("%s num.%d vs %d\n",peer->ipaddr,peer->numpeers,mypeer->numpeers);
if ( strcmp(peer->ipaddr,mypeer->ipaddr) != 0 )
LP_peersquery(amclient,mypeer,pubsock,peer->ipaddr,peer->port,mypeer->ipaddr,myport,profitmargin);
}
if ( peer->numutxos != mypeer->numutxos )
{
lastn = peer->numutxos - mypeer->numutxos + LP_PROPAGATION_SLACK;
if ( lastn < LP_PROPAGATION_SLACK * 2 )
lastn = LP_PROPAGATION_SLACK * 2;
printf("%s numutxos.%d vs %d lastn.%d\n",peer->ipaddr,peer->numutxos,mypeer->numutxos,lastn);
if ( strcmp(peer->ipaddr,mypeer->ipaddr) != 0 )
LP_utxosquery(0,mypeer,pubsock,peer->ipaddr,peer->port,"",lastn,mypeer->ipaddr,myport,profitmargin);
}
while ( peer->subsock >= 0 && (recvsize= nn_recv(peer->subsock,&ptr,NN_MSG,0)) >= 0 )
{
nonz++;
if ( (argjson= cJSON_Parse((char *)ptr)) != 0 )
{
portable_mutex_lock(&LP_commandmutex);
if ( (retstr= stats_JSON(argjson,"127.0.0.1",0)) != 0 )
{
//printf("%s RECV.[%d] %s\n",peer->ipaddr,recvsize,(char *)ptr);
free(retstr);
}
portable_mutex_unlock(&LP_commandmutex);
free_json(argjson);
} else printf("error parsing.(%s)\n",(char *)ptr);
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
}
}
}
free_json(array);
}
return(n);
}
char *issue_LP_getpeers(char *destip,uint16_t destport,char *ipaddr,uint16_t port,double profitmargin,int32_t numpeers,int32_t numutxos)
{
char url[512];
sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&profit=%.6f&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,profitmargin,numpeers,numutxos);
//printf("send.(%s)\n",url);
return(issue_curl(url));
}
char *issue_LP_getutxos(char *destip,uint16_t destport,char *coin,int32_t lastn,char *ipaddr,uint16_t port,double profitmargin,int32_t numpeers,int32_t numutxos)
{
char url[512];
sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=%s&port=%u&profit=%.6f&numpeers=%d&numutxos=%d",destip,destport,coin,lastn,ipaddr,port,profitmargin,numpeers,numutxos);
return(issue_curl(url));
}
char *issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,double profitmargin,int32_t numpeers,int32_t numutxos)
{
char url[512];
sprintf(url,"http://%s:%u/api/stats/notify?ipaddr=%s&port=%u&profit=%.6f&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,profitmargin,numpeers,numutxos);
return(issue_curl(url));
}
char *issue_LP_notifyutxo(char *destip,uint16_t destport,struct LP_utxoinfo *utxo)
{
char url[4096],str[65],str2[65];
sprintf(url,"http://%s:%u/api/stats/notifyutxo?ipaddr=%s&port=%u&profit=%.6f&coin=%s&txid=%s&vout=%d&value=%.8f&deposit=%s&dvout=%d&dvalue=%.8f&script=%s&address=%s",destip,destport,utxo->ipaddr,utxo->port,utxo->profitmargin,utxo->coin,bits256_str(str,utxo->txid),utxo->vout,dstr(utxo->satoshis),bits256_str(str2,utxo->deposittxid),utxo->depositvout,dstr(utxo->depositsatoshis),utxo->spendscript,utxo->coinaddr);
if ( strlen(url) > 1024 )
printf("WARNING long url.(%s)\n",url);
return(issue_curl(url));
}
void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport,double myprofit)
{
char *retstr; struct LP_peerinfo *peer,*tmp; uint32_t now,flag = 0;
peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport);
if ( peer != 0 && peer->errors > 0 )
return;
if ( (retstr= issue_LP_getpeers(destipaddr,destport,myipaddr,myport,myprofit,mypeer->numpeers,mypeer->numutxos)) != 0 )
{
//printf("got.(%s)\n",retstr);
now = (uint32_t)time(NULL);
LP_peersparse(mypeer,mypubsock,destipaddr,destport,retstr,now);
free(retstr);
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( peer->lasttime != now )
{
printf("{%s:%u %.6f} ",peer->ipaddr,peer->port,peer->profitmargin);
flag++;
if ( (retstr= issue_LP_notify(destipaddr,destport,peer->ipaddr,peer->port,peer->profitmargin,peer->numpeers,0)) != 0 )
free(retstr);
}
}
if ( flag != 0 )
printf(" <- missing peers\n");
} else if ( peer != 0 )
peer->errors++;
}
void LP_utxosquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *coin,int32_t lastn,char *myipaddr,uint16_t myport,double myprofit)
{
char *retstr; struct LP_utxoinfo *utxo,*tmp; struct LP_peerinfo *peer; int32_t i,firsti; uint32_t now,flag = 0;
peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport);
if ( (peer != 0 && peer->errors > 0) || mypeer == 0 )
return;
if ( coin == 0 )
coin = "";
if ( (retstr= issue_LP_getutxos(destipaddr,destport,coin,lastn,myipaddr,myport,myprofit,mypeer->numpeers,mypeer->numutxos)) != 0 )
{
now = (uint32_t)time(NULL);
LP_utxosparse(mypeer,mypubsock,destipaddr,destport,retstr,now);
free(retstr);
i = 0;
if ( lastn >= mypeer->numutxos )
firsti = -1;
else firsti = (mypeer->numutxos - lastn);
HASH_ITER(hh,LP_utxoinfos,utxo,tmp)
{
if ( i++ < firsti )
continue;
if ( utxo->lasttime != now )
{
char str[65]; printf("{%s:%u %s} ",utxo->ipaddr,utxo->port,bits256_str(str,utxo->txid));
flag++;
if ( (retstr= issue_LP_notifyutxo(destipaddr,destport,utxo)) != 0 )
free(retstr);
}
}
if ( flag != 0 )
printf(" <- missing utxos\n");
} else if ( peer != 0 )
peer->errors++;
}
int32_t LP_maxvalue(uint64_t *values,int32_t n)
{
int32_t i,maxi = -1; uint64_t maxval = 0;
for (i=0; i<n; i++)
if ( values[i] > maxval )
{
maxi = i;
maxval = values[i];
}
return(maxi);
}
int32_t LP_nearestvalue(uint64_t *values,int32_t n,uint64_t targetval)
{
int32_t i,mini = -1; int64_t dist; uint64_t mindist = (1 << 31);
for (i=0; i<n; i++)
{
dist = (values[i] - targetval);
if ( dist < 0 && -dist < values[i]/10 )
dist = -dist;
if ( dist >= 0 && dist < mindist )
{
mini = i;
mindist = dist;
}
}
return(mini);
}
uint64_t LP_privkey_init(struct LP_peerinfo *mypeer,int32_t mypubsock,char *coin,uint8_t addrtype,char *passphrase,char *wifstr)
{
char *retstr,coinaddr[64],*script; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,n,vout,depositvout; uint64_t *values,satoshis,depositval,targetval,value,total = 0; bits256 privkey,pubkey; uint8_t pubkey33[33];
if ( passphrase != 0 )
conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
else privkey = iguana_wif2privkey(wifstr);
iguana_priv2pub(pubkey33,coinaddr,privkey,addrtype);
retstr = iguana_listunspent(coin,coinaddr);
if ( retstr != 0 && retstr[0] == '[' && retstr[1] == ']' )
free(retstr), retstr = 0;
if ( retstr == 0 )
{
if ( (retstr= DEX_listunspent(coin,coinaddr)) == 0 )
{
printf("null listunspent\n");
return(0);
}
}
printf("LP_privkey_init.(%s)\n",retstr);
if ( (array= cJSON_Parse(retstr)) != 0 )
{
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
values = calloc(n,sizeof(*values));
for (i=0; i<n; i++)
{
item = jitem(array,i);
satoshis = SATOSHIDEN * jdouble(item,"amount");
values[i] = satoshis;
printf("%.8f ",dstr(satoshis));
}
printf("array.%d\n",n);
used = 0;
while ( used < n )
while ( pullsock >= 0 && (recvsize= nn_recv(pullsock,&ptr,NN_MSG,0)) >= 0 )
{
if ( (i= LP_maxvalue(values,n)) >= 0 )
nonz++;
if ( (argjson= cJSON_Parse((char *)ptr)) != 0 )
{
item = jitem(array,i);
deposittxid = jbits256(item,"txid");
depositvout = juint(item,"vout");
script = jstr(item,"scriptPubKey");
depositval = values[i];
values[i] = 0, used++;
targetval = (depositval / 9) * 8;
printf("i.%d %.8f target %.8f\n",i,dstr(depositval),dstr(targetval));
if ( (i= LP_nearestvalue(values,n,targetval)) >= 0 )
len = (int32_t)strlen((char *)ptr) + 1;
portable_mutex_lock(&LP_commandmutex);
if ( LP_command(mypeer,pubsock,argjson,&((uint8_t *)ptr)[len],recvsize - len,profitmargin) == 0 )
{
item = jitem(array,i);
txid = jbits256(item,"txid");
vout = juint(item,"vout");
if ( jstr(item,"scriptPubKey") != 0 && strcmp(script,jstr(item,"scriptPubKey")) == 0 )
if ( (retstr= stats_JSON(argjson,"127.0.0.1",0)) != 0 )
{
value = values[i];
values[i] = 0, used++;
LP_addutxo(mypeer,mypubsock,coin,txid,vout,value,deposittxid,depositvout,depositval,script,coinaddr,LP_peerinfos[0].ipaddr,LP_peerinfos[0].port,LP_peerinfos[0].profitmargin);
total += value;
//printf("%s RECV.[%d] %s\n",peer->ipaddr,recvsize,(char *)ptr);
free(retstr);
}
}
} else break;
portable_mutex_unlock(&LP_commandmutex);
free_json(argjson);
}
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
}
free(values);
if ( nonz == 0 )
usleep(50000);
}
free_json(array);
}
free(retstr);
return(total);
}
int32_t basilisk_istrustedbob(struct basilisk_swap *swap)
{
// for BTC and if trusted LP
return(0);
}
struct iguana_info KMDcoin,BTCcoin,LTCcoin;
struct iguana_info *LP_coinfind(char *symbol)
{
struct iguana_info *coin;
if ( strcmp(symbol,"BTC") == 0 )
return(&BTCcoin);
else if ( strcmp(symbol,"LTC") == 0 )
return(&LTCcoin);
else //if ( strcmp(symbol,"KMD") == 0 )
{
coin = calloc(1,sizeof(*coin));
*coin = KMDcoin;
strcpy(coin->symbol,symbol);
return(coin);
}
}
void tradebot_swap_balancingtrade(struct basilisk_swap *swap,int32_t iambob)
{
}
void tradebot_pendingadd(cJSON *tradejson,char *base,double basevolume,char *rel,double relvolume)
void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,double profitmargin,char *passphrase,int32_t amclient,char *userhome)
{
// add to trades
}
char GLOBAL_DBDIR[] = ".";
#include "LP_secp.c"
#include "LP_rpc.c"
#include "LP_bitcoin.c"
#include "LP_transaction.c"
#include "LP_remember.c"
#include "LP_statemachine.c"
#include "LP_swap.c"
#include "LP_commands.c"
void LPinit(uint16_t myport,uint16_t mypull,uint16_t mypub,double profitmargin)
{
char *myipaddr=0,*retstr; long filesize,n; int32_t len,timeout,maxsize,recvsize,nonz,i,lastn,pullsock=-1,pubsock=-1; struct LP_peerinfo *peer,*tmp,*mypeer=0; char pushaddr[128],subaddr[128]; void *ptr; cJSON *argjson;
char *myipaddr=0; long filesize,n; int32_t timeout,maxsize,pullsock=-1,pubsock=-1; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128];
IAMCLIENT = amclient;
LP_profitratio += profitmargin;
OS_randombytes((void *)&n,sizeof(n));
srand((int32_t)n);
if ( userhome != 0 && userhome[0] != 0 )
safecopy(USERHOME,userhome,sizeof(USERHOME));
portable_mutex_init(&LP_peermutex);
portable_mutex_init(&LP_utxomutex);
portable_mutex_init(&LP_commandmutex);
if ( profitmargin == 0. )
portable_mutex_init(&LP_cachemutex);
if ( amclient == 0 )
{
profitmargin = 0.01;
printf("default profit margin %f\n",profitmargin);
}
if ( system("curl -s4 checkip.amazonaws.com > /tmp/myipaddr") == 0 )
{
if ( (myipaddr= OS_filestr(&filesize,"/tmp/myipaddr")) != 0 && myipaddr[0] != 0 )
if ( profitmargin == 0. || profitmargin == 0.01 )
{
n = strlen(myipaddr);
if ( myipaddr[n-1] == '\n' )
myipaddr[--n] = 0;
pullsock = pubsock = -1;
nanomsg_tcpname(pushaddr,myipaddr,mypull);
nanomsg_tcpname(subaddr,myipaddr,mypub);
printf(">>>>>>>>> myipaddr.%s (%s %s)\n",myipaddr,pushaddr,subaddr);
if ( (pullsock= nn_socket(AF_SP,NN_PULL)) >= 0 && (pubsock= nn_socket(AF_SP,NN_PUB)) >= 0 )
{
if ( nn_bind(pullsock,pushaddr) >= 0 && nn_bind(pubsock,subaddr) >= 0 )
{
timeout = 10;
nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
timeout = 1;
nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
timeout = 1;
maxsize = 1024 * 1024;
nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize));
}
else
{
printf("error binding to (%s).%d (%s).%d\n",pushaddr,pullsock,subaddr,pubsock);
if ( pullsock >= 0 )
nn_close(pullsock), pullsock = -1;
if ( pubsock >= 0 )
nn_close(pubsock), pubsock = -1;
}
} else printf("error getting sockets %d %d\n",pullsock,pubsock);
LP_mypubsock = pubsock;
LP_mypeer = mypeer = LP_addpeer(mypeer,pubsock,myipaddr,myport,0,0,profitmargin,0,0);
//printf("my ipaddr.(%s) peers.(%s)\n",ipaddr,retstr!=0?retstr:"");
for (i=0; i<sizeof(default_LPnodes)/sizeof(*default_LPnodes); i++)
{
if ( (rand() % 100) > 25 )
continue;
LP_peersquery(mypeer,pubsock,default_LPnodes[i],myport,myipaddr,myport,profitmargin);
}
} else printf("error getting myipaddr\n");
} else printf("error issuing curl\n");
if ( myipaddr == 0 || mypeer == 0 )
{
printf("couldnt get myipaddr or null mypeer.%p\n",mypeer);
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 )
{
printf("error launching stats rpcloop for port.%u\n",myport);
exit(-1);
}
LP_privkey_init(mypeer,pubsock,"KMD",60,"test","");
printf("utxos.(%s)\n",LP_utxos(mypeer,"",10000));
while ( 1 )
{
nonz = 0;
HASH_ITER(hh,LP_peerinfos,peer,tmp)
profitmargin = 0.01 + (double)(rand() % 100)/100000;
printf("default profit margin %f\n",profitmargin);
}
if ( system("curl -s4 checkip.amazonaws.com > /tmp/myipaddr") == 0 )
{
if ( peer->numpeers != mypeer->numpeers || (rand() % 10) == 0 )
{
if ( peer->numpeers != mypeer->numpeers )
printf("%s num.%d vs %d\n",peer->ipaddr,peer->numpeers,mypeer->numpeers);
if ( strcmp(peer->ipaddr,myipaddr) != 0 )
LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport,profitmargin);
}
if ( peer->numutxos != mypeer->numutxos )
if ( (myipaddr= OS_filestr(&filesize,"/tmp/myipaddr")) != 0 && myipaddr[0] != 0 )
{
lastn = peer->numutxos - mypeer->numutxos + LP_PROPAGATION_SLACK;
if ( lastn < 0 )
lastn = LP_PROPAGATION_SLACK * 2;
printf("%s numutxos.%d vs %d lastn.%d\n",peer->ipaddr,peer->numutxos,mypeer->numutxos,lastn);
if ( strcmp(peer->ipaddr,myipaddr) != 0 )
LP_utxosquery(mypeer,pubsock,peer->ipaddr,peer->port,"",lastn,myipaddr,myport,profitmargin);
}
while ( peer->subsock >= 0 && (recvsize= nn_recv(peer->subsock,&ptr,NN_MSG,0)) >= 0 )
{
nonz++;
if ( (argjson= cJSON_Parse((char *)ptr)) != 0 )
n = strlen(myipaddr);
if ( myipaddr[n-1] == '\n' )
myipaddr[--n] = 0;
pullsock = pubsock = -1;
nanomsg_tcpname(pushaddr,myipaddr,mypullport);
nanomsg_tcpname(subaddr,myipaddr,mypubport);
printf(">>>>>>>>> myipaddr.%s (%s %s)\n",myipaddr,pushaddr,subaddr);
if ( (pullsock= nn_socket(AF_SP,NN_PULL)) >= 0 && (pubsock= nn_socket(AF_SP,NN_PUB)) >= 0 )
{
portable_mutex_lock(&LP_commandmutex);
if ( (retstr= stats_JSON(argjson,"127.0.0.1",mypub)) != 0 )
if ( nn_bind(pullsock,pushaddr) >= 0 && nn_bind(pubsock,subaddr) >= 0 )
{
printf("%s RECV.[%d] %s\n",peer->ipaddr,recvsize,(char *)ptr);
free(retstr);
timeout = 10;
nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
timeout = 1;
nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
timeout = 1;
maxsize = 1024 * 1024;
nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize));
}
portable_mutex_unlock(&LP_commandmutex);
free_json(argjson);
} else printf("error parsing.(%s)\n",(char *)ptr);
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
}
}
while ( pullsock >= 0 && (recvsize= nn_recv(pullsock,&ptr,NN_MSG,0)) >= 0 )
else
{
printf("error binding to (%s).%d (%s).%d\n",pushaddr,pullsock,subaddr,pubsock);
if ( pullsock >= 0 )
nn_close(pullsock), pullsock = -1;
if ( pubsock >= 0 )
nn_close(pubsock), pubsock = -1;
}
} else printf("error getting sockets %d %d\n",pullsock,pubsock);
LP_mypubsock = pubsock;
LP_mypeer = mypeer = LP_addpeer(amclient,mypeer,pubsock,myipaddr,myport,0,0,profitmargin,0,0);
//printf("my ipaddr.(%s) peers.(%s)\n",ipaddr,retstr!=0?retstr:"");
} else printf("error getting myipaddr\n");
} else printf("error issuing curl\n");
if ( myipaddr == 0 || mypeer == 0 )
{
nonz++;
if ( (argjson= cJSON_Parse((char *)ptr)) != 0 )
{
len = (int32_t)strlen((char *)ptr) + 1;
portable_mutex_lock(&LP_commandmutex);
LP_command(mypeer,mypub,argjson,&ptr[len],recvsize - len,profitmargin);
portable_mutex_unlock(&LP_commandmutex);
free_json(argjson);
}
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
printf("couldnt get myipaddr or null mypeer.%p\n",mypeer);
exit(-1);
}
if ( nonz == 0 )
sleep(mypeer->numpeers + 1);
printf("utxos.(%s)\n",LP_utxos(mypeer,"",10000));
}
LP_mainloop(mypeer,mypubport,pubsock,pullsock,myport,amclient,passphrase,profitmargin);
}
#ifdef __APPLE__
int32_t nn_bind() { return(-1); }
int32_t nn_close() { return(-1); }
int32_t nn_connect() { return(-1); }
int32_t nn_freemsg() { return(-1); }
int32_t nn_poll() { return(-1); }
int32_t nn_recv() { return(-1); }
int32_t nn_send() { return(-1); }
int32_t nn_setsockopt() { return(-1); }
int32_t nn_socket() { return(-1); }
#endif

249
iguana/exchanges/LP_network.c

@ -18,94 +18,6 @@
// marketmaker
//
void basilisk_psockinit(struct basilisk_swap *swap,int32_t amlp)
{
/* char keystr[64],databuf[1024],pubkeystr[128],*retstr,*retstr2,*datastr,*pushaddr=0,*subaddr=0; cJSON *retjson,*addrjson; uint8_t data[512]; int32_t datalen,timeout,pushsock = -1,subsock = -1;
if ( swap->connected == 1 )
return;
if ( swap->pushsock < 0 && swap->subsock < 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 && (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 )
{
timeout = 1000;
nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
timeout = 1;
nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0);
swap->pushsock = pushsock;
swap->subsock = subsock;
}
if ( (subsock= swap->subsock) < 0 || (pushsock= swap->pushsock) < 0 )
{
printf("error getting nn_sockets\n");
return;
}
sprintf(keystr,"%08x-%08x",swap->I.req.requestid,swap->I.req.quoteid);
if ( swap->connected == 0 && (retstr= _dex_kvsearch("KV",keystr)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (datastr= jstr(retjson,"value")) != 0 )
{
datalen = (int32_t)strlen(datastr) >> 1;
decode_hex((uint8_t *)databuf,datalen,datastr);
if ( (addrjson= cJSON_Parse(databuf)) != 0 )
{
pushaddr = jstr(addrjson,"push");
subaddr = jstr(addrjson,"sub");
if ( pushaddr != 0 && subaddr != 0 )
{
printf("KV decoded (%s and %s) %d %d\n",pushaddr,subaddr,swap->pushsock,swap->subsock);
if ( nn_connect(swap->pushsock,pushaddr) >= 0 && nn_connect(swap->subsock,subaddr) >= 0 )
swap->connected = 1;
}
free_json(addrjson);
}
}
free_json(retjson);
}
printf("KVsearch.(%s) -> (%s) connected.%d socks.(%d %d) amlp.%d\n",keystr,retstr,swap->connected,swap->pushsock,swap->subsock,amlp);
free(retstr);
}
printf("connected.%d amlp.%d subsock.%d pushsock.%d\n",swap->connected,amlp,subsock,pushsock);
if ( swap->connected <= 0 && amlp != 0 && subsock >= 0 && pushsock >= 0 )
{
if ( (retstr= _dex_psock("{}")) != 0 )
{
printf("psock returns.(%s)\n",retstr);
// {"result":"success","pushaddr":"tcp://5.9.102.210:30002","subaddr":"tcp://5.9.102.210:30003","randipbits":3606291758,"coin":"KMD","tag":"6952562460568228137"}
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
pushaddr = jstr(retjson,"pushaddr");
subaddr = jstr(retjson,"subaddr");
if ( pushaddr != 0 && subaddr != 0 )
{
if ( nn_connect(pushsock,pushaddr) >= 0 )
{
printf("connected to %d pushaddr.(%s)\n",pushsock,pushaddr);
if ( nn_connect(subsock,subaddr) >= 0 )
{
swap->connected = 1;
init_hexbytes_noT(pubkeystr,myinfo->persistent_pubkey33,33);
sprintf((char *)data,"{\"push\":\"%s\",\"sub\":\"%s\",\"trade\":[\"%s\", %.8f, \"%s\", %.8f],\"pub\":\"%s\"}",pushaddr,subaddr,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),pubkeystr);
datalen = (int32_t)strlen((char *)data) + 1;
printf("datalen.%d (%s)\n",datalen,(char *)data);
init_hexbytes_noT(databuf,data,datalen);
printf("%s -> %s\n",keystr,databuf);
if ( (retstr2= _dex_kvupdate("KV",keystr,databuf,1)) != 0 )
{
printf("KVupdate.(%s)\n",retstr2);
free(retstr2);
}
} else printf("nn_connect error to %d subaddr.(%s)\n",subsock,subaddr);
} else printf("nn_connect error to %d pushaddr.(%s)\n",pushsock,pushaddr);
}
else printf("missing addr (%p) (%p) (%s)\n",pushaddr,subaddr,jprint(retjson,0));
free_json(retjson);
} else printf("Error parsing psock.(%s)\n",retstr);
free(retstr);
} else printf("error issuing _dex_psock\n");
}*/
}
char *nanomsg_tcpname(char *str,char *ipaddr,uint16_t port)
{
sprintf(str,"tcp://%s:%u",ipaddr,port);
@ -115,6 +27,13 @@ char *nanomsg_tcpname(char *str,char *ipaddr,uint16_t port)
int32_t LP_send(int32_t sock,char *msg,int32_t freeflag)
{
int32_t sentbytes,len,i; struct nn_pollfd pfd;
if ( sock < 0 )
{
printf("LP_send.(%s) to illegal socket\n",msg);
if ( freeflag != 0 )
free(msg);
return(-1);
}
for (i=0; i<100; i++)
{
pfd.fd = sock;
@ -132,10 +51,12 @@ int32_t LP_send(int32_t sock,char *msg,int32_t freeflag)
usleep(1000);
}
printf("error LP_send\n");
if ( freeflag != 0 )
free(msg);
return(-1);
}
uint32_t LP_swapsend(struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t nextbits,uint32_t crcs[2])
uint32_t LP_swapsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t nextbits,uint32_t crcs[2])
{
uint8_t *buf; int32_t sentbytes,offset=0,i;
buf = malloc(datalen + sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2);
@ -147,161 +68,15 @@ uint32_t LP_swapsend(struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,i
offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits);
if ( datalen > 0 )
memcpy(&buf[offset],data,datalen), offset += datalen;
if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset )
if ( (sentbytes= nn_send(pairsock,buf,offset,0)) != offset )
{
printf("sentbytes.%d vs offset.%d\n",sentbytes,offset);
if ( sentbytes < 0 )
{
if ( swap->pushsock >= 0 )
nn_close(swap->pushsock), swap->pushsock = -1; //,
if ( swap->subsock >= 0 ) //
nn_close(swap->subsock), swap->subsock = -1;
swap->connected = swap->I.iambob != 0 ? -1 : 0;
swap->aborted = (uint32_t)time(NULL);
}
}
printf("sent %d bytes\n",sentbytes);
//else printf("send.[%d] %x offset.%d datalen.%d [%llx]\n",sentbytes,msgbits,offset,datalen,*(long long *)data);
free(buf);
return(nextbits);
}
void basilisk_swap_sendabort(struct basilisk_swap *swap)
{
uint32_t msgbits = 0; uint8_t buf[sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2]; int32_t sentbytes,offset=0;
memset(buf,0,sizeof(buf));
offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid);
offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits);
if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset )
{
if ( sentbytes < 0 )
{
if ( swap->pushsock >= 0 ) //
nn_close(swap->pushsock), swap->pushsock = -1;
if ( swap->subsock >= 0 ) //
nn_close(swap->subsock), swap->subsock = -1;
swap->connected = 0;
}
} else printf("basilisk_swap_sendabort\n");
}
void basilisk_psockinit(struct basilisk_swap *swap,int32_t amlp);
void basilisk_swapgotdata(struct basilisk_swap *swap,uint32_t crc32,bits256 srchash,bits256 desthash,uint32_t quoteid,uint32_t msgbits,uint8_t *data,int32_t datalen,int32_t reinit)
{
int32_t i; struct basilisk_swapmessage *mp;
for (i=0; i<swap->nummessages; i++)
if ( crc32 == swap->messages[i].crc32 && msgbits == swap->messages[i].msgbits && bits256_cmp(srchash,swap->messages[i].srchash) == 0 && bits256_cmp(desthash,swap->messages[i].desthash) == 0 )
return;
//printf(" new message.[%d] datalen.%d Q.%x msg.%x [%llx]\n",swap->nummessages,datalen,quoteid,msgbits,*(long long *)data);
swap->messages = realloc(swap->messages,sizeof(*swap->messages) * (swap->nummessages + 1));
mp = &swap->messages[swap->nummessages++];
mp->crc32 = crc32;
mp->srchash = srchash;
mp->desthash = desthash;
mp->msgbits = msgbits;
mp->quoteid = quoteid;
mp->data = malloc(datalen);
mp->datalen = datalen;
memcpy(mp->data,data,datalen);
if ( reinit == 0 && swap->fp != 0 )
{
fwrite(mp,1,sizeof(*mp),swap->fp);
fwrite(data,1,datalen,swap->fp);
fflush(swap->fp);
}
}
int32_t basilisk_swapget(struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,int32_t (*basilisk_verify_func)(void *ptr,uint8_t *data,int32_t datalen))
{
uint8_t *ptr; bits256 srchash,desthash; uint32_t crc32,_msgbits,quoteid; int32_t i,size,offset,retval = -1; struct basilisk_swapmessage *mp = 0;
while ( (size= nn_recv(swap->subsock,&ptr,NN_MSG,0)) >= 0 )
{
swap->lasttime = (uint32_t)time(NULL);
memset(srchash.bytes,0,sizeof(srchash));
memset(desthash.bytes,0,sizeof(desthash));
//printf("gotmsg.[%d] crc.%x\n",size,crc32);
offset = 0;
for (i=0; i<32; i++)
srchash.bytes[i] = ptr[offset++];
for (i=0; i<32; i++)
desthash.bytes[i] = ptr[offset++];
offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&quoteid);
offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&_msgbits);
if ( size > offset )
{
crc32 = calc_crc32(0,&ptr[offset],size-offset);
if ( size > offset )
{
//printf("size.%d offset.%d datalen.%d\n",size,offset,size-offset);
basilisk_swapgotdata(swap,crc32,srchash,desthash,quoteid,_msgbits,&ptr[offset],size-offset,0);
}
}
else if ( bits256_nonz(srchash) == 0 && bits256_nonz(desthash) == 0 )
{
if ( swap->aborted == 0 )
{
swap->aborted = (uint32_t)time(NULL);
printf("got abort signal from other side\n");
}
} else printf("basilisk_swapget: got strange packet\n");
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
}
//char str[65],str2[65];
for (i=0; i<swap->nummessages; i++)
{
//printf("%d: %s vs %s\n",i,bits256_str(str,swap->messages[i].srchash),bits256_str(str2,swap->messages[i].desthash));
if ( bits256_cmp(swap->messages[i].desthash,swap->I.myhash) == 0 )
{
if ( swap->messages[i].msgbits == msgbits )
{
if ( swap->I.iambob == 0 && swap->lasttime != 0 && time(NULL) > swap->lasttime+360 )
{
printf("nothing received for a while from Bob, try new sockets\n");
if ( swap->pushsock >= 0 ) //
nn_close(swap->pushsock), swap->pushsock = -1;
if ( swap->subsock >= 0 ) //
nn_close(swap->subsock), swap->subsock = -1;
swap->connected = 0;
basilisk_psockinit(swap,swap->I.iambob != 0);
}
mp = &swap->messages[i];
if ( msgbits != 0x80000000 )
break;
}
}
}
if ( mp != 0 )
retval = (*basilisk_verify_func)(swap,mp->data,mp->datalen);
//printf("mine/other %s vs %s\n",bits256_str(str,swap->I.myhash),bits256_str(str2,swap->I.otherhash));
return(retval);
}
int32_t basilisk_messagekeyread(uint8_t *key,uint32_t *channelp,uint32_t *msgidp,bits256 *srchashp,bits256 *desthashp)
{
int32_t keylen = 0;
keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),channelp);
keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),msgidp);
keylen += iguana_rwbignum(0,&key[keylen],sizeof(*srchashp),srchashp->bytes);
keylen += iguana_rwbignum(0,&key[keylen],sizeof(*desthashp),desthashp->bytes);
return(keylen);
}
int32_t basilisk_messagekey(uint8_t *key,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash)
{
int32_t keylen = 0;
keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&channel);
keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&msgid);
keylen += iguana_rwbignum(1,&key[keylen],sizeof(srchash),srchash.bytes);
keylen += iguana_rwbignum(1,&key[keylen],sizeof(desthash),desthash.bytes);
return(keylen);
}
void LP_channelsend(bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen)
{
int32_t keylen; uint8_t key[BASILISK_KEYSIZE]; //char *retstr;
keylen = basilisk_messagekey(key,channel,msgid,srchash,desthash);
//if ( (retstr= _dex_reqsend(myinfo,"DEX",key,keylen,data,datalen)) != 0 )
// free(retstr);
}

188
iguana/exchanges/LP_peers.c

@ -0,0 +1,188 @@
/******************************************************************************
* 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_peers.c
// marketmaker
//
struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port)
{
struct LP_peerinfo *peer=0; uint64_t ip_port;
ip_port = ((uint64_t)port << 32) | ipbits;
portable_mutex_lock(&LP_peermutex);
HASH_FIND(hh,LP_peerinfos,&ip_port,sizeof(ip_port),peer);
portable_mutex_unlock(&LP_peermutex);
return(peer);
}
cJSON *LP_peerjson(struct LP_peerinfo *peer)
{
cJSON *item = cJSON_CreateObject();
jaddstr(item,"ipaddr",peer->ipaddr);
jaddnum(item,"port",peer->port);
jaddnum(item,"profit",peer->profitmargin);
return(item);
}
char *LP_peers()
{
struct LP_peerinfo *peer,*tmp; cJSON *peersjson = cJSON_CreateArray();
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
jaddi(peersjson,LP_peerjson(peer));
}
return(jprint(peersjson,1));
}
struct LP_peerinfo *LP_addpeer(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,double profitmargin,int32_t numpeers,int32_t numutxos)
{
uint32_t ipbits; int32_t pushsock,subsock,timeout,enabled; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0;
ipbits = (uint32_t)calc_ipbits(ipaddr);
expand_ipbits(checkip,ipbits);
if ( strcmp(checkip,ipaddr) == 0 )
{
if ( (peer= LP_peerfind(ipbits,port)) != 0 )
{
if ( peer->profitmargin == 0. )
peer->profitmargin = profitmargin;
if ( numpeers > peer->numpeers )
peer->numpeers = numpeers;
if ( numutxos > peer->numutxos )
peer->numutxos = numutxos;
}
else
{
//printf("LPaddpeer %s\n",ipaddr);
peer = calloc(1,sizeof(*peer));
peer->pushsock = peer->subsock = pushsock = subsock = -1;
strcpy(peer->ipaddr,ipaddr);
if ( amclient == 0 )
enabled = 1;
else enabled = 1;//(rand() % (1 << Client_connections)) == 0;
if ( pushport != 0 && subport != 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 )
{
timeout = 1000;
nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
nanomsg_tcpname(pushaddr,peer->ipaddr,pushport);
if ( nn_connect(pushsock,pushaddr) >= 0 )
{
printf("connected to push.(%s) %d\n",pushaddr,pushsock);
peer->connected = (uint32_t)time(NULL);
peer->pushsock = pushsock;
if ( enabled != 0 && (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 )
{
timeout = 1;
nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0);
nanomsg_tcpname(subaddr,peer->ipaddr,subport);
if ( nn_connect(subsock,subaddr) >= 0 )
{
peer->subsock = subsock;
printf("connected to sub.(%s) %d\n",subaddr,peer->subsock);
Client_connections += amclient;
} else nn_close(subsock);
}
}
else
{
nn_close(pushsock);
printf("error connecting to push.(%s)\n",pushaddr);
}
} else printf("%s pushport.%u subport.%u pushsock.%d\n",ipaddr,pushport,subport,pushsock);
peer->profitmargin = profitmargin;
peer->ipbits = ipbits;
peer->port = port;
peer->ip_port = ((uint64_t)port << 32) | ipbits;
portable_mutex_lock(&LP_peermutex);
HASH_ADD(hh,LP_peerinfos,ip_port,sizeof(peer->ip_port),peer);
if ( mypeer != 0 )
{
mypeer->numpeers++;
printf("_LPaddpeer %s -> numpeers.%d mypubsock.%d other.(%d %d)\n",ipaddr,mypeer->numpeers,mypubsock,numpeers,numutxos);
} else peer->numpeers = 1; // will become mypeer
portable_mutex_unlock(&LP_peermutex);
if ( mypubsock >= 0 )
LP_send(mypubsock,jprint(LP_peerjson(peer),1),1);
}
} else printf("LP_addpeer: checkip.(%s) vs (%s)\n",checkip,ipaddr);
return(peer);
}
int32_t LP_peersparse(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now)
{
struct LP_peerinfo *peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0;
if ( (array= cJSON_Parse(retstr)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
if ( (argipaddr= jstr(item,"ipaddr")) != 0 && (argport= juint(item,"port")) != 0 )
{
if ( (pushport= juint(item,"push")) == 0 )
pushport = argport + 1;
if ( (subport= juint(item,"sub")) == 0 )
subport = argport + 2;
argipbits = (uint32_t)calc_ipbits(argipaddr);
if ( (peer= LP_peerfind(argipbits,argport)) == 0 )
{
peer = LP_addpeer(amclient,mypeer,mypubsock,argipaddr,argport,pushport,subport,jdouble(item,"profit"),jint(item,"numpeers"),jint(item,"numutxos"));
}
if ( peer != 0 )
{
peer->lasttime = now;
if ( strcmp(argipaddr,destipaddr) == 0 && destport == argport && peer->numpeers != n )
peer->numpeers = n;
}
}
}
}
free_json(array);
}
return(n);
}
void LP_peersquery(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport,double myprofit)
{
char *retstr; struct LP_peerinfo *peer,*tmp; uint32_t now,flag = 0;
peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport);
if ( peer != 0 && peer->errors > 0 )
return;
if ( (retstr= issue_LP_getpeers(destipaddr,destport,myipaddr,myport,myprofit,mypeer!=0?mypeer->numpeers:0,mypeer!=0?mypeer->numutxos:0)) != 0 )
{
//printf("got.(%s)\n",retstr);
now = (uint32_t)time(NULL);
LP_peersparse(amclient,mypeer,mypubsock,destipaddr,destport,retstr,now);
free(retstr);
if ( amclient == 0 )
{
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( peer->lasttime != now )
{
printf("{%s:%u %.6f}.%d ",peer->ipaddr,peer->port,peer->profitmargin,peer->lasttime - now);
flag++;
if ( (retstr= issue_LP_notify(destipaddr,destport,peer->ipaddr,peer->port,peer->profitmargin,peer->numpeers,0)) != 0 )
free(retstr);
}
}
if ( flag != 0 )
printf(" <- missing peers\n");
}
} else if ( peer != 0 )
peer->errors++;
}

350
iguana/exchanges/LP_prices.c

@ -18,24 +18,352 @@
// marketmaker
//
double LP_kmdbtc;
#define LP_MAXPRICEINFOS 64
struct LP_priceinfo
{
char symbol[16];
uint64_t coinbits;
int32_t ind,pad;
double diagval;
double relvals[LP_MAXPRICEINFOS];
double myprices[LP_MAXPRICEINFOS];
} LP_priceinfos[LP_MAXPRICEINFOS];
int32_t LP_numpriceinfos;
// very, very simple for now
struct LP_cacheinfo
{
UT_hash_handle hh;
struct LP_quoteinfo Q;
uint8_t key[sizeof(bits256)+sizeof(uint64_t)*2+sizeof(int32_t)];
double price;
uint32_t timestamp;
} *LP_cacheinfos;
void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32])
int32_t LP_cachekey(uint8_t *key,char *base,char *rel,bits256 txid,int32_t vout)
{
if ( avebid > SMALLVAL && aveask > SMALLVAL && strcmp(base,"KMD") == 0 && strcmp(rel,"BTC") == 0 )
LP_kmdbtc = (avebid + aveask) * 0.5;
uint64_t basebits,relbits; int32_t offset = 0;
basebits = stringbits(base);
relbits = stringbits(rel);
memcpy(&key[offset],&basebits,sizeof(basebits)), offset += sizeof(basebits);
memcpy(&key[offset],&relbits,sizeof(relbits)), offset += sizeof(relbits);
memcpy(&key[offset],&txid,sizeof(txid)), offset += sizeof(txid);
memcpy(&key[offset],&vout,sizeof(vout)), offset += sizeof(vout);
return(offset);
}
double LP_price(char *base,char *rel)
struct LP_cacheinfo *LP_cachefind(char *base,char *rel,bits256 txid,int32_t vout)
{
struct LP_cacheinfo *ptr=0; uint8_t key[sizeof(bits256)+sizeof(uint64_t)*2+sizeof(vout)];
if ( LP_cachekey(key,base,rel,txid,vout) == sizeof(key) )
{
portable_mutex_lock(&LP_cachemutex);
HASH_FIND(hh,LP_cacheinfos,key,sizeof(key),ptr);
portable_mutex_unlock(&LP_cachemutex);
} else printf("LP_cachefind keysize mismatch?\n");
if ( 0 && ptr != 0 && ptr->timestamp != 0 && ptr->timestamp < time(NULL)-LP_CACHEDURATION )
{
printf("expire price %.8f\n",ptr->price);
ptr->price = 0.;
ptr->timestamp = 0;
memset(&ptr->Q,0,sizeof(ptr->Q));
}
return(ptr);
}
double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,int32_t vout)
{
if ( LP_kmdbtc != 0. )
struct LP_cacheinfo *ptr;
if ( (ptr= LP_cachefind(base,rel,txid,vout)) != 0 )
{
if ( strcmp(base,"KMD") == 0 && strcmp(rel,"BTC") == 0 )
return(LP_kmdbtc);
else if ( strcmp(rel,"KMD") == 0 && strcmp(base,"BTC") == 0 )
return(1. / LP_kmdbtc);
if ( qp != 0 )
(*qp) = ptr->Q;
if ( ptr->price == 0. && ptr->Q.satoshis != 0 )
{
printf("null ptr->price? ");
ptr->price = (double)ptr->Q.destsatoshis / ptr->Q.satoshis;
}
//printf("found %s/%s %.8f\n",base,rel,ptr->price);
return(ptr->price);
}
//char str[65]; printf("cachemiss %s/%s %s/v%d\n",base,rel,bits256_str(str,txid),vout);
return(0.);
}
struct LP_priceinfo *LP_priceinfofind(char *symbol)
{
int32_t i; struct LP_priceinfo *pp; uint64_t coinbits;
if ( LP_numpriceinfos > 0 )
{
coinbits = stringbits(symbol);
pp = LP_priceinfos;
for (i=0; i<LP_numpriceinfos; i++,pp++)
if ( pp->coinbits == coinbits )
return(pp);
}
return(0);
}
struct LP_priceinfo *LP_priceinfoptr(int32_t *indp,char *base,char *rel)
{
struct LP_priceinfo *basepp,*relpp;
if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{
*indp = relpp->ind;
return(basepp);
}
else
{
*indp = -1;
return(0);
}
}
void LP_priceinfoupdate(char *base,char *rel,double price)
{
struct LP_priceinfo *basepp,*relpp;
if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{
dxblend(&basepp->relvals[relpp->ind],price,0.9);
dxblend(&relpp->relvals[basepp->ind],1. / price,0.9);
}
}
double LP_myprice(double *bidp,double *askp,char *base,char *rel)
{
struct LP_priceinfo *basepp,*relpp;
if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{
*askp = basepp->myprices[relpp->ind];
*bidp = relpp->myprices[basepp->ind];
return((*askp + *bidp) * 0.5);
} else return(0.);
}
int32_t LP_mypriceset(char *base,char *rel,double price)
{
struct LP_priceinfo *basepp,*relpp;
if ( price != 0. && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{
basepp->myprices[relpp->ind] = price * LP_profitratio; // ask
relpp->myprices[basepp->ind] = (1. / price) * LP_profitratio; // bid
return(0);
} else return(-1);
}
double LP_price(char *base,char *rel)
{
struct LP_priceinfo *basepp; int32_t relind; double price = 0.;
if ( (basepp= LP_priceinfoptr(&relind,base,rel)) != 0 )
{
if ( (price= basepp->myprices[relind]) == 0. )
price = basepp->relvals[relind];
}
return(price);
}
cJSON *LP_priceinfomatrix(int32_t usemyprices)
{
int32_t i,j,n,m; double total,sum,val; struct LP_priceinfo *pp; uint32_t now; struct LP_cacheinfo *ptr,*tmp; cJSON *vectorjson = cJSON_CreateObject();
now = (uint32_t)time(NULL);
HASH_ITER(hh,LP_cacheinfos,ptr,tmp)
{
if ( ptr->timestamp < now-60 || ptr->price == 0. )
continue;
LP_priceinfoupdate(ptr->Q.srccoin,ptr->Q.destcoin,ptr->price);
}
pp = LP_priceinfos;
total = m = 0;
for (i=0; i<LP_numpriceinfos; i++,pp++)
{
pp->diagval = sum = n = 0;
for (j=0; j<LP_numpriceinfos; j++)
{
if ( usemyprices == 0 || (val= pp->myprices[j]) == 0. )
val = pp->relvals[j];
if ( val != 0. )
{
sum += val;
n++;
}
}
if ( n > 0 )
{
pp->diagval = sum / n;
total += pp->diagval, m++;
}
}
if ( m > 0 )
{
pp = LP_priceinfos;
for (i=0; i<LP_numpriceinfos; i++,pp++)
{
pp->diagval /= total;
jaddnum(vectorjson,pp->symbol,pp->diagval);
}
}
return(vectorjson);
}
struct LP_priceinfo *LP_priceinfoadd(char *symbol)
{
struct LP_priceinfo *pp; cJSON *retjson;
if ( LP_numpriceinfos >= sizeof(LP_priceinfos)/sizeof(*LP_priceinfos) )
{
printf("cant add any more priceinfos\n");
return(0);
}
pp = &LP_priceinfos[LP_numpriceinfos];
memset(pp,0,sizeof(*pp));
safecopy(pp->symbol,symbol,sizeof(pp->symbol));
pp->coinbits = stringbits(symbol);
pp->ind = LP_numpriceinfos++;
/*pp->relvals = calloc(LP_numpriceinfos+1,sizeof(*pp->relvals));
//pp->myprices = calloc(LP_numpriceinfos+1,sizeof(*pp->myprices));
vecsize = sizeof(*LP_priceinfos[i].relvals) * (LP_numpriceinfos + 1);
for (i=0; i<LP_numpriceinfos; i++)
{
printf("realloc i.%d of %d relvals.%p\n",i,LP_numpriceinfos,LP_priceinfos[i].relvals);
LP_priceinfos[i].relvals = realloc(LP_priceinfos[i].relvals,vecsize);
memset(LP_priceinfos[i].relvals,0,vecsize);
LP_priceinfos[i].myprices[LP_numpriceinfos] = 0.;
}*/
LP_numpriceinfos++;
if ( (retjson= LP_priceinfomatrix(0)) != 0 )
free_json(retjson);
return(pp);
}
struct LP_cacheinfo *LP_cacheadd(char *base,char *rel,bits256 txid,int32_t vout,double price,struct LP_quoteinfo *qp)
{
char str[65]; struct LP_cacheinfo *ptr=0;
if ( (ptr= LP_cachefind(base,rel,txid,vout)) == 0 )
{
ptr = calloc(1,sizeof(*ptr));
if ( LP_cachekey(ptr->key,base,rel,txid,vout) == sizeof(ptr->key) )
{
portable_mutex_lock(&LP_cachemutex);
HASH_ADD(hh,LP_cacheinfos,key,sizeof(ptr->key),ptr);
portable_mutex_unlock(&LP_cachemutex);
} else printf("LP_cacheadd keysize mismatch?\n");
}
ptr->Q = *qp;
ptr->timestamp = (uint32_t)time(NULL);
if ( price != ptr->price )
{
ptr->price = price;
LP_priceinfoupdate(base,rel,price);
printf("updated %s/v%d %s/%s %llu price %.8f\n",bits256_str(str,txid),vout,base,rel,(long long)qp->satoshis,price);
} else ptr->price = price;
return(ptr);
}
static int _cmp_orderbook(const void *a,const void *b)
{
#define ptr_a ((struct LP_cacheinfo *)a)->price
#define ptr_b ((struct LP_cacheinfo *)b)->price
if ( ptr_b > ptr_a )
return(1);
else if ( ptr_b < ptr_a )
return(-1);
else
{
#undef ptr_a
#undef ptr_b
#define ptr_a ((struct LP_cacheinfo *)a)->Q.satoshis
#define ptr_b ((struct LP_cacheinfo *)b)->Q.satoshis
if ( ptr_b > ptr_a )
return(1);
else if ( ptr_b < ptr_a )
return(-1);
}
return(0);
#undef ptr_a
#undef ptr_b
}
static int _cmp_orderbookrev(const void *a,const void *b)
{
return(-_cmp_orderbook(a,b));
}
cJSON *LP_orderbookjson(struct LP_cacheinfo *ptr,int32_t polarity)
{
double price; cJSON *item = cJSON_CreateObject();
if ( ptr->Q.satoshis != 0 && ptr->Q.destsatoshis != 0 )
{
price = (double)ptr->Q.destsatoshis / ptr->Q.satoshis;
jaddnum(item,"price",polarity > 0 ? price : 1. / price);
jaddnum(item,"volume",polarity > 0 ? dstr(ptr->Q.satoshis) : dstr(ptr->Q.destsatoshis));
jaddbits256(item,"txid",ptr->Q.txid);
jaddnum(item,"vout",ptr->Q.vout);
}
return(item);
}
char *LP_orderbook(char *base,char *rel)
{
uint32_t now,i; struct LP_cacheinfo *ptr,*tmp,**bids = 0,**asks = 0; cJSON *retjson,*array; int32_t numbids=0,numasks=0;
now = (uint32_t)time(NULL);
HASH_ITER(hh,LP_cacheinfos,ptr,tmp)
{
if ( ptr->timestamp < now-60 || ptr->price == 0. )
continue;
if ( strcmp(ptr->Q.srccoin,base) == 0 && strcmp(ptr->Q.destcoin,rel) == 0 )
{
asks = realloc(asks,sizeof(*asks) * (numasks+1));
asks[numasks++] = ptr;
}
else if ( strcmp(ptr->Q.srccoin,rel) == 0 && strcmp(ptr->Q.destcoin,base) == 0 )
{
bids = realloc(bids,sizeof(*bids) * (numbids+1));
bids[numbids++] = ptr;
}
}
retjson = cJSON_CreateObject();
array = cJSON_CreateArray();
if ( numbids > 1 )
qsort(bids,numbids,sizeof(*bids),_cmp_orderbookrev);
for (i=0; i<numbids; i++)
jaddi(array,LP_orderbookjson(bids[i],-1));
jadd(retjson,"bids",array);
array = cJSON_CreateArray();
if ( numasks > 1 )
qsort(asks,numasks,sizeof(*asks),_cmp_orderbook);
for (i=0; i<numasks; i++)
jaddi(array,LP_orderbookjson(asks[i],1));
jadd(retjson,"asks",array);
jaddstr(retjson,"base",base);
jaddstr(retjson,"rel",rel);
jaddnum(retjson,"timestamp",now);
return(jprint(retjson,1));
}
void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32])
{
LP_priceinfoupdate(base,rel,price);
}
char *LP_pricestr(char *base,char *rel)
{
double price = 0.; cJSON *retjson;
if ( base != 0 && base[0] != 0 && rel != 0 && rel[0] != 0 )
price = LP_price(base,rel);
if ( price != 0. )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"base",base);
jaddstr(retjson,"rel",rel);
jaddnum(retjson,"price",price);
jadd(retjson,"theoretical",LP_priceinfomatrix(0));
jadd(retjson,"quotes",LP_priceinfomatrix(1));
return(jprint(retjson,1));
} else return(clonestr("{\"error\":\"cant find baserel pair\"}"));
}

210
iguana/exchanges/LP_remember.c

@ -18,143 +18,6 @@
// marketmaker
//
/*void basilisk_swaps_init(struct supernet_info *myinfo)
{
char fname[512]; uint32_t iter,swapcompleted,requestid,quoteid,optionduration,statebits; FILE *fp; bits256 privkey;struct basilisk_request R; struct basilisk_swapmessage M; struct basilisk_swap *swap = 0;
sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname);
if ( (myinfo->swapsfp= fopen(fname,"rb+")) != 0 )
{
while ( fread(&requestid,1,sizeof(requestid),myinfo->swapsfp) == sizeof(requestid) && fread(&quoteid,1,sizeof(quoteid),myinfo->swapsfp) == sizeof(quoteid) )
{
sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname);
printf("%s\n",fname);
if ( (fp= fopen(fname,"rb+")) != 0 ) // check to see if completed
{
memset(&M,0,sizeof(M));
swapcompleted = 1;
for (iter=0; iter<2; iter++)
{
if ( fread(privkey.bytes,1,sizeof(privkey),fp) == sizeof(privkey) &&
fread(&R,1,sizeof(R),fp) == sizeof(R) &&
fread(&statebits,1,sizeof(statebits),fp) == sizeof(statebits) &&
fread(&optionduration,1,sizeof(optionduration),fp) == sizeof(optionduration) )
{
while ( 0 && fread(&M,1,sizeof(M),fp) == sizeof(M) )
{
M.data = 0;
//printf("entry iter.%d crc32.%x datalen.%d\n",iter,M.crc32,M.datalen);
if ( M.datalen < 100000 )
{
M.data = malloc(M.datalen);
if ( fread(M.data,1,M.datalen,fp) == M.datalen )
{
if ( calc_crc32(0,M.data,M.datalen) == M.crc32 )
{
if ( iter == 1 )
{
if ( swap == 0 )
{
swap = basilisk_thread_start(privkey,&R,statebits,optionduration,1);
swap->I.choosei = swap->I.otherchoosei = -1;
}
if ( swap != 0 )
basilisk_swapgotdata(swap,M.crc32,M.srchash,M.desthash,M.quoteid,M.msgbits,M.data,M.datalen,1);
}
} else printf("crc mismatch %x vs %x\n",calc_crc32(0,M.data,M.datalen),M.crc32);
} else printf("error reading M.datalen %d\n",M.datalen);
free(M.data), M.data = 0;
}
}
}
if ( swapcompleted != 0 )
break;
rewind(fp);
}
}
}
} else myinfo->swapsfp = fopen(fname,"wb+");
}*/
FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit)
{
FILE *fp=0; /*char fname[512];
sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,rp->requestid,rp->quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"rb+")) == 0 )
{
if ( (fp= fopen(fname,"wb+")) != 0 )
{
fwrite(privkey.bytes,1,sizeof(privkey),fp);
fwrite(rp,1,sizeof(*rp),fp);
fwrite(&statebits,1,sizeof(statebits),fp);
fwrite(&optionduration,1,sizeof(optionduration),fp);
fflush(fp);
}
}
else if ( reinit != 0 )
{
}*/
return(fp);
}
int32_t basilisk_swap_load(uint32_t requestid,uint32_t quoteid,bits256 *privkeyp,struct basilisk_request *rp,uint32_t *statebitsp,int32_t *optiondurationp)
{
FILE *fp=0; char fname[512]; int32_t retval = -1;
sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"rb+")) != 0 )
{
if ( fread(privkeyp,1,sizeof(*privkeyp),fp) == sizeof(*privkeyp) &&
fread(rp,1,sizeof(*rp),fp) == sizeof(*rp) &&
fread(statebitsp,1,sizeof(*statebitsp),fp) == sizeof(*statebitsp) &&
fread(optiondurationp,1,sizeof(*optiondurationp),fp) == sizeof(*optiondurationp) )
retval = 0;
fclose(fp);
}
return(retval);
}
void basilisk_swap_saveupdate(struct basilisk_swap *swap)
{
FILE *fp; char fname[512];
sprintf(fname,"%s/SWAPS/%u-%u.swap",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"wb")) != 0 )
{
fwrite(&swap->I,1,sizeof(swap->I),fp);
/*fwrite(&swap->bobdeposit,1,sizeof(swap->bobdeposit),fp);
fwrite(&swap->bobpayment,1,sizeof(swap->bobpayment),fp);
fwrite(&swap->alicepayment,1,sizeof(swap->alicepayment),fp);
fwrite(&swap->myfee,1,sizeof(swap->myfee),fp);
fwrite(&swap->otherfee,1,sizeof(swap->otherfee),fp);
fwrite(&swap->aliceclaim,1,sizeof(swap->aliceclaim),fp);
fwrite(&swap->alicespend,1,sizeof(swap->alicespend),fp);
fwrite(&swap->bobreclaim,1,sizeof(swap->bobreclaim),fp);
fwrite(&swap->bobspend,1,sizeof(swap->bobspend),fp);
fwrite(&swap->bobrefund,1,sizeof(swap->bobrefund),fp);
fwrite(&swap->alicereclaim,1,sizeof(swap->alicereclaim),fp);*/
fwrite(swap->privkeys,1,sizeof(swap->privkeys),fp);
fwrite(swap->otherdeck,1,sizeof(swap->otherdeck),fp);
fwrite(swap->deck,1,sizeof(swap->deck),fp);
fclose(fp);
}
}
/*int32_t basilisk_swap_loadtx(struct basilisk_rawtx *rawtx,FILE *fp,char *bobcoinstr,char *alicecoinstr)
{
if ( fread(rawtx,1,sizeof(*rawtx),fp) == sizeof(*rawtx) )
{
rawtx->coin = 0;
rawtx->vins = 0;
if ( strcmp(rawtx->I.coinstr,bobcoinstr) == 0 || strcmp(rawtx->I.coinstr,alicecoinstr) == 0 )
{
rawtx->coin = LP_coinfind(rawtx->I.coinstr);
if ( rawtx->vinstr[0] != 0 )
rawtx->vins = cJSON_Parse(rawtx->vinstr);
printf("loaded.%s len.%d\n",rawtx->name,rawtx->I.datalen);
return(0);
}
}
return(-1);
}*/
void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,int32_t scriptlen)
{
int32_t i; char scriptstr[513];
@ -169,7 +32,7 @@ void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,in
void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,int32_t locktime,bits256 triggertxid)
{
char zeroes[32],fname[512],str[65],coinaddr[64],secretAmstr[41],secretAm256str[65],secretBnstr[41],secretBn256str[65],*tmp; FILE *fp; int32_t i,len; uint8_t redeemscript[256],script[256];
char zeroes[32],fname[512],str[65],coinaddr[64],secretAmstr[41],secretAm256str[65],secretBnstr[41],secretBn256str[65]; FILE *fp; int32_t i,len; uint8_t redeemscript[256],script[256];
sprintf(fname,"%s/SWAPS/%u-%u.%s",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid,rawtx->name), OS_compatible_path(fname);
coinaddr[0] = secretAmstr[0] = secretAm256str[0] = secretBnstr[0] = secretBn256str[0] = 0;
memset(zeroes,0,sizeof(zeroes));
@ -184,11 +47,10 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx
fprintf(fp,"\",\"txid\":\"%s\"",bits256_str(str,bits256_doublesha256(0,rawtx->txbytes,rawtx->I.datalen)));
if ( rawtx == &swap->bobdeposit || rawtx == &swap->bobpayment )
{
basilisk_swap_coinaddr(swap,&swap->bobcoin,coinaddr,rawtx->txbytes,rawtx->I.datalen);
LP_swap_coinaddr(swap,&swap->bobcoin,coinaddr,rawtx->txbytes,rawtx->I.datalen);
if ( coinaddr[0] != 0 )
{
if ( (tmp= LP_importaddress(swap->bobcoin.symbol,coinaddr)) != 0 )
free(tmp);
LP_importaddress(swap->bobcoin.symbol,coinaddr);
if ( rawtx == &swap->bobdeposit )
safecopy(swap->Bdeposit,coinaddr,sizeof(swap->Bdeposit));
else safecopy(swap->Bpayment,coinaddr,sizeof(swap->Bpayment));
@ -210,10 +72,15 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx
if ( bits256_nonz(swap->I.pubAm) != 0 && bits256_nonz(swap->I.pubBn) != 0 )
{
basilisk_alicescript(redeemscript,&len,script,0,coinaddr,swap->alicecoin.p2shtype,swap->I.pubAm,swap->I.pubBn);
if ( (tmp= LP_importaddress(swap->alicecoin.symbol,coinaddr)) != 0 )
free(tmp);
LP_importaddress(swap->alicecoin.symbol,coinaddr);
fprintf(fp,",\"Apayment\":\"%s\"",coinaddr);
}
if ( rawtx->I.redeemlen > 0 )
{
char scriptstr[2049];
init_hexbytes_noT(scriptstr,rawtx->redeemscript,rawtx->I.redeemlen);
fprintf(fp,",\"redeem\":\"%s\"",scriptstr);
}
/*basilisk_dontforget_userdata("Aclaim",fp,swap->I.userdata_aliceclaim,swap->I.userdata_aliceclaimlen);
basilisk_dontforget_userdata("Areclaim",fp,swap->I.userdata_alicereclaim,swap->I.userdata_alicereclaimlen);
basilisk_dontforget_userdata("Aspend",fp,swap->I.userdata_alicespend,swap->I.userdata_alicespendlen);
@ -346,8 +213,6 @@ void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx
basilisk_dontforget(swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid);
}
bits256 basilisk_swap_privbob_extract(char *symbol,bits256 spendtxid,int32_t vini,int32_t revflag)
{
bits256 privkey; int32_t i,scriptlen,siglen; uint8_t script[1024]; // from Bob refund of Bob deposit
@ -503,9 +368,10 @@ int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflag
cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid)
{
static void *ctx;
FILE *fp; int32_t sentflags[sizeof(txnames)/sizeof(*txnames)],i,n,j,len,needflag,secretstart,redeemlen,addflag,origfinishedflag = 0,finishedflag = 0,iambob = -1; int64_t srcamount,destamount=0,value,values[sizeof(txnames)/sizeof(*txnames)]; uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],pubkey33[33],redeemscript[1024],userdata[1024]; uint32_t plocktime,dlocktime,expiration=0,r,q,state,otherstate; char *secretstr,*srcstr,*deststr,str[65],src[64],dest[64],fname[512],*fstr,*dest33,*symbol,*txname,*Adest,*Bdest,*AAdest,*ABdest,destaddr[64],Adestaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)]; long fsize; cJSON *txobj,*item,*sentobj,*array; bits256 checktxid,txid,pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,zero,privkey,rev,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)],signedtxid; struct iguana_info *bob=0,*alice=0; uint64_t txfee = 10000;
FILE *fp; int32_t sentflags[sizeof(txnames)/sizeof(*txnames)],i,n,j,len,needflag,secretstart,redeemlen,addflag,origfinishedflag = 0,finishedflag = 0,iambob = -1; int64_t srcamount,destamount=0,value,values[sizeof(txnames)/sizeof(*txnames)]; uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],pubkey33[33],redeemscript[1024],userdata[1024]; uint32_t plocktime,dlocktime,expiration=0,r,q,state,otherstate; char *secretstr,*srcstr,*deststr,str[65],src[64],dest[64],fname[512],*fstr,*dest33,*symbol,*txname,*Adest,*Bdest,*AAdest,*ABdest,destaddr[64],Adestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)]; long fsize; cJSON *txobj,*item,*sentobj,*array; bits256 checktxid,txid,pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,zero,privkey,rev,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)],signedtxid; struct iguana_info *bob=0,*alice=0; uint64_t txfee = 10000;
if ( ctx == 0 )
ctx = bitcoin_ctx();
bobpaymentaddr[0] = bobdepositaddr[0] = alicepaymentaddr[0] = 0;
memset(values,0,sizeof(values));
memset(txids,0,sizeof(txids));
memset(secretAm,0,sizeof(secretAm));
@ -561,13 +427,13 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
if ( bits256_nonz(privkey) != 0 )
{
privAm = privkey;
//printf("set privAm <- %s\n",bits256_str(str,privAm));
printf("set privAm <- %s\n",bits256_str(str,privAm));
}
privkey = jbits256(item,"privBn");
if ( bits256_nonz(privkey) != 0 )
{
privBn = privkey;
//printf("set privBn <- %s\n",bits256_str(str,privBn));
printf("set privBn <- %s\n",bits256_str(str,privBn));
}
expiration = juint(item,"expiration");
state = jint(item,"state");
@ -642,6 +508,12 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
if ( bits256_nonz(txid) == 0 )
continue;
txids[i] = txid;
if ( jstr(txobj,"Apayment") != 0 )
strcpy(alicepaymentaddr,jstr(txobj,"Apayment"));
if ( jstr(txobj,"Bpayment") != 0 )
strcpy(bobpaymentaddr,jstr(txobj,"Bpayment"));
if ( jstr(txobj,"Bdeposit") != 0 )
strcpy(bobdepositaddr,jstr(txobj,"Bdeposit"));
if ( jobj(txobj,"tx") != 0 )
{
txbytes[i] = clonestr(jstr(txobj,"tx"));
@ -658,7 +530,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
safecopy(alicecoin,symbol,sizeof(alicecoin));
if ( finishedflag == 0 )
{
if ( (sentobj= LP_swapgettx(symbol,txid)) == 0 )
if ( (sentobj= LP_gettx(symbol,txid)) == 0 )
{
//printf("%s %s ready to broadcast\n",symbol,bits256_str(str2,txid));
}
@ -682,6 +554,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
} else if ( finishedflag == 0 )
printf("%s not finished\n",fname);
}
printf("alicepayment.%s bobpayment.%s bobdeposit.%s\n",alicepaymentaddr,bobpaymentaddr,bobdepositaddr);
//printf("iambob.%d src.%s dest.%s bob.%s alice.%s pubA0.(%s)\n",iambob,src,dest,bobcoin,alicecoin,bits256_str(str,pubA0));
Adestaddr[0] = destaddr[0] = 0;
Adest = Bdest = AAdest = ABdest = 0;
@ -722,7 +595,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
printf("txbytes.%p Apayment.%s\n",txbytes[BASILISK_ALICEPAYMENT],bits256_str(str,txids[BASILISK_ALICEPAYMENT]));
if ( txbytes[BASILISK_ALICEPAYMENT] != 0 )
sentflags[BASILISK_ALICEPAYMENT] = 1;
else if ( (sentobj= LP_swapgettx(alicecoin,txids[BASILISK_ALICEPAYMENT])) != 0 )
else if ( (sentobj= LP_gettx(alicecoin,txids[BASILISK_ALICEPAYMENT])) != 0 )
{
sentflags[BASILISK_ALICEPAYMENT] = 1;
free_json(sentobj);
@ -745,18 +618,25 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
// alicespend
for (j=0; j<32; j++)
rev.bytes[j] = privAm.bytes[31 - j];
revcalc_rmd160_sha256(secretAm,rev);//privAm);
vcalc_sha256(0,secretAm256,rev.bytes,sizeof(rev));
//revcalc_rmd160_sha256(secretAm,rev);//privAm);
//vcalc_sha256(0,secretAm256,rev.bytes,sizeof(rev));
redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,plocktime,pubA0,pubB0,pubB1,rev,privBn,secretAm,secretAm256,secretBn,secretBn256);
len = basilisk_swapuserdata(userdata,rev,0,myprivs[0],redeemscript,redeemlen);
printf("alicespend len.%d redeemlen.%d\n",len,redeemlen);
if ( (txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,txfee,"alicespend",bobcoin,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,pubkey33,1,expiration,&values[BASILISK_ALICESPEND])) != 0 )
{
char privaddr[64]; uint8_t privpub33[33];
bitcoin_pubkey33(ctx,privpub33,myprivs[0]);
bitcoin_address(privaddr,60,privpub33,33);
printf("alicespend len.%d redeemlen.%d priv0addr.(%s) priv0.(%s)\n",len,redeemlen,privaddr,bits256_str(str,myprivs[0]));
}
for (j=0; j<32; j++)
rev.bytes[j] = myprivs[0].bytes[31 - j];
if ( (txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,txfee,"alicespend",bobcoin,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,0,pubkey33,1,expiration,&values[BASILISK_ALICESPEND],0,0,bobpaymentaddr,1)) != 0 )
printf("alicespend.(%s)\n",txbytes[BASILISK_ALICESPEND]);
}
}
if ( txbytes[BASILISK_ALICESPEND] != 0 )
{
txids[BASILISK_ALICESPEND] = basilisk_swap_sendrawtransaction("alicespend",bobcoin,txbytes[BASILISK_ALICESPEND]);
txids[BASILISK_ALICESPEND] = LP_broadcast("alicespend",bobcoin,txbytes[BASILISK_ALICESPEND]);
if ( bits256_nonz(txids[BASILISK_ALICESPEND]) != 0 ) // tested
{
sentflags[BASILISK_ALICESPEND] = 1;
@ -775,13 +655,13 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
if ( redeemlen > 0 )
{
len = basilisk_swapuserdata(userdata,zero,1,myprivs[0],redeemscript,redeemlen);
if ( (txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,txfee,"aliceclaim",bobcoin,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,pubkey33,0,expiration,&values[BASILISK_ALICECLAIM])) != 0 )
if ( (txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,txfee,"aliceclaim",bobcoin,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,0,pubkey33,0,expiration,&values[BASILISK_ALICECLAIM],0,0,bobdepositaddr,1)) != 0 )
printf("privBn.(%s) aliceclaim.(%s)\n",bits256_str(str,privBn),txbytes[BASILISK_ALICECLAIM]);
}
}
if ( txbytes[BASILISK_ALICECLAIM] != 0 )
{
txids[BASILISK_ALICECLAIM] = basilisk_swap_sendrawtransaction("aliceclaim",bobcoin,txbytes[BASILISK_ALICECLAIM]);
txids[BASILISK_ALICECLAIM] = LP_broadcast("aliceclaim",bobcoin,txbytes[BASILISK_ALICECLAIM]);
if ( bits256_nonz(txids[BASILISK_ALICECLAIM]) != 0 ) // tested
{
sentflags[BASILISK_ALICECLAIM] = 1;
@ -797,13 +677,13 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
privBn = basilisk_swap_privBn_extract(&txids[BASILISK_BOBREFUND],bobcoin,txids[BASILISK_BOBDEPOSIT],privBn);
if ( bits256_nonz(txids[BASILISK_ALICEPAYMENT]) != 0 && bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 )
{
if ( (txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",alicecoin,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_ALICERECLAIM])) != 0 )
if ( (txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",alicecoin,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_ALICERECLAIM],alicepaymentaddr)) != 0 )
printf("privBn.(%s) alicereclaim.(%s)\n",bits256_str(str,privBn),txbytes[BASILISK_ALICERECLAIM]);
}
}
if ( txbytes[BASILISK_ALICERECLAIM] != 0 )
{
txids[BASILISK_ALICERECLAIM] = basilisk_swap_sendrawtransaction("alicereclaim",alicecoin,txbytes[BASILISK_ALICERECLAIM]);
txids[BASILISK_ALICERECLAIM] = LP_broadcast("alicereclaim",alicecoin,txbytes[BASILISK_ALICERECLAIM]);
if ( bits256_nonz(txids[BASILISK_ALICERECLAIM]) != 0 ) // tested
{
sentflags[BASILISK_ALICERECLAIM] = 1;
@ -827,13 +707,13 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
}
if ( bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 )
{
if ( (txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",alicecoin,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_BOBSPEND])) != 0 )
if ( (txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",alicecoin,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_BOBSPEND],alicepaymentaddr)) != 0 )
printf("bobspend.(%s)\n",txbytes[BASILISK_BOBSPEND]);
}
}
if ( txbytes[BASILISK_BOBSPEND] != 0 )
{
txids[BASILISK_BOBSPEND] = basilisk_swap_sendrawtransaction("bobspend",alicecoin,txbytes[BASILISK_BOBSPEND]);
txids[BASILISK_BOBSPEND] = LP_broadcast("bobspend",alicecoin,txbytes[BASILISK_BOBSPEND]);
if ( bits256_nonz(txids[BASILISK_BOBSPEND]) != 0 ) // tested
{
sentflags[BASILISK_BOBSPEND] = 1;
@ -851,7 +731,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
if ( redeemlen > 0 )
{
len = basilisk_swapuserdata(userdata,zero,1,myprivs[1],redeemscript,redeemlen);
if ( (txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,txfee,"bobrefund",bobcoin,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[1],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,pubkey33,0,expiration,&values[BASILISK_BOBRECLAIM])) != 0 )
if ( (txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,txfee,"bobrefund",bobcoin,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[1],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,0,pubkey33,0,expiration,&values[BASILISK_BOBRECLAIM],0,0,bobpaymentaddr,1)) != 0 )
{
int32_t z;
for (z=0; z<20; z++)
@ -862,7 +742,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
}
if ( txbytes[BASILISK_BOBRECLAIM] != 0 )
{
txids[BASILISK_BOBRECLAIM] = basilisk_swap_sendrawtransaction("bobreclaim",bobcoin,txbytes[BASILISK_BOBRECLAIM]);
txids[BASILISK_BOBRECLAIM] = LP_broadcast("bobreclaim",bobcoin,txbytes[BASILISK_BOBRECLAIM]);
if ( bits256_nonz(txids[BASILISK_BOBRECLAIM]) != 0 ) // tested
{
sentflags[BASILISK_BOBRECLAIM] = 1;
@ -881,12 +761,12 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
vcalc_sha256(0,secretBn256,privBn.bytes,sizeof(privBn));
redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,dlocktime,pubA0,pubB0,pubB1,privAm,privBn,secretAm,secretAm256,secretBn,secretBn256);
len = basilisk_swapuserdata(userdata,privBn,0,myprivs[0],redeemscript,redeemlen);
if ( (txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,txfee,"bobrefund",bobcoin,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,pubkey33,1,expiration,&values[BASILISK_BOBREFUND])) != 0 )
if ( (txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,txfee,"bobrefund",bobcoin,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,0,pubkey33,1,expiration,&values[BASILISK_BOBREFUND],0,0,bobdepositaddr,1)) != 0 )
printf("pubB1.(%s) bobrefund.(%s)\n",bits256_str(str,pubB1),txbytes[BASILISK_BOBREFUND]);
}
if ( txbytes[BASILISK_BOBREFUND] != 0 )
{
txids[BASILISK_BOBREFUND] = basilisk_swap_sendrawtransaction("bobrefund",bobcoin,txbytes[BASILISK_BOBREFUND]);
txids[BASILISK_BOBREFUND] = LP_broadcast("bobrefund",bobcoin,txbytes[BASILISK_BOBREFUND]);
if ( bits256_nonz(txids[BASILISK_BOBREFUND]) != 0 ) // tested
{
sentflags[BASILISK_BOBREFUND] = 1;

559
iguana/exchanges/LP_rpc.c

@ -17,489 +17,224 @@
// LP_rpc.c
// marketmaker
//
cJSON *basilisk_nullretjson(cJSON *retjson)
char *issue_LP_getpeers(char *destip,uint16_t destport,char *ipaddr,uint16_t port,double profitmargin,int32_t numpeers,int32_t numutxos)
{
char *outstr;
if ( retjson != 0 )
{
outstr = jprint(retjson,0);
if ( strcmp(outstr,"{}") == 0 )
{
free_json(retjson);
retjson = 0;
}
free(outstr);
}
return(retjson);
char url[512],*retstr;
sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&profit=%.6f&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,profitmargin,numpeers,numutxos);
//printf("send.(%s)\n",url);
retstr = issue_curl(url);
//printf("GETPEERS.(%s)\n",retstr);
return(retstr);
}
void LP_unspentslock(char *symbol,cJSON *vins)
char *issue_LP_getutxos(char *destip,uint16_t destport,char *coin,int32_t lastn,char *ipaddr,uint16_t port,double profitmargin,int32_t numpeers,int32_t numutxos)
{
char url[512];
sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=%s&port=%u&profit=%.6f&numpeers=%d&numutxos=%d",destip,destport,coin,lastn,ipaddr,port,profitmargin,numpeers,numutxos);
return(issue_curl(url));
}
void LP_unspents_mark(char *symbol,cJSON *vins)
char *issue_LP_clientgetutxos(char *destip,uint16_t destport,char *coin,int32_t lastn)
{
char url[512];
sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=127.0.0.1&port=0",destip,destport,coin,lastn);
//printf("getutxos.(%s)\n",url);
return(issue_curl(url));
}
uint64_t LP_getestimatedfee(char *symbol)
char *issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,double profitmargin,int32_t numpeers,int32_t numutxos)
{
return(200);
char url[512];
sprintf(url,"http://%s:%u/api/stats/notify?ipaddr=%s&port=%u&profit=%.6f&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,profitmargin,numpeers,numutxos);
return(issue_curl(url));
}
uint64_t LP_txfee(char *symbol)
char *issue_LP_notifyutxo(char *destip,uint16_t destport,struct LP_utxoinfo *utxo)
{
return(10000);
char url[4096],str[65],str2[65];
sprintf(url,"http://%s:%u/api/stats/notifyutxo?ipaddr=%s&port=%u&profit=%.6f&coin=%s&txid=%s&vout=%d&value=%.8f&txid2=%s&vout2=%d&value2=%.8f&script=%s&address=%s",destip,destport,utxo->ipaddr,utxo->port,utxo->profitmargin,utxo->coin,bits256_str(str,utxo->txid),utxo->vout,dstr(utxo->satoshis),bits256_str(str2,utxo->txid2),utxo->vout2,dstr(utxo->satoshis2),utxo->spendscript,utxo->coinaddr);
if ( strlen(url) > 1024 )
printf("WARNING long url.(%s)\n",url);
return(issue_curl(url));
}
char *dpow_validateaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address)
cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params)
{
char buf[128],*retstr=0;
if ( coin->FULLNODE < 0 )
char *retstr; cJSON *retjson = 0;
if ( coin != 0 )
{
sprintf(buf,"\"%s\"",address);
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"validateaddress",buf);
usleep(10000);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
retstr = bitcoinrpc_validateaddress(myinfo,coin,0,0,address);
}
else
{
return(0);
//printf("issue.(%s, %s, %s, %s, %s)\n",coin->symbol,coin->serverport,coin->userpass,method,params);
retstr = bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,method,params);
if ( retstr != 0 && retstr[0] != 0 )
{
//printf("%s: %s.%s -> (%s)\n",coin->symbol,method,params,retstr);
retjson = cJSON_Parse(retstr);
free(retstr);
}
//printf("dpow_gettxout.(%s)\n",retstr);
}
return(retstr);
return(retjson);
}
cJSON *dpow_gettxout(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t vout)
void LP_unspents_mark(char *symbol,cJSON *vins)
{
char buf[128],str[65],*retstr=0; cJSON *json = 0;
sprintf(buf,"\"%s\", %d",bits256_str(str,txid),vout);
if ( coin->FULLNODE < 0 )
{
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"gettxout",buf);
usleep(10000);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
printf("need to test following call\n");
retstr = bitcoinrpc_gettxout(myinfo,coin,0,buf,txid,1,0); // untested
}
else
{
return(0);
}
if ( retstr != 0 )
{
json = cJSON_Parse(retstr);
free(retstr);
}
//printf("dpow_gettxout.(%s)\n",retstr);
return(json);
printf("LOCK (%s)\n",jprint(vins,0));
}
char *dpow_decoderawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx)
cJSON *LP_getinfo(char *symbol)
{
char *retstr,*paramstr; cJSON *array;
if ( coin->FULLNODE < 0 )
{
array = cJSON_CreateArray();
jaddistr(array,rawtx);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"decoderawtransaction",paramstr);
//printf("%s decoderawtransaction.(%s) <- (%s)\n",coin->symbol,retstr,paramstr);
free(paramstr);
usleep(10000);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
retstr = bitcoinrpc_decoderawtransaction(myinfo,coin,0,0,rawtx,1);
}
else
{
return(0);
}
return(retstr);
struct iguana_info *coin = LP_coinfind(symbol);
return(bitcoin_json(coin,"getinfo","[]"));
}
cJSON *dpow_gettransaction(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid)
cJSON *LP_gettxout(char *symbol,bits256 txid,int32_t vout)
{
char buf[128],str[65],*retstr=0; cJSON *json = 0;
if ( coin->FULLNODE < 0 )
{
sprintf(buf,"[\"%s\", 1]",bits256_str(str,txid));
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",buf)) != 0 )
{
}
usleep(10000);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
retstr = bitcoinrpc_getrawtransaction(myinfo,coin,0,0,txid,1);
}
else
{
return(0);
}
if ( retstr != 0 )
{
json = cJSON_Parse(retstr);
free(retstr);
}
return(json);
char buf[128],str[65]; struct iguana_info *coin = LP_coinfind(symbol);
sprintf(buf,"\"%s\", %d",bits256_str(str,txid),vout);
return(bitcoin_json(coin,"gettxout",buf));
}
cJSON *dpow_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr)
cJSON *LP_gettx(char *symbol,bits256 txid)
{
char buf[128],*retstr; cJSON *array,*json = 0;
if ( coin->FULLNODE < 0 )
{
sprintf(buf,"0, 99999999, [\"%s\"]",coinaddr);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",buf)) != 0 )
{
json = cJSON_Parse(retstr);
//printf("%s (%s) listunspent.(%s)\n",coin->symbol,buf,retstr);
free(retstr);
} else printf("%s null retstr from (%s)n",coin->symbol,buf);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
array = cJSON_CreateArray();
jaddistr(array,coinaddr);
json = iguana_listunspents(myinfo,coin,array,1,coin->longestchain,"");
free_json(array);
}
else
{
return(0);
}
return(json);
char buf[128],str[65]; struct iguana_info *coin = LP_coinfind(symbol);
sprintf(buf,"[\"%s\", 1]",bits256_str(str,txid));
return(bitcoin_json(coin,"getrawtransaction",buf));
}
cJSON *dpow_listtransactions(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,int32_t count,int32_t skip)
cJSON *LP_listunspent(char *symbol,char *coinaddr)
{
char buf[128],*retstr; cJSON *json = 0;
if ( coin->FULLNODE < 0 )
{
if ( count == 0 )
count = 100;
sprintf(buf,"[\"%s\", %d, %d, true]",coinaddr,count,skip);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listtransactions",buf)) != 0 )
{
//printf("LIST.(%s)\n",retstr);
json = cJSON_Parse(retstr);
free(retstr);
return(json);
} else printf("%s null retstr from (%s)n",coin->symbol,buf);
}
return(0);
char buf[128]; struct iguana_info *coin = LP_coinfind(symbol);
sprintf(buf,"0, 99999999, [\"%s\"]",coinaddr);
return(bitcoin_json(coin,"listunspent",buf));
}
char *dpow_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx,cJSON *vins)
cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t count,int32_t skip)
{
cJSON *array,*privkeys,*item; char *wifstr,*str,*paramstr,*retstr; uint8_t script[256]; int32_t i,n,len,hashtype; struct vin_info V; struct iguana_waddress *waddr; struct iguana_waccount *wacct;
if ( coin->FULLNODE < 0 )
{
array = cJSON_CreateArray();
jaddistr(array,rawtx);
jaddi(array,jduplicate(vins));
paramstr = jprint(array,1);
//printf("signrawtransaction\n");
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"signrawtransaction",paramstr);
//printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr);
free(paramstr);
usleep(10000);
return(retstr);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
privkeys = cJSON_CreateArray();
if ( (n= cJSON_GetArraySize(vins)) > 0 )
{
for (i=0; i<n; i++)
{
wifstr = "";
item = jitem(vins,i);
if ( (str= jstr(item,"scriptPubkey")) != 0 && is_hexstr(str,0) > 0 && strlen(str) < sizeof(script)*2 )
{
len = (int32_t)strlen(str) >> 1;
decode_hex(script,len,str);
V.spendlen = len;
memcpy(V.spendscript,script,len);
if ( (hashtype= _iguana_calcrmd160(coin,&V)) >= 0 && V.coinaddr[0] != 0 )
{
if ( (waddr= iguana_waddresssearch(myinfo,&wacct,V.coinaddr)) != 0 )
{
if ( bits256_nonz(waddr->privkey) != 0 )
{
if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->chain->wiftype) > 0 )
{
wifstr = waddr->wifstr;
}
}
}
}
}
jaddistr(privkeys,wifstr);
}
}
retstr = bitcoinrpc_signrawtransaction(myinfo,coin,0,0,rawtx,vins,privkeys,"ALL");
printf("call sign.(%s) vins.(%s) privs.(%s) -> (%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),retstr);
free_json(privkeys);
return(retstr);
}
else
{
return(0);
}
char buf[128]; struct iguana_info *coin = LP_coinfind(symbol);
if ( count == 0 )
count = 100;
sprintf(buf,"[\"%s\", %d, %d, true]",coinaddr,count,skip);
return(bitcoin_json(coin,"listtransactions",buf));
}
char *dpow_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *signedtx)
cJSON *LP_validateaddress(char *symbol,char *address)
{
bits256 txid; cJSON *json,*array; char *paramstr,*retstr;
if ( coin->FULLNODE < 0 )
{
array = cJSON_CreateArray();
jaddistr(array,signedtx);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"sendrawtransaction",paramstr);
printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr);
free(paramstr);
return(retstr);
}
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 )
{
txid = iguana_sendrawtransaction(myinfo,coin,signedtx);
json = cJSON_CreateObject();
jaddbits256(json,"result",txid);
return(jprint(json,1));
}
else
{
return(0);
}
char buf[512]; struct iguana_info *coin = LP_coinfind(symbol);
sprintf(buf,"\"%s\"",address);
return(bitcoin_json(coin,"validateaddress",buf));
}
cJSON *LP_importprivkey(char *symbol,char *wifstr,char *label,int32_t flag)
{
char buf[512]; struct iguana_info *coin = LP_coinfind(symbol);
sprintf(buf,"[\"%s\", \"%s\", %s]",wifstr,label,flag < 0 ? "false" : "true");
return(bitcoin_json(coin,"importprivkey",buf));
}
char *LP_importaddress(char *symbol,char *address)
int32_t LP_importaddress(char *symbol,char *address)
{
char buf[1024],*retstr; cJSON *validatejson; int32_t isvalid=0,doneflag = 0;
if ( (retstr= LP_validateaddress(symbol,address)) != 0 )
char buf[1024],*retstr; cJSON *validatejson; int32_t isvalid=0,doneflag = 0; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 )
return(-2);
if ( (validatejson= LP_validateaddress(symbol,address)) != 0 )
{
if ( (validatejson= cJSON_Parse(retstr)) != 0 )
if ( (isvalid= is_cJSON_True(jobj(validatejson,"isvalid")) != 0) != 0 )
{
if ( (isvalid= is_cJSON_True(jobj(validatejson,"isvalid")) != 0) != 0 )
{
if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 )
doneflag = 1;
}
free_json(validatejson);
if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 )
doneflag = 1;
}
free(retstr);
retstr = 0;
free_json(validatejson);
}
if ( isvalid == 0 )
return(clonestr("{\"isvalid\":false}"));
update_alladdresses(myinfo,coin,address);
return(-1);
if ( doneflag != 0 )
return(0); // success
if ( coin->FULLNODE < 0 )
sprintf(buf,"[\"%s\", \"%s\", false]",address,address);
if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"importaddress",buf)) != 0 )
{
sprintf(buf,"[\"%s\", \"%s\", false]",address,address);
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"importaddress",buf);
printf("%s importaddress.(%s) -> (%s)\n",coin->symbol,address,retstr);
return(retstr);
}
else return(0);
}
char *LP_importaddress(char *symbol,char *coinaddr)
{
return(0);
}
char *LP_sendrawtransaction(char *symbol,char *signedtx)
{
return(0);
}
char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtxbytes,cJSON *privkeys,struct vin_info *V)
{
return(0);
}
cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_t skip)
{
return(0);
}
char *dex_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_t skip)
{
return(0);
}
bits256 LP_privkey(char *coinaddr)
{
bits256 privkey;
return(privkey);
}
bits256 LP_pubkey(bits256 privkey)
{
bits256 pubkey;
pubkey = curve25519(privkey,curve25519_basepoint9());
return(pubkey);
}
cJSON *LP_swapgettxout(char *symbol,bits256 trigger,int32_t vout)
{
cJSON *retjson=0; //char *retstr; struct iguana_info *coin;
/*if ( ((coin= iguana_coinfind(symbol)) == 0 || coin->FULLNODE == 0) && iguana_isnotarychain(symbol) >= 0 )
{
if ( (retstr= dex_gettxout(0,0,0,trigger,symbol,vout)) != 0 )
{
//printf("dexgettxout.(%s)\n",retstr);
retjson = cJSON_Parse(retstr);
free(retstr);
}
if ( 0 && strcmp("BTC",symbol) == 0 )
printf("%s gettxout.(%s)\n",symbol,jprint(retjson,0));
}
else
{
retjson = dpow_gettxout(coin,trigger,vout);
//printf("need to verify passthru has this info\n");
//printf("dpowgettxout.(%s)\n",jprint(retjson,0));
}*/
return(basilisk_nullretjson(retjson));
}
uint64_t LP_txvalue(char *symbol,bits256 txid,int32_t vout)
{
uint64_t value = 0;
return(value);
}
cJSON *LP_swapgettx(char *symbol,bits256 txid)
{
cJSON *retjson=0; //char *retstr; struct iguana_info *coin;
/*if ( ((coin= iguana_coinfind(symbol)) == 0 || coin->FULLNODE == 0) && iguana_isnotarychain(symbol) >= 0 )
{
if ( (retstr= dex_gettransaction(0,0,0,txid,symbol)) != 0 )
{
retjson = cJSON_Parse(retstr);
free(retstr);
}
//if ( strcmp("BTC",symbol) == 0 )
// printf("%s gettx.(%s)\n",symbol,jprint(retjson,0));
} else retjson = dpow_gettransaction(coin,txid);*/
return(basilisk_nullretjson(retjson));
printf("importaddress.(%s %s) -> (%s)\n",symbol,address,retstr);
free(retstr);
} else printf("importaddress.(%s %s)\n",symbol,address);
return(1);
}
bits256 basilisk_swap_sendrawtransaction(char *txname,char *symbol,char *txbytes)
double LP_getestimatedrate(char *symbol)
{
char *retstr; bits256 txid; int32_t i,sentflag = 0;
memset(&txid,0,sizeof(txid));
for (i=0; i<3; i++)
char buf[512],*retstr; double rate = 200; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin != 0 )
{
if ( (retstr= LP_sendrawtransaction(symbol,txbytes)) != 0 )
sprintf(buf,"[%d]",3);
if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"estimatefee",buf)) != 0 )
{
if ( is_hexstr(retstr,0) == 64 )
if ( retstr[0] != '-' )
{
decode_hex(txid.bytes,32,retstr);
sentflag = 1;
rate = atof(retstr) / 1024.;
printf("estimated rate.(%s) %s -> %.8f\n",symbol,retstr,rate);
}
char str[65]; printf("[%s] %s RETSTR.(%s) %s.%s\n",txname,txbytes,retstr,symbol,bits256_str(str,txid));
free(retstr);
}
if ( sentflag != 0 )
break;
}
return(txid);
return(rate);
}
bits256 LP_broadcast(char *name,char *symbol,uint8_t *data,int32_t datalen)
uint64_t LP_txfee(char *symbol)
{
bits256 txid; char *signedtx,*retstr; int32_t i;
memset(txid.bytes,0,sizeof(txid));
if ( data != 0 && datalen != 0 )
{
char str[65];
#ifdef BASILISK_DISABLESENDTX
txid = bits256_doublesha256(0,data,datalen);
printf("%s <- dont sendrawtransaction (%s)\n",name,bits256_str(str,txid));
return(txid);
#endif
signedtx = malloc(datalen*2 + 1);
init_hexbytes_noT(signedtx,data,datalen);
for (i=0; i<3; i++)
{
if ( (retstr= LP_sendrawtransaction(symbol,signedtx)) != 0 )
{
if ( is_hexstr(retstr,0) == 64 )
{
decode_hex(txid.bytes,32,retstr);
free(retstr);
printf("sendrawtransaction.%s %s.(%s)\n",name,symbol,bits256_str(str,txid));
break;
}
else
{
printf("sendrawtransaction.%s %s error.(%s)\n",name,symbol,retstr);
free(retstr);
}
} else printf("sendrawtransaction.%s %s got null return\n",name,symbol);
}
free(signedtx);
}
return(txid);
uint64_t txfee = 0;
if ( strcmp(symbol,"BTC") != 0 )
txfee = 10000;
return(txfee);
}
int32_t basilisk_confirmsobj(cJSON *item)
char *LP_sendrawtransaction(char *symbol,char *signedtx)
{
int32_t height,numconfirms;
height = jint(item,"height");
numconfirms = jint(item,"numconfirms");
if ( height > 0 && numconfirms >= 0 )
return(numconfirms);
printf("basilisk_confirmsobj height.%d numconfirms.%d (%s)\n",height,numconfirms,jprint(item,0));
return(-1);
cJSON *array; char *paramstr,*retstr; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 )
return(0);
array = cJSON_CreateArray();
jaddistr(array,signedtx);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"sendrawtransaction",paramstr);
printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr);
free(paramstr);
return(retstr);
}
int32_t LP_numconfirms(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx)
char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkeys,struct vin_info *V)
{
#ifdef BASILISK_DISABLEWAITTX
return(100);
#endif
/*cJSON *argjson,*valuearray=0; char *valstr; int32_t i,n,retval = -1;
argjson = cJSON_CreateObject();
jaddbits256(argjson,"txid",rawtx->I.actualtxid);
jaddnum(argjson,"vout",0);
jaddstr(argjson,"coin",rawtx->coin->symbol);
if ( (valstr= basilisk_value(rawtx->coin,0,0,swap->persistent_pubkey,argjson,0)) != 0 )
cJSON *array,*json; int32_t len; uint8_t *data; char *paramstr,*retstr,*hexstr,*signedtx=0; struct iguana_info *coin = LP_coinfind(symbol);
memset(signedtxidp,0,sizeof(*signedtxidp));
*completedp = 0;
if ( coin == 0 )
{
printf("LP_signrawtx cant find coin.(%s)\n",symbol);
return(0);
}
array = cJSON_CreateArray();
jaddistr(array,rawtx);
jaddi(array,jduplicate(vins));
jaddi(array,jduplicate(privkeys));
paramstr = jprint(array,1);
//printf("signrawtransaction\n");
if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"signrawtransaction",paramstr)) != 0 )
{
char str[65]; printf("basilisk_numconfirms required.%d %s %s valstr.(%s)\n",rawtx->I.numconfirms,rawtx->name,bits256_str(str,rawtx->I.actualtxid),valstr);
//basilisk_numconfirms required.0 alicespend 29a2a6b4a61b1da82096d533c71b6762d61a82ca771a633269d97c0ccb94fe85 valstr.({"result":"success","numconfirms":0,"address":"1JGvZ67oTdM7kCya4J8kj1uErbSRAoq3wH","satoshis":"1413818","value":0.01413818,"height":462440,"txid":"29a2a6b4a61b1da82096d533c71b6762d61a82ca771a633269d97c0ccb94fe85","vout":0,"coin":"BTC"})
if ( (valuearray= cJSON_Parse(valstr)) != 0 )
if ( (json= cJSON_Parse(retstr)) != 0 )
{
if ( valstr[0] == '[' && is_cJSON_Array(valuearray) != 0 )
if ( (hexstr= jstr(json,"hex")) != 0 )
{
n = cJSON_GetArraySize(valuearray);
for (i=0; i<n; i++)
{
printf("i.%d of n.%d\n",i,n);
if ( (retval= basilisk_confirmsobj(jitem(valuearray,i))) >= 0 )
break;
}
} else retval = basilisk_confirmsobj(valuearray);
free_json(valuearray);
} else printf("parse error\n");
free(valstr);
len = (int32_t)strlen(hexstr);
signedtx = calloc(1,len+1);
strcpy(signedtx,hexstr);
*completedp = is_cJSON_True(jobj(json,"complete"));
data = malloc(len >> 1);
decode_hex(data,len>>1,hexstr);
*signedtxidp = bits256_doublesha256(0,data,len >> 1);
}
//else
printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr);
free_json(json);
}
free(retstr);
}
free_json(argjson);
printf("numconfirms.%d returned\n",retval);
return(retval);*/
free(paramstr);
return(signedtx);
}

719
iguana/exchanges/LP_statemachine.c

@ -18,6 +18,504 @@
// marketmaker
//
/*void basilisk_swaps_init(struct supernet_info *myinfo)
{
char fname[512]; uint32_t iter,swapcompleted,requestid,quoteid,optionduration,statebits; FILE *fp; bits256 privkey;struct basilisk_request R; struct basilisk_swapmessage M; struct basilisk_swap *swap = 0;
sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname);
if ( (myinfo->swapsfp= fopen(fname,"rb+")) != 0 )
{
while ( fread(&requestid,1,sizeof(requestid),myinfo->swapsfp) == sizeof(requestid) && fread(&quoteid,1,sizeof(quoteid),myinfo->swapsfp) == sizeof(quoteid) )
{
sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname);
printf("%s\n",fname);
if ( (fp= fopen(fname,"rb+")) != 0 ) // check to see if completed
{
memset(&M,0,sizeof(M));
swapcompleted = 1;
for (iter=0; iter<2; iter++)
{
if ( fread(privkey.bytes,1,sizeof(privkey),fp) == sizeof(privkey) &&
fread(&R,1,sizeof(R),fp) == sizeof(R) &&
fread(&statebits,1,sizeof(statebits),fp) == sizeof(statebits) &&
fread(&optionduration,1,sizeof(optionduration),fp) == sizeof(optionduration) )
{
while ( 0 && fread(&M,1,sizeof(M),fp) == sizeof(M) )
{
M.data = 0;
//printf("entry iter.%d crc32.%x datalen.%d\n",iter,M.crc32,M.datalen);
if ( M.datalen < 100000 )
{
M.data = malloc(M.datalen);
if ( fread(M.data,1,M.datalen,fp) == M.datalen )
{
if ( calc_crc32(0,M.data,M.datalen) == M.crc32 )
{
if ( iter == 1 )
{
if ( swap == 0 )
{
swap = basilisk_thread_start(privkey,&R,statebits,optionduration,1);
swap->I.choosei = swap->I.otherchoosei = -1;
}
if ( swap != 0 )
basilisk_swapgotdata(swap,M.crc32,M.srchash,M.desthash,M.quoteid,M.msgbits,M.data,M.datalen,1);
}
} else printf("crc mismatch %x vs %x\n",calc_crc32(0,M.data,M.datalen),M.crc32);
} else printf("error reading M.datalen %d\n",M.datalen);
free(M.data), M.data = 0;
}
}
}
if ( swapcompleted != 0 )
break;
rewind(fp);
}
}
}
} else myinfo->swapsfp = fopen(fname,"wb+");
}*/
FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit)
{
FILE *fp=0; /*char fname[512];
sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,rp->requestid,rp->quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"rb+")) == 0 )
{
if ( (fp= fopen(fname,"wb+")) != 0 )
{
fwrite(privkey.bytes,1,sizeof(privkey),fp);
fwrite(rp,1,sizeof(*rp),fp);
fwrite(&statebits,1,sizeof(statebits),fp);
fwrite(&optionduration,1,sizeof(optionduration),fp);
fflush(fp);
}
}
else if ( reinit != 0 )
{
}*/
return(fp);
}
int32_t basilisk_swap_load(uint32_t requestid,uint32_t quoteid,bits256 *privkeyp,struct basilisk_request *rp,uint32_t *statebitsp,int32_t *optiondurationp)
{
FILE *fp=0; char fname[512]; int32_t retval = -1;
sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"rb+")) != 0 )
{
if ( fread(privkeyp,1,sizeof(*privkeyp),fp) == sizeof(*privkeyp) &&
fread(rp,1,sizeof(*rp),fp) == sizeof(*rp) &&
fread(statebitsp,1,sizeof(*statebitsp),fp) == sizeof(*statebitsp) &&
fread(optiondurationp,1,sizeof(*optiondurationp),fp) == sizeof(*optiondurationp) )
retval = 0;
fclose(fp);
}
return(retval);
}
void basilisk_swap_saveupdate(struct basilisk_swap *swap)
{
FILE *fp; char fname[512];
sprintf(fname,"%s/SWAPS/%u-%u.swap",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname);
if ( (fp= fopen(fname,"wb")) != 0 )
{
fwrite(&swap->I,1,sizeof(swap->I),fp);
/*fwrite(&swap->bobdeposit,1,sizeof(swap->bobdeposit),fp);
fwrite(&swap->bobpayment,1,sizeof(swap->bobpayment),fp);
fwrite(&swap->alicepayment,1,sizeof(swap->alicepayment),fp);
fwrite(&swap->myfee,1,sizeof(swap->myfee),fp);
fwrite(&swap->otherfee,1,sizeof(swap->otherfee),fp);
fwrite(&swap->aliceclaim,1,sizeof(swap->aliceclaim),fp);
fwrite(&swap->alicespend,1,sizeof(swap->alicespend),fp);
fwrite(&swap->bobreclaim,1,sizeof(swap->bobreclaim),fp);
fwrite(&swap->bobspend,1,sizeof(swap->bobspend),fp);
fwrite(&swap->bobrefund,1,sizeof(swap->bobrefund),fp);
fwrite(&swap->alicereclaim,1,sizeof(swap->alicereclaim),fp);*/
fwrite(swap->privkeys,1,sizeof(swap->privkeys),fp);
fwrite(swap->otherdeck,1,sizeof(swap->otherdeck),fp);
fwrite(swap->deck,1,sizeof(swap->deck),fp);
fclose(fp);
}
}
/*int32_t basilisk_swap_loadtx(struct basilisk_rawtx *rawtx,FILE *fp,char *bobcoinstr,char *alicecoinstr)
{
if ( fread(rawtx,1,sizeof(*rawtx),fp) == sizeof(*rawtx) )
{
rawtx->coin = 0;
rawtx->vins = 0;
if ( strcmp(rawtx->I.coinstr,bobcoinstr) == 0 || strcmp(rawtx->I.coinstr,alicecoinstr) == 0 )
{
rawtx->coin = LP_coinfind(rawtx->I.coinstr);
if ( rawtx->vinstr[0] != 0 )
rawtx->vins = cJSON_Parse(rawtx->vinstr);
printf("loaded.%s len.%d\n",rawtx->name,rawtx->I.datalen);
return(0);
}
}
return(-1);
}*/
void basilisk_swap_sendabort(struct basilisk_swap *swap)
{
uint32_t msgbits = 0; uint8_t buf[sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2]; int32_t sentbytes,offset=0;
memset(buf,0,sizeof(buf));
offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid);
offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits);
if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset )
{
if ( sentbytes < 0 )
{
if ( swap->pushsock >= 0 ) //
nn_close(swap->pushsock), swap->pushsock = -1;
if ( swap->subsock >= 0 ) //
nn_close(swap->subsock), swap->subsock = -1;
swap->connected = 0;
}
} else printf("basilisk_swap_sendabort\n");
}
void basilisk_psockinit(struct basilisk_swap *swap,int32_t amlp);
void basilisk_swapgotdata(struct basilisk_swap *swap,uint32_t crc32,bits256 srchash,bits256 desthash,uint32_t quoteid,uint32_t msgbits,uint8_t *data,int32_t datalen,int32_t reinit)
{
int32_t i; struct basilisk_swapmessage *mp;
for (i=0; i<swap->nummessages; i++)
if ( crc32 == swap->messages[i].crc32 && msgbits == swap->messages[i].msgbits && bits256_cmp(srchash,swap->messages[i].srchash) == 0 && bits256_cmp(desthash,swap->messages[i].desthash) == 0 )
return;
//printf(" new message.[%d] datalen.%d Q.%x msg.%x [%llx]\n",swap->nummessages,datalen,quoteid,msgbits,*(long long *)data);
swap->messages = realloc(swap->messages,sizeof(*swap->messages) * (swap->nummessages + 1));
mp = &swap->messages[swap->nummessages++];
mp->crc32 = crc32;
mp->srchash = srchash;
mp->desthash = desthash;
mp->msgbits = msgbits;
mp->quoteid = quoteid;
mp->data = malloc(datalen);
mp->datalen = datalen;
memcpy(mp->data,data,datalen);
if ( reinit == 0 && swap->fp != 0 )
{
fwrite(mp,1,sizeof(*mp),swap->fp);
fwrite(data,1,datalen,swap->fp);
fflush(swap->fp);
}
}
int32_t basilisk_swapget(struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,int32_t (*basilisk_verify_func)(void *ptr,uint8_t *data,int32_t datalen))
{
uint8_t *ptr; bits256 srchash,desthash; uint32_t crc32,_msgbits,quoteid; int32_t i,size,offset,retval = -1; struct basilisk_swapmessage *mp = 0;
while ( (size= nn_recv(swap->subsock,&ptr,NN_MSG,0)) >= 0 )
{
swap->lasttime = (uint32_t)time(NULL);
memset(srchash.bytes,0,sizeof(srchash));
memset(desthash.bytes,0,sizeof(desthash));
//printf("gotmsg.[%d] crc.%x\n",size,crc32);
offset = 0;
for (i=0; i<32; i++)
srchash.bytes[i] = ptr[offset++];
for (i=0; i<32; i++)
desthash.bytes[i] = ptr[offset++];
offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&quoteid);
offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&_msgbits);
if ( size > offset )
{
crc32 = calc_crc32(0,&ptr[offset],size-offset);
if ( size > offset )
{
//printf("size.%d offset.%d datalen.%d\n",size,offset,size-offset);
basilisk_swapgotdata(swap,crc32,srchash,desthash,quoteid,_msgbits,&ptr[offset],size-offset,0);
}
}
else if ( bits256_nonz(srchash) == 0 && bits256_nonz(desthash) == 0 )
{
if ( swap->aborted == 0 )
{
swap->aborted = (uint32_t)time(NULL);
printf("got abort signal from other side\n");
}
} else printf("basilisk_swapget: got strange packet\n");
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
}
//char str[65],str2[65];
for (i=0; i<swap->nummessages; i++)
{
//printf("%d: %s vs %s\n",i,bits256_str(str,swap->messages[i].srchash),bits256_str(str2,swap->messages[i].desthash));
if ( bits256_cmp(swap->messages[i].desthash,swap->I.myhash) == 0 )
{
if ( swap->messages[i].msgbits == msgbits )
{
if ( swap->I.iambob == 0 && swap->lasttime != 0 && time(NULL) > swap->lasttime+360 )
{
printf("nothing received for a while from Bob, try new sockets\n");
if ( swap->pushsock >= 0 ) //
nn_close(swap->pushsock), swap->pushsock = -1;
if ( swap->subsock >= 0 ) //
nn_close(swap->subsock), swap->subsock = -1;
swap->connected = 0;
basilisk_psockinit(swap,swap->I.iambob != 0);
}
mp = &swap->messages[i];
if ( msgbits != 0x80000000 )
break;
}
}
}
if ( mp != 0 )
retval = (*basilisk_verify_func)(swap,mp->data,mp->datalen);
//printf("mine/other %s vs %s\n",bits256_str(str,swap->I.myhash),bits256_str(str2,swap->I.otherhash));
return(retval);
}
int32_t basilisk_messagekeyread(uint8_t *key,uint32_t *channelp,uint32_t *msgidp,bits256 *srchashp,bits256 *desthashp)
{
int32_t keylen = 0;
keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),channelp);
keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),msgidp);
keylen += iguana_rwbignum(0,&key[keylen],sizeof(*srchashp),srchashp->bytes);
keylen += iguana_rwbignum(0,&key[keylen],sizeof(*desthashp),desthashp->bytes);
return(keylen);
}
int32_t basilisk_messagekey(uint8_t *key,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash)
{
int32_t keylen = 0;
keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&channel);
keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&msgid);
keylen += iguana_rwbignum(1,&key[keylen],sizeof(srchash),srchash.bytes);
keylen += iguana_rwbignum(1,&key[keylen],sizeof(desthash),desthash.bytes);
return(keylen);
}
void LP_channelsend(bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen)
{
int32_t keylen; uint8_t key[BASILISK_KEYSIZE]; //char *retstr;
keylen = basilisk_messagekey(key,channel,msgid,srchash,desthash);
//if ( (retstr= _dex_reqsend(myinfo,"DEX",key,keylen,data,datalen)) != 0 )
// free(retstr);
}
#ifdef adfafds
void iguana_ensure_privkey(struct iguana_info *coin,bits256 privkey)
{
uint8_t pubkey33[33]; struct iguana_waccount *wacct; struct iguana_waddress *waddr,addr; char coinaddr[128];
bitcoin_pubkey33(swap->ctx,pubkey33,privkey);
bitcoin_address(coinaddr,coin->pubtype,pubkey33,33);
//printf("privkey for (%s)\n",coinaddr);
if ( myinfo->expiration != 0 && ((waddr= iguana_waddresssearch(&wacct,coinaddr)) == 0 || bits256_nonz(waddr->privkey) == 0) )
{
if ( waddr == 0 )
{
memset(&addr,0,sizeof(addr));
iguana_waddresscalc(coin->pubtype,coin->wiftype,&addr,privkey);
if ( (wacct= iguana_waccountfind("default")) != 0 )
waddr = iguana_waddressadd(coin,wacct,&addr,0);
}
if ( waddr != 0 )
{
waddr->privkey = privkey;
if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->wiftype) > 0 )
{
if ( (0) && waddr->wiftype != coin->wiftype )
printf("ensurepriv warning: mismatched wiftype %02x != %02x\n",waddr->wiftype,coin->wiftype);
if ( (0) && waddr->addrtype != coin->pubtype )
printf("ensurepriv warning: mismatched addrtype %02x != %02x\n",waddr->addrtype,coin->pubtype);
}
}
}
}
#endif
int32_t basilisk_rawtx_return(struct basilisk_rawtx *rawtx,cJSON *item,int32_t lockinputs,struct vin_info *V)
{
char *signedtx,*txbytes; cJSON *vins,*privkeyarray; int32_t i,n,retval = -1;
if ( (txbytes= jstr(item,"rawtx")) != 0 && (vins= jobj(item,"vins")) != 0 )
{
privkeyarray = cJSON_CreateArray();
jaddistr(privkeyarray,wifstr);
if ( (signedtx= LP_signrawtx(rawtx->coin->symbol,&rawtx->I.signedtxid,&rawtx->I.completed,vins,txbytes,privkeyarray,V)) != 0 )
{
if ( lockinputs != 0 )
{
//printf("lockinputs\n");
LP_unspentslock(rawtx->coin->symbol,vins);
if ( (n= cJSON_GetArraySize(vins)) != 0 )
{
bits256 txid; int32_t vout;
for (i=0; i<n; i++)
{
item = jitem(vins,i);
txid = jbits256(item,"txid");
vout = jint(item,"vout");
}
}
}
rawtx->I.datalen = (int32_t)strlen(signedtx) >> 1;
//rawtx->txbytes = calloc(1,rawtx->I.datalen);
decode_hex(rawtx->txbytes,rawtx->I.datalen,signedtx);
//printf("%s SIGNEDTX.(%s)\n",rawtx->name,signedtx);
free(signedtx);
retval = 0;
} else printf("error signrawtx\n"); //do a very short timeout so it finishes via local poll
free_json(privkeyarray);
}
return(retval);
}
cJSON *LP_createvins(struct basilisk_rawtx *dest,struct vin_info *V,struct basilisk_rawtx *rawtx,uint8_t *userdata,int32_t userdatalen,uint32_t sequenceid)
{
cJSON *vins,*item,*sobj; char hexstr[8192];
vins = cJSON_CreateArray();
item = cJSON_CreateObject();
if ( userdata != 0 && userdatalen > 0 )
{
memcpy(V[0].userdata,userdata,userdatalen);
V[0].userdatalen = userdatalen;
init_hexbytes_noT(hexstr,userdata,userdatalen);
jaddstr(item,"userdata",hexstr);
#ifdef DISABLE_CHECKSIG
needsig = 0;
#endif
}
//printf("rawtx B\n");
if ( bits256_nonz(rawtx->I.actualtxid) != 0 )
jaddbits256(item,"txid",rawtx->I.actualtxid);
else jaddbits256(item,"txid",rawtx->I.signedtxid);
jaddnum(item,"vout",0);
//sobj = cJSON_CreateObject();
init_hexbytes_noT(hexstr,rawtx->spendscript,rawtx->I.spendlen);
//jaddstr(sobj,"hex",hexstr);
//jadd(item,"scriptPubKey",sobj);
jaddstr(item,"scriptPubKey",hexstr);
jaddnum(item,"suppress",dest->I.suppress_pubkeys);
jaddnum(item,"sequence",sequenceid);
if ( (dest->I.redeemlen= rawtx->I.redeemlen) != 0 )
{
init_hexbytes_noT(hexstr,rawtx->redeemscript,rawtx->I.redeemlen);
memcpy(dest->redeemscript,rawtx->redeemscript,rawtx->I.redeemlen);
jaddstr(item,"redeemScript",hexstr);
}
jaddi(vins,item);
return(vins);
}
int32_t _basilisk_rawtx_gen(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)
{
char scriptstr[1024],wifstr[256],coinaddr[64],*signedtx,*rawtxbytes; uint32_t basilisktag; int32_t retval = -1; cJSON *vins,*privkeys,*addresses,*valsobj; struct vin_info *V;
//bitcoin_address(coinaddr,rawtx->coin->chain->pubtype,myinfo->persistent_pubkey33,33);
if ( rawtx->coin->changeaddr[0] == 0 )
{
bitcoin_address(rawtx->coin->changeaddr,rawtx->coin->pubtype,pubkey33,33);
printf("set change address.(%s)\n",rawtx->coin->changeaddr);
}
init_hexbytes_noT(scriptstr,script,scriptlen);
basilisktag = (uint32_t)rand();
valsobj = cJSON_CreateObject();
jaddstr(valsobj,"coin",rawtx->coin->symbol);
jaddstr(valsobj,"spendscript",scriptstr);
jaddstr(valsobj,"changeaddr",rawtx->coin->changeaddr);
jadd64bits(valsobj,"satoshis",rawtx->I.amount);
if ( strcmp(rawtx->coin->symbol,"BTC") == 0 && txfee > 0 && txfee < 50000 )
txfee = 50000;
jadd64bits(valsobj,"txfee",txfee);
jaddnum(valsobj,"minconf",minconf);
if ( locktime == 0 )
locktime = (uint32_t)time(NULL) - 777;
jaddnum(valsobj,"locktime",locktime);
jaddnum(valsobj,"timeout",30000);
jaddnum(valsobj,"timestamp",swapstarted+delay);
addresses = cJSON_CreateArray();
bitcoin_address(coinaddr,rawtx->coin->pubtype,pubkey33,33);
jaddistr(addresses,coinaddr);
jadd(valsobj,"addresses",addresses);
rawtx->I.locktime = locktime;
printf("%s locktime.%u\n",rawtx->name,locktime);
V = calloc(256,sizeof(*V));
privkeys = cJSON_CreateArray();
bitcoin_priv2wif(wifstr,privkey,rawtx->coin->wiftype);
jaddistr(privkeys,wifstr);
vins = LP_createvins(rawtx,V,rawtx,0,0,0xffffffff);
rawtx->vins = jduplicate(vins);
jdelete(valsobj,"vin");
jadd(valsobj,"vin",vins);
if ( (rawtxbytes= bitcoin_json2hex(rawtx->coin->isPoS,&rawtx->I.txid,valsobj,V)) != 0 )
{
//printf("rawtx.(%s) vins.%p\n",rawtxbytes,vins);
if ( (signedtx= LP_signrawtx(rawtx->coin->symbol,&rawtx->I.signedtxid,&rawtx->I.completed,vins,rawtxbytes,privkeys,V)) != 0 )
{
rawtx->I.datalen = (int32_t)strlen(signedtx) >> 1;
if ( rawtx->I.datalen <= sizeof(rawtx->txbytes) )
decode_hex(rawtx->txbytes,rawtx->I.datalen,signedtx);
else printf("DEX tx is too big %d vs %d\n",rawtx->I.datalen,(int32_t)sizeof(rawtx->txbytes));
if ( signedtx != rawtxbytes )
free(signedtx);
if ( rawtx->I.completed != 0 )
retval = 0;
else printf("couldnt complete sign transaction %s\n",rawtx->name);
} else printf("error signing\n");
free(rawtxbytes);
} else printf("error making rawtx\n");
free_json(privkeys);
free_json(valsobj);
free(V);
return(retval);
}
int32_t _basilisk_rawtx_sign(char *symbol,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,struct basilisk_swap *swap,uint32_t timestamp,uint32_t locktime,uint32_t sequenceid,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr)
{
char *rawtxbytes=0,*signedtx=0,wifstr[128]; cJSON *txobj,*vins,*privkeys; int32_t needsig=1,retval = -1; struct vin_info *V;
V = calloc(256,sizeof(*V));
V[0].signers[0].privkey = privkey;
bitcoin_pubkey33(swap->ctx,V[0].signers[0].pubkey,privkey);
privkeys = cJSON_CreateArray();
bitcoin_priv2wif(wifstr,privkey,wiftype);
jaddistr(privkeys,wifstr);
if ( privkey2 != 0 )
{
V[0].signers[1].privkey = *privkey2;
bitcoin_pubkey33(swap->ctx,V[0].signers[1].pubkey,*privkey2);
bitcoin_priv2wif(wifstr,*privkey2,wiftype);
jaddistr(privkeys,wifstr);
V[0].N = V[0].M = 2;
//char str[65]; printf("add second privkey.(%s) %s\n",jprint(privkeys,0),bits256_str(str,*privkey2));
} else V[0].N = V[0].M = 1;
V[0].suppress_pubkeys = dest->I.suppress_pubkeys;
V[0].ignore_cltverr = ignore_cltverr;
if ( dest->I.redeemlen != 0 )
memcpy(V[0].p2shscript,dest->redeemscript,dest->I.redeemlen), V[0].p2shlen = dest->I.redeemlen;
txobj = bitcoin_txcreate(symbol,isPoS,locktime,userdata == 0 ? 1 : 1,timestamp);//rawtx->coin->locktime_txversion);
vins = LP_createvins(dest,V,rawtx,userdata,userdatalen,sequenceid);
jdelete(txobj,"vin");
jadd(txobj,"vin",vins);
//printf("basilisk_rawtx_sign locktime.%u/%u for %s spendscript.%s -> %s, suppress.%d\n",rawtx->I.locktime,dest->I.locktime,rawtx->name,hexstr,dest->name,dest->I.suppress_pubkeys);
txobj = bitcoin_txoutput(txobj,dest->spendscript,dest->I.spendlen,dest->I.amount);
if ( (rawtxbytes= bitcoin_json2hex(isPoS,&dest->I.txid,txobj,V)) != 0 )
{
//printf("rawtx.(%s) vins.%p\n",rawtxbytes,vins);
if ( needsig == 0 )
signedtx = rawtxbytes;
if ( signedtx != 0 || (signedtx= LP_signrawtx(symbol,&dest->I.signedtxid,&dest->I.completed,vins,rawtxbytes,privkeys,V)) != 0 )
{
dest->I.datalen = (int32_t)strlen(signedtx) >> 1;
if ( dest->I.datalen <= sizeof(dest->txbytes) )
decode_hex(dest->txbytes,dest->I.datalen,signedtx);
else printf("DEX tx is too big %d vs %d\n",dest->I.datalen,(int32_t)sizeof(dest->txbytes));
if ( signedtx != rawtxbytes )
free(signedtx);
if ( dest->I.completed != 0 )
retval = 0;
else printf("couldnt complete sign transaction %s\n",rawtx->name);
} else printf("error signing\n");
free(rawtxbytes);
} else printf("error making rawtx\n");
free_json(privkeys);
free_json(txobj);
free(V);
return(retval);
}
int32_t basilisk_process_swapverify(void *ptr,int32_t (*internal_func)(void *ptr,uint8_t *data,int32_t datalen),uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t expiration,uint32_t duration)
{
struct basilisk_swap *swap = ptr;
@ -26,8 +524,6 @@ int32_t basilisk_process_swapverify(void *ptr,int32_t (*internal_func)(void *ptr
else return(0);
}
int32_t basilisk_priviextract(struct iguana_info *coin,char *name,bits256 *destp,uint8_t secret160[20],bits256 srctxid,int32_t srcvout)
{
/*bits256 txid; char str[65]; int32_t i,vini,scriptlen; uint8_t rmd160[20],scriptsig[IGUANA_MAXSCRIPTSIZE];
@ -539,6 +1035,225 @@ cJSON *basilisk_privkeyarray(struct iguana_info *coin,cJSON *vins)
#endif
#ifdef old
void basilisk_swaploop(void *_utxo)
{
uint8_t *data; uint32_t expiration,savestatebits=0,saveotherbits=0; uint32_t channel; int32_t iters,retval=0,j,datalen,maxlen; struct basilisk_swap *swap; struct LP_utxoinfo *utxo = _utxo;
swap = utxo->swap;
fprintf(stderr,"start swap iambob.%d\n",swap->I.iambob);
maxlen = 1024*1024 + sizeof(*swap);
data = malloc(maxlen);
expiration = (uint32_t)time(NULL) + 300;
//myinfo->DEXactive = expiration;
channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16);
while ( swap->aborted == 0 && (swap->I.statebits & (0x08|0x02)) != (0x08|0x02) && time(NULL) < expiration )
{
LP_channelsend(swap->I.req.srchash,swap->I.req.desthash,channel,0x4000000,(void *)&swap->I.req.requestid,sizeof(swap->I.req.requestid)); //,60);
if ( swap->connected == 0 )
basilisk_psockinit(swap,swap->I.iambob != 0);
if ( swap->connected > 0 )
{
printf("A r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits);
basilisk_sendstate(swap,data,maxlen);
basilisk_sendpubkeys(swap,data,maxlen); // send pubkeys
if ( basilisk_checkdeck(swap,data,maxlen) == 0) // check for other deck 0x02
basilisk_sendchoosei(swap,data,maxlen);
basilisk_waitchoosei(swap,data,maxlen); // wait for choosei 0x08
if ( (swap->I.statebits & (0x08|0x02)) == (0x08|0x02) )
break;
}
if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits )
sleep(DEX_SLEEP + (swap->I.iambob == 0)*1);
savestatebits = swap->I.statebits;
saveotherbits = swap->I.otherstatebits;
}
if ( swap->connected == 0 )
{
printf("couldnt establish connection\n");
retval = -1;
}
while ( swap->aborted == 0 && retval == 0 && (swap->I.statebits & 0x20) == 0 )
{
if ( swap->connected == 0 )
basilisk_psockinit(swap,swap->I.iambob != 0);
printf("B r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits);
basilisk_sendstate(swap,data,maxlen);
basilisk_sendchoosei(swap,data,maxlen);
basilisk_sendmostprivs(swap,data,maxlen);
if ( basilisk_swapget(swap,0x20,data,maxlen,basilisk_verify_privkeys) == 0 )
{
swap->I.statebits |= 0x20;
break;
}
if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits )
sleep(DEX_SLEEP + (swap->I.iambob == 0)*1);
savestatebits = swap->I.statebits;
saveotherbits = swap->I.otherstatebits;
if ( time(NULL) > expiration )
break;
}
//myinfo->DEXactive = swap->I.expiration;
if ( time(NULL) >= expiration )
{
retval = -1;
//myinfo->DEXactive = 0;
}
if ( swap->aborted != 0 )
{
printf("swap aborted before tx sent\n");
retval = -1;
}
printf("C r%u/q%u swapstate.%x retval.%d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,retval);
iters = 0;
while ( swap->aborted == 0 && retval == 0 && (swap->I.statebits & 0x40) == 0 && iters++ < 10 ) // send fee
{
if ( swap->connected == 0 )
basilisk_psockinit(swap,swap->I.iambob != 0);
//printf("sendstate.%x\n",swap->I.statebits);
basilisk_sendstate(swap,data,maxlen);
//printf("swapget\n");
basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits);
//printf("after swapget\n");
if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen == 0 )
{
printf("bobscripts set\n");
if ( basilisk_bobscripts_set(swap,1,1) < 0 )
{
sleep(DEX_SLEEP);
printf("bobscripts set error\n");
continue;
}
}
if ( swap->I.iambob == 0 )
{
/*for (i=0; i<20; i++)
printf("%02x",swap->secretAm[i]);
printf(" <- secretAm\n");
for (i=0; i<32; i++)
printf("%02x",swap->secretAm256[i]);
printf(" <- secretAm256\n");
for (i=0; i<32; i++)
printf("%02x",swap->pubAm.bytes[i]);
printf(" <- pubAm\n");
for (i=0; i<20; i++)
printf("%02x",swap->secretBn[i]);
printf(" <- secretBn\n");
for (i=0; i<32; i++)
printf("%02x",swap->secretBn256[i]);
printf(" <- secretBn256\n");
for (i=0; i<32; i++)
printf("%02x",swap->pubBn.bytes[i]);
printf(" <- pubBn\n");
for (i=0; i<32; i++)
printf("%02x",swap->pubA0.bytes[i]);
printf(" <- pubA0\n");
for (i=0; i<32; i++)
printf("%02x",swap->pubA1.bytes[i]);
printf(" <- pubA1\n");
for (i=0; i<32; i++)
printf("%02x",swap->pubB0.bytes[i]);
printf(" <- pubB0\n");
for (i=0; i<32; i++)
printf("%02x",swap->pubB1.bytes[i]);
printf(" <- pubB1\n");*/
if ( (retval= basilisk_alicetxs(swap,data,maxlen)) != 0 )
{
printf("basilisk_alicetxs error\n");
break;
}
}
}
if ( swap->I.iambob == 0 && (swap->I.statebits & 0x40) == 0 )
{
printf("couldnt send fee\n");
retval = -8;
}
if ( retval == 0 )
{
if ( swap->I.iambob == 0 && (swap->myfee.I.datalen == 0 || swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.datalen == 0) )
{
printf("ALICE's error %d %d %d\n",swap->myfee.I.datalen,swap->alicepayment.I.datalen,swap->alicepayment.I.datalen);
retval = -7;
}
else if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen == 0 ) //swap->bobpayment.I.datalen == 0
{
printf("BOB's error %d %d %d\n",swap->myfee.I.datalen,swap->bobpayment.I.datalen,swap->bobdeposit.I.datalen);
retval = -7;
}
}
while ( swap->aborted == 0 && retval == 0 && basilisk_swapiteration(swap,data,maxlen) == 0 )
{
if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits )
sleep(DEX_SLEEP + (swap->I.iambob == 0)*1);
savestatebits = swap->I.statebits;
saveotherbits = swap->I.otherstatebits;
basilisk_sendstate(swap,data,maxlen);
basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits);
basilisk_swap_saveupdate(swap);
if ( time(NULL) > swap->I.expiration )
break;
}
if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen != 0 && bits256_nonz(swap->bobdeposit.I.actualtxid) != 0 )
{
printf("BOB waiting for confirm state.%x\n",swap->I.statebits);
sleep(60); // wait for confirm/propagation of msig
printf("BOB reclaims refund\n");
basilisk_bobdeposit_refund(swap,0);
if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->bobrefund,0x40000000,0) == 0 ) // use secretBn
{
printf("Bob submit error getting refund of deposit\n");
}
else
{
// maybe wait for bobrefund to be confirmed
for (j=datalen=0; j<32; j++)
data[datalen++] = swap->I.privBn.bytes[j];
LP_swapsend(swap,0x40000000,data,datalen,0x40000000,swap->I.crcs_mypriv);
}
basilisk_swap_saveupdate(swap);
}
if ( retval != 0 )
basilisk_swap_sendabort(swap);
printf("end of atomic swap\n");
if ( swapcompleted(swap) > 0 ) // only if swap completed
{
if ( swap->I.iambob != 0 )
tradebot_pendingadd(swapjson(swap),swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount));
else tradebot_pendingadd(swapjson(swap),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.src,dstr(swap->I.req.srcamount));
}
printf("%s swap finished statebits %x\n",swap->I.iambob!=0?"BOB":"ALICE",swap->I.statebits);
//basilisk_swap_purge(swap);
free(data);
}
#endif
int32_t bitcoin_coinptrs(bits256 pubkey,struct iguana_info **bobcoinp,struct iguana_info **alicecoinp,char *src,char *dest,bits256 srchash,bits256 desthash)
{
struct iguana_info *coin = LP_coinfind(src);
if ( coin == 0 || LP_coinfind(dest) == 0 )
return(0);
*bobcoinp = *alicecoinp = 0;
*bobcoinp = LP_coinfind(dest);
*alicecoinp = LP_coinfind(src);
if ( bits256_cmp(pubkey,srchash) == 0 )
{
if ( strcmp(src,(*bobcoinp)->symbol) == 0 )
return(1);
else if ( strcmp(dest,(*alicecoinp)->symbol) == 0 )
return(-1);
else return(0);
}
else if ( bits256_cmp(pubkey,desthash) == 0 )
{
if ( strcmp(src,(*bobcoinp)->symbol) == 0 )
return(-1);
else if ( strcmp(dest,(*alicecoinp)->symbol) == 0 )
return(1);
else return(0);
}
return(0);
}
/*void basilisk_swap_purge(struct basilisk_swap *swap)
{
int32_t i,n;

588
iguana/exchanges/LP_swap.c

@ -119,33 +119,6 @@
*/
int32_t bitcoin_coinptrs(bits256 pubkey,struct iguana_info **bobcoinp,struct iguana_info **alicecoinp,char *src,char *dest,bits256 srchash,bits256 desthash)
{
struct iguana_info *coin = LP_coinfind(src);
if ( coin == 0 || LP_coinfind(dest) == 0 )
return(0);
*bobcoinp = *alicecoinp = 0;
*bobcoinp = LP_coinfind(dest);
*alicecoinp = LP_coinfind(src);
if ( bits256_cmp(pubkey,srchash) == 0 )
{
if ( strcmp(src,(*bobcoinp)->symbol) == 0 )
return(1);
else if ( strcmp(dest,(*alicecoinp)->symbol) == 0 )
return(-1);
else return(0);
}
else if ( bits256_cmp(pubkey,desthash) == 0 )
{
if ( strcmp(src,(*bobcoinp)->symbol) == 0 )
return(-1);
else if ( strcmp(dest,(*alicecoinp)->symbol) == 0 )
return(1);
else return(0);
}
return(0);
}
void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx)
{
if ( rawtx->vins != 0 )
@ -177,6 +150,14 @@ void basilisk_swap_finished(struct basilisk_swap *swap)
swap->nummessages = 0;
}
uint32_t basilisk_quoteid(struct basilisk_request *rp)
{
struct basilisk_request R;
R = *rp;
R.unused = R.requestid = R.quoteid = R.DEXselector = 0;
return(calc_crc32(0,(void *)&R,sizeof(R)));
}
uint32_t basilisk_requestid(struct basilisk_request *rp)
{
struct basilisk_request R;
@ -190,19 +171,11 @@ uint32_t basilisk_requestid(struct basilisk_request *rp)
for (i=0; i<sizeof(R); i++)
printf("%02x",((uint8_t *)&R)[i]);
printf(" <- crc.%u\n",calc_crc32(0,(void *)&R,sizeof(R)));
char str[65],str2[65]; printf("B REQUESTID: t.%u r.%u q.%u %s %.8f %s -> %s %.8f %s crc.%u\n",R.timestamp,R.requestid,R.quoteid,R.src,dstr(R.srcamount),bits256_str(str,R.srchash),R.dest,dstr(R.destamount),bits256_str(str2,R.desthash),calc_crc32(0,(void *)&R,sizeof(R)));
char str[65],str2[65]; printf("B REQUESTID: t.%u r.%u q.%u %s %.8f %s -> %s %.8f %s crc.%u q%u\n",R.timestamp,R.requestid,R.quoteid,R.src,dstr(R.srcamount),bits256_str(str,R.srchash),R.dest,dstr(R.destamount),bits256_str(str2,R.desthash),calc_crc32(0,(void *)&R,sizeof(R)),basilisk_quoteid(&R));
}
return(calc_crc32(0,(void *)&R,sizeof(R)));
}
uint32_t basilisk_quoteid(struct basilisk_request *rp)
{
struct basilisk_request R;
R = *rp;
R.requestid = R.quoteid = R.unused = R.DEXselector = 0;
return(calc_crc32(0,(void *)&R,sizeof(R)));
}
int32_t LP_pubkeys_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)
{
int32_t i,datalen = 0;
@ -219,7 +192,9 @@ int32_t LP_pubkeys_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datal
for (i=0; i<sizeof(swap->otherdeck)/sizeof(swap->otherdeck[0][0]); i++)
len += iguana_rwnum(0,&data[len],sizeof(swap->otherdeck[i>>1][i&1]),&swap->otherdeck[i>>1][i&1]);
return(0);
} else return(-1);
}
printf("pubkeys verify size mismatch %d != %d\n",datalen,(int32_t)sizeof(swap->otherdeck));
return(-1);
}
int32_t LP_choosei_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)
@ -267,7 +242,7 @@ int32_t LP_choosei_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datal
vcalc_sha256(0,swap->I.secretBn256,swap->I.privBn.bytes,sizeof(swap->I.privBn));
swap->I.pubBn = bitcoin_pubkey33(swap->ctx,pubkey33,swap->I.privBn);
printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256));
basilisk_bobscripts_set(swap,1,1);
//basilisk_bobscripts_set(swap,1,1);
}
else
{
@ -371,8 +346,8 @@ int32_t basilisk_verify_privi(void *ptr,uint8_t *data,int32_t datalen)
basilisk_dontforget_update(swap,0);
char str[65]; printf("privi verified.(%s)\n",bits256_str(str,privkey));
return(0);
}
}
} else printf("pubpair doesnt verify privi\n");
} else printf("verify privi size mismatch %d != %d\n",datalen,(int32_t)sizeof(bits256));
return(-1);
}
@ -406,7 +381,7 @@ int32_t LP_mostprivs_verify(struct basilisk_swap *swap,uint8_t *data,int32_t dat
swap->I.secretAm[i] = data[len++];
for (i=0; i<32; i++)
swap->I.secretAm256[i] = data[len++];
basilisk_bobscripts_set(swap,1,1);
//basilisk_bobscripts_set(swap,1,1);
}
else
{
@ -431,10 +406,13 @@ int32_t LP_waitfor(int32_t pairsock,struct basilisk_swap *swap,int32_t timeout,i
{
if ( (datalen= nn_recv(pairsock,&data,NN_MSG,0)) >= 0 )
{
printf("wait for got.%d\n",datalen);
retval = (*verify)(swap,data,datalen);
nn_freemsg(data);
}
return(retval);
} else printf("error nn_recv\n");
}
printf("waitfor timedout\n");
return(retval);
}
@ -446,11 +424,10 @@ int32_t LP_waitsend(char *statename,int32_t timeout,int32_t pairsock,struct basi
if ( (datalen= (*datagen)(swap,data,maxlen)) > 0 )
{
if ( (sendlen= nn_send(pairsock,data,datalen,0)) == datalen )
{
retval = 0;
} else printf("send %s error\n",statename);
else printf("send %s error\n",statename);
}
} else printf("didnt get pubkeys\n");
} else printf("didnt get valid data\n");
return(retval);
}
@ -489,9 +466,63 @@ void LP_swapsfp_update(struct basilisk_request *rp)
}
}
struct basilisk_rawtx *LP_swapdata_rawtx(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx)
{
if ( rawtx->I.datalen != 0 && rawtx->I.datalen <= maxlen )
{
memcpy(data,rawtx->txbytes,rawtx->I.datalen);
return(rawtx);
}
printf("swapdata rawtx has null txbytes\n");
return(0);
}
uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend)
{
uint8_t sendbuf[32768]; int32_t sendlen;
if ( LP_swapdata_rawtx(swap,data,maxlen,rawtx) != 0 )
{
if ( bits256_nonz(rawtx->I.signedtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 )
{
rawtx->I.actualtxid = LP_broadcast_tx(rawtx->name,rawtx->coin->symbol,rawtx->txbytes,rawtx->I.datalen);
if ( bits256_cmp(rawtx->I.actualtxid,rawtx->I.signedtxid) != 0 )
{
//printf("%s rawtxsend.[%d] %s vs %s\n",rawtx->name,rawtx->I.datalen,bits256_str(str,rawtx->I.signedtxid),bits256_str(str2,rawtx->I.actualtxid));
rawtx->I.actualtxid = rawtx->I.signedtxid;
}
if ( bits256_nonz(rawtx->I.actualtxid) != 0 && msgbits != 0 )
{
sendlen = 0;
sendbuf[sendlen++] = rawtx->I.datalen & 0xff;
sendbuf[sendlen++] = (rawtx->I.datalen >> 8) & 0xff;
sendbuf[sendlen++] = rawtx->I.redeemlen;
//printf("datalen.%d redeemlen.%d\n",rawtx->I.datalen,rawtx->I.redeemlen);
memcpy(&sendbuf[sendlen],rawtx->txbytes,rawtx->I.datalen), sendlen += rawtx->I.datalen;
if ( rawtx->I.redeemlen > 0 && rawtx->I.redeemlen < 0x100 )
{
memcpy(&sendbuf[sendlen],rawtx->redeemscript,rawtx->I.redeemlen);
sendlen += rawtx->I.redeemlen;
}
basilisk_dontforget_update(swap,rawtx);
//printf("sendlen.%d datalen.%d redeemlen.%d\n",sendlen,rawtx->datalen,rawtx->redeemlen);
if ( suppress_swapsend == 0 )
return(LP_swapsend(pairsock,swap,msgbits,sendbuf,sendlen,nextbits,rawtx->I.crcs));
else
{
printf("suppress swapsend %x\n",msgbits);
return(0);
}
}
}
return(nextbits);
} //else if ( swap->I.iambob == 0 )
printf("error from basilisk_swapdata_rawtx.%s %p len.%d\n",rawtx->name,rawtx->txbytes,rawtx->I.datalen);
return(0);
}
void LP_bobloop(void *_utxo)
{
uint8_t *data; int32_t maxlen; uint32_t expiration; struct basilisk_swap *swap; struct LP_utxoinfo *utxo = _utxo;
uint8_t *data; char *retstr; int32_t maxlen; uint32_t expiration; struct basilisk_swap *swap; struct LP_utxoinfo *utxo = _utxo;
fprintf(stderr,"start swap iambob\n");
maxlen = 1024*1024 + sizeof(*swap);
data = malloc(maxlen);
@ -507,254 +538,91 @@ void LP_bobloop(void *_utxo)
else if ( LP_waitsend("mostprivs",10,utxo->pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 )
printf("error waitsend mostprivs\n");
else if ( basilisk_bobscripts_set(swap,1,1) < 0 )
printf("error bobscripts\n");
printf("error bobscripts deposit\n");
else
{
LP_swapsfp_update(&swap->I.req);
// wait alicefee
// send bobdeposit
// wait alicepayment
// send bobpayment
// bobspend
// bobrefund
// done
if ( LP_waitfor(utxo->pair,swap,10,LP_verify_otherfee) < 0 )
printf("error waiting for alicefee\n");
else if ( LP_swapdata_rawtxsend(utxo->pair,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0) == 0 )
printf("error sending bobdeposit\n");
else if ( LP_waitfor(utxo->pair,swap,10,LP_verify_alicepayment) < 0 )
printf("error waiting for alicepayment\n");
else if ( basilisk_bobscripts_set(swap,0,1) < 0 )
printf("error bobscripts payment\n");
else if ( LP_swapdata_rawtxsend(utxo->pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 )
printf("error sending bobpayment\n");
else
{
printf("looping on swaplist\n");
while ( 1 )
{
if ( (retstr= basilisk_swaplist()) != 0 )
{
printf("%s\n",retstr);
free(retstr);
}
sleep(100);
}
}
}
basilisk_swap_finished(swap);
free(utxo->swap);
} else printf("swap timed out\n");
basilisk_swap_finished(swap);
free(utxo->swap);
utxo->swap = 0;
nn_close(utxo->pair);
utxo->pair = -1;
}
void LP_aliceloop(void *_utxo)
void LP_aliceloop(void *_qp)
{
uint8_t *data; int32_t maxlen; uint32_t expiration; struct basilisk_swap *swap; struct LP_utxoinfo *utxo = _utxo;
fprintf(stderr,"start swap iambob\n");
uint8_t *data; char *retstr; int32_t maxlen; uint32_t expiration; struct basilisk_swap *swap = 0; struct LP_quoteinfo *qp = _qp;
fprintf(stderr,"start swap iamalice pair.%d\n",qp->pair);
maxlen = 1024*1024 + sizeof(*swap);
data = malloc(maxlen);
expiration = (uint32_t)time(NULL) + 10;
while ( (swap= utxo->swap) == 0 && time(NULL) < expiration )
sleep(1);
if ( (utxo->swap= swap) != 0 )
swap = LP_swapinit(0,0,qp->privkey,&qp->R,qp);
if ( swap != 0 )
{
if ( LP_sendwait("pubkeys",10,utxo->pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 )
if ( LP_sendwait("pubkeys",10,qp->pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 )
printf("error LP_sendwait pubkeys\n");
else if ( LP_sendwait("choosei",10,utxo->pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 )
else if ( LP_sendwait("choosei",10,qp->pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 )
printf("error LP_sendwait choosei\n");
else if ( LP_sendwait("mostprivs",10,utxo->pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 )
else if ( LP_sendwait("mostprivs",10,qp->pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 )
printf("error LP_sendwait mostprivs\n");
else if ( basilisk_alicetxs(swap,data,maxlen) != 0 )
else if ( basilisk_alicetxs(qp->pair,swap,data,maxlen) != 0 )
printf("basilisk_alicetxs error\n");
else
{
LP_swapsfp_update(&swap->I.req);
// send alicefee
// wait bobdeposit
// send alicepayment
// wait bobpayment
// alicespend
// done
}
} else printf("swap timed out\n");
basilisk_swap_finished(swap);
free(utxo->swap);
utxo->swap = 0;
nn_close(utxo->pair);
utxo->pair = -1;
}
#ifdef old
void basilisk_swaploop(void *_utxo)
{
uint8_t *data; uint32_t expiration,savestatebits=0,saveotherbits=0; uint32_t channel; int32_t iters,retval=0,j,datalen,maxlen; struct basilisk_swap *swap; struct LP_utxoinfo *utxo = _utxo;
swap = utxo->swap;
fprintf(stderr,"start swap iambob.%d\n",swap->I.iambob);
maxlen = 1024*1024 + sizeof(*swap);
data = malloc(maxlen);
expiration = (uint32_t)time(NULL) + 300;
//myinfo->DEXactive = expiration;
channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16);
while ( swap->aborted == 0 && (swap->I.statebits & (0x08|0x02)) != (0x08|0x02) && time(NULL) < expiration )
{
LP_channelsend(swap->I.req.srchash,swap->I.req.desthash,channel,0x4000000,(void *)&swap->I.req.requestid,sizeof(swap->I.req.requestid)); //,60);
if ( swap->connected == 0 )
basilisk_psockinit(swap,swap->I.iambob != 0);
if ( swap->connected > 0 )
{
printf("A r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits);
basilisk_sendstate(swap,data,maxlen);
basilisk_sendpubkeys(swap,data,maxlen); // send pubkeys
if ( basilisk_checkdeck(swap,data,maxlen) == 0) // check for other deck 0x02
basilisk_sendchoosei(swap,data,maxlen);
basilisk_waitchoosei(swap,data,maxlen); // wait for choosei 0x08
if ( (swap->I.statebits & (0x08|0x02)) == (0x08|0x02) )
break;
}
if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits )
sleep(DEX_SLEEP + (swap->I.iambob == 0)*1);
savestatebits = swap->I.statebits;
saveotherbits = swap->I.otherstatebits;
}
if ( swap->connected == 0 )
{
printf("couldnt establish connection\n");
retval = -1;
}
while ( swap->aborted == 0 && retval == 0 && (swap->I.statebits & 0x20) == 0 )
{
if ( swap->connected == 0 )
basilisk_psockinit(swap,swap->I.iambob != 0);
printf("B r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits);
basilisk_sendstate(swap,data,maxlen);
basilisk_sendchoosei(swap,data,maxlen);
basilisk_sendmostprivs(swap,data,maxlen);
if ( basilisk_swapget(swap,0x20,data,maxlen,basilisk_verify_privkeys) == 0 )
{
swap->I.statebits |= 0x20;
break;
}
if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits )
sleep(DEX_SLEEP + (swap->I.iambob == 0)*1);
savestatebits = swap->I.statebits;
saveotherbits = swap->I.otherstatebits;
if ( time(NULL) > expiration )
break;
}
//myinfo->DEXactive = swap->I.expiration;
if ( time(NULL) >= expiration )
{
retval = -1;
//myinfo->DEXactive = 0;
}
if ( swap->aborted != 0 )
{
printf("swap aborted before tx sent\n");
retval = -1;
}
printf("C r%u/q%u swapstate.%x retval.%d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,retval);
iters = 0;
while ( swap->aborted == 0 && retval == 0 && (swap->I.statebits & 0x40) == 0 && iters++ < 10 ) // send fee
{
if ( swap->connected == 0 )
basilisk_psockinit(swap,swap->I.iambob != 0);
//printf("sendstate.%x\n",swap->I.statebits);
basilisk_sendstate(swap,data,maxlen);
//printf("swapget\n");
basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits);
//printf("after swapget\n");
if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen == 0 )
{
printf("bobscripts set\n");
if ( basilisk_bobscripts_set(swap,1,1) < 0 )
{
sleep(DEX_SLEEP);
printf("bobscripts set error\n");
continue;
}
}
if ( swap->I.iambob == 0 )
{
/*for (i=0; i<20; i++)
printf("%02x",swap->secretAm[i]);
printf(" <- secretAm\n");
for (i=0; i<32; i++)
printf("%02x",swap->secretAm256[i]);
printf(" <- secretAm256\n");
for (i=0; i<32; i++)
printf("%02x",swap->pubAm.bytes[i]);
printf(" <- pubAm\n");
for (i=0; i<20; i++)
printf("%02x",swap->secretBn[i]);
printf(" <- secretBn\n");
for (i=0; i<32; i++)
printf("%02x",swap->secretBn256[i]);
printf(" <- secretBn256\n");
for (i=0; i<32; i++)
printf("%02x",swap->pubBn.bytes[i]);
printf(" <- pubBn\n");
for (i=0; i<32; i++)
printf("%02x",swap->pubA0.bytes[i]);
printf(" <- pubA0\n");
for (i=0; i<32; i++)
printf("%02x",swap->pubA1.bytes[i]);
printf(" <- pubA1\n");
for (i=0; i<32; i++)
printf("%02x",swap->pubB0.bytes[i]);
printf(" <- pubB0\n");
for (i=0; i<32; i++)
printf("%02x",swap->pubB1.bytes[i]);
printf(" <- pubB1\n");*/
if ( (retval= basilisk_alicetxs(swap,data,maxlen)) != 0 )
if ( LP_swapdata_rawtxsend(qp->pair,swap,0x80,data,maxlen,&swap->myfee,0x40,0) == 0 )
printf("error sending alicefee\n");
else if ( LP_waitfor(qp->pair,swap,10,LP_verify_bobdeposit) < 0 )
printf("error waiting for bobdeposit\n");
else if ( LP_swapdata_rawtxsend(qp->pair,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0) == 0 )
printf("error sending alicepayment\n");
else if ( LP_waitfor(qp->pair,swap,10,LP_verify_bobpayment) < 0 )
printf("error waiting for bobpayment\n");
else
{
printf("basilisk_alicetxs error\n");
break;
printf("looping on swaplist\n");
while ( 1 )
{
if ( (retstr= basilisk_swaplist()) != 0 )
{
printf("%s\n",retstr);
free(retstr);
}
sleep(100);
}
}
}
basilisk_swap_finished(swap);
free(swap);
}
if ( swap->I.iambob == 0 && (swap->I.statebits & 0x40) == 0 )
{
printf("couldnt send fee\n");
retval = -8;
}
if ( retval == 0 )
{
if ( swap->I.iambob == 0 && (swap->myfee.I.datalen == 0 || swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.datalen == 0) )
{
printf("ALICE's error %d %d %d\n",swap->myfee.I.datalen,swap->alicepayment.I.datalen,swap->alicepayment.I.datalen);
retval = -7;
}
else if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen == 0 ) //swap->bobpayment.I.datalen == 0
{
printf("BOB's error %d %d %d\n",swap->myfee.I.datalen,swap->bobpayment.I.datalen,swap->bobdeposit.I.datalen);
retval = -7;
}
}
while ( swap->aborted == 0 && retval == 0 && basilisk_swapiteration(swap,data,maxlen) == 0 )
{
if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits )
sleep(DEX_SLEEP + (swap->I.iambob == 0)*1);
savestatebits = swap->I.statebits;
saveotherbits = swap->I.otherstatebits;
basilisk_sendstate(swap,data,maxlen);
basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits);
basilisk_swap_saveupdate(swap);
if ( time(NULL) > swap->I.expiration )
break;
}
if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen != 0 && bits256_nonz(swap->bobdeposit.I.actualtxid) != 0 )
{
printf("BOB waiting for confirm state.%x\n",swap->I.statebits);
sleep(60); // wait for confirm/propagation of msig
printf("BOB reclaims refund\n");
basilisk_bobdeposit_refund(swap,0);
if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->bobrefund,0x40000000,0) == 0 ) // use secretBn
{
printf("Bob submit error getting refund of deposit\n");
}
else
{
// maybe wait for bobrefund to be confirmed
for (j=datalen=0; j<32; j++)
data[datalen++] = swap->I.privBn.bytes[j];
LP_swapsend(swap,0x40000000,data,datalen,0x40000000,swap->I.crcs_mypriv);
}
basilisk_swap_saveupdate(swap);
}
if ( retval != 0 )
basilisk_swap_sendabort(swap);
printf("end of atomic swap\n");
if ( swapcompleted(swap) > 0 ) // only if swap completed
{
if ( swap->I.iambob != 0 )
tradebot_pendingadd(swapjson(swap),swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount));
else tradebot_pendingadd(swapjson(swap),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.src,dstr(swap->I.req.srcamount));
}
printf("%s swap finished statebits %x\n",swap->I.iambob!=0?"BOB":"ALICE",swap->I.statebits);
//basilisk_swap_purge(swap);
free(data);
nn_close(qp->pair);
free(qp);
}
#endif
bits256 instantdex_derivekeypair(void *ctx,bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash)
{
@ -840,8 +708,8 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx *
rawtx->coin = coin;
strcpy(rawtx->I.coinstr,coin->symbol);
rawtx->I.numconfirms = numconfirms;
if ( (rawtx->I.amount= satoshis) < 50000 )
rawtx->I.amount = 50000;
if ( (rawtx->I.amount= satoshis) < 10000 )
rawtx->I.amount = 10000;
rawtx->I.vintype = vintype; // 0 -> std, 2 -> 2of2, 3 -> spend bobpayment, 4 -> spend bobdeposit
rawtx->I.vouttype = vouttype; // 0 -> fee, 1 -> std, 2 -> 2of2, 3 -> bobpayment, 4 -> bobdeposit
if ( rawtx->I.vouttype == 0 )
@ -873,14 +741,14 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
swap->I.putduration -= optionduration;
else if ( optionduration > 0 )
swap->I.callduration += optionduration;
swap->I.bobsatoshis = swap->I.req.destamount;
swap->I.alicesatoshis = swap->I.req.srcamount;
if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < 50000 )
swap->I.bobinsurance = 50000;
if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < 50000 )
swap->I.aliceinsurance = 50000;
strcpy(swap->I.bobstr,swap->I.req.dest);
strcpy(swap->I.alicestr,swap->I.req.src);
swap->I.bobsatoshis = swap->I.req.srcamount;
swap->I.alicesatoshis = swap->I.req.destamount;
if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < 10000 )
swap->I.bobinsurance = 10000;
if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < 10000 )
swap->I.aliceinsurance = 10000;
strcpy(swap->I.bobstr,swap->I.req.src);
strcpy(swap->I.alicestr,swap->I.req.dest);
swap->I.started = (uint32_t)time(NULL);
swap->I.expiration = swap->I.req.timestamp + swap->I.putduration + swap->I.callduration;
OS_randombytes((uint8_t *)&swap->I.choosei,sizeof(swap->I.choosei));
@ -904,16 +772,16 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
char str[65]; printf("couldnt generate privkeys %d %s\n",x,bits256_str(str,privkey));
return(0);
}
if ( (coin= LP_coinfind(swap->I.req.dest)) != 0 )
swap->bobcoin = *coin;
if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 )
swap->alicecoin = *coin;
else
{
printf("missing bobcoin.%p or missing alicecoin.%p src.%p dest.%p\n",&swap->bobcoin,&swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest));
free(swap);
return(0);
}
if ( (coin= LP_coinfind(swap->I.req.src)) != 0 )
swap->alicecoin = *coin;
if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 )
swap->bobcoin = *coin;
else
{
printf("missing bobcoin.%p or missing alicecoin.%p src.%p dest.%p\n",&swap->bobcoin,&swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest));
@ -975,7 +843,7 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
return(swap);
}
struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp)
struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp)
{
struct basilisk_swap *swap; bits256 pubkey25519; uint8_t pubkey33[33];
swap = calloc(1,sizeof(*swap));
@ -988,161 +856,19 @@ struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256
swap->persistent_pubkey = pubkey25519;
swap->persistent_privkey = privkey;
memcpy(swap->persistent_pubkey33,pubkey33,33);
calc_rmd160_sha256(swap->changermd160,pubkey33,33);
if ( bitcoin_swapinit(privkey,pubkey33,pubkey25519,swap,optionduration,!iambob) == 0 )
{
printf("error doing swapinit\n");
free(swap);
swap = 0;
}
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;
if ( iambob != 0 )
swap->otherfee.utxotxid = qp->feetxid, swap->otherfee.utxovout = qp->feevout;
else swap->myfee.utxotxid = qp->feetxid, swap->myfee.utxovout = qp->feevout;
return(swap);
}
#ifdef notanymore
struct basilisk_swap *basilisk_thread_start(bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit)
{
int32_t i,m,n,iter; uint8_t pubkey33[33]; bits256 pubkey25519; uint32_t channel,starttime; cJSON *retarray,*item,*msgobj; struct iguana_info *coin; double pending=0.; struct basilisk_swap *swap = 0;
// statebits 1 -> client, 0 -> LP
/*if ( myinfo->numswaps > 0 )
{
if ( (coin= LP_coinfind(rp->src)) == 0 || coin->FULLNODE >= 0 )
{
printf("dont have SRC coin.%s or not native and already swap pending\n",rp->src);
return(0);
}
if ( (coin= LP_coinfind(rp->dest)) == 0 || coin->FULLNODE >= 0 )
{
printf("dont have DEST coin.%s or not native and already swap pending\n",rp->dest);
return(0);
}
}
portable_mutex_lock(&myinfo->DEX_swapmutex);
for (i=0; i<myinfo->numswaps; i++)
if ( myinfo->swaps[i]->I.req.requestid == rp->requestid )
{
printf("basilisk_thread_start error trying to start requestid.%u which is already started\n",rp->requestid);
break;
}
if ( i == myinfo->numswaps && i < sizeof(myinfo->swaps)/sizeof(*myinfo->swaps) )*/
{
swap = calloc(1,sizeof(*swap));
swap->ctx = bitcoin_ctx();
swap->subsock = swap->pushsock = -1;
vcalc_sha256(0,swap->I.orderhash.bytes,(uint8_t *)rp,sizeof(*rp));
swap->I.req = *rp;
//swap->myinfoptr = myinfo;
printf("basilisk_thread_start request.%u statebits.%d (%s/%s) reinit.%d\n",rp->requestid,statebits,rp->src,rp->dest,reinit);
bitcoin_pubkey33(swap->ctx,pubkey33,privkey);
pubkey25519 = curve25519(privkey,curve25519_basepoint9());
swap->persistent_pubkey = pubkey25519;
swap->persistent_privkey = privkey;
memcpy(swap->persistent_pubkey33,pubkey33,33);
m = n = 0;
if ( bitcoin_swapinit(privkey,pubkey33,pubkey25519,swap,optionduration,statebits,reinit) != 0 )
{
for (iter=0; iter<16; iter++)
{
basilisk_psockinit(swap,statebits == 0);
sleep(3);
if ( swap->connected > 0 )
break;
sleep(10);
/*basilisk_sendstate(swap,data,sizeof(data));
basilisk_swapget(swap,0x80000000,data,sizeof(data),basilisk_verify_statebits);
if ( swap->connected > 0 )
break;
printf("loopback didntwork with %d %d\n",swap->pushsock,swap->subsock);*/
}
if ( reinit != 0 )
{
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)basilisk_swaploop,(void *)swap) != 0 )
{
}
//myinfo->swaps[myinfo->numswaps++] = swap;
}
else
{
starttime = (uint32_t)time(NULL);
printf("statebits.%x m.%d n.%d\n",statebits,m,n);
while ( statebits == 0 && m <= n/2 && time(NULL) < starttime+7*BASILISK_MSGDURATION )
{
uint32_t msgid; uint8_t data[1024]; int32_t datalen;
m = n = 0;
sleep(DEX_SLEEP);
printf("waiting for offer to be accepted\n");
channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16);
datalen = basilisk_rwDEXquote(1,data,rp);
msgid = (uint32_t)time(NULL);
printf("other req.%d >>>>>>>>>>> send response (%llx -> %llx) r.%u quoteid.%u\n",i,(long long)rp->desthash.txid,(long long)rp->srchash.txid,rp->requestid,rp->quoteid);
LP_channelsend(rp->desthash,rp->srchash,channel,msgid,data,datalen);
if ( (retarray= basilisk_channelget(rp->srchash,rp->desthash,channel,0x4000000,30)) != 0 )
{
if ( is_cJSON_Array(retarray) != 0 && (n= cJSON_GetArraySize(retarray)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(retarray,i);
if ( (msgobj= jarray(&n,item,"messages")) != 0 && n > 0 )
{
item = jitem(msgobj,0);
if ( jobj(item,"data") != 0 && jobj(item,"key") != 0 )
m++;
else printf("(%s)\n",jprint(item,0));
} //else printf("msgobj.%p m.%d n.%d\n",msgobj,m,n);
}
}
} else printf("no retarray\n");
}
printf("LAUNCH check.%d m.%d\n",statebits,m);
if ( statebits != 0 || m > 0 )//n/2 )
{
//for (i=0; i<sizeof(swap->I.req); i++)
// fprintf(stderr,"%02x",((uint8_t *)&swap->I.req)[i]);
if ( (swap->fp= basilisk_swap_save(swap,privkey,rp,statebits,optionduration,reinit)) != 0 )
{
}
if ( reinit == 0 )
{
static FILE *swapsfp;
if ( swapsfp == 0 )
{
char fname[512];
sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname);
if ( (swapsfp= fopen(fname,"rb+")) == 0 )
swapsfp = fopen(fname,"wb+");
else fseek(swapsfp,0,SEEK_END);
printf("LIST fp.%p\n",swapsfp);
}
if ( swapsfp != 0 )
{
fwrite(&rp->requestid,1,sizeof(rp->requestid),swapsfp);
fwrite(&rp->quoteid,1,sizeof(rp->quoteid),swapsfp);
fflush(swapsfp);
}
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)basilisk_swaploop,(void *)swap) != 0 )
{
}
//myinfo->swaps[myinfo->numswaps++] = swap;
}
else
{
if ( statebits != 0 )
{
if ( (coin= LP_coinfind(rp->src)) != 0 )
{
}
}
printf("%u/%u offer wasnt accepted statebits.%d m.%d n.%d pending %.8f\n",rp->requestid,rp->quoteid,statebits,m,n,pending);
}
}
}
}
//portable_mutex_unlock(&myinfo->DEX_swapmutex);
return(swap);
}
#endif

1436
iguana/exchanges/LP_transaction.c

File diff suppressed because it is too large

366
iguana/exchanges/LP_utxos.c

@ -0,0 +1,366 @@
/******************************************************************************
* 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_utxos.c
// marketmaker
//
struct LP_utxoinfo *LP_utxofind(bits256 txid,int32_t vout)
{
struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)];
memcpy(key,txid.bytes,sizeof(txid));
memcpy(&key[sizeof(txid)],&vout,sizeof(vout));
portable_mutex_lock(&LP_utxomutex);
HASH_FIND(hh,LP_utxoinfos,key,sizeof(key),utxo);
portable_mutex_unlock(&LP_utxomutex);
return(utxo);
}
cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo)
{
jaddstr(item,"coin",utxo->coin);
jaddstr(item,"address",utxo->coinaddr);
jaddbits256(item,"txid",utxo->txid);
jaddnum(item,"vout",utxo->vout);
jaddnum(item,"value",dstr(utxo->satoshis));
jaddbits256(item,"txid2",utxo->txid2);
jaddnum(item,"vout2",utxo->vout2);
jaddnum(item,"value2",dstr(utxo->satoshis2));
if ( utxo->swappending != 0 )
jaddnum(item,"pending",utxo->swappending);
if ( bits256_nonz(utxo->otherpubkey) != 0 )
jaddbits256(item,"desthash",utxo->otherpubkey);
if ( utxo->pair >= 0 )
jaddnum(item,"socket",utxo->pair);
if ( utxo->swap != 0 )
jaddstr(item,"swap","in progress");
return(item);
}
cJSON *LP_utxojson(struct LP_utxoinfo *utxo)
{
cJSON *item = cJSON_CreateObject();
item = LP_inventoryjson(item,utxo);
jaddstr(item,"ipaddr",utxo->ipaddr);
jaddnum(item,"port",utxo->port);
jaddnum(item,"profit",utxo->profitmargin);
jaddstr(item,"base",utxo->coin);
jaddstr(item,"script",utxo->spendscript);
return(item);
}
char *LP_utxos(struct LP_peerinfo *mypeer,char *coin,int32_t lastn)
{
int32_t i,firsti; struct LP_utxoinfo *utxo,*tmp; cJSON *utxosjson = cJSON_CreateArray();
i = 0;
if ( lastn >= mypeer->numutxos )
firsti = -1;
else firsti = (mypeer->numutxos - lastn);
HASH_ITER(hh,LP_utxoinfos,utxo,tmp)
{
if ( i++ < firsti )
continue;
if ( coin == 0 || coin[0] == 0 || strcmp(coin,utxo->coin) == 0 )
{
jaddi(utxosjson,LP_utxojson(utxo));
}
}
return(jprint(utxosjson,1));
}
struct LP_utxoinfo *LP_addutxo(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock,char *coin,bits256 txid,int32_t vout,int64_t satoshis,bits256 deposittxid,int32_t depositvout,int64_t depositsatoshis,char *spendscript,char *coinaddr,char *ipaddr,uint16_t port,double profitmargin)
{
struct LP_utxoinfo *utxo = 0;
if ( coin == 0 || coin[0] == 0 || spendscript == 0 || spendscript[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(deposittxid) == 0 || vout < 0 || depositvout < 0 || satoshis <= 0 || depositsatoshis <= 0 )
{
printf("malformed addutxo %d %d %d %d %d %d %d %d %d\n", coin == 0,spendscript == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(deposittxid) == 0,vout < 0,depositvout < 0,satoshis <= 0,depositsatoshis <= 0);
return(0);
}
if ( IAMCLIENT == 0 && strcmp(ipaddr,"127.0.0.1") == 0 )
{
printf("LP node got localhost utxo\n");
return(0);
}
if ( (utxo= LP_utxofind(txid,vout)) != 0 )
{
if ( bits256_cmp(txid,utxo->txid) != 0 || bits256_cmp(deposittxid,utxo->txid2) != 0 || vout != utxo->vout || satoshis != utxo->satoshis || depositvout != utxo->vout2 || depositsatoshis != utxo->satoshis2 || strcmp(coin,utxo->coin) != 0 || strcmp(spendscript,utxo->spendscript) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || strcmp(ipaddr,utxo->ipaddr) != 0 || port != utxo->port )
{
utxo->errors++;
char str[65],str2[65]; printf("error on subsequent utxo add.(%s v %s) %d %d %d %d %d %d %d %d %d %d %d\n",bits256_str(str,txid),bits256_str(str2,utxo->txid),bits256_cmp(txid,utxo->txid) != 0,bits256_cmp(deposittxid,utxo->txid2) != 0,vout != utxo->vout,satoshis != utxo->satoshis,depositvout != utxo->vout2,depositsatoshis != utxo->satoshis2,strcmp(coin,utxo->coin) != 0,strcmp(spendscript,utxo->spendscript) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,strcmp(ipaddr,utxo->ipaddr) != 0,port != utxo->port);
}
else if ( profitmargin != 0. )
utxo->profitmargin = profitmargin;
}
else
{
utxo = calloc(1,sizeof(*utxo));
utxo->pair = -1;
utxo->profitmargin = profitmargin;
strcpy(utxo->ipaddr,ipaddr);
utxo->port = port;
safecopy(utxo->coin,coin,sizeof(utxo->coin));
safecopy(utxo->coinaddr,coinaddr,sizeof(utxo->coinaddr));
safecopy(utxo->spendscript,spendscript,sizeof(utxo->spendscript));
utxo->txid = txid;
utxo->vout = vout;
utxo->satoshis = satoshis;
utxo->txid2 = deposittxid;
utxo->vout2 = depositvout;
utxo->satoshis2 = depositsatoshis;
memcpy(utxo->key,txid.bytes,sizeof(txid));
memcpy(&utxo->key[sizeof(txid)],&vout,sizeof(vout));
portable_mutex_lock(&LP_utxomutex);
HASH_ADD_KEYPTR(hh,LP_utxoinfos,utxo->key,sizeof(utxo->key),utxo);
if ( mypeer != 0 )
mypeer->numutxos++;
portable_mutex_unlock(&LP_utxomutex);
if ( mypubsock >= 0 )
LP_send(mypubsock,jprint(LP_utxojson(utxo),1),1);
char str[65],str2[65]; printf("amclient.%d %s:%u %s LP_addutxo.(%.8f %.8f) numutxos.%d %s %s\n",IAMCLIENT,ipaddr,port,utxo->coin,dstr(satoshis),dstr(depositsatoshis),mypeer!=0?mypeer->numutxos:0,bits256_str(str,utxo->txid),bits256_str(str2,txid));
}
return(utxo);
}
int32_t LP_utxosparse(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now)
{
struct LP_peerinfo *peer,*destpeer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; bits256 txid; struct LP_utxoinfo *utxo;
if ( amclient != 0 )
{
printf("LP_utxosparse not for clientside\n");
return(-1);
}
if ( (array= cJSON_Parse(retstr)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
if ( (argipaddr= jstr(item,"ipaddr")) != 0 && (argport= juint(item,"port")) != 0 )
{
if ( (pushport= juint(item,"push")) == 0 )
pushport = argport + 1;
if ( (subport= juint(item,"sub")) == 0 )
subport = argport + 2;
argipbits = (uint32_t)calc_ipbits(argipaddr);
if ( (peer= LP_peerfind(argipbits,argport)) == 0 )
peer = LP_addpeer(amclient,mypeer,mypubsock,argipaddr,argport,pushport,subport,jdouble(item,"profit"),jint(item,"numpeers"),jint(item,"numutxos"));
if ( jobj(item,"txid") != 0 )
{
txid = jbits256(item,"txid");
utxo = LP_addutxo(amclient,mypeer,mypubsock,jstr(item,"coin"),txid,jint(item,"vout"),SATOSHIDEN*jdouble(item,"value"),jbits256(item,"txid2"),jint(item,"vout2"),SATOSHIDEN * jdouble(item,"value2"),jstr(item,"script"),jstr(item,"address"),argipaddr,argport,jdouble(item,"profit"));
if ( utxo != 0 )
utxo->lasttime = now;
}
}
}
if ( (destpeer= LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport)) != 0 )
{
destpeer->numutxos = n;
if ( destpeer->numutxos < n )
{
//destpeer->numutxos = n;
//printf("got.(%s) from %s numutxos.%d\n",retstr,destpeer->ipaddr,destpeer->numutxos);
}
}
}
free_json(array);
}
return(n);
}
void LP_utxosquery(int32_t amclient,struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *coin,int32_t lastn,char *myipaddr,uint16_t myport,double myprofit)
{
char *retstr; struct LP_peerinfo *peer; int32_t i,firsti; uint32_t now;
if ( amclient != 0 )
{
printf("LP_utxosquery not for clientside\n");
return;
}
peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport);
if ( mypeer == 0 ) //(peer != 0 && peer->errors > 0) ||
return;
if ( coin == 0 )
coin = "";
if ( (retstr= issue_LP_getutxos(destipaddr,destport,coin,lastn,myipaddr,myport,myprofit,mypeer->numpeers,mypeer->numutxos)) != 0 )
{
now = (uint32_t)time(NULL);
LP_utxosparse(amclient,mypeer,mypubsock,destipaddr,destport,retstr,now);
free(retstr);
i = 0;
if ( lastn >= mypeer->numutxos )
firsti = -1;
else firsti = (mypeer->numutxos - lastn);
/*HASH_ITER(hh,LP_utxoinfos,utxo,tmp)
{
if ( i++ < firsti )
continue;
if ( utxo->lasttime != now && strcmp(utxo->ipaddr,"127.0.0.1") != 0 )
{
char str[65]; printf("{%s:%u %s} ",utxo->ipaddr,utxo->port,bits256_str(str,utxo->txid));
flag++;
if ( (retstr= issue_LP_notifyutxo(destipaddr,destport,utxo)) != 0 )
free(retstr);
}
}
if ( flag != 0 )
printf(" <- missing utxos\n");*/
} else if ( peer != 0 )
peer->errors++;
}
char *LP_inventory(char *symbol)
{
struct LP_utxoinfo *utxo,*tmp; char *myipaddr; cJSON *array = cJSON_CreateArray();
if ( LP_mypeer != 0 )
myipaddr = LP_mypeer->ipaddr;
else myipaddr = "127.0.0.1";
HASH_ITER(hh,LP_utxoinfos,utxo,tmp)
{
if ( strcmp(symbol,utxo->coin) == 0 && (IAMCLIENT != 0 || strcmp(utxo->ipaddr,myipaddr) == 0) )
jaddi(array,LP_inventoryjson(cJSON_CreateObject(),utxo));
}
return(jprint(array,1));
}
int32_t LP_maxvalue(uint64_t *values,int32_t n)
{
int32_t i,maxi = -1; uint64_t maxval = 0;
for (i=0; i<n; i++)
if ( values[i] > maxval )
{
maxi = i;
maxval = values[i];
}
return(maxi);
}
int32_t LP_nearestvalue(uint64_t *values,int32_t n,uint64_t targetval)
{
int32_t i,mini = -1; int64_t dist; uint64_t mindist = (1 << 31);
for (i=0; i<n; i++)
{
dist = (values[i] - targetval);
if ( dist < 0 && -dist < values[i]/10 )
dist = -dist;
if ( dist >= 0 && dist < mindist )
{
mini = i;
mindist = dist;
}
}
return(mini);
}
uint64_t LP_privkey_init(struct LP_peerinfo *mypeer,int32_t mypubsock,char *symbol,char *passphrase,char *wifstr,int32_t amclient)
{
static uint32_t counter;
char coinaddr[64],*script; struct LP_utxoinfo *utxo; cJSON *array,*item,*retjson; bits256 userpass,userpub,txid,deposittxid; int32_t used,i,n,vout,depositvout; uint64_t *values,satoshis,depositval,targetval,value,total = 0; bits256 privkey,pubkey; uint8_t pubkey33[33],tmptype,rmd160[20]; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 )
{
printf("cant add privkey for %s, coin not active\n",symbol);
return(0);
}
if ( passphrase != 0 )
conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
else privkey = iguana_wif2privkey(wifstr);
iguana_priv2pub(pubkey33,coinaddr,privkey,coin->pubtype);
if ( strcmp("BTC",symbol) == 0 )
strcpy(BTCADDR,coinaddr);
else if ( strcmp("KMD",symbol) == 0 )
strcpy(KMDADDR,coinaddr);
if ( counter == 0 )
{
char tmpstr[128];
counter++;
bitcoin_priv2wif(USERPASS_WIFSTR,privkey,188);
bitcoin_priv2wif(tmpstr,privkey,coin->wiftype);
conv_NXTpassword(userpass.bytes,pubkey.bytes,(uint8_t *)tmpstr,(int32_t)strlen(tmpstr));
userpub = curve25519(userpass,curve25519_basepoint9());
printf("userpass.(%s)\n",bits256_str(USERPASS,userpub));
printf("%s (%s) %d wif.(%s) (%s)\n",symbol,coinaddr,coin->pubtype,tmpstr,passphrase);
if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coinaddr,-1)) != 0 )
printf("importprivkey -> (%s)\n",jprint(retjson,1));
}
bitcoin_addr2rmd160(&tmptype,rmd160,coinaddr);
LP_privkeyadd(privkey,rmd160);
if ( (array= LP_listunspent(symbol,coinaddr)) != 0 )
{
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
values = calloc(n,sizeof(*values));
for (i=0; i<n; i++)
{
item = jitem(array,i);
satoshis = SATOSHIDEN * jdouble(item,"amount");
values[i] = satoshis;
//printf("%.8f ",dstr(satoshis));
}
//printf("array.%d\n",n);
used = 0;
while ( used < n )
{
if ( (i= LP_maxvalue(values,n)) >= 0 )
{
item = jitem(array,i);
deposittxid = jbits256(item,"txid");
depositvout = juint(item,"vout");
script = jstr(item,"scriptPubKey");
depositval = values[i];
values[i] = 0, used++;
if ( amclient != 0 )
targetval = (depositval / 776) + 50000;
else targetval = (depositval / 9) * 8;
//printf("i.%d %.8f target %.8f\n",i,dstr(depositval),dstr(targetval));
if ( (i= LP_nearestvalue(values,n,targetval)) >= 0 )
{
item = jitem(array,i);
txid = jbits256(item,"txid");
vout = juint(item,"vout");
if ( jstr(item,"scriptPubKey") != 0 && strcmp(script,jstr(item,"scriptPubKey")) == 0 )
{
value = values[i];
values[i] = 0, used++;
if ( amclient == 0 )
{
if ( (utxo= LP_addutxo(amclient,mypeer,mypubsock,symbol,txid,vout,value,deposittxid,depositvout,depositval,script,coinaddr,LP_peerinfos[0].ipaddr,LP_peerinfos[0].port,LP_peerinfos[0].profitmargin)) != 0 )
utxo->mypub = curve25519(privkey,curve25519_basepoint9());
}
else
{
if ( (utxo= LP_addutxo(amclient,mypeer,mypubsock,symbol,deposittxid,depositvout,depositval,txid,vout,value,script,coinaddr,"127.0.0.1",0,0)) != 0 )
utxo->mypub = curve25519(privkey,curve25519_basepoint9());
}
total += value;
}
}
} else break;
}
free(values);
}
free_json(array);
}
return(total);
}
void LP_privkey_updates(struct LP_peerinfo *mypeer,int32_t pubsock,char *passphrase,int32_t amclient)
{
int32_t i;
for (i=0; i<sizeof(activecoins)/sizeof(*activecoins); i++)
LP_privkey_init(mypeer,pubsock,activecoins[i],passphrase,"",amclient);
}

2
iguana/exchanges/autotrade

@ -0,0 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"autotrade\",\"txid\":\"$1\",\"vout\":$2,\"coin\":\"REVS\",\"maxprice\":$3}"

2
iguana/exchanges/candidates

@ -0,0 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"candidates\",\"txid\":\"$1\",\"vout\":$2,\"coin\":\"REVS\"}"

2
iguana/exchanges/client

@ -0,0 +1,2 @@
source randval
pkill -15 marketmaker; git pull; cd ..; ./m_mm; ./marketmaker "{\"client\":1,\"passphrase\":\"$randval\"}" &

2
iguana/exchanges/getpeers

@ -0,0 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"getpeers\"}"

10
iguana/exchanges/getpeersIP

@ -0,0 +1,10 @@
curl --url "http://5.9.253.195:7779" --data "{\"method\":\"getpeers\"}"
curl --url "http://5.9.253.196:7779" --data "{\"method\":\"getpeers\"}"
curl --url "http://5.9.253.197:7779" --data "{\"method\":\"getpeers\"}"
curl --url "http://5.9.253.198:7779" --data "{\"method\":\"getpeers\"}"
curl --url "http://5.9.253.199:7779" --data "{\"method\":\"getpeers\"}"
curl --url "http://5.9.253.200:7779" --data "{\"method\":\"getpeers\"}"
curl --url "http://5.9.253.201:7779" --data "{\"method\":\"getpeers\"}"
curl --url "http://5.9.253.202:7779" --data "{\"method\":\"getpeers\"}"
curl --url "http://5.9.253.203:7779" --data "{\"method\":\"getpeers\"}"
curl --url "http://5.9.253.204:7779" --data "{\"method\":\"getpeers\"}"

2
iguana/exchanges/getprice

@ -0,0 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"REVS\",\"rel\":\"KMD\"}"

2
iguana/exchanges/inv

@ -0,0 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"inventory\",\"coin\":\"KMD\"}"

125
iguana/exchanges/mm.c

@ -26,7 +26,7 @@
#define MAX(a,b) ((a) > (b) ? (a) : (b))
char *stats_JSON(cJSON *argjson,char *remoteaddr,uint16_t port);
#include "stats.c"
#include "LP_prices.c"
void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]);
#if defined(__APPLE__) || defined(WIN32) || defined(USE_STATIC_NANOMSG)
#include "../../crypto777/nanosrc/nn.h"
@ -35,6 +35,7 @@ char *stats_JSON(cJSON *argjson,char *remoteaddr,uint16_t port);
#include "../../crypto777/nanosrc/pipeline.h"
#include "../../crypto777/nanosrc/reqrep.h"
#include "../../crypto777/nanosrc/tcp.h"
#include "../../crypto777/nanosrc/pair.h"
#else
#include "/usr/local/include/nanomsg/nn.h"
#include "/usr/local/include/nanomsg/bus.h"
@ -42,6 +43,7 @@ char *stats_JSON(cJSON *argjson,char *remoteaddr,uint16_t port);
#include "/usr/local/include/nanomsg/pipeline.h"
#include "/usr/local/include/nanomsg/reqrep.h"
#include "/usr/local/include/nanomsg/tcp.h"
#include "/usr/local/include/nanomsg/pair.h"
#endif
char DEX_baseaddr[64],DEX_reladdr[64];
@ -168,13 +170,13 @@ char *iguana_walletpassphrase(char *passphrase,int32_t timeout)
return(bitcoind_RPC(0,"",url,0,"walletpassphrase",postdata));
}
char *iguana_listunspent(char *coin,char *coinaddr)
/*char *iguana_listunspent(char *coin,char *coinaddr)
{
char url[512],postdata[1024];
sprintf(url,"%s/coin=%s&agent=bitcoinrpc&method=listunspent?",IGUANA_URL,coin);
sprintf(postdata,"[\"%s\"]",coinaddr);
return(bitcoind_RPC(0,"",url,0,"listunspent",postdata));
}
}*/
/*char *issue_LP_intro(char *destip,uint16_t destport,char *ipaddr,uint16_t port,double profitmargin,int32_t numpeers)
{
@ -678,10 +680,43 @@ int32_t marketmaker_spread(char *exchange,char *base,char *rel,double bid,double
return(n);
}
void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double start_BASE,double start_REL,double profitmargin,double maxexposure,double ratioincr,char *exchange,char *name,char *base,char *rel)
double marketmaker_updateprice(char *name,char *base,char *rel,double theoretical,double *incrp)
{
static uint32_t counter;
cJSON *fiatjson; char *retstr; double bid,ask,start_DEXbase,start_DEXrel,USD_average=0.,DEX_base = 0.,DEX_rel = 0.,balance_base=0.,balance_rel=0.,mmbid,mmask,usdprice=0.,CMC_average=0.,aveprice,incr,pendingbids,pendingasks,buyvol,sellvol,bidincr,askincr,filledprice,avebid=0.,aveask=0.,val,changes[3],highbid=0.,lowask=0.,theoretical = 0.; uint32_t lasttime = 0;
cJSON *fiatjson; double USD_average=0.,usdprice=0.,CMC_average=0.,avebid=0.,aveask=0.,val,changes[3],highbid=0.,lowask=0.;
if ( (val= get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,name,base,rel,&USD_average)) != 0. )
{
if ( theoretical == 0. )
{
theoretical = val;
if ( *incrp > 2 )
{
*incrp = (int32_t)*incrp;
*incrp += 0.777;
}
} else theoretical = (theoretical + val) * 0.5;
if ( (counter++ % 12) == 0 )
{
if ( USD_average > SMALLVAL && CMC_average > SMALLVAL && theoretical > SMALLVAL )
{
usdprice = USD_average * (theoretical / CMC_average);
printf("USD %.4f <- (%.6f * (%.8f / %.8f))\n",usdprice,USD_average,theoretical,CMC_average);
PAXPRICES[0] = usdprice;
if ( (fiatjson= yahoo_allcurrencies()) != 0 )
{
marketmaker_fiatupdate(fiatjson);
free_json(fiatjson);
}
}
}
LP_priceupdate(base,rel,theoretical,avebid,aveask,highbid,lowask,PAXPRICES);
}
return(theoretical);
}
void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double start_BASE,double start_REL,double profitmargin,double maxexposure,double ratioincr,char *exchange,char *name,char *base,char *rel)
{
char *retstr; double bid,ask,start_DEXbase,start_DEXrel,DEX_base = 0.,DEX_rel = 0.,balance_base=0.,balance_rel=0.,mmbid,mmask,aveprice,incr,pendingbids,pendingasks,buyvol,sellvol,bidincr,askincr,filledprice,avebid=0.,aveask=0.,highbid=0.,lowask=0.,theoretical = 0.; uint32_t lasttime = 0;
incr = maxexposure * ratioincr;
buyvol = sellvol = 0.;
start_DEXbase = dex_balance(base,baseaddr);
@ -690,34 +725,10 @@ void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double
{
if ( time(NULL) > lasttime+60 )
{
if ( (val= get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,name,base,rel,&USD_average)) != 0. )
if ( (theoretical= marketmaker_updateprice(name,base,rel,theoretical,&incr)) != 0. )
{
if ( theoretical == 0. )
{
theoretical = val;
incr /= theoretical;
if ( lasttime == 0 )
maxexposure /= theoretical;
if ( incr > 2 )
{
incr = (int32_t)incr;
incr += 0.777;
}
} else theoretical = (theoretical + val) * 0.5;
if ( (counter++ % 12) == 0 )
{
if ( USD_average > SMALLVAL && CMC_average > SMALLVAL && theoretical > SMALLVAL )
{
usdprice = USD_average * (theoretical / CMC_average);
printf("USD %.4f <- (%.6f * (%.8f / %.8f))\n",usdprice,USD_average,theoretical,CMC_average);
PAXPRICES[0] = usdprice;
if ( (fiatjson= yahoo_allcurrencies()) != 0 )
{
marketmaker_fiatupdate(fiatjson);
free_json(fiatjson);
}
}
}
LP_priceupdate(base,rel,theoretical,avebid,aveask,highbid,lowask,PAXPRICES);
}
if ( strcmp(exchange,"bittrex") == 0 )
{
@ -796,30 +807,60 @@ void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double
void LP_main(void *ptr)
{
double profitmargin = *(double *)ptr;
LPinit(7779,7780,7781,profitmargin);
char *passphrase; double profitmargin; cJSON *argjson = ptr;
if ( (passphrase= jstr(argjson,"passphrase")) != 0 )
{
profitmargin = jdouble(argjson,"profitmargin");
LPinit(7779,7780,7781,profitmargin,passphrase,jint(argjson,"client"),jstr(argjson,"userhome"));
}
}
int main(int argc, const char * argv[])
{
char *base,*rel,*name,*exchange,*apikey,*apisecret,*blocktrail,*retstr,*baseaddr,*reladdr,*passphrase;
double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid;
cJSON *retjson,*loginjson; int32_t i;
double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid,incr,theoretical = 0.;
cJSON *retjson,*loginjson,*matchjson; int32_t i;
if ( argc > 1 && (retjson= cJSON_Parse(argv[1])) != 0 )
{
minask = jdouble(retjson,"minask");
maxbid = jdouble(retjson,"maxbid");
profitmargin = jdouble(retjson,"profitmargin");
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_main,(void *)&profitmargin) != 0 )
if ( (passphrase= jstr(retjson,"passphrase")) == 0 )
jaddstr(retjson,"passphrase","test");
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_main,(void *)retjson) != 0 )
{
printf("error launching LP_main %f\n",profitmargin);
printf("error launching LP_main (%s)\n",jprint(retjson,0));
exit(-1);
} getchar();
} else printf("(%s) launched.(%s)\n",argv[1],passphrase);
if ( (0) && (retstr= basilisk_swaplist()) != 0 )
{
printf("%s\ngetchar to continue\n",retstr);
getchar();
free(retstr);
}
incr = 100.;
while ( (0) && IAMCLIENT != 0 )
{
theoretical = marketmaker_updateprice("komodo","REVS","KMD",theoretical,&incr);
sleep(3);
LP_privkey_updates(0,-1,passphrase,1);
if ( jint(retjson,"client") != 0 )
{
struct LP_utxoinfo *utxo,*utmp;
HASH_ITER(hh,LP_utxoinfos,utxo,utmp)
{
if ( strcmp(utxo->coin,"REVS") == 0 && (matchjson= LP_autotrade(utxo,"KMD",0.)) != 0 )
printf("bestprice (%s)\n",jprint(matchjson,1));
}
}
sleep(1000);
}
while ( 1 )
sleep(1);
profitmargin = jdouble(retjson,"profitmargin");
minask = jdouble(retjson,"minask");
maxbid = jdouble(retjson,"maxbid");
maxexposure = jdouble(retjson,"maxexposure");
incrratio = jdouble(retjson,"lotratio");
start_base = jdouble(retjson,"start_base");
start_rel = jdouble(retjson,"start_rel");
passphrase = jstr(retjson,"passphrase");
apikey = jstr(retjson,"apikey");
apisecret = jstr(retjson,"apisecret");
base = jstr(retjson,"base");

2
iguana/exchanges/myprice

@ -0,0 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"myprice\",\"base\":\"REVS\",\"rel\":\"KMD\"}"

2
iguana/exchanges/orderbook

@ -0,0 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"orderbook\",\"base\":\"REVS\",\"rel\":\"KMD\"}"

1
iguana/exchanges/randval

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

2
iguana/exchanges/run

@ -0,0 +1,2 @@
source randval
pkill -15 marketmaker; git pull; cd ..; ./m_mm; ./marketmaker "{\"profitmargin\":0.01,\"passphrase\":\"$randval\"}" &

2
iguana/exchanges/setprice

@ -0,0 +1,2 @@
source userpass
curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":1.234}"

1
iguana/exchanges/userpass

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

2
iguana/m_mm

@ -1,2 +1,2 @@
cd secp256k1; ./m_unix; cd ..
gcc -o marketmaker -I../crypto777 exchanges/mm.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm
gcc -g -o marketmaker -I../crypto777 exchanges/mm.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm

6
iguana/main.c

@ -2056,10 +2056,12 @@ FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase)
void komodo_ICO_batch(cJSON *array,int32_t batchid)
{
int32_t i,n,iter; cJSON *item; uint64_t kmdamount,revsamount; char *coinaddr,cmd[512]; double totalKMD,totalREVS; struct supernet_info *myinfo = SuperNET_MYINFO(0);
if ( myinfo->rpcport == 0 )
myinfo->rpcport = 7778;
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
totalKMD = totalREVS = 0;
for (iter=3; iter<4; iter++)
for (iter=0; iter<1; iter++)
for (i=0; i<n; i++)
{
item = jitem(array,i);
@ -2159,7 +2161,7 @@ void iguana_main(void *arg)
else printf("ENDIAN ERROR\n");
mycalloc(0,0,0);
#ifdef __APPLE__
char *batchstr,*batchstr2; cJSON *batchjson; long batchsize; char fname[512],fname2[512]; int32_t batchid = 17;
char *batchstr,*batchstr2; cJSON *batchjson; long batchsize; char fname[512],fname2[512]; int32_t batchid = 18;
sprintf(fname,"REVS.raw"), sprintf(fname2,"REVS.rawtxids");
if ( (0) && (batchstr= OS_filestr(&batchsize,fname)) != 0 && (batchstr2= OS_filestr(&batchsize,fname2)) != 0 )
{

434
iguana/tests/KMD.batch17

@ -0,0 +1,434 @@
sleep 9999999
# RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 KMD 108998.28313606
./komodo-cli sendtoaddress RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 108998.28313606
sleep 3
echo "108998.28313606 <- expected amount RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8"
# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 196.34763557
./komodo-cli sendtoaddress RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ 196.34763557
sleep 3
echo "196.34763557 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ"
# RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU KMD 14524.72874062
./komodo-cli sendtoaddress RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU 14524.72874062
sleep 3
echo "14524.72874062 <- expected amount RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU"
# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 16017.97255691
./komodo-cli sendtoaddress REVcoi6A4GRfuchCXTwBTszbakhoh9inLs 16017.97255691
sleep 3
echo "16017.97255691 <- expected amount REVcoi6A4GRfuchCXTwBTszbakhoh9inLs"
# RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22 KMD 145928.92215821
./komodo-cli sendtoaddress RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22 145928.92215821
sleep 3
echo "145928.92215821 <- expected amount RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22"
# RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6 KMD 114940.35721379
./komodo-cli sendtoaddress RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6 114940.35721379
sleep 3
echo "114940.35721379 <- expected amount RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6"
# RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU KMD 28699.34324752
./komodo-cli sendtoaddress RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU 28699.34324752
sleep 3
echo "28699.34324752 <- expected amount RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU"
# RV25zizocv445ht9My45WaxpGuAC42cxLa KMD 101090.11347764
./komodo-cli sendtoaddress RV25zizocv445ht9My45WaxpGuAC42cxLa 101090.11347764
sleep 3
echo "101090.11347764 <- expected amount RV25zizocv445ht9My45WaxpGuAC42cxLa"
# RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S KMD 1704.23483890
./komodo-cli sendtoaddress RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S 1704.23483890
sleep 3
echo "1704.23483890 <- expected amount RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S"
# RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD KMD 96831.52493750
./komodo-cli sendtoaddress RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD 96831.52493750
sleep 3
echo "96831.52493750 <- expected amount RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD"
# RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve KMD 11.06362104
./komodo-cli sendtoaddress RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve 11.06362104
sleep 3
echo "11.06362104 <- expected amount RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve"
# RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv KMD 32009.28059927
./komodo-cli sendtoaddress RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv 32009.28059927
sleep 3
echo "32009.28059927 <- expected amount RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv"
# RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh KMD 305.48459176
./komodo-cli sendtoaddress RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh 305.48459176
sleep 3
echo "305.48459176 <- expected amount RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh"
# RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 KMD 162977.74808228
./komodo-cli sendtoaddress RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 162977.74808228
sleep 3
echo "162977.74808228 <- expected amount RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3"
# RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn KMD 9683.15249375
./komodo-cli sendtoaddress RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn 9683.15249375
sleep 3
echo "9683.15249375 <- expected amount RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn"
# RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3 KMD 1593.10203942
./komodo-cli sendtoaddress RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3 1593.10203942
sleep 3
echo "1593.10203942 <- expected amount RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3"
# RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu KMD 4066.11066256
./komodo-cli sendtoaddress RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu 4066.11066256
sleep 3
echo "4066.11066256 <- expected amount RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu"
# RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc KMD 4014.80536992
./komodo-cli sendtoaddress RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc 4014.80536992
sleep 3
echo "4014.80536992 <- expected amount RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc"
# RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd KMD 2904.94574812
./komodo-cli sendtoaddress RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd 2904.94574812
sleep 3
echo "2904.94574812 <- expected amount RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd"
# REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc KMD 38080.08587787
./komodo-cli sendtoaddress REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc 38080.08587787
sleep 3
echo "38080.08587787 <- expected amount REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc"
# RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7 KMD 875.08198390
./komodo-cli sendtoaddress RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7 875.08198390
sleep 3
echo "875.08198390 <- expected amount RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7"
# RULousSwdVGhaP6vusva8u9AQWTs8ugjfp KMD 9683.15249375
./komodo-cli sendtoaddress RULousSwdVGhaP6vusva8u9AQWTs8ugjfp 9683.15249375
sleep 3
echo "9683.15249375 <- expected amount RULousSwdVGhaP6vusva8u9AQWTs8ugjfp"
# RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK KMD 2954.24166783
./komodo-cli sendtoaddress RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK 2954.24166783
sleep 3
echo "2954.24166783 <- expected amount RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK"
# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193, REVS 708.36533209
# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193
./komodo-cli sendtoaddress RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU 35716.07599193
sleep 3
echo "35716.07599193 <- expected amount RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU"
# R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH KMD 1681.36207445
./komodo-cli sendtoaddress R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH 1681.36207445
sleep 3
echo "1681.36207445 <- expected amount R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH"
# RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ KMD 7119.36644540
./komodo-cli sendtoaddress RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ 7119.36644540
sleep 3
echo "7119.36644540 <- expected amount RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ"
# RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV KMD 29049.45748125
./komodo-cli sendtoaddress RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV 29049.45748125
sleep 3
echo "29049.45748125 <- expected amount RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV"
# RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG KMD 216.38341633
./komodo-cli sendtoaddress RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG 216.38341633
sleep 3
echo "216.38341633 <- expected amount RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG"
# RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 KMD 3239.94057692
./komodo-cli sendtoaddress RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 3239.94057692
sleep 3
echo "3239.94057692 <- expected amount RWc6GouJggQDsBCeW1DYck629FPrDJCTP9"
# R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY KMD 723.21529345
./komodo-cli sendtoaddress R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY 723.21529345
sleep 3
echo "723.21529345 <- expected amount R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY"
# RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd KMD 20415.81928042
./komodo-cli sendtoaddress RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd 20415.81928042
sleep 3
echo "20415.81928042 <- expected amount RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd"
# RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 KMD 4319.48050817
./komodo-cli sendtoaddress RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 4319.48050817
sleep 3
echo "4319.48050817 <- expected amount RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63"
# RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1 KMD 155.08169171
./komodo-cli sendtoaddress RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1 155.08169171
sleep 3
echo "155.08169171 <- expected amount RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1"
# RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC KMD 5177.29144163
./komodo-cli sendtoaddress RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC 5177.29144163
sleep 3
echo "5177.29144163 <- expected amount RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC"
# RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS KMD 2034.11335616
./komodo-cli sendtoaddress RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS 2034.11335616
sleep 3
echo "2034.11335616 <- expected amount RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS"
# RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk KMD 8034.62340879
./komodo-cli sendtoaddress RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk 8034.62340879
sleep 3
echo "8034.62340879 <- expected amount RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk"
# RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW KMD 987.78018920
./komodo-cli sendtoaddress RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW 987.78018920
sleep 3
echo "987.78018920 <- expected amount RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW"
# RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM KMD 98.35737149
./komodo-cli sendtoaddress RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM 98.35737149
sleep 3
echo "98.35737149 <- expected amount RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM"
# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 8442.69675032
./komodo-cli sendtoaddress RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz 8442.69675032
sleep 3
echo "8442.69675032 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz"
# RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU KMD 35.32468867
./komodo-cli sendtoaddress RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU 35.32468867
sleep 3
echo "35.32468867 <- expected amount RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU"
# RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww KMD 2418.19228276
./komodo-cli sendtoaddress RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww 2418.19228276
sleep 3
echo "2418.19228276 <- expected amount RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww"
# RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb KMD 34.72735411
./komodo-cli sendtoaddress RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb 34.72735411
sleep 3
echo "34.72735411 <- expected amount RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb"
# RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ KMD 49.50870613
./komodo-cli sendtoaddress RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ 49.50870613
sleep 3
echo "49.50870613 <- expected amount RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ"
# RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ KMD 9683.15249375
./komodo-cli sendtoaddress RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ 9683.15249375
sleep 3
echo "9683.15249375 <- expected amount RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ"
# RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u KMD 56.66050704
./komodo-cli sendtoaddress RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u 56.66050704
sleep 3
echo "56.66050704 <- expected amount RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u"
# RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74 KMD 722.28571081
./komodo-cli sendtoaddress RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74 722.28571081
sleep 3
echo "722.28571081 <- expected amount RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74"
# RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68 KMD 226.29998024
./komodo-cli sendtoaddress RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68 226.29998024
sleep 3
echo "226.29998024 <- expected amount RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68"
# RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P KMD 1160.04166875
./komodo-cli sendtoaddress RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P 1160.04166875
sleep 3
echo "1160.04166875 <- expected amount RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P"
# REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3 KMD 5365.78339027
./komodo-cli sendtoaddress REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3 5365.78339027
sleep 3
echo "5365.78339027 <- expected amount REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3"
# RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab KMD 9683.15249375
./komodo-cli sendtoaddress RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab 9683.15249375
sleep 3
echo "9683.15249375 <- expected amount RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab"
# RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv KMD 2475.13554655
./komodo-cli sendtoaddress RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv 2475.13554655
sleep 3
echo "2475.13554655 <- expected amount RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv"
# RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp KMD 6778.20674562
./komodo-cli sendtoaddress RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp 6778.20674562
sleep 3
echo "6778.20674562 <- expected amount RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp"
# RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh KMD 3898.73512521
./komodo-cli sendtoaddress RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh 3898.73512521
sleep 3
echo "3898.73512521 <- expected amount RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh"
# R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ KMD 18775.43011383
./komodo-cli sendtoaddress R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ 18775.43011383
sleep 3
echo "18775.43011383 <- expected amount R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ"
# RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL KMD 49.27663407
./komodo-cli sendtoaddress RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL 49.27663407
sleep 3
echo "49.27663407 <- expected amount RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL"
# RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3 KMD 1177.96870224
./komodo-cli sendtoaddress RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3 1177.96870224
sleep 3
echo "1177.96870224 <- expected amount RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3"
# RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW KMD 3692.18604586
./komodo-cli sendtoaddress RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW 3692.18604586
sleep 3
echo "3692.18604586 <- expected amount RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW"
# RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S KMD 422.98413624
./komodo-cli sendtoaddress RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S 422.98413624
sleep 3
echo "422.98413624 <- expected amount RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S"
# RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk KMD 428171.85680159
./komodo-cli sendtoaddress RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk 428171.85680159
sleep 3
echo "428171.85680159 <- expected amount RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk"
# RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB KMD 27228.79164783
./komodo-cli sendtoaddress RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB 27228.79164783
sleep 3
echo "27228.79164783 <- expected amount RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB"
# RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU KMD 6109.56883640
./komodo-cli sendtoaddress RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU 6109.56883640
sleep 3
echo "6109.56883640 <- expected amount RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU"
# RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN KMD 316058.09739600
./komodo-cli sendtoaddress RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN 316058.09739600
sleep 3
echo "316058.09739600 <- expected amount RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN"
# RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH KMD 51229.88531218
./komodo-cli sendtoaddress RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH 51229.88531218
sleep 3
echo "51229.88531218 <- expected amount RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH"
# RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s KMD 110083.51536582
./komodo-cli sendtoaddress RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s 110083.51536582
sleep 3
echo "110083.51536582 <- expected amount RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s"
# RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX KMD 9295.82639400
./komodo-cli sendtoaddress RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX 9295.82639400
sleep 3
echo "9295.82639400 <- expected amount RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX"
# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 2611.69343481
./komodo-cli sendtoaddress RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK 2611.69343481
sleep 3
echo "2611.69343481 <- expected amount RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK"
# RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs KMD 4841.57624687
./komodo-cli sendtoaddress RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs 4841.57624687
sleep 3
echo "4841.57624687 <- expected amount RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs"
# RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW KMD 813.38480947
./komodo-cli sendtoaddress RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW 813.38480947
sleep 3
echo "813.38480947 <- expected amount RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW"
# RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH KMD 20170.43419449
./komodo-cli sendtoaddress RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH 20170.43419449
sleep 3
echo "20170.43419449 <- expected amount RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH"
# RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD KMD 681.69393556
./komodo-cli sendtoaddress RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD 681.69393556
sleep 3
echo "681.69393556 <- expected amount RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD"
# RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim KMD 1510.02573700
./komodo-cli sendtoaddress RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim 1510.02573700
sleep 3
echo "1510.02573700 <- expected amount RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim"
# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289
./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289
sleep 3
echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv"
# RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy KMD 842.93959567
./komodo-cli sendtoaddress RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy 842.93959567
sleep 3
echo "842.93959567 <- expected amount RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy"
# RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue KMD 1580.29048698
./komodo-cli sendtoaddress RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue 1580.29048698
sleep 3
echo "1580.29048698 <- expected amount RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue"
# RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN KMD 2904.94574812
./komodo-cli sendtoaddress RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN 2904.94574812
sleep 3
echo "2904.94574812 <- expected amount RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN"
# RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX KMD 594.35547049
./komodo-cli sendtoaddress RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX 594.35547049
sleep 3
echo "594.35547049 <- expected amount RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX"
# RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE KMD 929.58263940
./komodo-cli sendtoaddress RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE 929.58263940
sleep 3
echo "929.58263940 <- expected amount RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE"
# RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP KMD 95491.01211941
./komodo-cli sendtoaddress RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP 95491.01211941
sleep 3
echo "95491.01211941 <- expected amount RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP"
# RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY KMD 2631.59182505
./komodo-cli sendtoaddress RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY 2631.59182505
sleep 3
echo "2631.59182505 <- expected amount RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY"
# RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn KMD 5701.16057828
./komodo-cli sendtoaddress RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn 5701.16057828
sleep 3
echo "5701.16057828 <- expected amount RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn"
# RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a KMD 49.10934879
./komodo-cli sendtoaddress RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a 49.10934879
sleep 3
echo "49.10934879 <- expected amount RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a"
# RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR KMD 911.94644914
./komodo-cli sendtoaddress RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR 911.94644914
sleep 3
echo "911.94644914 <- expected amount RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR"
# RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH KMD 2169.54630422
./komodo-cli sendtoaddress RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH 2169.54630422
sleep 3
echo "2169.54630422 <- expected amount RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH"
# RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi KMD 12470.86256471
./komodo-cli sendtoaddress RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi 12470.86256471
sleep 3
echo "12470.86256471 <- expected amount RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi"
# R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj KMD 3365.89754092
./komodo-cli sendtoaddress R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj 3365.89754092
sleep 3
echo "3365.89754092 <- expected amount R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj"
# RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv KMD 511.26690948
./komodo-cli sendtoaddress RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv 511.26690948
sleep 3
echo "511.26690948 <- expected amount RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv"
# total KMD 2201860.11979328 REVS 0.00000000

346
iguana/tests/KMD.batch17.listunspent

@ -0,0 +1,346 @@
sleep 999999
# RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 KMD 108998.28313606
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8\",\"symbol\":\"KMD\"}"
echo "108998.28313606 <- expected amount RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8"
# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 196.34763557
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}"
echo "196.34763557 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ"
# RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU KMD 14524.72874062
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU\",\"symbol\":\"KMD\"}"
echo "14524.72874062 <- expected amount RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU"
# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 16017.97255691
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REVcoi6A4GRfuchCXTwBTszbakhoh9inLs\",\"symbol\":\"KMD\"}"
echo "16017.97255691 <- expected amount REVcoi6A4GRfuchCXTwBTszbakhoh9inLs"
# RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22 KMD 145928.92215821
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22\",\"symbol\":\"KMD\"}"
echo "145928.92215821 <- expected amount RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22"
# RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6 KMD 114940.35721379
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6\",\"symbol\":\"KMD\"}"
echo "114940.35721379 <- expected amount RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6"
# RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU KMD 28699.34324752
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU\",\"symbol\":\"KMD\"}"
echo "28699.34324752 <- expected amount RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU"
# RV25zizocv445ht9My45WaxpGuAC42cxLa KMD 101090.11347764
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RV25zizocv445ht9My45WaxpGuAC42cxLa\",\"symbol\":\"KMD\"}"
echo "101090.11347764 <- expected amount RV25zizocv445ht9My45WaxpGuAC42cxLa"
# RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S KMD 1704.23483890
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S\",\"symbol\":\"KMD\"}"
echo "1704.23483890 <- expected amount RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S"
# RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD KMD 96831.52493750
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD\",\"symbol\":\"KMD\"}"
echo "96831.52493750 <- expected amount RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD"
# RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve KMD 11.06362104
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve\",\"symbol\":\"KMD\"}"
echo "11.06362104 <- expected amount RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve"
# RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv KMD 32009.28059927
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv\",\"symbol\":\"KMD\"}"
echo "32009.28059927 <- expected amount RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv"
# RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh KMD 305.48459176
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh\",\"symbol\":\"KMD\"}"
echo "305.48459176 <- expected amount RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh"
# RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 KMD 162977.74808228
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3\",\"symbol\":\"KMD\"}"
echo "162977.74808228 <- expected amount RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3"
# RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn KMD 9683.15249375
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn\",\"symbol\":\"KMD\"}"
echo "9683.15249375 <- expected amount RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn"
# RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3 KMD 1593.10203942
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3\",\"symbol\":\"KMD\"}"
echo "1593.10203942 <- expected amount RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3"
# RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu KMD 4066.11066256
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu\",\"symbol\":\"KMD\"}"
echo "4066.11066256 <- expected amount RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu"
# RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc KMD 4014.80536992
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc\",\"symbol\":\"KMD\"}"
echo "4014.80536992 <- expected amount RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc"
# RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd KMD 2904.94574812
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd\",\"symbol\":\"KMD\"}"
echo "2904.94574812 <- expected amount RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd"
# REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc KMD 38080.08587787
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc\",\"symbol\":\"KMD\"}"
echo "38080.08587787 <- expected amount REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc"
# RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7 KMD 875.08198390
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7\",\"symbol\":\"KMD\"}"
echo "875.08198390 <- expected amount RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7"
# RULousSwdVGhaP6vusva8u9AQWTs8ugjfp KMD 9683.15249375
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RULousSwdVGhaP6vusva8u9AQWTs8ugjfp\",\"symbol\":\"KMD\"}"
echo "9683.15249375 <- expected amount RULousSwdVGhaP6vusva8u9AQWTs8ugjfp"
# RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK KMD 2954.24166783
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK\",\"symbol\":\"KMD\"}"
echo "2954.24166783 <- expected amount RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK"
# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193, REVS 708.36533209
# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU\",\"symbol\":\"KMD\"}"
echo "35716.07599193 <- expected amount RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU"
# R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH KMD 1681.36207445
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH\",\"symbol\":\"KMD\"}"
echo "1681.36207445 <- expected amount R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH"
# RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ KMD 7119.36644540
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ\",\"symbol\":\"KMD\"}"
echo "7119.36644540 <- expected amount RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ"
# RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV KMD 29049.45748125
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV\",\"symbol\":\"KMD\"}"
echo "29049.45748125 <- expected amount RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV"
# RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG KMD 216.38341633
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG\",\"symbol\":\"KMD\"}"
echo "216.38341633 <- expected amount RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG"
# RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 KMD 3239.94057692
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWc6GouJggQDsBCeW1DYck629FPrDJCTP9\",\"symbol\":\"KMD\"}"
echo "3239.94057692 <- expected amount RWc6GouJggQDsBCeW1DYck629FPrDJCTP9"
# R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY KMD 723.21529345
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY\",\"symbol\":\"KMD\"}"
echo "723.21529345 <- expected amount R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY"
# RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd KMD 20415.81928042
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd\",\"symbol\":\"KMD\"}"
echo "20415.81928042 <- expected amount RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd"
# RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 KMD 4319.48050817
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63\",\"symbol\":\"KMD\"}"
echo "4319.48050817 <- expected amount RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63"
# RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1 KMD 155.08169171
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1\",\"symbol\":\"KMD\"}"
echo "155.08169171 <- expected amount RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1"
# RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC KMD 5177.29144163
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC\",\"symbol\":\"KMD\"}"
echo "5177.29144163 <- expected amount RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC"
# RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS KMD 2034.11335616
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS\",\"symbol\":\"KMD\"}"
echo "2034.11335616 <- expected amount RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS"
# RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk KMD 8034.62340879
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk\",\"symbol\":\"KMD\"}"
echo "8034.62340879 <- expected amount RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk"
# RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW KMD 987.78018920
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW\",\"symbol\":\"KMD\"}"
echo "987.78018920 <- expected amount RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW"
# RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM KMD 98.35737149
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM\",\"symbol\":\"KMD\"}"
echo "98.35737149 <- expected amount RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM"
# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 8442.69675032
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}"
echo "8442.69675032 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz"
# RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU KMD 35.32468867
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU\",\"symbol\":\"KMD\"}"
echo "35.32468867 <- expected amount RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU"
# RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww KMD 2418.19228276
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww\",\"symbol\":\"KMD\"}"
echo "2418.19228276 <- expected amount RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww"
# RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb KMD 34.72735411
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb\",\"symbol\":\"KMD\"}"
echo "34.72735411 <- expected amount RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb"
# RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ KMD 49.50870613
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ\",\"symbol\":\"KMD\"}"
echo "49.50870613 <- expected amount RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ"
# RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ KMD 9683.15249375
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ\",\"symbol\":\"KMD\"}"
echo "9683.15249375 <- expected amount RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ"
# RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u KMD 56.66050704
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u\",\"symbol\":\"KMD\"}"
echo "56.66050704 <- expected amount RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u"
# RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74 KMD 722.28571081
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74\",\"symbol\":\"KMD\"}"
echo "722.28571081 <- expected amount RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74"
# RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68 KMD 226.29998024
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68\",\"symbol\":\"KMD\"}"
echo "226.29998024 <- expected amount RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68"
# RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P KMD 1160.04166875
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P\",\"symbol\":\"KMD\"}"
echo "1160.04166875 <- expected amount RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P"
# REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3 KMD 5365.78339027
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3\",\"symbol\":\"KMD\"}"
echo "5365.78339027 <- expected amount REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3"
# RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab KMD 9683.15249375
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab\",\"symbol\":\"KMD\"}"
echo "9683.15249375 <- expected amount RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab"
# RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv KMD 2475.13554655
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv\",\"symbol\":\"KMD\"}"
echo "2475.13554655 <- expected amount RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv"
# RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp KMD 6778.20674562
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp\",\"symbol\":\"KMD\"}"
echo "6778.20674562 <- expected amount RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp"
# RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh KMD 3898.73512521
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh\",\"symbol\":\"KMD\"}"
echo "3898.73512521 <- expected amount RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh"
# R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ KMD 18775.43011383
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ\",\"symbol\":\"KMD\"}"
echo "18775.43011383 <- expected amount R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ"
# RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL KMD 49.27663407
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL\",\"symbol\":\"KMD\"}"
echo "49.27663407 <- expected amount RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL"
# RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3 KMD 1177.96870224
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3\",\"symbol\":\"KMD\"}"
echo "1177.96870224 <- expected amount RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3"
# RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW KMD 3692.18604586
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW\",\"symbol\":\"KMD\"}"
echo "3692.18604586 <- expected amount RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW"
# RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S KMD 422.98413624
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S\",\"symbol\":\"KMD\"}"
echo "422.98413624 <- expected amount RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S"
# RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk KMD 428171.85680159
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk\",\"symbol\":\"KMD\"}"
echo "428171.85680159 <- expected amount RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk"
# RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB KMD 27228.79164783
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB\",\"symbol\":\"KMD\"}"
echo "27228.79164783 <- expected amount RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB"
# RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU KMD 6109.56883640
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU\",\"symbol\":\"KMD\"}"
echo "6109.56883640 <- expected amount RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU"
# RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN KMD 316058.09739600
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN\",\"symbol\":\"KMD\"}"
echo "316058.09739600 <- expected amount RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN"
# RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH KMD 51229.88531218
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH\",\"symbol\":\"KMD\"}"
echo "51229.88531218 <- expected amount RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH"
# RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s KMD 110083.51536582
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s\",\"symbol\":\"KMD\"}"
echo "110083.51536582 <- expected amount RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s"
# RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX KMD 9295.82639400
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX\",\"symbol\":\"KMD\"}"
echo "9295.82639400 <- expected amount RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX"
# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 2611.69343481
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK\",\"symbol\":\"KMD\"}"
echo "2611.69343481 <- expected amount RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK"
# RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs KMD 4841.57624687
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs\",\"symbol\":\"KMD\"}"
echo "4841.57624687 <- expected amount RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs"
# RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW KMD 813.38480947
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW\",\"symbol\":\"KMD\"}"
echo "813.38480947 <- expected amount RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW"
# RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH KMD 20170.43419449
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH\",\"symbol\":\"KMD\"}"
echo "20170.43419449 <- expected amount RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH"
# RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD KMD 681.69393556
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD\",\"symbol\":\"KMD\"}"
echo "681.69393556 <- expected amount RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD"
# RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim KMD 1510.02573700
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim\",\"symbol\":\"KMD\"}"
echo "1510.02573700 <- expected amount RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim"
# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}"
echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv"
# RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy KMD 842.93959567
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy\",\"symbol\":\"KMD\"}"
echo "842.93959567 <- expected amount RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy"
# RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue KMD 1580.29048698
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue\",\"symbol\":\"KMD\"}"
echo "1580.29048698 <- expected amount RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue"
# RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN KMD 2904.94574812
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN\",\"symbol\":\"KMD\"}"
echo "2904.94574812 <- expected amount RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN"
# RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX KMD 594.35547049
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX\",\"symbol\":\"KMD\"}"
echo "594.35547049 <- expected amount RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX"
# RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE KMD 929.58263940
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE\",\"symbol\":\"KMD\"}"
echo "929.58263940 <- expected amount RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE"
# RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP KMD 95491.01211941
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP\",\"symbol\":\"KMD\"}"
echo "95491.01211941 <- expected amount RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP"
# RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY KMD 2631.59182505
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY\",\"symbol\":\"KMD\"}"
echo "2631.59182505 <- expected amount RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY"
# RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn KMD 5701.16057828
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn\",\"symbol\":\"KMD\"}"
echo "5701.16057828 <- expected amount RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn"
# RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a KMD 49.10934879
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a\",\"symbol\":\"KMD\"}"
echo "49.10934879 <- expected amount RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a"
# RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR KMD 911.94644914
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR\",\"symbol\":\"KMD\"}"
echo "911.94644914 <- expected amount RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR"
# RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH KMD 2169.54630422
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH\",\"symbol\":\"KMD\"}"
echo "2169.54630422 <- expected amount RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH"
# RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi KMD 12470.86256471
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi\",\"symbol\":\"KMD\"}"
echo "12470.86256471 <- expected amount RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi"
# R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj KMD 3365.89754092
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj\",\"symbol\":\"KMD\"}"
echo "3365.89754092 <- expected amount R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj"
# RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv KMD 511.26690948
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv\",\"symbol\":\"KMD\"}"
echo "511.26690948 <- expected amount RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv"

5
iguana/tests/REVS.batch17

@ -0,0 +1,5 @@
# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193, REVS 708.36533209
sleep 100000
fiat/revs sendtoaddress RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU 708.36533209
2781e7d1a888c22083832e46241aca1cb512605cb4c5492c9a36cc7f2d7829f3
# total KMD 0.00000000 REVS 708.36533209

2
iguana/tests/dexgetbalance

@ -1,2 +1,2 @@
#!/bin/bash
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"RHrAStvASzi5pJB6xqgmsVGD5AxxpAFzZ6\",\"symbol\":\"KMD\"}"
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"RYZx1e7kVNTuQ6RTrvTkYeZAz5uJobC3pg\",\"symbol\":\"KMD\"}"

2
iguana/tests/dexlistunspent

@ -1,2 +1,2 @@
#!/bin/bash
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVy1qgs2HRmXKWWawoqFSo3WGBkjC19cmJ\",\"symbol\":\"KMD\"}"
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYZx1e7kVNTuQ6RTrvTkYeZAz5uJobC3pg\",\"symbol\":\"KMD\"}"

Loading…
Cancel
Save