Browse Source

Merge pull request #551 from jl777/beta

Beta
dPoW
jl777 7 years ago
committed by GitHub
parent
commit
cab46c25a0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      .gitignore
  2. 1
      crypto777/OS_portable.h
  3. 6
      crypto777/OS_time.c
  4. 32
      crypto777/bitcoind_RPC.c
  5. 2
      crypto777/iguana_OS.c
  6. 2
      crypto777/iguana_utils.c
  7. 15
      crypto777/ramcoder.c
  8. 2
      iguana/coins/axo_7776
  9. 2
      iguana/coins/basilisk/axo
  10. 1
      iguana/coins/basilisk/btch
  11. 2
      iguana/coins/basilisk/etomic
  12. 2
      iguana/coins/basilisk/mshark
  13. 2
      iguana/coins/btch_7776
  14. 2
      iguana/coins/etomic_7776
  15. 0
      iguana/coins/genREVS
  16. 2
      iguana/coins/genshark
  17. 2
      iguana/coins/mshark_7776
  18. 2
      iguana/coins/shark_7776
  19. 52
      iguana/dpow/dpow_network.c
  20. 344
      iguana/exchanges/LP_NXT.c
  21. 60
      iguana/exchanges/LP_RTmetrics.c
  22. 338
      iguana/exchanges/LP_bitcoin.c
  23. 27
      iguana/exchanges/LP_cache.c
  24. 67
      iguana/exchanges/LP_coins.c
  25. 266
      iguana/exchanges/LP_commands.c
  26. 149
      iguana/exchanges/LP_include.h
  27. 650
      iguana/exchanges/LP_instantdex.c
  28. 708
      iguana/exchanges/LP_mmjson.c
  29. 525
      iguana/exchanges/LP_nativeDEX.c
  30. 120
      iguana/exchanges/LP_network.c
  31. 1179
      iguana/exchanges/LP_ordermatch.c
  32. 6
      iguana/exchanges/LP_peers.c
  33. 425
      iguana/exchanges/LP_portfolio.c
  34. 366
      iguana/exchanges/LP_prices.c
  35. 575
      iguana/exchanges/LP_privkey.c
  36. 245
      iguana/exchanges/LP_remember.c
  37. 628
      iguana/exchanges/LP_rpc.c
  38. 17
      iguana/exchanges/LP_scan.c
  39. 13
      iguana/exchanges/LP_secp.c
  40. 154
      iguana/exchanges/LP_signatures.c
  41. 142
      iguana/exchanges/LP_socket.c
  42. 2117
      iguana/exchanges/LP_statemachine.c
  43. 672
      iguana/exchanges/LP_stats.c
  44. 159
      iguana/exchanges/LP_swap.c
  45. 32
      iguana/exchanges/LP_tradebots.c
  46. 309
      iguana/exchanges/LP_transaction.c
  47. 371
      iguana/exchanges/LP_utxo.c
  48. 905
      iguana/exchanges/LP_utxos.c
  49. 2
      iguana/exchanges/auto_chipsbtc
  50. 2
      iguana/exchanges/auto_chipskmd
  51. 3
      iguana/exchanges/autofill
  52. 3
      iguana/exchanges/autotrade
  53. 3
      iguana/exchanges/balances
  54. 4
      iguana/exchanges/bots
  55. 3
      iguana/exchanges/claim
  56. 5
      iguana/exchanges/coins
  57. 5
      iguana/exchanges/coins.json
  58. 3
      iguana/exchanges/deposit1
  59. 3
      iguana/exchanges/deposit10
  60. 4
      iguana/exchanges/dex
  61. 3
      iguana/exchanges/dynamictrust
  62. 17
      iguana/exchanges/enable
  63. 4
      iguana/exchanges/fundvalue
  64. 15
      iguana/exchanges/get_supernet
  65. 4
      iguana/exchanges/hodl
  66. 2
      iguana/exchanges/install
  67. 4
      iguana/exchanges/jumblr
  68. 3
      iguana/exchanges/kickstart
  69. 943
      iguana/exchanges/mm 17740.c
  70. 935
      iguana/exchanges/mm.c
  71. 4
      iguana/exchanges/mshark
  72. 3
      iguana/exchanges/pendingswaps
  73. 49
      iguana/exchanges/prices/autoprice
  74. 3
      iguana/exchanges/prices/bet
  75. 3
      iguana/exchanges/prices/bots
  76. 3
      iguana/exchanges/prices/crypto
  77. 3
      iguana/exchanges/prices/dex
  78. 18
      iguana/exchanges/prices/gets
  79. 3
      iguana/exchanges/prices/jumblr
  80. 3
      iguana/exchanges/prices/mgw
  81. 3
      iguana/exchanges/prices/pangea
  82. 3
      iguana/exchanges/prices/revs
  83. 2
      iguana/exchanges/sell
  84. 160
      iguana/exchanges/stats.c
  85. 20
      iguana/exchanges/supernet
  86. 3
      iguana/exchanges/ticker
  87. 2
      iguana/exchanges/trackbtc
  88. 3
      iguana/exchanges/tradesarray
  89. 13
      iguana/iguana777.h
  90. 11
      iguana/iguana_init.c
  91. 73
      iguana/iguana_notary.c
  92. 48
      iguana/m_notary
  93. 50
      iguana/m_notary_run
  94. 69
      iguana/m_splitfund
  95. 28
      iguana/main.c
  96. 252
      iguana/mini-gmp.c

6
.gitignore

@ -244,3 +244,9 @@ iguana/DB/KMD/0/.tmpmarker
iguana/myipaddr
iguana/DB/UNSPENTS/.tmpmarker
*.RQ4z6KrMZeEnCSCsChv1ZoR9ExQitHjbpg
iguana/DB/instantdex_RQ4z6KrMZeEnCSCsChv1ZoR9ExQitHjbpg_append.json
iguana/DB/instantdex_RQ4z6KrMZeEnCSCsChv1ZoR9ExQitHjbpg.json

1
crypto777/OS_portable.h

@ -326,6 +326,7 @@ int32_t btc_convaddr(char *hexaddr,char *addr58);
uint64_t RS_decode(char *rs);
int32_t RS_encode(char *rsaddr,uint64_t id);
char *cmc_ticker(char *base);
void calc_sha1(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len);
void calc_md2(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len);

6
crypto777/OS_time.c

@ -21,7 +21,7 @@
#define TAI_PACK 8
#define TAI_UTC_DIFF ((uint64_t)4611686018427387914ULL)
//#define UTC_ADJUST -36
//#define UTC_ADJUST -37
#define tai_approx(t) ((double) ((t)->x))
#define tai_less(t,u) ((t)->x < (u)->x)
@ -300,7 +300,7 @@ void tai_add(struct tai *t,struct tai *u,struct tai *v) { t->x = u->x + v->x; }
void tai_sub(struct tai *t,struct tai *u,struct tai *v) { t->x = u->x - v->x; }
// {"leapseconds":["+1972-06-30", "+1972-12-31", "+1973-12-31", "+1974-12-31", "+1975-12-31", "+1976-12-31", "+1977-12-31", "+1982-06-30", "+1983-06-30", "+1985-06-30", "+1987-12-31", "+1989-12-31", "+1990-12-31", "+1992-06-30", "+1993-06-30", "+1994-06-30", "+1995-12-31", "+1997-06-30", "+1998-12-31", "+2005-12-31", "+2008-12-31", "+2012-06-30", "+2015-06-30"]}
char *leapseconds[] = { "+1972-06-30", "+1972-12-31", "+1973-12-31", "+1974-12-31", "+1975-12-31", "+1976-12-31", "+1977-12-31", "+1982-06-30", "+1983-06-30", "+1985-06-30", "+1987-12-31", "+1989-12-31", "+1990-12-31", "+1992-06-30", "+1993-06-30", "+1994-06-30", "+1995-12-31", "+1997-06-30", "+1998-12-31", "+2005-12-31", "+2008-12-31", "+2012-06-30", "+2015-06-30" };
char *leapseconds[] = { "+1972-06-30", "+1972-12-31", "+1973-12-31", "+1974-12-31", "+1975-12-31", "+1976-12-31", "+1977-12-31", "+1982-06-30", "+1983-06-30", "+1985-06-30", "+1987-12-31", "+1989-12-31", "+1990-12-31", "+1992-06-30", "+1993-06-30", "+1994-06-30", "+1995-12-31", "+1997-06-30", "+1998-12-31", "+2005-12-31", "+2008-12-31", "+2012-06-30", "+2015-06-30", "+2016-12-31" };
struct tai leaptais[sizeof(leapseconds)/sizeof(*leapseconds)];
char *dayname[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" } ;
@ -355,7 +355,7 @@ struct tai tai_now()
{
First_TAI = t, First_utc = (uint32_t)now;
#ifndef DISABLE_LEAPS
UTC_ADJUST = -36;
UTC_ADJUST = -37;
#endif
//printf("TAINOW.%llu %03.3f UTC.%u vs %u [diff %d]\n",(long long)t.x,t.millis,First_utc,tai2utc(t),UTC_ADJUST);
}

32
crypto777/bitcoind_RPC.c

@ -30,6 +30,7 @@ void *LP_alloc(uint64_t len);
void LP_free(void *ptr);
char *LP_clonestr(char *str);*/
int32_t bitcoind_RPC_inittime;
#if LIQUIDITY_PROVIDER
#include <curl/curl.h>
@ -73,7 +74,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
char *retstr = 0;
cJSON *json,*result,*error;
#ifdef FROM_MARKETMAKER
usleep(3000);
//usleep(3000);
#endif
//printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr);
if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 )
@ -96,6 +97,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
if ( (error->type&0xff) == cJSON_NULL && (result->type&0xff) != cJSON_NULL )
{
retstr = jprint(result,0);
//printf("%s %s rpc retstr.%p\n",command,params,retstr);
len = strlen(retstr);
if ( retstr[0] == '"' && retstr[len-1] == '"' )
{
@ -112,7 +114,10 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
rpcstr = 0;
}
if ( rpcstr != 0 )
{
//printf("free rpcstr.%p\n",rpcstr);
free(rpcstr);
}
} else retstr = rpcstr;
free_json(json);
//fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: postprocess returns.(%s)\n",retstr);
@ -186,7 +191,16 @@ try_again:
curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash
curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS, 1L); // no progress callback
if ( timeout > 0 )
curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT, timeout); // causes problems with iguana timeouts
{
if ( bitcoind_RPC_inittime != 0 )
{
#ifndef _WIN32
curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT,1);
#else
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, timeout*100);
#endif
} else curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT,timeout); // causes problems with iguana timeouts
}
if ( strncmp(url,"https",5) == 0 )
{
curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0);
@ -231,30 +245,30 @@ try_again:
free(databuf);
databuf = 0;
}
retstr = chunk.memory; // retstr = s.ptr;
if ( res != CURLE_OK )
{
numretries++;
if ( specialcase != 0 || timeout != 0 )
{
//printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res);
free(chunk.memory); //free(s.ptr);
//printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,retstr,res);
free(retstr);
return(0);
}
else if ( numretries >= 4 )
{
printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries);
//printf("Maximum number of retries exceeded!\n");
free(chunk.memory);//free(s.ptr);
free(retstr);
return(0);
}
free(chunk.memory);//free(s.ptr);
free(retstr);
sleep((1<<numretries));
goto try_again;
}
else
{
retstr = chunk.memory; // retstr = s.ptr;
if ( command != 0 && specialcase == 0 )
{
count++;
@ -279,9 +293,6 @@ try_again:
return(retstr);
}
}
//printf("bitcoind_RPC: impossible case\n");
//free(s.ptr);
//return(0);
}
/************************************************************************
@ -337,6 +348,7 @@ static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data)
{
//printf("curl needs %d more\n",(int32_t)realsize);
mem->memory = (ptr != 0) ? realloc(mem->memory,needed) : malloc(needed);
//printf("mem->memory.%p len.%d\n",mem->memory,(int32_t)needed);
mem->allocsize = needed;
}
//mem->memory = (ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1);

2
crypto777/iguana_OS.c

@ -877,7 +877,7 @@ void *OS_loadfile(char *fname,char **bufp,long *lenp,long *allocsizep)
{
fclose(fp);
*lenp = 0;
printf("OS_loadfile null size.(%s)\n",fname);
//printf("OS_loadfile null size.(%s)\n",fname);
return(0);
}
if ( filesize > buflen-1 )

2
crypto777/iguana_utils.c

@ -992,6 +992,7 @@ int32_t RS_encode(char *rsaddr,uint64_t id)
rsaddr[j++] = '-';
}
rsaddr[j] = 0;
//printf("%llu -> NXT RS (%s)\n",(long long)id,rsaddr);
return(0);
}
@ -1122,6 +1123,7 @@ void calc_NXTaddr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len)
{
uint8_t mysecret[32]; uint64_t nxt64bits;
nxt64bits = conv_NXTpassword(mysecret,buf,msg,len);
//printf("call RSencode with %llu\n",(long long)nxt64bits);
RS_encode(hexstr,nxt64bits);
}

15
crypto777/ramcoder.c

@ -430,19 +430,22 @@ int32_t ramcoder_decoder(struct ramcoder *coder,int32_t updateprobs,uint8_t *buf
return(n);
}
int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 seed)
int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 origseed)
{
int32_t numbits; HUFF H,*hp = &H;
uint64_t histo[256]; bits256 seed; char str[65]; int32_t numbits; HUFF H,*hp = &H;
_init_HUFF(hp,maxlen,bits);
if ( ramcoder_encoder(0,1,data,datalen,hp,0,&seed) < 0 )
memset(histo,0,sizeof(histo));
seed = origseed;
if ( ramcoder_encoder(0,1,data,datalen,hp,histo,&seed) < 0 )
return(-1);
printf("seed.%s\n",bits256_str(str,seed));
numbits = hp->bitoffset;
if ( (0) )
if ( (1) )
{
void *malloc(size_t); void free(void *);
int32_t i,checklen; uint8_t *checkbuf;
checkbuf = malloc(datalen*2);
memset(seed.bytes,0,sizeof(seed));
seed = origseed;
hrewind(hp);
checklen = ramcoder_decoder(0,1,checkbuf,datalen*2,hp,&seed);
if ( checklen != datalen || memcmp(checkbuf,data,datalen) != 0 )
@ -457,7 +460,7 @@ int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t dat
printf("%02x ",checkbuf[i]);
printf("checklen.%d\n",checklen);
getchar();
} // else printf("CODEC passed datalen.%d -> numbits %d %d\n",datalen,numbits,numbits/8);
} else printf("CODEC passed datalen.%d -> numbits %d %d origseed.%s\n",datalen,numbits,numbits/8,bits256_str(str,origseed));
free(checkbuf);
}
return(numbits);

2
iguana/coins/axo_7776

@ -0,0 +1,2 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"AXO.conf\",\"path\":\"${HOME#"/"}/.komodo/AXO\",\"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\":\"AXO\",\"name\":\"AXO\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"ba009d17\",\"p2p\":12926,\"rpc\":12927,\"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/basilisk/axo

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

1
iguana/coins/basilisk/btch

@ -0,0 +1 @@
curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"BTCH.conf\",\"path\":\"${HOME#"/"}/.komodo/BTCH\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"BTCH\",\"name\":\"BTCH\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"b0ed1968\",\"p2p\":8799,\"rpc\":8800,\"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/basilisk/etomic

@ -0,0 +1,2 @@
curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"ETOMIC.conf\",\"path\":\"${HOME#"/"}/.komodo/ETOMIC\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"ETOMIC\",\"name\":\"ETOMIC\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"072a90e8\",\"p2p\":10270,\"rpc\":10271,\"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/basilisk/mshark

@ -0,0 +1,2 @@
curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":14103,\"rpc\":14104,\"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/btch_7776

@ -0,0 +1,2 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"BTCH.conf\",\"path\":\"${HOME#"/"}/.komodo/BTCH\",\"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\":\"BTCH\",\"name\":\"BTCH\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"b0ed1968\",\"p2p\":8799,\"rpc\":8800,\"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/etomic_7776

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

0
iguana/coins/genREVS

2
iguana/coins/genshark

@ -1,2 +1,2 @@
curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":10113,\"rpc\":10114,\"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:7778" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":14103,\"rpc\":14104,\"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/mshark_7776

@ -0,0 +1,2 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MSHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/MSHARK\",\"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\":\"MSHARK\",\"name\":\"MSHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":8845,\"rpc\":8846,\"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/shark_7776

@ -1,2 +1,2 @@
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"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\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":10113,\"rpc\":10114,\"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\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"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\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":14103,\"rpc\":14104,\"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\"}"

52
iguana/dpow/dpow_network.c

@ -21,56 +21,6 @@ struct signed_nnpacket
uint8_t packet[];
} PACKED;
/*
NN_CONNECT to (tcp://167.114.118.5:7775)
NN_CONNECT to (tcp://10.0.0.4:7775)
NN_CONNECT to (tcp://85.143.211.6:7775)
NN_CONNECT to (tcp://158.69.25.7:7775)
NN_CONNECT to (tcp://123.249.79.12:7775)
NN_CONNECT to (tcp://141.105.66.18:7775)
NN_CONNECT to (tcp://198.27.75.27:7775)
NN_CONNECT to (tcp://198.204.226.34:7775)
NN_CONNECT to (tcp://144.76.94.38:7775)
NN_CONNECT to (tcp://142.54.174.42:7775)
NN_CONNECT to (tcp://88.198.70.43:7775)
NN_CONNECT to (tcp://182.162.169.44:7775)
NN_CONNECT to (tcp://104.168.128.50:7775)
NN_CONNECT to (tcp://167.114.64.64:7775)
NN_CONNECT to (tcp://185.169.229.64:7775)
NN_CONNECT to (tcp://46.4.68.72:7775)
NN_CONNECT to (tcp://173.208.203.74:7775)
NN_CONNECT to (tcp://192.99.232.81:7775)
NN_CONNECT to (tcp://149.56.28.84:7775)
NN_CONNECT to (tcp://148.251.190.89:7775)
NN_CONNECT to (tcp://149.56.240.91:7775)
NN_CONNECT to (tcp://88.99.56.99:7775)
NN_CONNECT to (tcp://217.106.238.109:7775)
NN_CONNECT to (tcp://142.54.164.114:7775)
NN_CONNECT to (tcp://163.172.101.118:7775)
NN_CONNECT to (tcp://189.1.174.119:7775)
NN_CONNECT to (tcp://1.234.19.123:7775)
NN_CONNECT to (tcp://221.121.144.138:7775)
NN_CONNECT to (tcp://46.166.168.138:7775)
NN_CONNECT to (tcp://221.121.144.140:7775)
NN_CONNECT to (tcp://163.172.100.144:7775)
NN_CONNECT to (tcp://185.106.122.147:7775)
NN_CONNECT to (tcp://103.18.58.150:7775)
NN_CONNECT to (tcp://23.88.234.153:7775)
NN_CONNECT to (tcp://164.132.202.176:7775)
NN_CONNECT to (tcp://178.63.85.196:7775)
NN_CONNECT to (tcp://69.12.77.197:7775)
NN_CONNECT to (tcp://192.157.238.198:7775)
NN_CONNECT to (tcp://209.58.183.199:7775)
NN_CONNECT to (tcp://149.202.65.200:7775)
NN_CONNECT to (tcp://173.208.184.202:7775)
NN_CONNECT to (tcp://94.102.63.208:7775)
NN_CONNECT to (tcp://5.9.109.208:7775)
NN_CONNECT to (tcp://94.102.63.209:7775)
NN_CONNECT to (tcp://197.189.248.210:7775)
NN_CONNECT to (tcp://149.56.19.212:7775)
NN_CONNECT to (tcp://46.165.243.214:7775)
NN_CONNECT to (tcp://45.64.168.216:7775)
*/
void dex_init(struct supernet_info *myinfo)
{
@ -584,6 +534,8 @@ char *dex_response(int32_t *broadcastflagp,struct supernet_info *myinfo,struct d
{
char buf[65],*retstr = 0; int32_t i,datalen; bits256 hash2; cJSON *retjson=0; struct iguana_info *coin; struct dex_request dexreq;
*broadcastflagp = 0;
return(clonestr("{\"error\":\"basilisk disabled\"}"));
if ( strcmp(dexp->handler,"request") == 0 )
{
datalen = dex_rwrequest(0,dexp->packet,&dexreq);

344
iguana/exchanges/LP_NXT.c

@ -0,0 +1,344 @@
/******************************************************************************
* 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_NXT.c
// marketmaker
//
char *NXTnodes[] = { "62.75.159.113", "91.44.203.238", "82.114.88.225", "78.63.207.76", "188.174.110.224", "91.235.72.49", "213.144.130.91", "209.222.98.250", "216.155.128.10", "178.33.203.157", "162.243.122.251", "69.163.47.173", "193.151.106.129", "78.94.2.74", "192.3.196.10", "173.33.112.87", "104.198.173.28", "35.184.154.126", "174.140.167.239", "23.88.113.131", "198.71.84.173", "178.150.207.53", "23.88.61.53", "192.157.233.106", "192.157.241.212", "23.89.192.88", "23.89.200.27", "192.157.241.139", "23.89.200.63", "23.89.192.98", "163.172.214.102", "176.9.85.5", "80.150.243.88", "80.150.243.92", "80.150.243.98", "109.70.186.198", "146.148.84.237", "104.155.56.82", "104.197.157.140", "37.48.73.249", "146.148.77.226", "84.57.170.200", "107.161.145.131", "80.150.243.97", "80.150.243.93", "80.150.243.100", "80.150.243.95", "80.150.243.91", "80.150.243.99", "80.150.243.96", "93.231.187.177", "212.237.23.85", "35.158.179.254", "46.36.66.41", "185.170.113.79", "163.172.68.112", "78.47.35.210", "77.90.90.75", "94.177.196.134", "212.237.22.215", "94.177.234.11", "167.160.180.199", "54.68.189.9", "94.159.62.14", "195.181.221.89", "185.33.145.94", "195.181.209.245", "195.181.221.38", "195.181.221.162", "185.33.145.12", "185.33.145.176", "178.79.128.235", "94.177.214.120", "94.177.199.41", "94.177.214.200", "94.177.213.201", "212.237.13.162", "195.181.221.236", "195.181.221.185", "185.28.103.187", "185.33.146.244", "217.61.123.71", "195.181.214.45", "195.181.212.99", "195.181.214.46", "195.181.214.215", "195.181.214.68", "217.61.123.118", "195.181.214.79", "217.61.123.14", "217.61.124.100", "195.181.214.111", "85.255.0.176", "81.2.254.116", "217.61.123.184", "195.181.212.231", "94.177.214.110", "195.181.209.164", "104.129.56.238", "85.255.13.64", "167.160.180.206", "217.61.123.226", "167.160.180.208", "93.186.253.127", "212.237.6.208", "94.177.207.190", "217.61.123.119", "85.255.1.245", "217.61.124.157", "37.59.57.141", "167.160.180.58", "104.223.53.14", "217.61.124.69", "195.181.212.103", "85.255.13.141", "104.207.133.204", "71.90.7.107", "107.150.18.108", "23.94.134.161", "80.150.243.13", "80.150.243.11", "185.81.165.52", "80.150.243.8" };
static char *assetids[][4] =
{
{ "13502152099823770958", "SUPERNETx2", "10000", "10000" },
{ "12071612744977229797", "SUPERNET", "10000", "10000" },
{ "12071612744977229797", "UNITY", "10000", "10000" },
{ "15344649963748848799", "DEX", "1", "100000000" },
{ "6883271355794806507", "PANGEA", "10000", "10000" },
{ "17911762572811467637", "JUMBLR", "10000", "10000" },
{ "17083334802666450484", "BET", "10000", "10000" },
{ "13476425053110940554", "CRYPTO", "1000", "100000" },
{ "6932037131189568014", "HODL", "1", "100000000" },
//{ "3006420581923704757", "SHARK", "10000", "10000" },
{ "3006420581923704757", "MSHARK", "10", "10000000" },
{ "17571711292785902558", "BOTS", "1", "100000000" },
{ "10524562908394749924", "MGW", "1", "100000000" },
{ "8217222248380501882", "MESH", "10000", "10000" },
{ "15641806960898178066", "TOKEN", "1", "100000000" },
};
void LP_sendtoaddress_line(char *validaddress,char *assetname,uint64_t satoshis,uint64_t txnum)
{
char line[1024],lowerstr[64];
if ( strcmp(assetname,"SUPERNETx2") == 0 )
{
sprintf(line,"fiat/supernet sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long)txnum);
printf("%s\n",line);
sprintf(line,"fiat/revs sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long)txnum);
}
else
{
if ( strcmp(assetname,"TOKEN") == 0 )
strcpy(lowerstr,"supernet");
else strcpy(lowerstr,assetname);
tolowercase(lowerstr);
sprintf(line,"sleep 1; fiat/%s sendtoaddress %s %.8f # txnum.%llu",lowerstr,validaddress,dstr(satoshis),(long long)txnum);
}
printf("%s\n",line);
}
uint64_t LP_assetid_mult(int32_t *assetindp,char *name,uint64_t assetid)
{
int32_t i; uint64_t mult = 0;
name[0] = 0;
*assetindp = -1;
for (i=0; i<sizeof(assetids)/sizeof(*assetids); i++)
{
if ( assetid == calc_nxt64bits(assetids[i][0]) )
{
*assetindp = i;
mult = atoi(assetids[i][3]);
strcpy(name,assetids[i][1]);
break;
}
}
return(mult);
}
cJSON *LP_NXT_message(char *method,uint64_t txnum,char *passphrase)
{
char url[1024],*retstr; cJSON *retjson = 0;
sprintf(url,"http://127.0.0.1:7876/nxt?requestType=%s&transaction=%llu&secretPhrase=%s",method,(long long)txnum,passphrase);
//printf("issue.(%s)\n",url);
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
}
free(retstr);
}
return(retjson);
}
cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char *passphrase)
{
char url[1024],*retstr; cJSON *retjson = 0;
if ( account != 0 && data != 0 && nonce != 0 && passphrase != 0 )
{
sprintf(url,"http://127.0.0.1:7876/nxt?requestType=readMessage&transaction=%llu&secretPhrase=%s",(long long)txnum,passphrase);
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
}
free(retstr);
}
}
return(retjson);
}
int64_t NXTventure_qty(uint64_t assetid)
{
char url[1024],*retstr; uint64_t qty=0; cJSON *retjson;
sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAccountAssets&account=NXT-XRK4-5HYK-5965-9FH4Z&includeAssetInfo=true");
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 )
{
printf("NXT_venture_qty(%s)\n",retstr);
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
free_json(retjson);
}
free(retstr);
}
//NXT_venture_qty({"accountAssets":[{"quantityQNT":"3900000000","unconfirmedQuantityQNT":"3900000000","decimals":4,"name":"ATOMIC","asset":"11694807213441909013"},{"quantityQNT":"2900000000","unconfirmedQuantityQNT":"2900000000","decimals":8,"name":"NSC","asset":"6775372232354238105"},{"quantityQNT":"750000000","unconfirmedQuantityQNT":"750000000","decimals":4,"name":"omnigames","asset":"7441230892853180965"},{"quantityQNT":"607438148","unconfirmedQuantityQNT":"607438148","decimals":4,"name":"ARDR","asset":"12422608354438203866"},{"quantityQNT":"451991779","unconfirmedQuantityQNT":"451991779","decimals":4,"name":"SuperNET","asset":"12071612744977229797"},{"quantityQNT":"146960000","unconfirmedQuantityQNT":"146960000","decimals":4,"name":"Privatebet","asset":"17083334802666450484"},{"quantityQNT":"79500188","unconfirmedQuantityQNT":"79500188","decimals":3,"name":"crypto777","asset":"13476425053110940554"},{"quantityQNT":"1495473","unconfirmedQuantityQNT":"1495473","decimals":0,"name":"jl777hodl","asset":"6932037131189568014"},{"quantityQNT":"500000","unconfirmedQuantityQNT":"500000","decimals":0,"name":"Boost","asset":"9719950459730291994"},{"quantityQNT":"200000","unconfirmedQuantityQNT":"200000","decimals":0,"name":"NXTforex","asset":"15245281832566929110"},{"quantityQNT":"150000","unconfirmedQuantityQNT":"150000","decimals":0,"name":"NXTsharks","asset":"8049009002993773168"},{"quantityQNT":"100000","unconfirmedQuantityQNT":"100000","decimals":5,"name":"solarweb","asset":"13604572534081373849"},{"quantityQNT":"75000","unconfirmedQuantityQNT":"75000","decimals":0,"name":"SNN","asset":"15113552914305929842"},{"quantityQNT":"57299","unconfirmedQuantityQNT":"57299","decimals":2,"name":"SLEUTH","asset":"4174874835406708311"},{"quantityQNT":"18801","unconfirmedQuantityQNT":"18801","decimals":2,"name":"BTCDdev","asset":"15131486578879082754"},{"quantityQNT":"18767","unconfirmedQuantityQNT":"18767","decimals":2,"name":"longzai","asset":"10955830010602647139"},{"quantityQNT":"13000","unconfirmedQuantityQNT":"13000","decimals":0,"name":"NXTventure","asset":"16212446818542881180"},{"quantityQNT":"7250","unconfirmedQuantityQNT":"7250","decimals":0,"name":"InstantDEX","asset":"15344649963748848799"},{"quantityQNT":"2873","unconfirmedQuantityQNT":"2873","decimals":4,"name":"EDinar","asset":"17740527756732147253"},{"quantityQNT":"39","unconfirmedQuantityQNT":"39","decimals":0,"name":"JebBush","asset":"1929419574701797581"},{"quantityQNT":"30","unconfirmedQuantityQNT":"30","decimals":0,"name":"Hilary","asset":"11814755740231942504"}],"requestProcessingTime":1})
return(qty);
}
void *curl_post(void **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3);
void NXTventure_liquidation()
{
/*{"quantityQNT":"607438148","unconfirmedQuantityQNT":"607438148","decimals":4,"name":"ARDR","asset":""},
{"quantityQNT":"451991779","unconfirmedQuantityQNT":"451991779","decimals":4,"name":"SuperNET","asset":"12071612744977229797"},
{"quantityQNT":"146960000","unconfirmedQuantityQNT":"146960000","decimals":4,"name":"Privatebet","asset":"17083334802666450484"},
{"quantityQNT":"79500188","unconfirmedQuantityQNT":"79500188","decimals":3,"name":"crypto777","asset":"13476425053110940554"},
{"quantityQNT":"1495473","unconfirmedQuantityQNT":"1495473","decimals":0,"name":"jl777hodl","asset":"6932037131189568014"},
{"quantityQNT":"7250","unconfirmedQuantityQNT":"7250","decimals":0,"name":"InstantDEX","asset":"15344649963748848799"},*/
char *assetids[][4] =
{
{ "12422608354438203866", "607438148", "ARDR", "10000" },
{ "12071612744977229797", "451991779", "SuperNET", "10000" },
{ "17083334802666450484", "146960000", "Privatebet", "10000" },
{ "13476425053110940554", "79500188", "crypto777", "1000" },
{ "6932037131189568014", "1495473", "jl777hodl", "1" },
{ "15344649963748848799", "7250", "InstantDEX", "1" },
};
void *cHandle=0; char *retstr,*retstr2,url[1024],*account; uint64_t txid,qty,qtyA,assetid,sum; double ratio; cJSON *array,*retjson2,*item,*retjson; int32_t i,j,decimals,numassetids=(int32_t)(sizeof(assetids)/sizeof(*assetids)),n=0;
char *passphrase = "";
sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getAssetAccounts&asset=16212446818542881180");
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (array= jarray(&n,retjson,"accountAssets")) != 0 )
{
for (j=0; j<numassetids; j++)
{
assetid = calc_nxt64bits(assetids[j][0]);
qtyA = calc_nxt64bits(assetids[j][1]);
decimals = (int32_t)calc_nxt64bits(assetids[j][3]);
printf("distribute %llu QNT of %s assetid %llu %.8f\n",(long long)qtyA,assetids[j][2],(long long)assetid,(double)qtyA / decimals);
sum = 0;
for (i=0; i<n; i++)
{
item = jitem(array,i);
qty = j64bits(item,"quantityQNT");
ratio = (double)qty / (1000000. - 13000.);
if ( (account= jstr(item,"accountRS")) != 0 && qtyA*ratio >= 1 )
{
if ( strcmp(account,"NXT-XRK4-5HYK-5965-9FH4Z") != 0 )
{
sum += (long long)(qtyA * ratio);
sprintf(url,"requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000&deadline=60",passphrase,account,(long long)assetid,(long long)(qtyA * ratio));
if ( (retstr2= curl_post(&cHandle,"http://127.0.0.1:7876/nxt","",url,"","","","")) != 0 )
{
if ( (retjson2= cJSON_Parse(retstr2)) != 0 )
{
txid = j64bits(retjson2,"transaction");
printf("%s %.6f %8llu QNT %s -> %llu %.8f txid %llu\n",account,ratio,(long long)qtyA,assetids[j][2],(long long)(qtyA * ratio),((double)(long long)(qtyA * ratio))/decimals,(long long)txid);
free_json(retjson2);
}
free(retstr2);
}
usleep(250000);
}
}
}
printf("%s distribution total %llu QNT %.8f\n",assetids[j][2],(long long)sum,(double)sum/decimals);
}
}
free_json(retjson);
}
printf("NXTventure assethodlers.%d\n",n);
free(retstr);
}
}
cJSON *LP_NXT_redeems()
{
char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[2][sizeof(assetids)/sizeof(*assetids)],mult,txnum,assetid,qty; int32_t i,ind,numtx=0,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0;
//sleep 1; fiat/supernet sendtoaddress RNZZuQYu8xJLZHuekhd96hYfoQuiCMz99T 1001.44150000 # txnum.8537615468620726612
//sleep 1; fiat/pangea sendtoaddress RWMdRaUmMZqKkEibwEhY6XS3RLCXJDWHTi 22.10910000 # txnum.2649622877615958504
uint64_t txnum_marker = calc_nxt64bits("8537615468620726612"); // 2649622877615958504"); // set to most recent processed
uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); // dont change, end marker
char *passphrase = "";
char *account = "NXT-MRBN-8DFH-PFMK-A4DBM";
memset(totals,0,sizeof(totals));
sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getBlockchainTransactions&account=%s",account);
//printf("calling (%s)\n",url);
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (array= jarray(&numtx,retjson,"transactions")) != 0 )
{
for (i=0; i<numtx; i++)
{
msgjson = encjson = decjson = 0;
txnum = assetid = qty = 0;
item = jitem(array,i);
msgstr = jstr(item,"message");
txnum = j64bits(item,"transaction");
if ( txnum == txnum_marker )
past_marker = 1;
//printf("%d: %s\n",i,jprint(item,0));
if ( (recv= jstr(item,"recipientRS")) != 0 && strcmp(recv,"NXT-MRBN-8DFH-PFMK-A4DBM") == 0 )
{
if ( (attach= jobj(item,"attachment")) != 0 && jint(attach,"version.AssetTransfer") == 1 )
{
assetid = j64bits(attach,"asset");
qty = j64bits(attach,"quantityQNT");
//printf("txnum.%llu (%s)\n",(long long)txnum,jprint(attach,0));
if ( (msgstr == 0 || msgstr[0] == 0) && jint(attach,"version.PrunablePlainMessage") == 1 )
{
method = "getPrunableMessage";
if ( (msgjson= LP_NXT_message(method,txnum,"test")) != 0 )
{
msgstr = jstr(msgjson,"message");
//printf("%d method.(%s) (%s)\n",i,method,msgstr);
}
}
if ( msgstr == 0 || msgstr[0] == 0 )
msgstr = jstr(attach,"message");
if ( msgstr == 0 || msgstr[0] == 0 )
{
if ( (encjson= jobj(attach,"encryptedMessage")) != 0 )
{
msgstr = "encryptedMessage";//jstr(encjson,"data");
if ( (decjson= LP_NXT_decrypt(txnum,account,jstr(encjson,"data"),jstr(encjson,"nonce"),passphrase)) != 0 )
{
//printf("%s\n",jprint(decjson,0));
if ( jstr(decjson,"decryptedMessage") != 0 )
msgstr = jstr(decjson,"decryptedMessage");
}
}
}
}
mult = LP_assetid_mult(&ind,assetname,assetid);
if ( ind >= 0 )
totals[past_marker][ind] += qty * mult;
if ( msgstr != 0 && assetname[0] != 0 && qty != 0 )
{
char validaddress[64]; int32_t z,n;
n = (int32_t)strlen(msgstr);
for (z=0; z<n; z++)
{
if ( msgstr[z] == 'R' )
break;
}
memset(validaddress,0,sizeof(validaddress));
if ( n-z >= 34 )
strncpy(validaddress,&msgstr[z],34);
if ( txnum == calc_nxt64bits("4545341872872347590") )
strcpy(validaddress,"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni");
if ( past_marker == 0 )
{
if ( strlen(validaddress) == 34 || strlen(validaddress) == 33 )
{
//printf("%-4d: (%34s) <- %13.5f %10s tx.%llu past_marker.%d\n",i,validaddress,dstr(qty * mult),assetname,(long long)txnum,past_marker);
LP_sendtoaddress_line(validaddress,assetname,(qty * mult),txnum);
} else printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum);
}
}
if ( msgjson != 0 )
free_json(msgjson);
if ( decjson != 0 )
free_json(decjson);
}
if ( txnum == txnum_marker2 )
break;
}
}
//free_json(retjson);
}
free(retstr);
}
printf("\nTotal redeemed.%d\n",numtx);
for (past_marker=0; past_marker<2; past_marker++)
{
for (i=0; i<sizeof(totals[0])/sizeof(*totals[0]); i++)
{
if ( totals[past_marker][i] != 0 )
printf("%-10s %13.5f past_marker.%d\n",assetids[i][1],dstr(totals[past_marker][i]),past_marker);
}
printf("\n>>>>>>>>>> already processed:\n");
}
return(retjson);
}
cJSON *LP_assethbla(char *assetid)
{
char url[1024],*retstr; int32_t n; cJSON *array,*bid=0,*ask=0,*retjson;
sprintf(url,"http://%s:7876/nxt?requestType=getBidOrders&asset=%s&firstIndex=0&lastIndex=0",NXTnodes[LP_rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid);
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 )
{
bid = cJSON_Parse(retstr);
free(retstr);
}
sprintf(url,"http://%s:7876/nxt?requestType=getAskOrders&asset=%s&firstIndex=0&lastIndex=0",NXTnodes[LP_rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid);
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 )
{
ask = cJSON_Parse(retstr);
free(retstr);
}
retjson = cJSON_CreateObject();
if ( bid != 0 && ask != 0 )
{
if ( (array= jarray(&n,bid,"bidOrders")) != 0 )
jadd(retjson,"bid",jduplicate(jitem(array,0)));
if ( (array= jarray(&n,ask,"askOrders")) != 0 )
jadd(retjson,"ask",jduplicate(jitem(array,0)));
}
if ( bid != 0 )
free_json(bid);
if ( ask != 0 )
free_json(ask);
return(retjson);
}

60
iguana/exchanges/LP_RTmetrics.c

@ -27,11 +27,13 @@ struct LP_metricinfo
int32_t ind,numutxos,age,pendingswaps;
};
#define LP_NUMRT 1024
struct LP_RTmetrics_pendings
{
char refbase[65],refrel[65];
int32_t numswaps,numavoidtxids,numwhitelist,numblacklist,numpendings,pending_swaps[1024];
bits256 avoidtxids[8192],whitelist[1024],blacklist[1024],pending_pubkeys[1024];
char refbase[128],refrel[128];
int64_t pending_kmdvalue[LP_NUMRT];
int32_t numswaps,numavoidtxids,numwhitelist,numblacklist,numpendings,pending_swaps[LP_NUMRT];
bits256 avoidtxids[8192],whitelist[LP_NUMRT],blacklist[LP_NUMRT],pending_pubkeys[LP_NUMRT];
} LP_RTmetrics;
int32_t LP_bits256_find(bits256 *list,int32_t num,bits256 val)
@ -72,11 +74,14 @@ int32_t LP_RTmetrics_blacklistadd(bits256 pubkey)
return(LP_bits256_add("LP_RTmetrics_blacklistadd blacklist",LP_RTmetrics.blacklist,&LP_RTmetrics.numblacklist,(int32_t)(sizeof(LP_RTmetrics.blacklist)/sizeof(*LP_RTmetrics.blacklist)),pubkey));
}
int32_t LP_RTmetrics_pendingswap(bits256 pubkey)
int32_t LP_RTmetrics_pendingswap(bits256 pubkey,int64_t kmdvalue)
{
int32_t ind;
if ( (ind= LP_bits256_add("LP_RTmetrics_pendingswap",LP_RTmetrics.pending_pubkeys,&LP_RTmetrics.numpendings,(int32_t)(sizeof(LP_RTmetrics.pending_pubkeys)/sizeof(*LP_RTmetrics.pending_pubkeys)),pubkey)) >= 0 )
{
LP_RTmetrics.pending_swaps[ind]++;
LP_RTmetrics.pending_kmdvalue[ind] += kmdvalue;
}
return(ind);
}
@ -113,7 +118,9 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums
base = "";
if ( (rel= jstr(item,"rel")) == 0 )
rel = "";
if ( strcmp(base,refbase) != 0 && strcmp(base,refrel) != 0 && strcmp(rel,refbase) != 0 && strcmp(rel,refrel) != 0 )
if ( refbase[0] != 0 && strcmp(base,refbase) != 0 && strcmp(base,refrel) != 0 )
continue;
if ( refrel[0] != 0 && strcmp(rel,refbase) != 0 && strcmp(rel,refrel) != 0 )
continue;
aliceid = j64bits(item,"aliceid");
basesatoshis = SATOSHIDEN * jdouble(item,"basevol");
@ -123,9 +130,9 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums
price = jdouble(item,"price");
requestid = juint(item,"requestid");
quoteid = juint(item,"quoteid");
LP_RTmetrics_pendingswap(srcpub);
LP_RTmetrics_pendingswap(destpub);
if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid)) != 0 ) // no need for this
LP_RTmetrics_pendingswap(srcpub,LP_kmdvalue(base,basesatoshis));
LP_RTmetrics_pendingswap(destpub,LP_kmdvalue(rel,relsatoshis));
if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) // no need for this
{
if ( (swapjson= cJSON_Parse(retstr)) != 0 )
{
@ -142,9 +149,9 @@ void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t nums
}
}
void LP_RTmetrics_update(char *base,char *rel)
/*void LP_RTmetrics_init()
{
struct LP_pubkeyinfo *pubp,*tmp; uint32_t futuretime; int32_t i,numswaps; bits256 zero; char *retstr; cJSON *statsjson,*swaps;
struct LP_pubkey_info *pubp,*tmp; uint32_t futuretime; int32_t i,numswaps; bits256 pubkey,zero; cJSON *statsjson,*swaps;
memset(&LP_RTmetrics,0,sizeof(LP_RTmetrics));
HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp)
{
@ -152,31 +159,38 @@ void LP_RTmetrics_update(char *base,char *rel)
LP_RTmetrics_whitelistadd(pubp->pubkey);
else if ( pubp->istrusted < 0 )
LP_RTmetrics_blacklistadd(pubp->pubkey);
pubp->swaps_kmdvalue = 0;
}
futuretime = (uint32_t)time(NULL) + 3600*100;
memset(zero.bytes,0,sizeof(zero));
if ( (retstr= LP_statslog_disp(100,futuretime,futuretime,"",zero)) != 0 )
if ( (statsjson= LP_statslog_disp(futuretime,futuretime,"",zero,0,0)) != 0 )
{
if ( (statsjson= cJSON_Parse(retstr)) != 0 )
if ( (swaps= jarray(&numswaps,statsjson,"swaps")) != 0 )
{
if ( (swaps= jarray(&numswaps,statsjson,"swaps")) != 0 )
{
//printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0));
if ( numswaps > 0 )
LP_RTmetrics_swapsinfo(base,rel,swaps,numswaps);
}
free_json(statsjson);
//printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0));
if ( numswaps > 0 )
LP_RTmetrics_swapsinfo("","",swaps,numswaps);
}
free(retstr);
free_json(statsjson);
}
for (i=0; i<LP_RTmetrics.numpendings; i++)
{
pubkey = LP_RTmetrics.pending_pubkeys[i];
if ( LP_RTmetrics.pending_swaps[i] > LP_MAXPENDING_SWAPS )
{
char str[65]; printf("%s has %d pending swaps! which is more than %d\n",bits256_str(str,LP_RTmetrics.pending_pubkeys[i]),LP_RTmetrics.pending_swaps[i],LP_MAXPENDING_SWAPS);
LP_RTmetrics_blacklistadd(LP_RTmetrics.pending_pubkeys[i]);
char str[65]; printf("%s has %d pending swaps! which is more than %d\n",bits256_str(str,pubkey),LP_RTmetrics.pending_swaps[i],LP_MAXPENDING_SWAPS);
LP_RTmetrics_blacklistadd(pubkey);
}
else if ( (pubp= LP_pubkeyfind(pubkey)) != 0 )
{
char str[65]; printf("%s has %d pending swaps %.8f kmdvalue\n",bits256_str(str,pubkey),LP_RTmetrics.pending_swaps[i],dstr(LP_RTmetrics.pending_kmdvalue[i]));
pubp->swaps_kmdvalue = LP_RTmetrics.pending_kmdvalue[i];
}
}
//printf("%d pubkeys have pending swaps, whitelist.%d blacklist.%d avoidtxids.%d\n",LP_RTmetrics.numpendings,LP_RTmetrics.numwhitelist,LP_RTmetrics.numblacklist,LP_RTmetrics.numavoidtxids);
}
}*/
double _LP_RTmetric_calc(struct LP_metricinfo *mp,double bestprice,double maxprice,double relvolume)
{

338
iguana/exchanges/LP_bitcoin.c

@ -1959,13 +1959,13 @@ int32_t bitcoin_timelockspend(uint8_t *script,int32_t n,uint8_t rmd160[20],uint3
return(n);
}
int32_t bitcoin_performancebond(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,uint32_t unlocktimestamp,uint8_t cltv_rmd160[20],uint8_t anytime_rmd160[20])
int32_t bitcoin_performancebond(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,uint32_t unlocktimestamp,uint8_t *cltvpub33,uint8_t *elsepub33)
{
script[n++] = SCRIPT_OP_IF;
n = bitcoin_checklocktimeverify(script,n,unlocktimestamp);
n = bitcoin_standardspend(script,n,cltv_rmd160);
n = bitcoin_pubkeyspend(script,n,cltvpub33);
script[n++] = SCRIPT_OP_ELSE;
n = bitcoin_standardspend(script,n,anytime_rmd160);
n = bitcoin_pubkeyspend(script,n,elsepub33);
script[n++] = SCRIPT_OP_ENDIF;
calc_rmd160_sha256(p2sh_rmd160,script,n);
return(n);
@ -2008,6 +2008,8 @@ int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,c
char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params)
{
if ( userpass[0] == 0 )
return(clonestr("{\"error\":\"no rpcusername rpcpassword in coin.conf\"}"));
return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,4));
}
@ -2135,30 +2137,46 @@ int32_t base58encode_checkbuf(uint8_t taddr,uint8_t addrtype,uint8_t *data,int32
int32_t bitcoin_wif2priv(uint8_t wiftaddr,uint8_t *addrtypep,bits256 *privkeyp,char *wifstr)
{
int32_t offset,len = -1; bits256 hash; uint8_t buf[256];
int32_t offset,len = -1; bits256 hash; uint8_t buf[256],*ptr;
offset = 1 + (wiftaddr != 0);
memset(buf,0,sizeof(buf));
memset(privkeyp,0,sizeof(*privkeyp));
if ( (len= bitcoin_base58decode(buf,wifstr)) >= 4 )
{
// validate with trailing hash, then remove hash
if ( len < 38 )
if ( len >= 32+offset )
memcpy(privkeyp,buf+offset,32);
else
{
//printf("wif %s -> buf too short len.%d\n",wifstr,len);
return(-1);
}
ptr = buf;
/*if ( len < 38 )
{
memset(pbuf,0,sizeof(pbuf));
memcpy(pbuf,buf,len-4);
memcpy(&pbuf[34],&buf[len-4],4);
ptr = pbuf;
int32_t i; for (i=0; i<38; i++)
printf("%02x ",pbuf[i]);
printf("pbuf from %d\n",len);
len = 38;
hash = bits256_doublesha256(0,buf,len - 4);
*addrtypep = (wiftaddr == 0) ? *buf : buf[1];
memcpy(privkeyp,buf+offset,32);
if ( (buf[len - 4]&0xff) == hash.bytes[31] && (buf[len - 3]&0xff) == hash.bytes[30] &&(buf[len - 2]&0xff) == hash.bytes[29] && (buf[len - 1]&0xff) == hash.bytes[28] )
}*/
hash = bits256_doublesha256(0,ptr,len - 4);
*addrtypep = (wiftaddr == 0) ? *ptr : ptr[1];
if ( (ptr[len - 4]&0xff) == hash.bytes[31] && (ptr[len - 3]&0xff) == hash.bytes[30] &&(ptr[len - 2]&0xff) == hash.bytes[29] && (ptr[len - 1]&0xff) == hash.bytes[28] )
{
//int32_t i; for (i=0; i<len; i++)
// printf("%02x ",buf[i]);
//printf(" buf, hash.%02x %02x %02x %02x ",hash.bytes[28],hash.bytes[29],hash.bytes[30],hash.bytes[31]);
// printf("%02x ",ptr[i]);
//printf(" ptr, hash.%02x %02x %02x %02x ",hash.bytes[28],hash.bytes[29],hash.bytes[30],hash.bytes[31]);
//printf("wifstr.(%s) valid len.%d\n",wifstr,len);
return(32);
}
else
else if ( 0 ) // gets errors when len is 37
{
int32_t i; for (i=0; i<len; i++)
printf("%02x ",buf[i]);
printf(" buf, hash.%02x %02x %02x %02x\n",hash.bytes[28],hash.bytes[29],hash.bytes[30],hash.bytes[31]);
printf(" buf, hash.%02x %02x %02x %02x len.%d\n",hash.bytes[28],hash.bytes[29],hash.bytes[30],hash.bytes[31],len);
}
}
return(-1);
@ -2178,13 +2196,26 @@ int32_t bitcoin_wif2addr(void *ctx,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtyp
int32_t bitcoin_priv2wif(uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype)
{
uint8_t data[128]; int32_t offset,len = 32;
memcpy(data+1,privkey.bytes,sizeof(privkey));
offset = 1 + (wiftaddr != 0);
if ( wiftaddr != 0 )
{
//data[0] = wiftaddr;
//data[1] = addrtype;
offset = 2;
}
else
{
//data[0] = addrtype;
offset = 1;
}
memcpy(data+offset,privkey.bytes,len);
data[offset + len++] = 1;
len = base58encode_checkbuf(wiftaddr,addrtype,data,len);
if ( bitcoin_base58encode(wifstr,data,len) == 0 )
{
char str[65]; printf("error making wif from %s\n",bits256_str(str,privkey));
return(-1);
if ( 1 )
}
if ( 0 )
{
uint8_t checktype; bits256 checkpriv; char str[65],str2[65];
if ( bitcoin_wif2priv(wiftaddr,&checktype,&checkpriv,wifstr) == sizeof(bits256) )
@ -2204,7 +2235,7 @@ int32_t bitcoin_priv2wiflong(uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8
len = base58encode_checkbuf(wiftaddr,addrtype,data,len);
if ( bitcoin_base58encode(wifstr,data,len) == 0 )
return(-1);
if ( 1 )
if ( 0 )
{
uint8_t checktype; bits256 checkpriv; char str[65],str2[65];
if ( bitcoin_wif2priv(wiftaddr,&checktype,&checkpriv,wifstr) == sizeof(bits256) )
@ -2340,20 +2371,20 @@ int32_t iguana_scriptgen(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,int32_t
return(scriptlen);
}
int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype)
int32_t bitcoin_scriptget(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype,int32_t zcash)
{
int32_t j,n,siglen,plen; uint8_t *p2shscript;
j = n = 0;
*userdatap = 0;
*userdatalenp = *pubkeysizep = *sigsizep = 0;
*hashtypep = SIGHASH_ALL;
*hashtypep = LP_sighash(symbol,zcash);
while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen < len && j < 16 )
{
vp->signers[j].siglen = siglen;
memcpy(vp->signers[j].sig,&scriptsig[n+1],siglen);
if ( j == 0 )
*hashtypep = vp->signers[j].sig[siglen-1];
else if ( vp->signers[j].sig[siglen-1] != *hashtypep )
else if ( vp->signers[j].sig[siglen-1] != (*hashtypep & (~SIGHASH_FORKID)) )
{
//printf("SIGHASH.%d mismatch %d vs %d\n",j,vp->signers[j].sig[siglen-1],*hashtypep);
break;
@ -2408,14 +2439,7 @@ int32_t bitcoin_scriptget(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_
}
if ( *userdatap == p2shscript )
*userdatap = 0;
/*if ( len == 0 )
{
// txid.(eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2).v1
decode_hex(vp->rmd160,20,"010966776006953d5567439e5e39f86a0d273bee");//3564a74f9ddb4372301c49154605573d7d1a88fe");
vp->type = IGUANA_SCRIPT_76A988AC;
}*/
vp->spendlen = iguana_scriptgen(taddr,pubtype,p2shtype,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,0,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout);
//printf("type.%d asmstr.(%s) spendlen.%d\n",vp->type,asmstr,vp->spendlen);
return(vp->spendlen);
}
@ -2583,39 +2607,6 @@ int32_t iguana_calcrmd160(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,char *a
return(vp->type);
}
uint32_t iguana_vinscriptparse(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *userdatalenp,uint8_t *vinscript,int32_t scriptlen)
{
uint32_t hashtype; uint8_t *userdata = 0;
*sigsizep = *pubkeysizep = *p2shsizep = *userdatalenp = 0;
if ( bitcoin_scriptget(taddr,pubtype,p2shtype,&hashtype,sigsizep,pubkeysizep,&userdata,userdatalenp,vp,vinscript,scriptlen,0) < 0 )
{
printf("iguana_vinscriptparse: error parsing vinscript?\n");
return(-1);
}
if ( userdata != 0 && *userdatalenp > 0 )
memcpy(vp->userdata,userdata,*userdatalenp);
if ( vp->type == IGUANA_SCRIPT_P2SH )
{
*p2shsizep = vp->p2shlen + 1 + (vp->p2shlen >= 0xfd)*2;
//printf("P2SHSIZE.%d\n",*p2shsizep);
}
return(hashtype);
}
/*char *iguana_scriptget(struct iguana_info *coin,char *scriptstr,char *asmstr,int32_t max,int32_t hdrsi,uint32_t unspentind,bits256 txid,int32_t vout,uint8_t *rmd160,int32_t type,uint8_t *pubkey33)
{
int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; struct vin_info V,*vp = &V;
memset(vp,0,sizeof(*vp));
scriptstr[0] = 0;
if ( asmstr != 0 )
asmstr[0] = 0;
if ( pubkey33 != 0 && bitcoin_pubkeylen(pubkey33) > 0 )
memcpy(vp->signers[0].pubkey,pubkey33,33);
scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,rmd160,type,(const struct vin_info *)vp,vout);
init_hexbytes_noT(scriptstr,script,scriptlen);
return(scriptstr);
}*/
cJSON *bitcoin_txscript(char *asmstr,char **vardata,int32_t numvars)
{
int32_t i; cJSON *scriptjson,*array;
@ -3040,7 +3031,7 @@ int32_t iguana_parsevinobj(uint8_t *serialized,int32_t maxsize,struct iguana_msg
siglen = serialized[len + m++];
//if ( i == 0 && m == 1 && siglen == 0 ) // multisig backward compatible
// continue;
if ( serialized[len + m + siglen - 1] == SIGHASH_ALL )
if ( ((serialized[len + m + siglen - 1] & ~SIGHASH_FORKID) & 0xff) == SIGHASH_ALL )
memcpy(V->signers[i++].sig,&serialized[len + m],siglen);
if ( (0) )
{
@ -3279,58 +3270,186 @@ int32_t iguana_vinarray_check(cJSON *vinarray,bits256 txid,int32_t vout)
return(-1);
}
int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash);
int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash);
bits256 bitcoin_sigtxid(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,uint32_t hashtype,char *vpnstr,int32_t suppress_pubkeys,int32_t zcash)
bits256 bitcoin_sigtxid(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,uint64_t spendamount,uint32_t hashtype,char *vpnstr,int32_t suppress_pubkeys,int32_t zcash)
{
int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest;
int32_t i,len,sbtcflag = 0; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest;
dest = *msgtx;
dest.vins = calloc(dest.tx_in,sizeof(*dest.vins));
dest.vouts = calloc(dest.tx_out,sizeof(*dest.vouts));
memcpy(dest.vins,msgtx->vins,dest.tx_in * sizeof(*dest.vins));
memcpy(dest.vouts,msgtx->vouts,dest.tx_out * sizeof(*dest.vouts));
memset(sigtxid.bytes,0,sizeof(sigtxid));
if ( (hashtype & ~SIGHASH_FORKID) != SIGHASH_ALL )
if ( strcmp(symbol,"SBTC") == 0 )
sbtcflag = 1;
if ( ((hashtype & ~SIGHASH_FORKID) & 0xff) != SIGHASH_ALL )
{
printf("currently only SIGHASH_ALL supported, not %d\n",hashtype);
return(sigtxid);
}
for (i=0; i<dest.tx_in; i++)
if ( (hashtype & SIGHASH_FORKID) == 0 || sbtcflag != 0 )
{
if ( i == vini )
for (i=0; i<dest.tx_in; i++)
{
dest.vins[i].vinscript = spendscript;
dest.vins[i].scriptlen = spendlen;
//int32_t j; for (j=0; j<spendlen; j++)
// printf("%02x",spendscript[j]);
//printf(" tmpscript.%d vini.%d\n",spendlen,vini);
if ( i == vini )
{
dest.vins[i].vinscript = spendscript;
dest.vins[i].scriptlen = spendlen;
//int32_t j; for (j=0; j<spendlen; j++)
// printf("%02x",spendscript[j]);
//printf(" tmpscript.%d vini.%d\n",spendlen,vini);
}
else
{
dest.vins[i].vinscript = (uint8_t *)"";
dest.vins[i].scriptlen = 0;
}
dest.vins[i].p2shlen = 0;
dest.vins[i].redeemscript = 0;
dest.vins[i].userdata = 0;
dest.vins[i].userdatalen = 0;
}
else
len = iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0,0,suppress_pubkeys,zcash);
if ( len > 0 )
{
dest.vins[i].vinscript = (uint8_t *)"";
dest.vins[i].scriptlen = 0;
#ifdef BTC2_VERSION
if ( height >= BTC2_HARDFORK_HEIGHT )
hashtype |= (0x777 << 20);
#endif
len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype);
if ( sbtcflag != 0 )
{
memcpy(&serialized[len],"sbtc",4);
len += 4;
}
}
dest.vins[i].p2shlen = 0;
dest.vins[i].redeemscript = 0;
dest.vins[i].userdata = 0;
dest.vins[i].userdatalen = 0;
revsigtxid = bits256_doublesha256(0,serialized,len);
for (i=0; i<sizeof(revsigtxid); i++)
sigtxid.bytes[31-i] = revsigtxid.bytes[i];
}
len = iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0,0,suppress_pubkeys,zcash);
//for (i=0; i<len; i++)
// printf("%02x",serialized[i]);
//printf(" <- sigtx len.%d supp.%d user[0].%d\n",len,suppress_pubkeys,dest.vins[0].userdatalen);
if ( len > 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 &&
else
{
#ifdef BTC2_VERSION
if ( height >= BTC2_HARDFORK_HEIGHT )
hashtype |= (0x777 << 20);
#endif
/*
https://github.com/Bitcoin-UAHF/spec/blob/master/replay-protected-sighash.md
CHashWriter ss(SER_GETHASH, 0);
// Version
ss << txTo.nVersion;
// Input prevouts/nSequence (none/all, depending on flags)
ss << hashPrevouts;
ss << hashSequence;
// The input being signed (replacing the scriptSig with scriptCode +
// amount). The prevout may already be contained in hashPrevout, and the
// nSequence may already be contain in hashSequence.
ss << txTo.vin[nIn].prevout;
ss << static_cast<const CScriptBase &>(scriptCode);
ss << amount;
ss << txTo.vin[nIn].nSequence;
// Outputs (none/one/all, depending on flags)
ss << hashOutputs;
// Locktime
ss << txTo.nLockTime;
// Sighash type
ss << ((GetForkId() << 8) | nHashType);
return ss.GetHash();
}
Computation of midstates:
uint256 GetPrevoutHash(const CTransaction &txTo) {
CHashWriter ss(SER_GETHASH, 0);
for (unsigned int n = 0; n < txTo.vin.size(); n++) {
ss << txTo.vin[n].prevout;
}
return ss.GetHash();
}
uint256 GetSequenceHash(const CTransaction &txTo) {
CHashWriter ss(SER_GETHASH, 0);
for (unsigned int n = 0; n < txTo.vin.size(); n++) {
ss << txTo.vin[n].nSequence;
}
return ss.GetHash();
}
uint256 GetOutputsHash(const CTransaction &txTo) {
CHashWriter ss(SER_GETHASH, 0);
for (unsigned int n = 0; n < txTo.vout.size(); n++) {
ss << txTo.vout[n];
}
return ss.GetHash();
}
*/
bits256 prevouthash,seqhash,outputhash;
for (i=len=0; i<dest.tx_in; i++)
{
len += iguana_rwbignum(1,&serialized[len],sizeof(dest.vins[i].prev_hash),dest.vins[i].prev_hash.bytes);
len += iguana_rwnum(1,&serialized[len],sizeof(dest.vins[i].prev_vout),&dest.vins[i].prev_vout);
}
prevouthash = bits256_doublesha256(0,serialized,len);
for (i=len=0; i<dest.tx_in; i++)
len += iguana_rwnum(1,&serialized[len],sizeof(dest.vins[i].sequence),&dest.vins[i].sequence);
seqhash = bits256_doublesha256(0,serialized,len);
for (i=len=0; i<dest.tx_out; i++)
len += iguana_voutparse(1,&serialized[len],&dest.vouts[i]);
outputhash = bits256_doublesha256(0,serialized,len);
char str[65]; printf("prevouthash.%s ",bits256_str(str,prevouthash));
printf("seqhash.%s ",bits256_str(str,seqhash));
printf("outputhash.%s ",bits256_str(str,outputhash));
printf("vini.%d prev.%s/v%d\n",vini,bits256_str(str,dest.vins[vini].prev_hash),dest.vins[vini].prev_vout);
/*01000000
997c1040c67ee2f9ab21abf7457f7aec4503970e974e532b6578f326c270b7eb
445066705e799022b7095f7ceca255149f43acfc47e7f59e551f7bce2930b13b
b19ce2c564f7dc57b3f95593e2b287c72d388e86de12dc562d9f8a6bea65b310 01000000
1976a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688ac
5be9290000000000
ffffffff
a919fd9f636c08f4989be95c999230408dbc0f602c3f000bcedba9d5bbe98914
00000000
41000000*/
/*
01000000 ss.write size.4
ebb770c226f378652b534e970e970345ec7a7f45f7ab21abf9e27ec640107c99 ss.write size.32
3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044 ss.write size.32
10b365ea6b8a9f2d56dc12de868e382dc787b2e29355f9b357dcf764c5e29cb1 ss.write size.32
01000000 ss.write size.4
19 ss.write size.1
76a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688ac ss.write size.25
76a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688ac scriptCode
5be9290000000000 ss.write size.8
ffffffff ss.write size.4
hashtype.41 locktime.0 seq.ffffffff amount 29e95b
1489e9bbd5a9dbce0b003f2c600fbc8d403092995ce99b98f4086c639ffd19a9 ss.write size.32
00000000 ss.write size.4
41000000 ss.write size.4
-> sighash.fc55acc3666c43b8f75908ca06ea2d343cd09eb846f14c5d7d0748a11e081a9d*/
len = 0;
len += iguana_rwnum(1,&serialized[len],sizeof(dest.version),&dest.version);
len += iguana_rwbignum(1,&serialized[len],sizeof(prevouthash),prevouthash.bytes);
len += iguana_rwbignum(1,&serialized[len],sizeof(seqhash),seqhash.bytes);
len += iguana_rwbignum(1,&serialized[len],sizeof(dest.vins[vini].prev_hash),dest.vins[vini].prev_hash.bytes);
len += iguana_rwnum(1,&serialized[len],sizeof(dest.vins[vini].prev_vout),&dest.vins[vini].prev_vout);
serialized[len++] = spendlen;
memcpy(&serialized[len],spendscript,spendlen), len += spendlen;
len += iguana_rwnum(1,&serialized[len],sizeof(spendamount),&spendamount);
len += iguana_rwnum(1,&serialized[len],sizeof(dest.vins[vini].sequence),&dest.vins[vini].sequence);
len += iguana_rwbignum(1,&serialized[len],sizeof(outputhash),outputhash.bytes);
len += iguana_rwnum(1,&serialized[len],sizeof(dest.lock_time),&dest.lock_time);
len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype);
//for (i=0; i<len; i++)
// printf("%02x",serialized[i]);
revsigtxid = bits256_doublesha256(0,serialized,len);
//printf(" B path version.%08x spendamount %.8f locktime %u hashtype %08x %s\n",dest.version,dstr(spendamount),dest.lock_time,hashtype,bits256_str(str,revsigtxid));
for (i=0; i<sizeof(revsigtxid); i++)
sigtxid.bytes[31-i] = revsigtxid.bytes[i];
//char str[65]; printf("SIGTXID.(%s) numvouts.%d\n",bits256_str(str,sigtxid),dest.tx_out);
//sigtxid = revsigtxid;
}
//char str[65]; printf("SIGTXID.(%s) numvouts.%d\n",bits256_str(str,sigtxid),dest.tx_out);
free(dest.vins);
free(dest.vouts);
return(sigtxid);
@ -3362,9 +3481,25 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj
return(len);
}
int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash)
uint32_t LP_sighash(char *symbol,int32_t zcash)
{
uint32_t sighash;
sighash = SIGHASH_ALL;
if ( zcash == LP_IS_BITCOINCASH )
sighash |= SIGHASH_FORKID;
else if ( zcash == LP_IS_BITCOINGOLD )
{
sighash |= SIGHASH_FORKID;
sighash |= (LP_IS_BITCOINGOLD << 8);
}
else if ( strcmp(symbol,"SBTC") == 0 )
sighash |= SIGHASH_FORKID;
return(sighash);
}
int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash)
{
int32_t i,j,n,segtxlen,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t *segtx=0,segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid;
int32_t i,j,n,segtxlen,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t *segtx=0,segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; uint64_t spendamount; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version);
if ( json != 0 )
@ -3535,10 +3670,9 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is
{
uint32_t sighash;
iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript));
sighash = SIGHASH_ALL;
if ( zcash == LP_IS_BITCOINCASH )
sighash |= SIGHASH_FORKID;
sigtxid = bitcoin_sigtxid(taddr,pubtype,p2shtype,isPoS,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,sighash,vpnstr,suppress_pubkeys,zcash);
sighash = LP_sighash(symbol,zcash);
spendamount = LP_outpoint_amount(symbol,msg->vins[i].prev_hash,msg->vins[i].prev_vout);
sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,spendamount,sighash,vpnstr,suppress_pubkeys,zcash);
//printf("after vini.%d vinscript.%p spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].vinscript,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0));
if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 )
jaddi(vinarray,iguana_vinjson(&msg->vins[i],sigtxid));
@ -3636,13 +3770,13 @@ bits256 iguana_parsetxobj(uint8_t isPoS,int32_t *txstartp,uint8_t *serialized,in
return(txid);
}
char *iguana_rawtxbytes(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,cJSON *json,struct iguana_msgtx *msgtx,int32_t suppress_pubkeys,int32_t zcash)
char *iguana_rawtxbytes(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,cJSON *json,struct iguana_msgtx *msgtx,int32_t suppress_pubkeys,int32_t zcash)
{
int32_t n; char *txbytes = 0,vpnstr[64]; uint8_t *serialized;
serialized = malloc(IGUANA_MAXPACKETSIZE);
vpnstr[0] = 0;
//char str[65]; printf("%d of %d: %s\n",i,msg.txn_count,bits256_str(str,tx.txid));
if ( (n= iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&msgtx->txid,vpnstr,0,0,0,suppress_pubkeys,zcash)) > 0 )
if ( (n= iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&msgtx->txid,vpnstr,0,0,0,suppress_pubkeys,zcash)) > 0 )
{
txbytes = malloc(n*2+1);
init_hexbytes_noT(txbytes,serialized,n);
@ -3670,7 +3804,7 @@ char *bitcoin_json2hex(uint8_t isPoS,bits256 *txidp,cJSON *txjson,struct vin_inf
return(txbytes);
}
cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash)
cJSON *bitcoin_data2json(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash)
{
int32_t n; char vpnstr[64]; struct iguana_msgtx M; cJSON *txobj;
if ( serialized == 0 )
@ -3681,7 +3815,7 @@ cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t
memset(msgtx,0,sizeof(M));
vpnstr[0] = 0;
memset(txidp,0,sizeof(*txidp));
if ( (n= iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,0,txobj,serialized,len,msgtx,txidp,vpnstr,extraspace,extralen,vins,suppress_pubkeys,zcash)) <= 0 )
if ( (n= iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,0,txobj,serialized,len,msgtx,txidp,vpnstr,extraspace,extralen,vins,suppress_pubkeys,zcash)) <= 0 )
{
printf("errortxobj.(%s)\n",jprint(txobj,0));
free_json(txobj);
@ -3699,7 +3833,7 @@ cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t
return(txobj);
}
cJSON *bitcoin_hex2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extraspace,int32_t extralen,uint8_t *origserialized,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash)
cJSON *bitcoin_hex2json(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extraspace,int32_t extralen,uint8_t *origserialized,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash)
{
int32_t len; uint8_t *serialized; cJSON *txobj;
if ( txbytes == 0 )
@ -3708,7 +3842,7 @@ cJSON *bitcoin_hex2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t i
if ( (serialized= origserialized) == 0 )
serialized = calloc(1,len+4096);
decode_hex(serialized,len,txbytes);
txobj = bitcoin_data2json(taddr,pubtype,p2shtype,isPoS,height,txidp,msgtx,extraspace,extralen,serialized,len,vins,suppress_pubkeys,zcash);
txobj = bitcoin_data2json(symbol,taddr,pubtype,p2shtype,isPoS,height,txidp,msgtx,extraspace,extralen,serialized,len,vins,suppress_pubkeys,zcash);
if ( serialized != origserialized )
free(serialized);
return(txobj);

27
iguana/exchanges/LP_cache.c

@ -23,7 +23,7 @@ cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *se
uint8_t *extraspace; cJSON *txobj; char str[65],str2[65]; struct iguana_msgtx msgtx; bits256 checktxid;
extraspace = calloc(1,4000000);
memset(&msgtx,0,sizeof(msgtx));
txobj = bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->height,&checktxid,&msgtx,extraspace,4000000,serialized,len,0,0,coin->zcash);
txobj = bitcoin_data2json(coin->symbol,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->height,&checktxid,&msgtx,extraspace,4000000,serialized,len,0,0,coin->zcash);
//printf("TX.(%s) match.%d\n",jprint(txobj,0),bits256_cmp(txid,checktxid));
free(extraspace);
if ( bits256_cmp(txid,checktxid) != 0 )
@ -45,10 +45,9 @@ struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 tx
vins = jarray(&numvins,txobj,"vin");
vouts = jarray(&numvouts,txobj,"vout");
tx = LP_transactionadd(coin,txid,height,numvouts,numvins);
tx->serialized = 0;//serialized;
free(serialized);
tx->serialized = serialized, tx->len = len;
// free(serialized), tx->len = 0;
tx->fpos = fpos;
tx->len = 0;//tx->len;
tx->SPV = tx->height = height;
//printf("tx.%s numvins.%d numvouts.%d\n",bits256_str(str,txid),numvins,numvouts);
for (i=0; i<numvouts; i++)
@ -230,17 +229,24 @@ bits256 LP_merkleroot(struct iguana_info *coin,struct electrum_info *ep,int32_t
int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height)
{
struct LP_transaction *tx=0; cJSON *merkobj,*merkles,*retjson; bits256 roothash,merkleroot; int32_t m,SPV = 0;
struct LP_transaction *tx=0; cJSON *merkobj,*merkles,*retjson; bits256 roothash,merkleroot; int32_t m,ht=0,SPV = 0;
if ( height <= 0 )
return(0);
if ( (tx= LP_transactionfind(coin,txid)) == 0 && strcmp(coinaddr,coin->smartaddr) == 0 )
{
if ( (retjson= electrum_transaction(coin->symbol,ep,&retjson,txid,0)) != 0 )
if ( (retjson= electrum_transaction(&ht,coin->symbol,ep,&retjson,txid,0)) != 0 )
free_json(retjson);
}
if ( tx != 0 )
{
tx->height = height;
if ( tx->height == 0 )
{
if ( height != 0 )
tx->height = height;
else if ( ht != 0 )
tx->height = ht;
height = tx->height;
}
if ( tx->SPV > 0 )
return(tx->SPV);
}
@ -262,7 +268,7 @@ int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_i
if ( tx != 0 )
{
tx->SPV = height;
if ( tx->serialized != 0 )
if ( strcmp(coinaddr,coin->smartaddr) != 0 && tx->serialized != 0 )
{
free(tx->serialized);
tx->serialized = 0;
@ -314,7 +320,7 @@ void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedfla
uint64_t LP_unspents_load(char *symbol,char *addr)
{
char *arraystr; uint64_t balance = 0; int32_t i,n; cJSON *retjson,*item; struct iguana_info *coin;
char *arraystr; uint64_t balance = 0; int32_t i,n; bits256 zero; cJSON *retjson,*item; struct iguana_info *coin;
if ( (coin= LP_coinfind(symbol)) != 0 )
{
if ( (arraystr= LP_unspents_filestr(symbol,addr)) != 0 )
@ -330,7 +336,8 @@ uint64_t LP_unspents_load(char *symbol,char *addr)
balance += j64bits(item,"value");
}
}
electrum_process_array(coin,coin->electrum,coin->smartaddr,retjson,1);
memset(zero.bytes,0,sizeof(zero));
electrum_process_array(coin,coin->electrum,addr,retjson,1,zero,zero);
free_json(retjson);
}
free(arraystr);

67
iguana/exchanges/LP_coins.c

@ -99,7 +99,34 @@ void LP_statefname(char *fname,char *symbol,char *assetname,char *str,char *name
{
if ( confpath != 0 && confpath[0] != 0 )
{
strcpy(fname,confpath);
#if defined(NATIVE_WINDOWS)
// need to do something with "confpath":"`${process.env.HOME}`/.muecore/mue.conf" under Windows
char *ht = "`${process.env.USERHOME}`", *ht_start, *p_ht;
char ht_symbol[2];
ht_start = strstr(confpath, ht);
if (ht_start) {
ht_start = ht_start + strlen(ht);
sprintf(fname, "%s\\", LP_getdatadir());
p_ht = ht_start;
if (p_ht[0] == '/' && p_ht[1] == '.') {
p_ht += 2;
//printf("%s\n", p_ht);
while (p_ht[0] != '\0') {
if (p_ht[0] == '/') strcat(fname, "\\"); else
{
ht_symbol[0] = p_ht[0]; ht_symbol[1] = '\0';
strcat(fname, ht_symbol);
}
p_ht++;
}
//printf("%s\n", fname);
}
} else strcpy(fname, confpath);
#else
strcpy(fname,confpath);
#endif
return;
}
sprintf(fname,"%s",LP_getdatadir());
@ -119,7 +146,7 @@ void LP_statefname(char *fname,char *symbol,char *assetname,char *str,char *name
else if ( name != 0 )
{
char name2[64];
#ifdef __APPLE__
#if defined(__APPLE__) || defined(NATIVE_WINDOWS)
int32_t len;
strcpy(name2,name);
name2[0] = toupper(name2[0]);
@ -164,7 +191,7 @@ uint16_t LP_userpass(char *userpass,char *symbol,char *assetname,char *confroot,
sprintf(confname,"%s.conf",confroot);
if ( 0 )
printf("%s (%s) %s confname.(%s) confroot.(%s)\n",symbol,assetname,name,confname,confroot);
#ifdef __APPLE__
#if defined(__APPLE__) || defined(NATIVE_WINDOWS)
int32_t len;
confname[0] = toupper(confname[0]);
len = (int32_t)strlen(confname);
@ -187,7 +214,7 @@ uint16_t LP_userpass(char *userpass,char *symbol,char *assetname,char *confroot,
cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif)
{
struct electrum_info *ep; uint64_t balance; char wifstr[128],ipaddr[64]; uint8_t tmptype; bits256 checkkey; cJSON *item = cJSON_CreateObject();
struct electrum_info *ep; bits256 zero; int32_t notarized; uint64_t balance; char wifstr[128],ipaddr[64]; uint8_t tmptype; bits256 checkkey; cJSON *item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol);
if ( showwif != 0 )
{
@ -200,7 +227,9 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif)
jadd(item,"installed",coin->userpass[0] == 0 ? jfalse() : jtrue());
if ( coin->userpass[0] != 0 )
{
jaddnum(item,"height",LP_getheight(coin));
jaddnum(item,"height",LP_getheight(&notarized,coin));
if ( notarized > 0 )
jaddnum(item,"notarized",notarized);
if ( coin->electrum != 0 )
balance = LP_unspents_load(coin->symbol,coin->smartaddr);
else balance = LP_RTsmartbalance(coin);
@ -230,6 +259,17 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif)
jaddnum(item,"p2shtype",coin->p2shtype);
jaddnum(item,"wiftype",coin->wiftype);
jaddnum(item,"txfee",strcmp(coin->symbol,"BTC") != 0 ? coin->txfee : LP_txfeecalc(coin,0,0));
if ( strcmp(coin->symbol,"KMD") == 0 )
{
memset(zero.bytes,0,sizeof(zero));
if ( strcmp(coin->smartaddr,coin->instantdex_address) != 0 )
{
LP_instantdex_depositadd(coin->smartaddr,zero);
strcpy(coin->instantdex_address,coin->smartaddr);
}
jaddnum(item,"zcredits",dstr(LP_myzcredits()));
jadd(item,"zdebits",LP_myzdebits());
}
return(item);
}
@ -314,6 +354,9 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse
char *name2;
memset(coin,0,sizeof(*coin));
safecopy(coin->symbol,symbol,sizeof(coin->symbol));
if ( strcmp(symbol,"PART") == 0 )
coin->txversion = 160;
else coin->txversion = 1;
coin->updaterate = (uint32_t)time(NULL);
coin->isPoS = isPoS;
coin->taddr = taddr;
@ -353,6 +396,11 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse
coin->zcash = LP_IS_BITCOINCASH;
//printf("set coin.%s <- LP_IS_BITCOINCASH %d\n",symbol,coin->zcash);
}
else if ( strcmp(symbol,"BTG") == 0 )
{
coin->zcash = LP_IS_BITCOINGOLD;
printf("set coin.%s <- LP_IS_BITCOINGOLD %d\n",symbol,coin->zcash);
}
return(port);
}
@ -464,3 +512,12 @@ struct iguana_info *LP_coincreate(cJSON *item)
return(0);
}
void LP_otheraddress(char *destcoin,char *otheraddr,char *srccoin,char *coinaddr)
{
uint8_t addrtype,rmd160[20]; struct iguana_info *src,*dest;
if ( (src= LP_coinfind(srccoin)) != 0 && (dest= LP_coinfind(destcoin)) != 0 )
{
bitcoin_addr2rmd160(src->taddr,&addrtype,rmd160,coinaddr);
bitcoin_address(otheraddr,dest->taddr,dest->pubtype,rmd160,20);
} else printf("couldnt find %s or %s\n",srccoin,destcoin);
}

266
iguana/exchanges/LP_commands.c

@ -34,11 +34,11 @@ char *LP_numutxos()
char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port
{
char *method,*userpass,*base,*rel,*coin,*retstr = 0; int32_t changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr;
char *method,*userpass,*base,*rel,*coin,*passphrase,*retstr = 0; int32_t authenticated=0,changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr;
method = jstr(argjson,"method");
if ( method != 0 && (strcmp(method,"addr_unspents") == 0 || strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0) )
return(0);
//printf("stats_JSON %s\n",method);
//printf("stats_JSON.(%s)\n",jprint(argjson,0));
/*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) )
{
if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 )
@ -68,8 +68,16 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r
}
if ( strcmp(method,"hello") == 0 )
{
//int32_t i; cJSON *array = cJSON_CreateArray();
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"status","got hello");
//for (i=0; i<10000; i++)
// jaddinum(array,i);
//jadd(retjson,"array",array);
return(jprint(retjson,1));
//printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport);
return(clonestr("{\"result\":\"success\",\"status\":\"got hello\"}"));
//return(clonestr("{\"result\":\"success\",\"status\":\"got hello\"}"));
}
/*else if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 0 )
{
@ -94,29 +102,30 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r
else if ( strcmp(method,"help") == 0 )
return(clonestr("{\"result\":\" \
available localhost RPC commands: \n \
pricearray(base, rel, starttime=0, endtime=-1, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\
setprice(base, rel, price)\n\
setprice(base, rel, price, broadcast=1)\n\
autoprice(base, rel, fixed, minprice, margin, refbase, refrel, factor, offset)*\n\
goal(coin=*, val=<autocalc>)\n\
myprice(base, rel)\n\
enable(coin)\n\
disable(coin)\n\
notarizations(coin)\n\
parselog()\n\
statsdisp(starttime=0, endtime=0, gui="", pubkey="")\n\
statsdisp(starttime=0, endtime=0, gui="", pubkey="", base="", rel="")\n\
ticker(base="", rel="")\n\
tradesarray(base, rel, starttime=<now>-timescale*1024, endtime=<now>, timescale=60) -> [timestamp, high, low, open, close, relvolume, basevolume, aveprice, numtrades]\n\
pricearray(base, rel, starttime=0, endtime=0, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\
getrawtransaction(coin, txid)\n\
inventory(coin, reset=0, [passphrase=])\n\
bestfit(rel, relvolume)\n\
lastnonce()\n\
buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce, destpubkey="")\n\
sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce, destpubkey="")\n\
buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce)\n\
sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)\n\
withdraw(coin, outputs[])\n\
sendrawtransaction(coin, signedtx)\n\
swapstatus()\n\
swapstatus(pending=0)\n\
swapstatus(coin, limit=10)\n\
swapstatus(base, rel, limit=10)\n\
swapstatus(requestid, quoteid)\n\
recentswaps(limit=3)\n\
notarizations(coin)\n\
public API:\n \
getcoins()\n\
getcoin(coin)\n\
@ -127,8 +136,11 @@ listunspent(coin, address)\n\
setconfirms(coin, numconfirms, maxconfirms=6)\n\
trust(pubkey, trust) # positive to trust, 0 for normal, negative to blacklist\n\
balance(coin, address)\n\
balances(address)\n\
fundvalue(address="", holdings=[], divisor=0)\n\
orderbook(base, rel, duration=3600)\n\
getprices(base, rel)\n\
getprices()\n\
getprice(base, rel)\n\
//sendmessage(base=coin, rel="", pubkey=zero, <argjson method2>)\n\
//getmessages(firsti=0, num=100)\n\
//deletemessages(firsti=0, num=100)\n\
@ -146,7 +158,9 @@ bot_settings(botid, newprice, newvolume)\n\
bot_status(botid)\n\
bot_stop(botid)\n\
bot_pause(botid)\n\
bot_resume(botid)\n\
instantdex_deposit(weeks, amount, broadcast=1)\n\
instantdex_claim()\n\
jpg(srcfile, destfile, power2=7, passphrase, data="", required)\n\
\"}"));
//sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\
@ -160,18 +174,32 @@ bot_resume(botid)\n\
{
if ( G.USERPASS_COUNTER == 0 )
{
char pub33str[67];
G.USERPASS_COUNTER = 1;
retjson = cJSON_CreateObject();
jaddstr(retjson,"userpass",G.USERPASS);
jaddbits256(retjson,"mypubkey",G.LP_mypub25519);
init_hexbytes_noT(pub33str,G.LP_pubsecp,33);
jaddstr(retjson,"pubsecp",pub33str);
jadd(retjson,"coins",LP_coinsjson(LP_showwif));
return(jprint(retjson,1));
}
if ( strcmp(method,"passphrase") != 0 && ((userpass= jstr(argjson,"userpass")) == 0 || strcmp(userpass,G.USERPASS) != 0) )
// if passphrase api and passphrase is right, ignore userpass, use hass of passphrase
if ( strcmp(method,"passphrase") == 0 && (passphrase= jstr(argjson,"passphrase")) != 0 )
{
bits256 passhash; char str[65],str2[65];
vcalc_sha256(0,passhash.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
if ( bits256_cmp(passhash,G.LP_passhash) == 0 )
authenticated = 1;
else printf("passhash %s != G %s\n",bits256_str(str,passhash),bits256_str(str2,G.LP_passhash));
}
if ( authenticated == 0 && ((userpass= jstr(argjson,"userpass")) == 0 || strcmp(userpass,G.USERPASS) != 0) )
return(clonestr("{\"error\":\"authentication error you need to make sure userpass is set\"}"));
jdelete(argjson,"userpass");
if ( jobj(argjson,"userpass") != 0 )
jdelete(argjson,"userpass");
if ( strcmp(method,"passphrase") == 0 )
{
char coinaddr[64],pub33str[67];
G.USERPASS_COUNTER = 1;
if ( LP_passphrase_init(jstr(argjson,"passphrase"),jstr(argjson,"gui")) < 0 )
return(clonestr("{\"error\":\"couldnt change passphrase\"}"));
@ -180,9 +208,39 @@ bot_resume(botid)\n\
jaddstr(retjson,"result","success");
jaddstr(retjson,"userpass",G.USERPASS);
jaddbits256(retjson,"mypubkey",G.LP_mypub25519);
init_hexbytes_noT(pub33str,G.LP_pubsecp,33);
jaddstr(retjson,"pubsecp",pub33str);
bitcoin_address(coinaddr,0,60,G.LP_myrmd160,20);
jaddstr(retjson,"KMD",coinaddr);
bitcoin_address(coinaddr,0,0,G.LP_myrmd160,20);
jaddstr(retjson,"BTC",coinaddr);
jaddstr(retjson,"NXT",G.LP_NXTaddr);
jadd(retjson,"coins",LP_coinsjson(LP_showwif));
return(jprint(retjson,1));
}
}
else if ( strcmp(method,"instantdex_deposit") == 0 )
{
if ( (ptr= LP_coinsearch("KMD")) != 0 )
{
if ( jint(argjson,"weeks") <= 0 || jdouble(argjson,"amount") < 10. )
return(clonestr("{\"error\":\"instantdex_deposit needs to have weeks and amount\"}"));
else return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jobj(argjson,"broadcast") != 0 ? jint(argjson,"broadcast") : 1));
}
return(clonestr("{\"error\":\"cant find KMD\"}"));
}
else if ( strcmp(method,"instantdex_claim") == 0 )
{
if ( (ptr= LP_coinsearch("KMD")) != 0 )
{
return(LP_instantdex_claim(ptr));
}
return(clonestr("{\"error\":\"cant find KMD\"}"));
}
else if ( strcmp(method,"jpg") == 0 )
{
return(LP_jpg(jstr(argjson,"srcfile"),jstr(argjson,"destfile"),jint(argjson,"power2"),jstr(argjson,"passphrase"),jstr(argjson,"data"),jint(argjson,"required")));
}
/*else if ( strcmp(method,"sendmessage") == 0 )
{
if ( jobj(argjson,"method2") == 0 )
@ -224,15 +282,13 @@ bot_resume(botid)\n\
return(jprint(LP_coinsjson(0),1));
else if ( strcmp(method,"notarizations") == 0 )
{
int32_t height,bestheight;
if ( (ptr= LP_coinsearch(coin)) != 0 )
{
height = LP_notarization_latest(&bestheight,ptr);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"coin",coin);
jaddnum(retjson,"lastnotarization",height);
jaddnum(retjson,"bestheight",bestheight);
jaddnum(retjson,"lastnotarization",ptr->notarized);
jaddnum(retjson,"bestheight",ptr->height);
return(jprint(retjson,1));
} else return(clonestr("{\"error\":\"cant find coin\"}"));
}
@ -240,16 +296,13 @@ bot_resume(botid)\n\
{
return(LP_portfolio());
}
else if ( strcmp(method,"parselog") == 0 )
else if ( strcmp(method,"statsdisp") == 0 )
{
bits256 zero; int32_t n = LP_statslog_parse();
memset(zero.bytes,0,sizeof(zero));
return(LP_statslog_disp(n,2000000000,2000000000,"",zero));
return(jprint(LP_statslog_disp(juint(argjson,"starttime"),juint(argjson,"endtime"),jstr(argjson,"gui"),jbits256(argjson,"pubkey"),jstr(argjson,"base"),jstr(argjson,"rel")),1));
}
else if ( strcmp(method,"statsdisp") == 0 )
else if ( strcmp(method,"ticker") == 0 )
{
int32_t n = LP_statslog_parse();
return(LP_statslog_disp(n,juint(argjson,"starttime"),juint(argjson,"endtime"),jstr(argjson,"gui"),jbits256(argjson,"pubkey")));
return(LP_ticker(jstr(argjson,"base"),jstr(argjson,"rel")));
}
else if ( strcmp(method,"secretaddresses") == 0 )
{
@ -262,12 +315,29 @@ bot_resume(botid)\n\
{
uint32_t requestid,quoteid;
if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 )
return(basilisk_swapentry(requestid,quoteid));
return(basilisk_swapentry(requestid,quoteid,1));
else if ( coin[0] != 0 )
return(basilisk_swapentries(coin,0,jint(argjson,"limit")));
else if ( base[0] != 0 && rel[0] != 0 )
return(basilisk_swapentries(base,rel,jint(argjson,"limit")));
else return(basilisk_swaplist(0,0));
else return(basilisk_swaplist(0,0,0,jint(argjson,"pending")));
}
else if ( strcmp(method,"dynamictrust") == 0 )
{
struct LP_address *ap; char *coinaddr;
if ( (ptr= LP_coinsearch("KMD")) != 0 && (coinaddr= jstr(argjson,"address")) != 0 )
{
//LP_zeroconf_deposits(ptr);
if ( (ap= LP_addressfind(ptr,coinaddr)) != 0 )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"address",coinaddr);
jaddnum(retjson,"zcredits",dstr(ap->instantdex_credits));
return(jprint(retjson,1));
}
}
return(clonestr("{\"error\":\"cant find address\"}"));
}
else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 )
return(retstr);
@ -276,10 +346,24 @@ bot_resume(botid)\n\
double price,bid,ask;
if ( strcmp(method,"autoprice") == 0 )
{
if ( LP_autoprice(base,rel,argjson) < 0 )
if ( LP_autoprice(ctx,base,rel,argjson) < 0 )
return(clonestr("{\"error\":\"couldnt set autoprice\"}"));
else return(clonestr("{\"result\":\"success\"}"));
}
else if ( strcmp(method,"pricearray") == 0 )
{
uint32_t firsttime;
if ( base[0] != 0 && rel[0] != 0 )
{
if ( (firsttime= juint(argjson,"starttime")) < time(NULL)-30*24*3600 )
firsttime = (uint32_t)(time(NULL)-30*24*3600);
return(jprint(LP_pricearray(base,rel,firsttime,juint(argjson,"endtime"),jint(argjson,"timescale")),1));
} else return(clonestr("{\"error\":\"pricearray needs base and rel\"}"));
}
else if ( strcmp(method,"tradesarray") == 0 )
{
return(jprint(LP_tradesarray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1));
}
if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 )
return(clonestr("{\"error\":\"at least one of coins disabled\"}"));
price = jdouble(argjson,"price");
@ -289,22 +373,10 @@ bot_resume(botid)\n\
return(clonestr("{\"error\":\"couldnt set price\"}"));
//else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 )
// return(clonestr("{\"error\":\"couldnt set price\"}"));
else return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio));
}
else if ( strcmp(method,"pricearray") == 0 )
{
uint32_t firsttime;
if ( base[0] != 0 && rel[0] != 0 )
{
if ( (firsttime= juint(argjson,"firsttime")) < time(NULL)-30*24*3600 )
firsttime = (uint32_t)(time(NULL)-30*24*3600);
return(jprint(LP_pricearray(base,rel,firsttime,juint(argjson,"lasttime"),jint(argjson,"timescale")),1));
} else return(clonestr("{\"error\":\"pricearray needs base and rel\"}"));
else if ( price == 0. || jobj(argjson,"broadcast") == 0 || jint(argjson,"broadcast") != 0 )
return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio));
else return(clonestr("{\"result\":\"success\"}"));
}
/*else if ( strcmp(method,"pricearray") == 0 )
{
return(jprint(LP_pricearray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1));
}*/
else if ( strcmp(method,"orderbook") == 0 )
return(LP_orderbook(base,rel,jint(argjson,"duration")));
else if ( strcmp(method,"myprice") == 0 )
@ -336,13 +408,13 @@ bot_resume(botid)\n\
} else return(clonestr("{\"error\":\"no price set\"}"));
}
}
else if ( rel[0] != 0 && strcmp(method,"bestfit") == 0 )
/*else if ( rel[0] != 0 && strcmp(method,"bestfit") == 0 )
{
double relvolume;
if ( (relvolume= jdouble(argjson,"relvolume")) > SMALLVAL )
return(LP_bestfit(rel,relvolume));
else return(clonestr("{\"error\":\"no relvolume set\"}"));
}
}*/
else if ( coin[0] != 0 )
{
if ( strcmp(method,"enable") == 0 )
@ -353,21 +425,29 @@ bot_resume(botid)\n\
if ( ptr->userpass[0] == 0 )
{
cJSON *retjson = cJSON_CreateObject();
jaddstr(retjson,"error","couldnt find coin locally installed");
jaddstr(retjson,"error",LP_DONTCHANGE_ERRMSG0);
jaddstr(retjson,"coin",coin);
return(jprint(retjson,1));
}
if ( LP_conflicts_find(ptr) == 0 )
{
ptr->inactive = 0;
cJSON *array;
if ( ptr->smartaddr[0] != 0 )
LP_unspents_load(coin,ptr->smartaddr);
if ( LP_getheight(ptr) <= 0 )
cJSON *array; int32_t notarized;
if ( LP_getheight(&notarized,ptr) <= 0 )
{
ptr->inactive = (uint32_t)time(NULL);
return(clonestr("{\"error\":\"coin cant be activated till synced\"}"));
} else LP_unspents_load(coin,ptr->smartaddr);
}
else
{
if ( ptr->smartaddr[0] != 0 )
LP_unspents_load(coin,ptr->smartaddr);
LP_unspents_load(coin,ptr->smartaddr);
if ( strcmp(ptr->symbol,"KMD") == 0 )
LP_importaddress("KMD",BOTS_BONDADDRESS);
}
if ( 0 && strcmp(coin,"BCH") == 0 )
test_validate(ptr,"010000000110b365ea6b8a9f2d56dc12de868e382dc787b2e29355f9b357dcf764c5e29cb1010000006b483045022100c605b993f1db5f31046ebb9065bea0a047f478342bbad8fcfc6af81d05236bd502206e9993a737a8814b935b5e522e750c915e7d37e3bd8367f087d4510f66acac47412102ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92ffffffff014bc22900000000001976a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688ac00000000");
array = cJSON_CreateArray();
jaddi(array,LP_coinjson(ptr,0));
return(jprint(array,1));
@ -389,7 +469,8 @@ bot_resume(botid)\n\
{
if ( (ptr= LP_coinsearch(coin)) != 0 )
{
char *coinaddr;
char *coinaddr; bits256 zero;
memset(zero.bytes,0,sizeof(zero));
if ( (coinaddr= jstr(argjson,"address")) != 0 )
{
if ( coinaddr[0] != 0 )
@ -397,20 +478,13 @@ bot_resume(botid)\n\
LP_address(ptr,coinaddr);
if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 )
{
LP_listunspent_issue(coin,coinaddr,2);
LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519);
//LP_smartutxos_push(ptr);
if ( ptr->electrum != 0 )
return(LP_unspents_filestr(coin,ptr->smartaddr));
else return(jprint(LP_address_utxos(ptr,coinaddr,1),1));
}
else
{
return(clonestr("{\"error\":\"not my address\"}"));
LP_listunspent_issue(coin,coinaddr,2,zero,zero);
//LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519);
}
return(jprint(LP_listunspent(coin,coinaddr,zero,zero),1));
}
return(jprint(LP_address_utxos(ptr,coinaddr,1),1));
} else return(clonestr("{\"error\":\"no address specified\"}"));
}
return(clonestr("{\"error\":\"no address specified\"}"));
} else return(clonestr("{\"error\":\"cant find coind\"}"));
}
else if ( strcmp(method,"balance") == 0 )
@ -433,7 +507,7 @@ bot_resume(botid)\n\
}
else if ( strcmp(method,"getrawtransaction") == 0 )
{
return(jprint(LP_gettx(coin,jbits256(argjson,"txid")),1));
return(jprint(LP_gettx(coin,jbits256(argjson,"txid"),0),1));
}
else if ( strcmp(method,"withdraw") == 0 )
{
@ -480,7 +554,11 @@ bot_resume(botid)\n\
else return(clonestr("{\"error\":\"cant find coind\"}"));
}
if ( LP_isdisabled(coin,0) != 0 )
return(clonestr("{\"error\":\"coin is disabled\"}"));
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"error",LP_DONTCHANGE_ERRMSG1);
return(jprint(retjson,1));
}
if ( strcmp(method,"inventory") == 0 )
{
struct iguana_info *ptr;
@ -500,9 +578,11 @@ bot_resume(botid)\n\
jaddstr(retjson,"result","success");
jaddstr(retjson,"coin",coin);
jaddnum(retjson,"timestamp",time(NULL));
jadd(retjson,"alice",LP_inventory(coin));
jadd(retjson,"alice",cJSON_Parse("[]"));
//jadd(retjson,"alice",LP_inventory(coin));
//jadd(retjson,"bob",LP_inventory(coin,1));
LP_smartutxos_push(ptr);
//LP_smartutxos_push(ptr);
LP_address_utxo_reset(ptr);
return(jprint(retjson,1));
}
}
@ -539,18 +619,58 @@ bot_resume(botid)\n\
}
argjson = reqjson;
}
if ( strcmp(method,"getdPoW") == 0 )
retstr = clonestr("{\"result\":\"success\"}");
}
else
{
if ( strcmp(method,"tradesarray") == 0 )
{
return(jprint(LP_tradesarray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1));
}
else if ( strcmp(method,"getdPoW") == 0 )
{
if ( (ptr= LP_coinfind(jstr(argjson,"coin"))) != 0 )
LP_dPoW_broadcast(ptr);
retstr = clonestr("{\"result\":\"success\"}");
}
}
// received response
if ( strcmp(method,"postprice") == 0 )
if ( strcmp(method,"swapstatus") == 0 )
return(LP_swapstatus_recv(argjson));
else if ( strcmp(method,"gettradestatus") == 0 )
return(LP_gettradestatus(j64bits(argjson,"aliceid"),juint(argjson,"requestid"),juint(argjson,"quoteid")));
else if ( strcmp(method,"postprice") == 0 )
return(LP_postprice_recv(argjson));
else if ( strcmp(method,"postutxos") == 0 )
return(LP_postutxos_recv(argjson));
else if ( strcmp(method,"uitem") == 0 )
return(LP_uitem_recv(argjson));
else if ( strcmp(method,"dPoW") == 0 )
return(LP_dPoW_recv(argjson));
else if ( strcmp(method,"notify") == 0 )
return(LP_notify_recv(argjson));
else if ( strcmp(method,"getpeers") == 0 )
retstr = clonestr("{\"error\":\"deprecated\"}");
else if ( strcmp(method,"balances") == 0 )
return(jprint(LP_balances(jstr(argjson,"address")),1));
else if ( strcmp(method,"fundvalue") == 0 )
return(jprint(LP_fundvalue(argjson),1));
else if ( strcmp(method,"getprice") == 0 )
{
double price,bid,ask;
ask = LP_price(base,rel);
if ( (bid= LP_price(rel,base)) > SMALLVAL )
bid = 1./bid;
price = _pairaved(bid,ask);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"base",base);
jaddstr(retjson,"rel",rel);
jaddnum(retjson,"timestamp",time(NULL));
jaddnum(retjson,"bid",bid);
jaddnum(retjson,"ask",ask);
jaddnum(retjson,"price",price);
return(jprint(retjson,1));
}
/*else if ( strcmp(method,"getpeers") == 0 )
{
char *tmpstr;
@ -569,7 +689,7 @@ bot_resume(botid)\n\
else if ( strcmp(method,"tradestatus") == 0 )
{
LP_tradecommand_log(argjson);
printf("GOT TRADESTATUS! %s\n",jprint(argjson,0));
printf("%-4d tradestatus | aliceid.%llu RT.%d %d\n",(uint32_t)time(NULL) % 3600,(long long)j64bits(argjson,"aliceid"),LP_RTcount,LP_swapscount);
retstr = clonestr("{\"result\":\"success\"}");
}
else if ( strcmp(method,"wantnotify") == 0 )

149
iguana/exchanges/LP_include.h

@ -21,11 +21,19 @@
#ifndef LP_INCLUDE_H
#define LP_INCLUDE_H
#ifdef FROMGUI
#define printf dontprintf
voind dontprintf(char *formatstr,...) {}
#endif
#define LP_MAJOR_VERSION "0"
#define LP_MINOR_VERSION "1"
#define LP_BUILD_NUMBER "15256"
#define LP_BUILD_NUMBER "17752"
#define LP_BARTERDEX_VERSION 1
#define LP_MAGICBITS 8
#define LP_MAGICBITS 1
#define LP_DONT_IMPORTPRIVKEY
#ifdef FROM_JS
#include <emscripten.h>
@ -43,23 +51,25 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#define LP_MAXVINS 64
#define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL)
#define LP_AUTOTRADE_TIMEOUT 30
#define LP_RESERVETIME (LP_AUTOTRADE_TIMEOUT * 2)
#define ELECTRUM_TIMEOUT 7
#define LP_AUTOTRADE_TIMEOUT 60
#define LP_RESERVETIME 600 //(LP_AUTOTRADE_TIMEOUT * 2)
#define ELECTRUM_TIMEOUT 13
#define LP_ELECTRUM_KEEPALIVE 60
#define LP_ELECTRUM_MAXERRORS 777
#define LP_MEMPOOL_TIMEINCR 10
#define LP_SCREENWIDTH 1024
#define LP_MIN_PEERS 8
#define LP_MAX_PEERS 32
#define LP_MAXDESIRED_UTXOS (IAMLP != 0 ? 128 : 64)
#define LP_MINDESIRED_UTXOS (IAMLP != 0 ? 32 : 16)
#define LP_MAXDESIRED_UTXOS (IAMLP != 0 ? 256 : 64)
#define LP_MINDESIRED_UTXOS (IAMLP != 0 ? 64 : 16)
#define LP_DUSTCOMBINE_THRESHOLD 1000000
// RTmetrics
#define LP_RTMETRICS_TOPGROUP 1.01
#define LP_MAXPENDING_SWAPS 13
//#define LP_MAXPENDING_SWAPS 13
#define LP_CLIENT_STATSPARSE (90 * 1024 * 1024)
#define LP_COMMAND_SENDSOCK NN_PUSH
#define LP_COMMAND_RECVSOCK NN_PULL
@ -82,7 +92,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#define LP_SWAPSTEP_TIMEOUT 30
#define LP_MIN_TXFEE 10000
#define LP_MINVOL 20
#define LP_MINCLIENTVOL 100
#define LP_MINCLIENTVOL 200
#define LP_MINSIZE_TXFEEMULT 10
#define LP_REQUIRED_TXFEE 0.8
@ -98,6 +108,11 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146"
#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu"
#define INSTANTDEX_KMD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf"
#define BOTS_BONDADDRESS "RNdqHx26GWy9bk8MtmH1UiXjQcXE4RKK2P"
#define BOTS_BONDPUBKEY33 "03e641d22e1ff5a7d45c8880537e0b0a114d7b9fee2c18a6b4a8a80b6285292990"
#define LP_WEEKMULTBAD (7 * 24 * 2600)
#define LP_WEEKMULT (7 * 24 * 3600)
#define LP_FIRSTWEEKTIME 1510790400 // must be 0 mod LP_WEEKMULT
//#define BASILISK_DISABLEWAITTX
//#define BASILISK_DISABLESENDTX
@ -113,15 +128,29 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#define LP_IS_ZCASHPROTOCOL 1
#define LP_IS_BITCOINCASH 2
#define LP_IS_BITCOINGOLD 79
#define SIGHASH_FORKID 0x40
#define ZKSNARK_PROOF_SIZE 296
#define ZCASH_SOLUTION_ELEMENTS 1344
#define LP_REQUEST 0
#define LP_RESERVED 1
#define LP_CONNECT 2
#define LP_CONNECTED 3
#define LP_DONTCHANGE_ERRMSG0 "couldnt find coin locally installed"
#define LP_DONTCHANGE_ERRMSG1 "coin is disabled"
extern char GLOBAL_DBDIR[];
extern int32_t IAMLP;
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_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; };
@ -155,12 +184,12 @@ struct vin_info
uint8_t rmd160[20],spendscript[10000],p2shscript[10000],userdata[10000];
};
struct basilisk_swapmessage
/*struct basilisk_swapmessage
{
bits256 srchash,desthash;
uint32_t crc32,msgbits,quoteid,datalen;
uint8_t *data;
};
};*/
struct basilisk_swap;
@ -266,18 +295,18 @@ struct iguana_info
UT_hash_handle hh;
portable_mutex_t txmutex,addrmutex; struct LP_transaction *transactions; struct LP_address *addresses;
uint64_t txfee;
int32_t numutxos,longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport;
uint32_t loadedcache,electrumlist,lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime;
int32_t numutxos,notarized,longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport;
uint32_t txversion,dPoWtime,loadedcache,electrumlist,lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime;
uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag,userconfirms,isassetchain,maxconfirms;
char symbol[128],smartaddr[64],userpass[1024],serverport[128];
char symbol[128],smartaddr[64],userpass[1024],serverport[128],instantdex_address[64];
// portfolio
double price_kmd,force,perc,goal,goalperc,relvolume,rate;
void *electrum; void *ctx;
uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB;
uint8_t pubkey33[33],zcash;
int32_t privkeydepth;
bits256 cachedtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen;
bits256 cachedmerkle; int32_t cachedmerkleheight;
bits256 cachedtxid,notarizationtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen;
bits256 cachedmerkle,notarizedhash; int32_t cachedmerkleheight;
};
struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t vout,height; };
@ -288,7 +317,7 @@ struct LP_utxobob { struct _LP_utxoinfo utxo,deposit; };
struct LP_utxoalice { struct _LP_utxoinfo utxo,fee; };
struct LP_utxoswap { bits256 otherpubkey; uint64_t satoshis; };
//struct LP_utxoswap { bits256 otherpubkey; uint64_t satoshis; };
struct LP_utxoinfo
{
@ -296,7 +325,8 @@ struct LP_utxoinfo
bits256 pubkey;
struct _LP_utxoinfo payment,deposit,fee;
struct LP_utxostats T;
struct LP_utxoswap S;
int64_t swap_satoshis;
//struct LP_utxoswap S;
int32_t iambob,iamlp;
uint8_t key[sizeof(bits256) + sizeof(int32_t)];
uint8_t key2[sizeof(bits256) + sizeof(int32_t)];
@ -316,11 +346,11 @@ struct LP_address
UT_hash_handle hh;
struct LP_address_utxo *utxos;
bits256 pubkey;
int64_t balance,total;
int64_t balance,total,instantdex_credits;
uint32_t timestamp,n,unspenttime;
int32_t unspentheight;
char coinaddr[40];
uint8_t pubsecp[33],pad;
uint8_t pubsecp[33],didinstantdex;
};
struct LP_peerinfo
@ -337,6 +367,7 @@ struct LP_quoteinfo
{
struct basilisk_request R;
bits256 srchash,desthash,txid,txid2,desttxid,feetxid,privkey;
int64_t othercredits;
uint64_t satoshis,txfee,destsatoshis,desttxfee,aliceid;
uint32_t timestamp,quotetime,tradeid;
int32_t vout,vout2,destvout,feevout,pair;
@ -357,11 +388,10 @@ struct basilisk_swap
struct basilisk_swapinfo I;
struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim;
bits256 privkeys[INSTANTDEX_DECKSIZE];
struct basilisk_swapmessage *messages; int32_t nummessages,sentflag;
//struct basilisk_swapmessage *messages; int32_t nummessages,sentflag;
char Bdeposit[64],Bpayment[64];
uint64_t aliceid,otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2];
uint8_t persistent_pubkey33[33],persistent_other33[33],changermd160[20],pad[15],verifybuf[100000];
};
struct LP_pubkey_quote
@ -372,15 +402,30 @@ struct LP_pubkey_quote
uint8_t baseind,relind,numutxos,scale;
};
struct LP_swapstats
{
UT_hash_handle hh;
struct LP_quoteinfo Q;
bits256 bobdeposit,alicepayment,bobpayment,paymentspent,Apaymentspent,depositspent;
int32_t bobdeposit_ht,alicepayment_ht,bobpayment_ht,paymentspent_ht,Apaymentspent_ht,depositspent_ht;
double qprice;
uint64_t aliceid;
int32_t bobneeds_dPoW,aliceneeds_dPoW;
uint32_t ind,methodind,finished,expired,lasttime,dPoWfinished;
char alicegui[32],bobgui[32];
};
struct LP_pubswap { struct LP_pubswap *next,*prev; struct LP_swapstats *swap; };
#define LP_MAXPRICEINFOS 256
struct LP_pubkeyinfo
struct LP_pubkey_info
{
UT_hash_handle hh;
bits256 pubkey;
struct LP_pubkey_quote *quotes;
//float matrix[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS];
//uint32_t timestamps[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS];
uint32_t timestamp,numerrors,lasttime;
struct LP_pubswap *bobswaps,*aliceswaps;
int64_t dynamictrust,unconfcredits;
uint32_t timestamp,numerrors,lasttime,slowresponse;
int32_t istrusted;
uint8_t rmd160[20],sig[65],pubsecp[33],siglen;
};
@ -398,7 +443,20 @@ struct electrum_info
uint8_t buf[];
};
int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item);
struct LP_trade
{
struct LP_trade *next,*prev;
UT_hash_handle hh;
uint64_t aliceid;
int64_t besttrust,bestunconfcredits;
double bestprice;
uint32_t negotiationdone,bestresponse,connectsent,firsttime,lasttime,firstprocessed,lastprocessed,newtime;
char pairstr[64],funcid,iambob;
struct LP_quoteinfo Qs[4],Q;
};
uint32_t LP_sighash(char *symbol,int32_t zcash);
int32_t LP_pubkey_sigcheck(struct LP_pubkey_info *pubp,cJSON *item);
int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp);
int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson);
struct LP_address *LP_address(struct iguana_info *coin,char *coinaddr);
@ -406,38 +464,41 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u
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);
struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp,int32_t dynamictrust);
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);
//double LP_query(char *method,struct LP_quoteinfo *qp,char *base,char *rel,bits256 mypub);
int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys);
void LP_quotesinit(char *base,char *rel);
int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,bits256 pubkey,char *jsonstr,int32_t freeflag);
int32_t LP_ismine(struct LP_utxoinfo *utxo);
int32_t LP_isavailable(struct LP_utxoinfo *utxo);
struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port);
uint64_t LP_value_extract(cJSON *obj,int32_t addinterest);
int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen);
int64_t LP_kmdvalue(char *symbol,int64_t satoshis);
int64_t LP_komodo_interest(bits256 txid,int64_t value);
void LP_availableset(bits256 txid,int32_t vout);
int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol,bits256 txid,int32_t vout,uint64_t satoshis,bits256 txid2,int32_t vout2);
int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock);
int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item);
void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag);
uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired);
//void LP_utxo_clientpublish(struct LP_utxoinfo *utxo);
int32_t LP_coinbus(uint16_t coin_busport);
int32_t LP_nanomsg_recvs(void *ctx);
int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool);
void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid,uint32_t quoteid);
void LP_autoprices_update(char *method,char *base,double basevol,char *rel,double relvol);
cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len);
cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len);
uint64_t LP_RTsmartbalance(struct iguana_info *coin);
int32_t LP_getheight(struct iguana_info *coin);
int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin);
int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,char *msg);
struct iguana_info *LP_coinfind(char *symbol);
int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32);
char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price);
int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height);
cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid);
cJSON *LP_myzdebits();
int32_t _LP_utxos_remove(bits256 txid,int32_t vout);
int32_t LP_utxos_remove(bits256 txid,int32_t vout);
struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins);
@ -449,9 +510,13 @@ struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr);
int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson,int32_t zcash);
//void LP_butxo_swapfields_set(struct LP_utxoinfo *butxo);
struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout);
int64_t LP_myzcredits();
void test_validate(struct iguana_info *coin,char *signedtx);
void LP_instantdex_depositadd(char *coinaddr,bits256 txid);
int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid,char *refaddr);
int32_t LP_destaddr(char *destaddr,cJSON *item);
int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration);
char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey);
cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel);
uint32_t LP_heighttime(char *symbol,int32_t height);
uint64_t LP_unspents_load(char *symbol,char *addr);
int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
@ -460,8 +525,9 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS
int32_t LP_mempoolscan(char *symbol,bits256 searchtxid);
int32_t LP_txheight(struct iguana_info *coin,bits256 txid);
int32_t LP_numpeers();
char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid);
uint64_t LP_KMDvalue(struct iguana_info *coin,uint64_t balance);
double LP_CMCbtcprice(double *price_usdp,char *symbol);
char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid,int32_t forceflag);
int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance);
int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight);
void LP_smartutxos_push(struct iguana_info *coin);
void LP_cacheptrs_init(struct iguana_info *coin);
@ -470,15 +536,22 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
void LP_postutxos(char *symbol,char *coinaddr);
int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag);
uint16_t LP_randpeer(char *destip);
void LP_tradebot_pauseall();
void LP_portfolio_reset();
uint32_t LP_atomic_locktime(char *base,char *rel);
struct LP_pubkey_info *LP_pubkeyfind(bits256 pubkey);
char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired);
char *LP_unspents_filestr(char *symbol,char *addr);
cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash);
cJSON *bitcoin_data2json(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash);
//int32_t LP_butxo_findeither(bits256 txid,int32_t vout);
cJSON *LP_listunspent(char *symbol,char *coinaddr);
cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxid2);
int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid);
double LP_getestimatedrate(struct iguana_info *coin);
struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout);
struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid,int32_t vout);
int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue);
struct LP_address *LP_addressfind(struct iguana_info *coin,char *coinaddr);
int64_t LP_outpoint_amount(char *symbol,bits256 txid,int32_t vout);
void LP_listunspent_query(char *symbol,char *coinaddr);
int32_t bitcoin_priv2wif(uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype);

650
iguana/exchanges/LP_instantdex.c

@ -0,0 +1,650 @@
/******************************************************************************
* 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_instantdex.c
// marketmaker
//
void LP_instantdex_txidaddfname(char *fname,char *afname,char *coinaddr)
{
if ( coinaddr == 0 || coinaddr[0] == 0 )
{
sprintf(fname,"%s/instantdex.json",GLOBAL_DBDIR);
sprintf(afname,"%s/instantdex_append.json",GLOBAL_DBDIR);
}
else
{
sprintf(fname,"%s/instantdex_%s.json",GLOBAL_DBDIR,coinaddr);
sprintf(afname,"%s/instantdex_%s_append.json",GLOBAL_DBDIR,coinaddr);
}
}
cJSON *LP_instantdex_txids(int32_t appendonly,char *coinaddr)
{
char *filestr,fname[1024],afname[1024]; long fsize; cJSON *retjson=0;
LP_instantdex_txidaddfname(fname,afname,coinaddr);
if ( (filestr= OS_filestr(&fsize,appendonly != 0 ? afname : fname)) != 0 )
{
retjson = cJSON_Parse(filestr);
free(filestr);
} else printf("couldnt open (%s) or (%s)\n",fname,afname);
return(retjson);
}
void LP_instantdex_filewrite(int32_t appendfile,cJSON *array,char *coinaddr)
{
FILE *fp; char *filestr,fname[1024],afname[1024];
LP_instantdex_txidaddfname(fname,afname,coinaddr);
if ( (fp= fopen(appendfile == 0 ? fname : afname,"wb")) != 0 )
{
filestr = jprint(array,0);
fwrite(filestr,1,strlen(filestr)+1,fp);
fclose(fp);
free(filestr);
}
}
void LP_instantdex_deposituniq(FILE *fp,bits256 txid)
{
int32_t i,n; bits256 prevtxid; char str[65];
n = (int32_t)(ftell(fp) / sizeof(txid));
for (i=0; i<n; i++)
{
fseek(fp,sizeof(prevtxid) * i,SEEK_SET);
fread(&prevtxid,1,sizeof(prevtxid),fp);
if ( bits256_cmp(prevtxid,txid) == 0 )
{
//printf("%s duplicate of deposits[%d]\n",bits256_str(str,prevtxid),i);
break;
}
}
if ( i == n )
{
fwrite(&txid,1,sizeof(txid),fp);
printf("uniq %s, ftell.%ld\n",bits256_str(str,txid),ftell(fp));
} else fseek(fp,n * sizeof(txid),SEEK_SET);
}
void LP_instantdex_filescreate(char *coinaddr)
{
char fname[512]; FILE *fp; bits256 txid; int32_t i,n; cJSON *array,*newarray,*txobj;
sprintf(fname,"%s/deposits.%s",GLOBAL_DBDIR,coinaddr), OS_compatible_path(fname);
if ( (fp= fopen(fname,"rb")) != 0 )
{
array = cJSON_CreateArray();
newarray = cJSON_CreateArray();
fseek(fp,0,SEEK_END);
n = (int32_t)(ftell(fp) / sizeof(txid));
for (i=0; i<n; i++)
{
fseek(fp,sizeof(txid) * i,SEEK_SET);
fread(&txid,1,sizeof(txid),fp);
jaddibits256(array,txid);
if ( (txobj= LP_gettxout("KMD",coinaddr,txid,0)) != 0 )
free_json(txobj);
else
{
char str[65]; printf("%s/v%d is already spent\n",bits256_str(str,txid),0);
continue;
}
jaddibits256(newarray,txid);
}
fclose(fp);
LP_instantdex_filewrite(0,newarray,coinaddr);
free_json(newarray);
LP_instantdex_filewrite(1,array,coinaddr);
free_json(array);
}
}
void LP_instantdex_depositadd(char *coinaddr,bits256 txid)
{
FILE *fp; struct iguana_info *coin; char fname[512],*addr; bits256 prevtxid; cJSON *array; int32_t i,n,iter;
coin = LP_coinfind("KMD");
sprintf(fname,"%s/deposits.%s",GLOBAL_DBDIR,coinaddr), OS_compatible_path(fname);
if ( (fp= fopen(fname,"rb+")) == 0 )
{
if ( (fp= fopen(fname,"wb+")) != 0 )
{
for (iter=0; iter<4; iter++)
{
if ( iter < 2 )
addr = coinaddr;
else addr = "";
if ( coin != 0 && (array= LP_instantdex_txids(iter&1,addr)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
prevtxid = jbits256i(array,i);
//char str[65]; printf("instantdex iter.%d i.%d check %s\n",iter,i,bits256_str(str,prevtxid));
if ( LP_instantdex_creditcalc(coin,0,prevtxid,coinaddr) > 0 )
{
LP_instantdex_deposituniq(fp,prevtxid);
fflush(fp);
}
}
}
free_json(array);
}
}
}
} else fseek(fp,0,SEEK_END);
if ( fp != 0 && bits256_nonz(txid) != 0 )
{
LP_instantdex_deposituniq(fp,txid);
fclose(fp);
}
LP_instantdex_filescreate(coinaddr);
}
int32_t LP_deposit_addr(char *p2shaddr,uint8_t *script,uint8_t taddr,uint8_t p2shtype,uint32_t timestamp,uint8_t *pubsecp33)
{
uint8_t elsepub33[33],p2sh_rmd160[20]; int32_t n;
decode_hex(elsepub33,33,BOTS_BONDPUBKEY33);
n = bitcoin_performancebond(p2sh_rmd160,script,0,timestamp,pubsecp33,elsepub33);
bitcoin_address(p2shaddr,taddr,p2shtype,script,n);
return(n);
}
char *LP_instantdex_deposit(struct iguana_info *coin,int32_t weeks,double amount,int32_t broadcast)
{
char p2shaddr[64],*retstr,*hexstr; uint8_t script[512]; int32_t weeki,scriptlen; cJSON *argjson,*retjson,*array,*item,*obj; uint32_t timestamp; bits256 txid,sendtxid; uint64_t amount64;
if ( strcmp(coin->symbol,"KMD") != 0 )
return(clonestr("{\"error\":\"instantdex deposit must be in KMD\"}"));
if ( amount < 10.0 )
return(clonestr("{\"error\":\"minimum instantdex deposit is 10 KMD\"}"));
if ( weeks <= 0 || weeks > 52 )
return(clonestr("{\"error\":\"weeks must be between 1 and 52\"}"));
if ( weeks > 0 )
{
timestamp = (uint32_t)time(NULL);
timestamp /= LP_WEEKMULT;
timestamp += weeks+2;
timestamp *= LP_WEEKMULT;
weeki = (timestamp - LP_FIRSTWEEKTIME) / LP_WEEKMULT;
if ( weeks >= 10000 )
return(clonestr("{\"error\":\"numweeks must be less than 10000\"}"));
} else timestamp = (uint32_t)time(NULL) + 300, weeki = 0;
scriptlen = LP_deposit_addr(p2shaddr,script,coin->taddr,coin->p2shtype,timestamp,G.LP_pubsecp);
argjson = cJSON_CreateObject();
array = cJSON_CreateArray();
item = cJSON_CreateObject();
jaddnum(item,p2shaddr,amount);
jaddi(array,item);
item = cJSON_CreateObject();
amount64 = (amount * SATOSHIDEN) / 1000;
amount64 = (amount64 / 10000) * 10000 + weeki;
jaddnum(item,BOTS_BONDADDRESS,dstr(amount64));
jaddi(array,item);
item = cJSON_CreateObject();
jaddnum(item,coin->smartaddr,0.0001);
jaddi(array,item);
jadd(argjson,"outputs",array);
//printf("deposit.(%s)\n",jprint(argjson,0));
if ( (retstr= LP_withdraw(coin,argjson)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( jobj(retjson,"result") != 0 )
jdelete(retjson,"result");
jaddstr(retjson,"address",p2shaddr);
jaddnum(retjson,"expiration",timestamp);
jaddnum(retjson,"deposit",amount);
if ( (obj= jobj(retjson,"complete")) != 0 && is_cJSON_True(obj) != 0 && (hexstr= jstr(retjson,"hex")) != 0 )
{
txid = jbits256(retjson,"txid");
if ( broadcast != 0 )
{
if (bits256_nonz(txid) != 0 )
{
sendtxid = LP_broadcast("deposit","KMD",hexstr,txid);
if ( bits256_cmp(sendtxid,txid) != 0 )
{
jaddstr(retjson,"error","broadcast txid mismatch");
jaddbits256(retjson,"broadcast",sendtxid);
free(retstr);
return(jprint(retjson,1));
}
else
{
jaddstr(retjson,"result","success");
jaddbits256(retjson,"broadcast",sendtxid);
LP_instantdex_depositadd(coin->smartaddr,txid);
free(retstr);
return(jprint(retjson,1));
}
}
else
{
jaddstr(retjson,"error","couldnt broadcast since no txid created");
free(retstr);
return(jprint(retjson,1));
}
}
else
{
jaddstr(retjson,"result","success");
free(retstr);
return(jprint(retjson,1));
}
}
else
{
jaddstr(retjson,"error","couldnt create deposit txid");
free(retstr);
return(jprint(retjson,1));
}
free_json(retjson);
}
free(retstr);
}
return(clonestr("{\"error\":\"error with LP_withdraw for instantdex deposit\"}"));
}
int64_t LP_claimtx(void *ctx,struct iguana_info *coin,bits256 *claimtxidp,bits256 utxotxid,int32_t utxovout,uint64_t satoshis,char *vinaddr,uint32_t claimtime,uint8_t *redeemscript,int32_t redeemlen)
{
uint8_t userdata[2]; char *signedtx; bits256 signedtxid,sendtxid; int32_t isbots,userdatalen; int64_t destamount,sum = 0;
if ( strcmp(coin->smartaddr,BOTS_BONDADDRESS) == 0 )
isbots = 1;
else isbots = 0;
userdata[0] = (isbots == 0) ? 0x51 : 0;
userdatalen = 1;
utxovout = 0;
memset(claimtxidp,0,sizeof(*claimtxidp));
char str[65]; printf("LP_claimtx satoshis %.8f %s/v%d\n",dstr(satoshis),bits256_str(str,utxotxid),utxovout);
if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"instantdexclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 )
{
printf("signedtx.(%s)\n",signedtx);
sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid);
if ( bits256_cmp(sendtxid,signedtxid) == 0 )
{
*claimtxidp = sendtxid;
sum += (satoshis - coin->txfee);
}
else printf("error sending %s\n",bits256_str(str,signedtxid));
free(signedtx);
} else printf("error claiming instantdex deposit %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(satoshis));
return(sum);
}
int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info *coin,bits256 utxotxid)
{
uint8_t redeemscript[512]; bits256 claimtxid; cJSON *txjson,*vout0,*vout1,*vout2,*vouts,*item; int32_t numvouts; char str[65],vinaddr[64],destaddr[64],checkaddr[64]; int32_t j,utxovout,flagi = 0,redeemlen,weeki,iter; int64_t weeksatoshis,satoshis; uint32_t expiration,claimtime;
if ( (txjson= LP_gettx(coin->symbol,utxotxid,1)) != 0 )
{
if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts >= 3 )
{
vout0 = jitem(vouts,0);
LP_destaddr(vinaddr,vout0);
satoshis = LP_value_extract(vout0,1);
vout2 = jitem(vouts,2);
LP_destaddr(destaddr,vout2);
if ( strcmp(destaddr,coin->smartaddr) == 0 )
{
vout1 = jitem(vouts,1);
weeksatoshis = LP_value_extract(vout1,0);
weeki = (int32_t)(weeksatoshis % 10000);
for (iter=0; iter<2; iter++)
for (j=-168; j<=168; j++)
{
if ( iter == 1 )
expiration = ((weeki * LP_WEEKMULTBAD + j*3600) + LP_FIRSTWEEKTIME);
else expiration = ((weeki * LP_WEEKMULT + j*3600) + LP_FIRSTWEEKTIME);
redeemlen = LP_deposit_addr(checkaddr,redeemscript,coin->taddr,coin->p2shtype,expiration,G.LP_pubsecp);
if ( strcmp(checkaddr,vinaddr) == 0 )
{
flagi = 1;
claimtime = (uint32_t)time(NULL)-777;
item = cJSON_CreateObject();
jaddbits256(item,"txid",utxotxid);
jaddnum(item,"deposit",dstr(LP_value_extract(vout0,0)));
if ( coin->electrum == 0 )
jaddnum(item,"interest",dstr(satoshis)-dstr(LP_value_extract(vout0,0)));
else jaddnum(item,"interest",dstr(LP_komodo_interest(utxotxid,satoshis)));
if ( claimtime <= expiration )
{
printf("iter.%d j.%d claimtime.%u vs %u, wait %d seconds to %s claim %.8f\n",iter,j,claimtime,expiration,(int32_t)expiration-claimtime,bits256_str(str,utxotxid),dstr(satoshis));
jaddnum(item,"waittime",(int32_t)expiration-claimtime);
jaddi(txids,item);
break;
}
else
{
utxovout = 0;
*sump += LP_claimtx(ctx,coin,&claimtxid,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen);
if ( bits256_nonz(claimtxid) != 0 )
{
jaddbits256(item,"claimtxid",claimtxid);
jaddi(txids,item);
}
}
} //else printf("expiration.%u j.%d checkaddr.(%s) != vinaddr.%s\n",expiration,j,checkaddr,vinaddr);
if ( flagi != 0 )
break;
}
} else printf("vout2 dest.(%s) != %s\n",destaddr,coin->smartaddr);
} else printf("numvouts %d != 3\n",numvouts);
free_json(txjson);
} else printf("cant get transaction flagi.%d\n",flagi);
return(flagi);
}
char *LP_instantdex_claim(struct iguana_info *coin)
{
static void *ctx; static int32_t firsttime = 1;
int32_t i,n; cJSON *array,*txids,*newarray,*retjson; int64_t sum; bits256 utxotxid;
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( strcmp(coin->symbol,"KMD") != 0 )
return(clonestr("{\"error\":\"instantdex deposit must be in KMD\"}"));
sum = 0;
txids = cJSON_CreateArray();
newarray = cJSON_CreateArray();
if ( (array= LP_instantdex_txids(firsttime,coin->smartaddr)) != 0 )
{
printf("claiming from.(%s)\n",jprint(array,0));
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
utxotxid = jbits256i(array,i);
//char str[65]; printf("%s\n",bits256_str(str,utxotxid));
if ( LP_claim_submit(ctx,txids,&sum,coin,utxotxid) == 0 )
jaddibits256(newarray,utxotxid);
}
}
free_json(array);
}
firsttime = 0;
if ( cJSON_GetArraySize(newarray) > 0 )
LP_instantdex_filewrite(0,newarray,coin->smartaddr);
free_json(newarray);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddnum(retjson,"claimed",dstr(sum));
jadd(retjson,"txids",txids);
return(jprint(retjson,1));
}
int64_t LP_instantdex_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,int32_t weeki,char *p2shaddr,bits256 txid)
{
uint32_t timestamp; struct LP_address *ap; struct iguana_info *coin = LP_coinfind("KMD");
if ( coin != 0 )
{
timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT;
if ( (ap= LP_address(coin,coinaddr)) != 0 && time(NULL) < timestamp-60*3600 )
{
ap->instantdex_credits += satoshis;
ap->didinstantdex = 1;
if ( 0 && dispflag != 0 )
printf("InstantDEX credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->instantdex_credits));
return(satoshis);
} //else printf("null ap.%p or expired %ld\n",ap,time(NULL) - (timestamp-60*3600));
}
return(0);
}
int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid,char *refaddr)
{
cJSON *txjson,*vouts,*txobj,*item; int64_t satoshis=0,amount64; int32_t weeki,numvouts; char destaddr[64],p2shaddr[64];
if ( (txjson= LP_gettx(coin->symbol,txid,0)) != 0 )
{
// vout0 deposit, vout1 botsfee, vout2 smartaddress
if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 && numvouts >= 3 && LP_destaddr(destaddr,jitem(vouts,2)) == 0 )
{
if ( refaddr != 0 && strcmp(refaddr,destaddr) != 0 )
{
printf("LP_instantdex_creditcalc for (%s) but deposit sent for (%s)\n",refaddr,destaddr);
}
else
{
amount64 = LP_value_extract(jitem(vouts,1),0);
weeki = (amount64 % 10000);
item = jitem(vouts,0);
satoshis = LP_value_extract(item,0);
//char str[65]; printf("%s %s funded %.8f weeki.%d (%s)\n",bits256_str(str,txid),destaddr,dstr(satoshis),weeki,jprint(item,0));
if ( LP_destaddr(p2shaddr,item) == 0 )
{
if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) != 0 )
{
free_json(txobj);
LP_instantdex_credit(dispflag,destaddr,satoshis,weeki,p2shaddr,txid);
} //else printf("already spent\n");
} else printf("error getting p2shaddr.(%s)\n",p2shaddr);
}
}
free_json(txjson);
}
return(satoshis);
}
#ifdef bruteforce
void LP_instantdex_deposits(struct iguana_info *coin)
{
static int dispflag = 1;
cJSON *array,*item; int32_t i,n,height,vout; bits256 txid; struct LP_address *ap,*tmp;
if ( coin->electrum != 0 )//&& coin->electruminstantdex != 0 )
return;
HASH_ITER(hh,coin->addresses,ap,tmp)
{
ap->instantdex_credits = 0;
}
if ( (array= LP_listreceivedbyaddress("KMD",BOTS_BONDADDRESS)) != 0 )
{
//printf("instantdex.(%s)\n",jprint(array,0));
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
if ( coin->electrum != 0 )
{
item = jitem(array,i);
LP_listunspent_parseitem(coin,&txid,&vout,&height,item);
} else txid = jbits256i(array,i);
LP_instantdex_creditcalc(coin,dispflag,txid,0);
}
}
free_json(array);
}
dispflag = 0;
}
#endif
int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue)
{
struct LP_pubswap *ptr,*tmp; struct LP_swapstats *sp; struct LP_pubkey_info *pubp; struct LP_address *ap; char coinaddr[64]; struct iguana_info *coin; int64_t swaps_kmdvalue = 0;
if ( (coin= LP_coinfind("KMD")) != 0 && (pubp= LP_pubkeyfind(pubkey)) != 0 )
{
bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pubp->pubsecp,33);
DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp)
{
if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 )
swaps_kmdvalue += LP_kmdvalue(sp->Q.srccoin,sp->Q.satoshis);
}
DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp)
{
if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 )
swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis);
}
if ( credits == 0 && (ap= LP_address(coin,coinaddr)) != 0 )
credits = ap->instantdex_credits;
if ( credits != 0 && (swaps_kmdvalue+kmdvalue) > credits )
{
if ( 0 )
{
DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp)
{
if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 )
printf("unfinished bob %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis)));
}
DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp)
{
if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 )
printf("unfinished alice %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis)));
}
}
printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue));
}
if ( 0 && credits != 0 )
printf("%s %s othercredits %.8f debits %.8f + %.8f -> %.8f\n",coin->symbol,coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue),dstr(credits - (swaps_kmdvalue+kmdvalue)));
return(credits - (swaps_kmdvalue+kmdvalue));
}
return(0);
}
int64_t LP_instantdex_proofcheck(char *coinaddr,cJSON *proof,int32_t num)
{
uint8_t rmd160[20],addrtype; int64_t credits=0; int32_t i,j; bits256 prevtxid,txid; char othersmartaddr[64]; struct iguana_info *coin; struct LP_address *ap = 0;
if ( (coin= LP_coinfind("KMD")) != 0 )
{
bitcoin_addr2rmd160(0,&addrtype,rmd160,coinaddr);
bitcoin_address(othersmartaddr,0,60,rmd160,20);
//printf("proofcheck addrtype.%d (%s) -> %s\n",addrtype,coinaddr,othersmartaddr);
if ((ap= LP_address(coin,othersmartaddr)) != 0 )
{
ap->instantdex_credits = 0;
for (i=0; i<num; i++)
{
txid = jbits256i(proof,i);
for (j=0; j<i; j++)
{
prevtxid = jbits256i(proof,j);
if ( bits256_cmp(prevtxid,txid) == 0 )
break;
}
if ( j == i )
LP_instantdex_creditcalc(coin,1,txid,othersmartaddr);
}
credits = ap->instantdex_credits;
ap->didinstantdex = 1;
if ( 0 && ap->instantdex_credits > 0 )
printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits));
} //else printf("cant find ap.%p or already did %d %.8f\n",ap,ap!=0?ap->didinstantdex:-1,ap!=0?dstr(ap->instantdex_credits):-1);
}
return(credits);
}
int64_t LP_myzcredits()
{
cJSON *proof; struct iguana_info *coin; int64_t zcredits;
if ( (coin= LP_coinfind("KMD")) != 0 )
{
if ( (proof= LP_instantdex_txids(0,coin->smartaddr)) != 0 )
{
zcredits = LP_instantdex_proofcheck(coin->smartaddr,proof,cJSON_GetArraySize(proof));
free_json(proof);
return(zcredits);
}
}
return(0);
}
cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob)
{
struct iguana_info *bob,*alice; int32_t flag = 0; char *retstr,*swapstr; bits256 zero; cJSON *item,*reqjson,*swapjson;
item = cJSON_CreateObject();
jaddnum(item,"iambob",iambob);
jaddnum(item,"aliceid",sp->aliceid);
jaddnum(item,"requestid",sp->Q.R.requestid);
jaddnum(item,"quoteid",sp->Q.R.quoteid);
jaddstr(item,"base",sp->Q.srccoin);
jaddnum(item,"satoshis",sp->Q.satoshis);
jaddstr(item,"rel",sp->Q.destcoin);
jaddnum(item,"destsatoshis",sp->Q.destsatoshis);
jaddnum(item,"price",sp->Q.destsatoshis/((double)sp->Q.satoshis+1));
if ( LP_swap_finished(sp,1) == 0 )
{
jaddnum(item,"finished",sp->finished);
if ( sp->bobneeds_dPoW != 0 && (bob= LP_coinfind(sp->Q.srccoin)) != 0 )
{
jaddnum(item,"bobneeds_dPoW",sp->bobneeds_dPoW);
jaddnum(item,"bob_dPoWheight",bob->notarized);
if ( sp->bobneeds_dPoW == 1 )
flag = 1;
if ( bob->notarized == 0 )
LP_dPoW_request(bob);
}
if ( sp->aliceneeds_dPoW != 0 && (alice= LP_coinfind(sp->Q.destcoin)) != 0 )
{
jaddnum(item,"aliceneeds_dPoW",sp->aliceneeds_dPoW);
jaddnum(item,"alice_dPoWheight",alice->notarized);
if ( sp->aliceneeds_dPoW == 1 )
flag = 1;
if ( alice->notarized == 0 )
LP_dPoW_request(alice);
}
if ( flag != 0 )
{
reqjson = cJSON_CreateObject();
jaddstr(reqjson,"method","gettradestatus");
jadd64bits(reqjson,"aliceid",sp->aliceid);
memset(zero.bytes,0,sizeof(zero));
LP_reserved_msg(0,"","",zero,jprint(reqjson,1));
if ( (swapstr= basilisk_swapentry(sp->Q.R.requestid,sp->Q.R.quoteid,0)) != 0 )
{
if ( (swapjson= cJSON_Parse(swapstr)) != 0 )
{
if ( (retstr= LP_swapstatus_recv(swapjson)) != 0 )
free(retstr);
free_json(swapjson);
}
free(swapstr);
}
}
}
return(item);
}
cJSON *LP_myzdebits()
{
struct LP_pubswap *ptr,*tmp; struct LP_pubkey_info *pubp; struct LP_swapstats *sp; int64_t kmdvalue,swaps_kmdvalue = 0; struct iguana_info *coin; cJSON *retjson,*array,*item;
array = cJSON_CreateArray();
if ( (coin= LP_coinfind("KMD")) != 0 )
{
if ( (pubp= LP_pubkeyfind(G.LP_mypub25519)) != 0 )
{
DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp)
{
if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 )
{
kmdvalue = LP_kmdvalue(sp->Q.srccoin,sp->Q.satoshis);
item = LP_swapstats_item(sp,1);
jaddnum(item,"kmdvalue",dstr(kmdvalue));
jaddi(array,item);
swaps_kmdvalue += kmdvalue;
}
}
DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp)
{
if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 )
{
kmdvalue = LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis);
item = LP_swapstats_item(sp,0);
jaddnum(item,"kmdvalue",dstr(kmdvalue));
jaddi(array,item);
swaps_kmdvalue += kmdvalue;
}
}
}
}
retjson = cJSON_CreateObject();
jadd(retjson,"swaps",array);
jaddnum(retjson,"pendingswaps",dstr(swaps_kmdvalue));
return(retjson);
}

708
iguana/exchanges/LP_mmjson.c

@ -0,0 +1,708 @@
/******************************************************************************
* 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_mmjson.c
// marketmaker
//
#define MMJSON_IPADDR 255
#define MMJSON_BITS256 254
#define MMJSON_SECP33 253
#define MMJSON_SIG 252
#define MMJSON_RMD160 251
#define MMJSON_DECIMAL8 250
#define MMJSON_DECIMAL8STR 249
#define MMJSON_DECIMAL16 248
#define MMJSON_DECIMAL16STR 247
#define MMJSON_DECIMAL24 246
#define MMJSON_DECIMAL24STR 245
#define MMJSON_DECIMAL32 244
#define MMJSON_DECIMAL32STR 243
#define MMJSON_DECIMAL40 242
#define MMJSON_DECIMAL40STR 241
#define MMJSON_DECIMAL48 240
#define MMJSON_DECIMAL48STR 239
#define MMJSON_DOUBLE 238
#define MMJSON_DECIMAL64 237
#define MMJSON_DECIMAL64STR 236
#define MMJSON_TIMESTAMP 235
#define MMJSON_TIMEDIFF8 234
#define MMJSON_TIMEDIFF16 233
#define MMJSON_ZERO 232
#define MMJSON_ZEROSTR 231
#define MMJSON_COIN 230
#define MMJSON_STRING 229
#define MMJSON_ARRAY8 228
#define MMJSON_ARRAY16 227
#define MMJSON_ARRAY32 226
#define MMJSON_BOUNDARY 98
int32_t MM_numfields;
char *MM_fields[256] =
{
"timestamp", "getdPoW", "dPoW", "aliceid", "src", "base", "basevol", "dest", "rel", "relvol", "price", "requestid", "quoteid", "finished", "expired", "bobdeposit", "alicepayment", "bobpayment", "paymentspent", "Apaymentspent", "depositspent", "ind", "method", "swapstatus", "method2", "gettradestatus", "coin", "rmd160", "pub", "pubsecp", "sig", "session", "notify", "pubkey", "price64", "credits", "utxocoin", "n", "bal", "min", "max", "postprice", "notarized", "notarizedhash", "notarizationtxid", "wantnotify", "isLP", "gui", "nogui", "tradeid", "address", "txid", "vout", "srchash", "txfee", "quotetime", "satoshis", "desthash", "txid2", "vout2", "destaddr", "desttxid", "destvout", "feetxid", "feevout", "desttxfee", "destsatoshis", "pending", "reserved", "broadcast", "ismine", "simplegui", "request", "proof", "connect", "expiration", "iambob", "Bgui", "", "Agui", "bob", "srcamount", "bobtxfee", "alice", "destamount", "alicetxfee", "sentflags", "values", "result", "success", "status", "finishtime", "tradestatus", "pair", "connected", "warning", "critical", "endcritical",
};
char *MM_coins[256] =
{
"KMD", "BTC", "CRC", "VOT", "INN", "MOON", "CRW", "EFL", "GBX", "BCO", "BLK", "BTG", "BCH", "ABY", "STAK", "XZC", "QTUM", "PURA", "DSR", "MNZ", "BTCZ", "MAGA", "BSD", "IOP", "BLOCK", "CHIPS", "888", "ARG", "GLT", "ZER", "HODLC", "UIS", "HUC", "PIVX", "BDL", "ARC", "ZCL", "VIA", "ERC", "FAIR", "FLO", "SXC", "CREA", "TRC", "BTA", "SMC", "NMC", "NAV", "EMC2", "SYS", "I0C", "DASH", "STRAT", "MUE", "MONA", "XMY", "MAC", "BTX", "XRE", "LBC", "SIB", "VTC", "REVS", "JUMBLR", "DOGE", "HUSH", "ZEC", "DGB", "ZET", "GAME", "LTC", "SUPERNET", "WLC", "PANGEA", "DEX", "BET", "CRYPTO", "HODL", "MSHARK", "BOTS", "MGW", "COQUI", "KV", "CEAL", "MESH",
};
int32_t mmjson_coinfind(char *symbol)
{
int32_t i;
for (i=0; i<sizeof(MM_coins)/sizeof(*MM_coins); i++)
{
if ( MM_coins[i] == 0 )
return(-1);
if ( strcmp(MM_coins[i],symbol) == 0 )
return(i);
}
return(-1);
};
int32_t mmadd(char *field)
{
MM_fields[MM_numfields] = calloc(1,strlen(field)+1);
strcpy(MM_fields[MM_numfields],field);
return(MM_numfields++);
}
int32_t mmfind(char *field)
{
int32_t i;
if ( MM_numfields == 0 )
{
for (i=0; i<sizeof(MM_fields)/sizeof(*MM_fields); i++)
if ( MM_fields[i] == 0 )
break;
MM_numfields = i;
}
for (i=0; i<MM_numfields; i++)
{
if ( strcmp(MM_fields[i],field) == 0 )
return(i);
}
return(-1);
}
int32_t MMJSON_rwnum(int32_t rwflag,uint8_t *buf,uint64_t *longp,int32_t n)
{
int32_t i; uint64_t l = 0;
if ( rwflag != 0 )
{
l = *longp;
for (i=0; i<n; i++)
{
buf[i] = (uint8_t)l;
l >>= 8;
}
}
else
{
for (i=n-1; i>=0; i--)
{
l <<= 8;
l |= buf[i];
}
*longp = l;
}
return(n);
}
int32_t MMJSON_decodeitem(cJSON *lineobj,uint8_t *linebuf,int32_t i,int32_t len,char *fieldstr,uint32_t *timestampp)
{
int32_t c,valind,j; char tmpstr[64],ipaddr[64],hexstr[256],arbstr[8192]; uint64_t l;
switch ( (valind= linebuf[i++]) )
{
case MMJSON_IPADDR:
i += MMJSON_rwnum(0,&linebuf[i],&l,4);
expand_ipbits(ipaddr,(uint32_t)l);
jaddstr(lineobj,fieldstr,ipaddr);
break;
case MMJSON_BITS256:
init_hexbytes_noT(hexstr,&linebuf[i],32);
i += 32;
jaddstr(lineobj,fieldstr,hexstr);
break;
case MMJSON_SECP33:
init_hexbytes_noT(hexstr,&linebuf[i],33);
i += 33;
jaddstr(lineobj,fieldstr,hexstr);
break;
case MMJSON_SIG:
init_hexbytes_noT(hexstr,&linebuf[i],65);
i += 65;
jaddstr(lineobj,fieldstr,hexstr);
break;
case MMJSON_RMD160:
init_hexbytes_noT(hexstr,&linebuf[i],20);
i += 20;
jaddstr(lineobj,fieldstr,hexstr);
break;
case MMJSON_DECIMAL8:
l = linebuf[i++];
jaddnum(lineobj,fieldstr,l);
break;
case MMJSON_DECIMAL8STR:
l = linebuf[i++];
jadd64bits(lineobj,fieldstr,l);
break;
case MMJSON_DECIMAL16:
i += MMJSON_rwnum(0,&linebuf[i],&l,2);
jaddnum(lineobj,fieldstr,l);
break;
case MMJSON_DECIMAL16STR:
i += MMJSON_rwnum(0,&linebuf[i],&l,2);
jadd64bits(lineobj,fieldstr,l);
break;
case MMJSON_DECIMAL24:
i += MMJSON_rwnum(0,&linebuf[i],&l,3);
jaddnum(lineobj,fieldstr,l);
break;
case MMJSON_DECIMAL24STR:
i += MMJSON_rwnum(0,&linebuf[i],&l,3);
sprintf(tmpstr,"%llu",(long long)l);
jaddstr(lineobj,fieldstr,tmpstr);
break;
case MMJSON_DECIMAL32:
i += MMJSON_rwnum(0,&linebuf[i],&l,4);
//printf("decimal32.%u %08x\n",(uint32_t)l,(uint32_t)l);
jaddnum(lineobj,fieldstr,l);
break;
case MMJSON_DECIMAL32STR:
i += MMJSON_rwnum(0,&linebuf[i],&l,4);
//printf("decimal32.%u %08x\n",(uint32_t)l,(uint32_t)l);
jadd64bits(lineobj,fieldstr,l);
break;
case MMJSON_DECIMAL40:
i += MMJSON_rwnum(0,&linebuf[i],&l,5);
jaddnum(lineobj,fieldstr,l);
break;
case MMJSON_DECIMAL40STR:
i += MMJSON_rwnum(0,&linebuf[i],&l,5);
jadd64bits(lineobj,fieldstr,l);
break;
case MMJSON_DECIMAL48:
i += MMJSON_rwnum(0,&linebuf[i],&l,6);
jaddnum(lineobj,fieldstr,l);
break;
case MMJSON_DECIMAL48STR:
i += MMJSON_rwnum(0,&linebuf[i],&l,6);
jadd64bits(lineobj,fieldstr,l);
break;
case MMJSON_DOUBLE:
i += MMJSON_rwnum(0,&linebuf[i],&l,8);
//printf("double %llu -> %.8f\n",(long long)l,dstr(l));
jaddnum(lineobj,fieldstr,dstr(l));
break;
case MMJSON_DECIMAL64:
i += MMJSON_rwnum(0,&linebuf[i],&l,8);
jadd64bits(lineobj,fieldstr,l);
break;
case MMJSON_DECIMAL64STR:
i += MMJSON_rwnum(0,&linebuf[i],&l,8);
jadd64bits(lineobj,fieldstr,l);
break;
case MMJSON_TIMESTAMP:
if ( *timestampp == 0 )
{
i += MMJSON_rwnum(0,&linebuf[i],&l,4);
*timestampp = (uint32_t)l;
jaddnum(lineobj,fieldstr,l);
}
else
{
printf("timestamp %u already exists\n",*timestampp);
free_json(lineobj);
return(-1);
}
break;
case MMJSON_TIMEDIFF8:
jaddnum(lineobj,fieldstr,*timestampp + linebuf[i++]);
break;
case MMJSON_TIMEDIFF16:
i += MMJSON_rwnum(0,&linebuf[i],&l,2);
jaddnum(lineobj,fieldstr,*timestampp + l);
break;
case MMJSON_ZERO:
jaddnum(lineobj,fieldstr,0);
break;
case MMJSON_ZEROSTR:
//printf("%s.zerostr\n",fieldstr);
jadd64bits(lineobj,fieldstr,0);
break;
case MMJSON_COIN:
jaddstr(lineobj,fieldstr,MM_coins[linebuf[i++]]);
break;
case MMJSON_STRING:
j = 0;
while ( (c= linebuf[i++]) != 0 )
{
if ( i > len )
{
printf("string overflow i.%d vs len.%d\n",i,len);
free_json(lineobj);
return(-1);
}
arbstr[j++] = c;
}
arbstr[j] = 0;
jaddstr(lineobj,fieldstr,arbstr);
break;
default:
if ( valind < MMJSON_BOUNDARY )
jaddstr(lineobj,fieldstr,MM_fields[valind]);
else
{
printf("%s unhandled valind.%d k.%d len.%d (%s)\n",fieldstr,valind,i,len,jprint(lineobj,0));
free_json(lineobj);
return(-1);
}
break;
}
return(i);
}
char *MMJSON_decode(uint8_t *linebuf,int32_t len)
{
uint32_t timestamp = 0; char *fieldstr; uint64_t l; int32_t ind,i=0,j,m=-1; cJSON *obj,*item,*array,*lineobj = cJSON_CreateObject();
while ( i+1 < len )
{
//printf("ind.%d i.%d vs len.%d\n",linebuf[i],i,len);
if ( (ind= linebuf[i++]) >= MMJSON_BOUNDARY )
{
if ( ind != MMJSON_STRING )
{
printf("illegal field ind.%d (%s)\n",ind,jprint(lineobj,0));
free_json(lineobj);
return(0);
}
else
{
fieldstr = (char *)&linebuf[i++];
while ( linebuf[i] != 0 )
i++;
i++;
}
} else fieldstr = MM_fields[ind];
if ( linebuf[i] == MMJSON_ARRAY8 )
{
i++;
m = linebuf[i++];
}
else if ( linebuf[i] == MMJSON_ARRAY16 )
{
i++;
i += MMJSON_rwnum(0,&linebuf[i],&l,2);
m = (int32_t)l;
}
else if ( linebuf[i] == MMJSON_ARRAY32 )
{
i++;
i += MMJSON_rwnum(0,&linebuf[i],&l,4);
m = (int32_t)l;
} else m = -1;
if ( m >= 0 )
{
//printf("%s i.%d m.%d\n",fieldstr,i,m);
array = cJSON_CreateArray();
for (j=0; j<m; j++)
{
item = cJSON_CreateObject();
if ( (i= MMJSON_decodeitem(item,linebuf,i,len,fieldstr,&timestamp)) < 0 )
{
printf("error decoding item ind.%s (%s)\n",fieldstr,jprint(lineobj,0));
free_json(array);
free_json(lineobj);
return(0);
}
obj = jobj(item,fieldstr);
jaddi(array,jduplicate(obj));
free_json(item);
}
jadd(lineobj,fieldstr,array);
}
else if ( (i= MMJSON_decodeitem(lineobj,linebuf,i,len,fieldstr,&timestamp)) < 0 )
{
printf("error decoding item ind.%s (%s)\n",fieldstr,jprint(lineobj,0));
free_json(lineobj);
return(0);
}
//printf("i.%d/%d ind.%d %s valind.%d\n",i,len,ind,MM_fields[ind],linebuf[i]);
}
return(jprint(lineobj,1));
}
int32_t MMJSON_encodeval(uint8_t *linebuf,int32_t k,int32_t ind,char *v,uint32_t *timestampp,cJSON *ptr,char *fieldstr)
{
double val; char checkstr[512]; uint64_t l; int32_t valind,len,isstr=0,coinind,j,dots,diff;
if ( ind >= 0 )
{
fieldstr = MM_fields[ind];
if ( strcmp("utxocoin",fieldstr) == 0 || strcmp("alice",fieldstr) == 0 || strcmp("bob",fieldstr) == 0 || strcmp("base",fieldstr) == 0 || strcmp("rel",fieldstr) == 0 || strcmp("coin",fieldstr) == 0 || strcmp("txfee",fieldstr) == 0 || strcmp("desttxfee",fieldstr) == 0 || strcmp("price64",fieldstr) == 0 || strcmp("satoshis",fieldstr) == 0 || strcmp("destsatoshis",fieldstr) == 0 )
isstr = 1;
else isstr = 0;
}
//printf("%s.(%s) k.%d\n",fieldstr,v,k);
if ( (valind= mmfind(v)) >= 0 )
{
linebuf[k++] = valind;
return(k);
}
else if ( strcmp("0",v) == 0 )
{
if ( isstr != 0 )
linebuf[k++] = MMJSON_ZEROSTR;
else linebuf[k++] = MMJSON_ZERO;
return(k);
}
for (j=dots=0; v[j]!=0; j++)
{
if ( (v[j] < '0' || v[j] > '9') && v[j] != '.' )
break;
else if ( v[j] == '.' )
dots++;
}
if ( dots == 3 && v[j] == 0 && strlen(v) < 17 && is_ipaddr(v) != 0 )
{
//printf("<ipaddr> ");
linebuf[k++] = MMJSON_IPADDR;
l = calc_ipbits(v);
k += MMJSON_rwnum(1,&linebuf[k],&l,4);
}
else if ( dots == 1 && v[j] == 0 )
{
if ( (val= atof(v)) > SMALLVAL )
{
l = SATOSHIDEN * (val + 0.000000005);
sprintf(checkstr,"%.8f",dstr(l));
if ( strcmp(checkstr,v) == 0 )
{
//printf("<double> ");
linebuf[k++] = MMJSON_DOUBLE;
k += MMJSON_rwnum(1,&linebuf[k],&l,8);
} else printf("ERR.<%s %s> ",v,checkstr);
}
}
else if ( (len= is_hexstr(v,0)) == 64 )
{
//printf("<bits256> ");
linebuf[k++] = MMJSON_BITS256;
decode_hex(&linebuf[k],32,v), k += 32;
}
else if ( len == 66 )
{
//printf("<secp33> ");
linebuf[k++] = MMJSON_SECP33;
decode_hex(&linebuf[k],33,v), k += 33;
}
else if ( len == 65*2 )
{
//printf("<sig> ");
linebuf[k++] = MMJSON_SIG;
decode_hex(&linebuf[k],65,v), k += 65;
}
else if ( len == 40 )
{
//printf("<rmd160> ");
linebuf[k++] = MMJSON_RMD160;
decode_hex(&linebuf[k],20,v), k += 20;
}
else if ( len > 40 )
{
printf("ERR.<hex.%d> ",len/2);
}
else if ( is_decimalstr(v) != 0 && (l= calc_nxt64bits(v)) > 0 )
{
if ( l < 0x100 )
{
//printf("<decimal8> ");
if ( l == 0 )
{
linebuf[k++] = isstr != 0 ? MMJSON_ZEROSTR : MMJSON_ZERO;
}
else
{
linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL8STR : MMJSON_DECIMAL8;
linebuf[k++] = (uint8_t)l;
}
}
else if ( l < 0x10000 )
{
//printf("<decimal16> ");
linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL16STR : MMJSON_DECIMAL16;
k += MMJSON_rwnum(1,&linebuf[k],&l,2);
}
else if ( l < 0x1000000 )
{
linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL24STR : MMJSON_DECIMAL24;
//printf("decimal24 %llu %s (%s) %d\n",(long long)l,v,fieldstr,linebuf[k-1]);
k += MMJSON_rwnum(1,&linebuf[k],&l,3);
}
else if ( l < 0x100000000LL )
{
if ( v[0] != '"' && *timestampp == 0 && strcmp(fieldstr,"timestamp") == 0 )
{
*timestampp = (uint32_t)atol(v);
//printf("<timestamp> ");
linebuf[k++] = MMJSON_TIMESTAMP;
l = *timestampp;
k += MMJSON_rwnum(1,&linebuf[k],&l,4);
}
else if ( v[0] != '"' && *timestampp != 0 && (diff= ((uint32_t)atol(v)-*timestampp)) < 0x100 && diff >= 0 )
{
//printf("<timediff.8> ");
linebuf[k++] = MMJSON_TIMEDIFF8;
linebuf[k++] = (uint8_t)diff;
}
else if ( v[0] != '"' && *timestampp != 0 && (diff= ((uint32_t)atol(v)-*timestampp)) < 0x10000 && diff >= 0 )
{
//printf("<timediff.16> ");
linebuf[k++] = MMJSON_TIMEDIFF16;
l = diff;
k += MMJSON_rwnum(1,&linebuf[k],&l,2);
}
else
{
//printf("<decimal32>.%u %08x\n",(uint32_t)l,(uint32_t)l);
linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL32STR : MMJSON_DECIMAL32;
k += MMJSON_rwnum(1,&linebuf[k],&l,4);
}
}
else if ( l < 0x10000000000LL )
{
//printf("<decimal40> ");
linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL40STR : MMJSON_DECIMAL40;
k += MMJSON_rwnum(1,&linebuf[k],&l,5);
}
else if ( l < 0x1000000000000LL )
{
//printf("<decimal48> ");
linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL48STR : MMJSON_DECIMAL48;
k += MMJSON_rwnum(1,&linebuf[k],&l,6);
}
//else if ( l < 0x100000000000000LL )
// printf("<decimal56> ");
else
{
//printf("<decimal64> ");
linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL64STR : MMJSON_DECIMAL64;
k += MMJSON_rwnum(1,&linebuf[k],&l,8);
}
}
else
{
if ( (ind= mmfind(v)) >= 0 )
linebuf[k++] = ind;
else
{
for (j=0; v[j]!=0; j++)
{
if ( v[j] >= 'a' && v[j] <= 'z' )
continue;
else break;
}
if ( v[j] == 0 )
{
printf("unexpected missing string value.(%s)\n",v);
//ind = mmadd(v);
//printf("%s.<%s>.%d ",s,v,ind);
//linebuf[k++] = ind;
linebuf[k++] = MMJSON_STRING;
memcpy(&linebuf[k],v,strlen(v)+1);
k += (int32_t)strlen(v) + 1;
}
else
{
for (j=0; v[j]!=0; j++)
{
if ( v[j] >= 'A' && v[j] <= 'Z' )
continue;
else break;
}
if ( v[j] == 0 && (coinind= mmjson_coinfind(v)) >= 0 )
{
//printf("<coin> ");
linebuf[k++] = MMJSON_COIN;
linebuf[k++] = coinind;
}
/*else if ( strlen(v) == 34 )
{
printf("<coinaddr> ");
k += 22;
}*/
else
{
linebuf[k++] = MMJSON_STRING;
if ( v[0] == '"' )
{
v++;
v[strlen(v)-1] = 0;
}
//printf("str.<%s> ",v);
memcpy(&linebuf[k],v,strlen(v)+1);
k += (int32_t)strlen(v) + 1;
}
}
}
}
return(k);
}
int32_t MMJSON_encode(uint8_t *linebuf,char *line)
{
uint32_t timestamp; uint64_t l; char *decodestr,*s,*v=0; cJSON *lineobj,*array,*ptr; int32_t k=0,m,i,asize,ind,z,allocv_flag;
timestamp = 0;
if ( (lineobj= cJSON_Parse(line)) != 0 )
{
if ( line[strlen(line)-1] == '\n' )
line[strlen(line)-1] = 0;
//printf("%s\n",jprint(lineobj,0));
if ( (m= cJSON_GetArraySize(lineobj)) > 0 )
{
ptr = lineobj->child;
for (i=0; i<m; i++,ptr=ptr->next)
{
allocv_flag = 0;
s = jfieldname(ptr);
if ( (ind= mmfind(s)) < 0 )
{
printf("missing field.(%s) add to MM_fields[]\n",s);
linebuf[k++] = MMJSON_STRING;
memcpy(&linebuf[k],s,strlen(s)+1);
k += (int32_t)strlen(s) + 1;
//ind = mmadd(s);
} else linebuf[k++] = ind;
//printf("%s ",s);
if ( (array= jobj(lineobj,s)) != 0 && is_cJSON_Array(array) != 0 )
{
asize = cJSON_GetArraySize(array);
if ( asize < 0x100 )
{
linebuf[k++] = MMJSON_ARRAY8;
linebuf[k++] = asize;
}
else if ( asize < 0x10000 )
{
linebuf[k++] = MMJSON_ARRAY16;
l = asize;
k += MMJSON_rwnum(1,&linebuf[k],&l,2);
}
else
{
linebuf[k++] = MMJSON_ARRAY32;
l = asize;
k += MMJSON_rwnum(1,&linebuf[k],&l,4);
}
for (z=0; z<asize; z++)
{
if ( (v= jprint(jitem(array,z),0)) != 0 )
{
//printf("%d.(%s k.%d).%d ",z,v,k,asize);
k = MMJSON_encodeval(linebuf,k,ind,v,&timestamp,ptr,s);
free(v);
} else printf("ERROR.(%s) ",jprint(jitem(array,z),0));
}
//printf("%s array.%d k.%d\n",fieldstr,asize,k);
continue;
}
else if ( (v= jstr(lineobj,s)) == 0 )
{
v = jprint(jobj(lineobj,s),0);
//printf("allocate v.%p\n",v);
allocv_flag = 1;
}
if ( v != 0 )
{
//printf("%s\n",v);
k = MMJSON_encodeval(linebuf,k,ind,v,&timestamp,ptr,s);
}
else printf("ERROR.(%s) ",jprint(jobj(lineobj,s),0));
if ( allocv_flag != 0 && v != 0 )
{
//printf("free allocated v\n");
free(v);
}
//printf("m.%d values\n",m);
}
}
free_json(lineobj);
if ( (decodestr= MMJSON_decode(linebuf,k)) == 0 || strcmp(decodestr,line) != 0 )
{
for (i=0; i<k; i++)
printf("%d ",linebuf[i]);
printf(" k.%d error decoding (%s) -> (%s)\n",k,line,decodestr==0?"":decodestr);
if ( decodestr != 0 )
free(decodestr);
return(-1);
} //else printf("decoded\n");
free(decodestr);
}
return(k);
}
#ifndef FROM_MARKETMAKER
#define packetout "/Users/mac/mmjson/packet.out"
#define packetlog "/Users/mac/mmjson/packet.log"
int main(int argc, const char * argv[])
{
FILE *fp,*outfp; uint8_t linebuf[8192]; char line[8192],str[65]; int32_t i,k,compressed=0,n=0,total = 0;
outfp = fopen(packetout,"wb");
if ( (fp= fopen(packetlog,"rb")) != 0 )
{
while ( fgets(line,sizeof(line),fp) > 0 )
{
n++;
total += strlen(line);
if ( (k= MMJSON_encode(linebuf,line)) > 0 )
{
//printf("\n");
if ( outfp != 0 )
fwrite(linebuf,1,k,outfp);
compressed += k;
}
else
{
compressed += strlen(line);
//printf("error parsing.(%s)\n",line);
}
}
fclose(fp);
if ( outfp != 0 )
{
uint8_t *data,*bits; int32_t numbits; bits256 seed; long fsize = ftell(outfp);
fclose(outfp);
if ( (0) && (outfp= fopen(packetout,"rb")) != 0 )
{
data = calloc(1,fsize);
bits = calloc(1,fsize);
if ( fread(data,1,fsize,outfp) == fsize )
{
memset(seed.bytes,0,sizeof(seed));
decode_hex(seed.bytes,32,"ffffff070000810478800084000800b200101400002001400404844402d29fc4");
numbits = ramcoder_compress(bits,(int32_t)fsize,data,(int32_t)fsize,seed);
fclose(outfp);
printf("numbits.%d %d bytes %.1f seed.%s\n",numbits,numbits/8+1,(double)compressed/(numbits/8),bits256_str(str,seed));
}
}
}
} else printf("cant find packet.log\n");
printf("char *MM_fields[256] = \n{\n");
for (i=0; i<MM_numfields; i++)
printf("\"%s\", ",MM_fields[i]);
printf("\n};\nnumlines.%d size %d compressed.%d %.3f maxind.%d\n",n,total,compressed,(double)total/compressed,MM_numfields);
}
#endif

525
iguana/exchanges/LP_nativeDEX.c

@ -17,14 +17,17 @@
// LP_nativeDEX.c
// marketmaker
//
// BCH signing: FORKID_BCC = 0, FORKID_BTG = 79, // Atomic number AU
// alice waiting for bestprice
// MNZ getcoin strangeness
// improve critical section detection when parallel trades
// reduce mem: dont redundant store pubkey utxo info
// previously, it used to show amount, kmd equiv, perc
// portfolio to set prices from historical
// portfolio value based on ask?
// else claim path
//
// WONTFIX:
// dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections
// bigendian architectures need to use little endian for sighash calcs
// improve critical section detection when parallel trades
// use electrum in case of addr change in swap
// locktime claiming on sporadic assetchains
// there is an issue about waiting for notarization for a swap that never starts (expiration ok)
#include <stdio.h>
@ -35,8 +38,9 @@ struct LP_millistats
double lastmilli,millisum,threshold;
uint32_t count;
char name[64];
} LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloopBTC_stats,LP_coinsloopKMD_stats,LP_pubkeysloop_stats,LP_privkeysloop_stats,LP_swapsloop_stats,LP_gcloop_stats;
} LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloopBTC_stats,LP_coinsloopKMD_stats,LP_pubkeysloop_stats,LP_swapsloop_stats,LP_gcloop_stats,LP_tradesloop_stats;
extern int32_t IAMLP;
char LP_methodstr[64];
void LP_millistats_update(struct LP_millistats *mp)
{
@ -56,7 +60,7 @@ void LP_millistats_update(struct LP_millistats *mp)
mp = &LP_coinsloopBTC_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count);
mp = &LP_coinsloopKMD_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count);
mp = &LP_pubkeysloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count);
mp = &LP_privkeysloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count);
mp = &LP_tradesloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count);
mp = &LP_swapsloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count);
mp = &LP_gcloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count);
}
@ -73,7 +77,7 @@ void LP_millistats_update(struct LP_millistats *mp)
if ( mp->threshold != 0. && elapsed > mp->threshold )
{
//if ( IAMLP == 0 )
printf("%32s elapsed %10.2f millis > threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count);
printf("%32s elapsed %10.2f millis > threshold %10.2f, ave %10.2f millis, count.%u %s\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count,LP_methodstr);
}
mp->lastmilli = millis;
}
@ -81,21 +85,21 @@ void LP_millistats_update(struct LP_millistats *mp)
}
#include "LP_include.h"
portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex;
portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex,LP_tradesmutex;
int32_t LP_canbind;
char *Broadcaststr,*Reserved_msgs[2][1000];
int32_t num_Reserved_msgs[2],max_Reserved_msgs[2];
struct LP_peerinfo *LP_peerinfos,*LP_mypeer;
struct LP_forwardinfo *LP_forwardinfos;
struct iguana_info *LP_coins;
struct LP_pubkeyinfo *LP_pubkeyinfos;
struct LP_pubkey_info *LP_pubkeyinfos;
struct rpcrequest_info *LP_garbage_collector;
struct LP_address_utxo *LP_garbage_collector2;
struct LP_trade *LP_trades,*LP_tradesQ;
//uint32_t LP_deadman_switch;
uint16_t LP_fixed_pairport,LP_publicport;
uint32_t LP_lastnonce,LP_counter,LP_swap_endcritical,LP_swap_critical;
uint32_t LP_lastnonce,LP_swap_endcritical,LP_swap_critical,LP_RTcount,LP_swapscount;
int32_t LP_mybussock = -1;
int32_t LP_mypubsock = -1;
int32_t LP_mypullsock = -1;
@ -106,13 +110,13 @@ struct LP_privkey { bits256 privkey; uint8_t rmd160[20]; };
struct LP_globals
{
struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2];
bits256 LP_mypub25519,LP_privkey,LP_mypriv25519;
//struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2];
bits256 LP_mypub25519,LP_privkey,LP_mypriv25519,LP_passhash;
uint64_t LP_skipstatus[10000];
uint8_t LP_myrmd160[20],LP_pubsecp[33];
uint32_t LP_sessionid,counter;
int32_t LP_IAMLP,LP_pendingswaps,USERPASS_COUNTER,LP_numprivkeys,initializing,waiting,LP_numskips;
char USERPASS[65],USERPASS_WIFSTR[64],LP_myrmd160str[41],gui[16];
char USERPASS[65],USERPASS_WIFSTR[64],LP_myrmd160str[41],gui[16],LP_NXTaddr[64];
struct LP_privkey LP_privkeys[100];
} G;
@ -134,9 +138,9 @@ char LP_myipaddr[64],LP_publicaddr[64],USERHOME[512] = { "/root" };
char LP_gui[16] = { "cli" };
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",
//"24.54.206.138", "173.212.225.176", "136.243.45.140", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88",
"51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155",
};//"5.9.253.204" }; //
//"24.54.206.138", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88",
"51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", "173.212.225.176", "136.243.45.140"
};
// stubs
@ -160,11 +164,13 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_
return(0);
}
#include "LP_mmjson.c"
#include "LP_socket.c"
#include "LP_secp.c"
#include "LP_bitcoin.c"
#include "LP_coins.c"
#include "LP_rpc.c"
#include "LP_NXT.c"
#include "LP_cache.c"
#include "LP_RTmetrics.c"
#include "LP_utxo.c"
@ -173,9 +179,10 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_
#include "LP_transaction.c"
#include "LP_stats.c"
#include "LP_remember.c"
#include "LP_instantdex.c"
#include "LP_swap.c"
#include "LP_peers.c"
#include "LP_utxos.c"
#include "LP_privkey.c"
#include "LP_forwarding.c"
#include "LP_signatures.c"
#include "LP_ordermatch.c"
@ -186,7 +193,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_
char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen)
{
char *retstr=0;
char *retstr=0; cJSON *retjson; bits256 zero;
if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 )
return(0);
if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 )
@ -197,18 +204,24 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson
//if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 &&
//LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0);
}
} //else printf("finished tradecommand (%s)\n",jprint(argjson,0));
}
else if ( LP_statslog_parse() > 0 )
{
memset(zero.bytes,0,sizeof(zero));
if ( (retjson= LP_statslog_disp(2000000000,2000000000,"",zero,0,0))) // pending swaps
free_json(retjson);
}
return(retstr);
}
char *LP_decrypt(uint8_t *ptr,int32_t *recvlenp)
char *LP_decrypt(uint8_t decoded[LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES],uint8_t *ptr,int32_t *recvlenp)
{
uint8_t decoded[LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES],*nonce,*cipher; int32_t recvlen,cipherlen; char *jsonstr = 0;
uint8_t *nonce,*cipher; int32_t recvlen,cipherlen; char *jsonstr = 0;
recvlen = *recvlenp;
nonce = &ptr[2];
cipher = &ptr[2 + crypto_box_NONCEBYTES];
cipherlen = recvlen - (2 + crypto_box_NONCEBYTES);
if ( cipherlen > 0 && cipherlen <= sizeof(decoded) )
if ( cipherlen > 0 && cipherlen <= LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES )
{
if ( (jsonstr= (char *)_SuperNET_decipher(nonce,cipher,decoded,cipherlen,GENESIS_PUBKEY,G.LP_mypriv25519)) != 0 )
{
@ -219,7 +232,7 @@ char *LP_decrypt(uint8_t *ptr,int32_t *recvlenp)
jsonstr = 0;
} //else printf("decrypted (%s)\n",jsonstr);
}
} else printf("cipher.%d too big for %d\n",cipherlen,(int32_t)sizeof(decoded));
} else printf("cipher.%d too big for %d\n",cipherlen,LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES);
*recvlenp = recvlen;
return(jsonstr);
}
@ -227,7 +240,7 @@ char *LP_decrypt(uint8_t *ptr,int32_t *recvlenp)
char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,uint8_t *ptr,int32_t recvlen,int32_t recvsock)
{
static uint32_t dup,uniq;
int32_t i,len,cipherlen,datalen=0,duplicate=0,encrypted=0; char *method,*method2,*tmp,*cipherstr,*retstr=0,*jsonstr=0; cJSON *argjson; uint32_t crc32;
uint8_t jdecoded[LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES]; int32_t i,len,cipherlen,datalen=0,duplicate=0,encrypted=0; char *method,*method2,*tmp,*cipherstr,*retstr=0,*jsonstr=0; cJSON *argjson; uint32_t crc32;
//double millis = OS_milliseconds();
crc32 = calc_crc32(0,&ptr[2],recvlen-2);
if ( (crc32 & 0xff) == ptr[0] && ((crc32>>8) & 0xff) == ptr[1] )
@ -244,7 +257,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,
if ( i >= 0 )
LP_crc32find(&duplicate,i,crc32);
if ( encrypted != 0 )
jsonstr = LP_decrypt(ptr,&recvlen);
jsonstr = LP_decrypt(jdecoded,ptr,&recvlen);
else if ( (datalen= is_hexstr((char *)ptr,0)) > 0 )
{
datalen >>= 1;
@ -265,7 +278,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,
cipherlen >>= 1;
decode_hex(decoded,cipherlen,cipherstr);
crc32 = calc_crc32(0,&decoded[2],cipherlen-2);
if ( (tmp= LP_decrypt(decoded,&cipherlen)) != 0 )
if ( (tmp= LP_decrypt(jdecoded,decoded,&cipherlen)) != 0 )
{
jsonstr = tmp;
free_json(argjson);
@ -307,8 +320,8 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,
else
{
memset(zero.bytes,0,sizeof(zero));
/*if ( (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"request") == 0 || strcmp(method,"requested") == 0 || strcmp(method,"connect") == 0 || strcmp(method,"connected") == 0) )
printf("broadcast.(%s)\n",Broadcaststr);*/
if ( 0 && (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"tradestatus") == 0) )
printf("broadcast.(%s)\n",Broadcaststr);
LP_reserved_msg(0,"","",zero,jprint(reqjson,0));
}
retstr = clonestr("{\"result\":\"success\"}");
@ -334,11 +347,15 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,
int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int32_t sock,char *remoteaddr,int32_t maxdepth)
{
int32_t recvlen=1,nonz = 0; cJSON *argjson; void *ptr; char methodstr[64],*retstr,*str; struct nn_pollfd pfd;
static char *line;
int32_t recvlen=1,msglen,nonz = 0; cJSON *argjson,*recvjson; void *ptr,*msg; char methodstr[64],*decodestr,*retstr,*str; struct nn_pollfd pfd;
if ( line == 0 )
line = calloc(1,1024*1024);
if ( sock >= 0 )
{
while ( nonz < maxdepth && recvlen > 0 )
{
decodestr = 0;
nonz++;
memset(&pfd,0,sizeof(pfd));
pfd.fd = sock;
@ -346,56 +363,67 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int
if ( nn_poll(&pfd,1,1) != 1 )
break;
ptr = 0;
//buf = malloc(1000000);
//if ( (recvlen= nn_recv(sock,buf,1000000,0)) > 0 )
if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 )
{
//ptr = buf;
methodstr[0] = 0;
//printf("%s.(%s)\n",typestr,(char *)ptr);
if ( 0 )
decodestr = 0;
if ( recvlen > 32768 )
{
cJSON *recvjson; char *mstr;//,*cstr;
if ( (recvjson= cJSON_Parse((char *)ptr)) != 0 )
printf("unexpectedly large packet\n");
}
else
{
msg = ptr;
msglen = recvlen;
if ( (recvjson= cJSON_Parse((char *)ptr)) == 0 )
{
if ( (mstr= jstr(recvjson,"method")) != 0 )//&& strcmp(mstr,"uitem") == 0 && (cstr= jstr(recvjson,"coin")) != 0 && strcmp(cstr,"REVS") == 0 )
if ( (decodestr= MMJSON_decode(ptr,recvlen)) != 0 )
{
//printf("%s RECV.(%s)\n",typestr,(char *)ptr);
}
safecopy(methodstr,jstr(recvjson,"method"),sizeof(methodstr));
free_json(recvjson);
if ( (recvjson= cJSON_Parse(decodestr)) != 0 )
{
msg = decodestr;
msglen = (int32_t)strlen(decodestr) + 1;
}
//printf("decoded.(%s)\n",decodestr);
} else printf("couldnt decode linebuf[%d]\n",recvlen);
}
}
int32_t validreq = 0;
if ( strlen((char *)ptr)+sizeof(bits256) <= recvlen )
{
if ( LP_magic_check(ptr,recvlen,remoteaddr) <= 0 )
methodstr[0] = 0;
//printf("%s.(%s)\n",typestr,(char *)ptr);
if ( recvjson != 0 )
{
//printf("magic check error\n");
} else validreq = 1;
recvlen -= sizeof(bits256);
}
if ( validreq != 0 )
{
if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,ptr,recvlen,sock)) != 0 )
free(retstr);
if ( Broadcaststr != 0 )
safecopy(LP_methodstr,jstr(recvjson,"method"),sizeof(LP_methodstr));
free_json(recvjson);
}
int32_t validreq = 1;
/*if ( strlen((char *)ptr)+sizeof(bits256) <= recvlen )
{
if ( LP_magic_check(ptr,recvlen,remoteaddr) <= 0 )
{
//printf("magic check error\n");
} else validreq = 1;
recvlen -= sizeof(bits256);
}*/
if ( validreq != 0 )
{
//printf("self broadcast.(%s)\n",Broadcaststr);
str = Broadcaststr;
Broadcaststr = 0;
if ( (argjson= cJSON_Parse(str)) != 0 )
if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,msg,msglen,sock)) != 0 )
free(retstr);
if ( Broadcaststr != 0 )
{
portable_mutex_lock(&LP_commandmutex);
if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,0,0) <= 0 )
//printf("self broadcast.(%s)\n",Broadcaststr);
str = Broadcaststr;
Broadcaststr = 0;
if ( (argjson= cJSON_Parse(str)) != 0 )
{
if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 )
free(retstr);
portable_mutex_lock(&LP_commandmutex);
if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,0,0) <= 0 )
{
if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 )
free(retstr);
}
portable_mutex_unlock(&LP_commandmutex);
free_json(argjson);
}
portable_mutex_unlock(&LP_commandmutex);
free_json(argjson);
free(str);
}
free(str);
}
}
}
@ -404,6 +432,8 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int
nn_freemsg(ptr), ptr = 0;
//free(buf);
}
if ( decodestr != 0 )
free(decodestr);
}
}
return(nonz);
@ -445,12 +475,11 @@ int32_t LP_nanomsg_recvs(void *ctx)
return(nonz);
}
void command_rpcloop(void *myipaddr)
void command_rpcloop(void *ctx)
{
int32_t nonz = 0; void *ctx;
ctx = bitcoin_ctx();
int32_t nonz = 0;
strcpy(command_rpcloop_stats.name,"command_rpcloop");
command_rpcloop_stats.threshold = 1000.;
command_rpcloop_stats.threshold = 2500.;
while ( 1 )
{
LP_millistats_update(&command_rpcloop_stats);
@ -468,21 +497,9 @@ void command_rpcloop(void *myipaddr)
}
}
void utxosQ_loop(void *myipaddr)
{
strcpy(utxosQ_loop_stats.name,"utxosQ_loop");
utxosQ_loop_stats.threshold = 5000.;
while ( 1 )
{
LP_millistats_update(&utxosQ_loop_stats);
if ( LP_utxosQ_process() == 0 )
usleep(50000);
}
}
void LP_coinsloop(void *_coins)
{
struct LP_address *ap=0,*atmp; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t oldht,j,nonz; char *coins = _coins;
struct LP_address *ap=0,*atmp; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t notarized,oldht,j,nonz; char *coins = _coins;
if ( strcmp("BTC",coins) == 0 )
{
strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop");
@ -527,20 +544,23 @@ void LP_coinsloop(void *_coins)
if ( coin->inactive != 0 )
continue;
if ( coin->longestchain == 1 ) // special init value
coin->longestchain = LP_getheight(coin);
coin->longestchain = LP_getheight(&notarized,coin);
if ( (ep= coin->electrum) != 0 )
{
/*if ( strcmp("KMD",coin->symbol) == 0 && coin->electrumzeroconf == 0 )
{
LP_zeroconf_deposits(coin);
coin->electrumzeroconf = (uint32_t)time(NULL);
}*/
if ( (backupep= ep->prev) == 0 )
backupep = ep;
if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 )
{
if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 )
free_json(retjson);
}
if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1,zero,zero)) != 0 )
free_json(retjson);
HASH_ITER(hh,coin->addresses,ap,atmp)
{
break;
//printf("call unspent %s\n",ap->coinaddr);
if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 )
if ( strcmp(coin->smartaddr,ap->coinaddr) != 0 && (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1,zero,zero)) != 0 )
free_json(retjson);
}
if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 )
@ -567,7 +587,7 @@ void LP_coinsloop(void *_coins)
nonz++;
printf("SPV failure for %s %s\n",coin->symbol,bits256_str(str,up->U.txid));
oldht = up->U.height;
LP_txheight_check(coin,ap->coinaddr,up);
LP_txheight_check(coin,ap->coinaddr,up->U.txid);
if ( oldht != up->U.height )
up->SPV = LP_merkleproof(coin,coin->smartaddr,backupep,up->U.txid,up->U.height);
if ( up->SPV <= 0 )
@ -582,8 +602,9 @@ void LP_coinsloop(void *_coins)
if ( time(NULL) > ep->keepalive+LP_ELECTRUM_KEEPALIVE )
{
//printf("%s electrum.%p needs a keepalive: lag.%d\n",ep->symbol,ep,(int32_t)(time(NULL) - ep->keepalive));
if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1)) != 0 )
if ( (retjson= electrum_banner(coin->symbol,ep,&retjson)) != 0 )
free_json(retjson);
ep->keepalive = (uint32_t)time(NULL);
}
ep = ep->prev;
}
@ -613,21 +634,26 @@ void LP_coinsloop(void *_coins)
coin->lastscanht = coin->firstscanht;
continue;
}
nonz++;
if ( 0 && coin->lastscanht < coin->longestchain-3 )
printf("[%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain);
for (j=0; j<100; j++)
if ( strcmp(coin->symbol,"BTC") != 0 && strcmp(coin->symbol,"KMD") != 0 ) // SPV as backup
{
if ( LP_blockinit(coin,coin->lastscanht) < 0 )
nonz++;
if ( strcmp("BTC",coins) == 0 )//&& coin->lastscanht < coin->longestchain-3 )
printf("[%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain);
for (j=0; j<100; j++)
{
static uint32_t counter;
if ( counter++ < 3 )
printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht);
break;
if ( LP_blockinit(coin,coin->lastscanht) < 0 )
{
static uint32_t counter;
if ( counter++ < 3 )
printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht);
break;
}
coin->lastscanht++;
if ( coin->lastscanht == coin->longestchain+1 || strcmp("BTC",coins) == 0 )
break;
}
coin->lastscanht++;
if ( coin->lastscanht == coin->longestchain+1 )
break;
if ( strcmp("BTC",coins) == 0 )
printf("done [%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain);
}
}
if ( coins == 0 )
@ -639,8 +665,8 @@ void LP_coinsloop(void *_coins)
int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock,char *pushaddr,uint16_t myport)
{
static uint32_t counter;
struct iguana_info *coin,*ctmp; char *origipaddr; uint32_t now; int32_t height,nonz = 0;
static uint32_t counter;//,didinstantdex;
struct iguana_info *coin,*ctmp; char *origipaddr; uint32_t now; int32_t notarized,height,nonz = 0;
if ( (origipaddr= myipaddr) == 0 )
origipaddr = "127.0.0.1";
if ( mypeer == 0 )
@ -648,19 +674,32 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht
{
now = (uint32_t)time(NULL);
if ( (coin->addr_listunspent_requested != 0 && now > coin->lastpushtime+LP_ORDERBOOK_DURATION*.5) || now > coin->lastpushtime+LP_ORDERBOOK_DURATION*5 )
#ifdef bruteforce
if ( IAMLP != 0 && coin->inactive == 0 && coin->electrum == 0 && didinstantdex == 0 && strcmp("KMD",coin->symbol) == 0 )
{
LP_instantdex_deposits(coin);
didinstantdex = now;
}
#endif
/*if ( (coin->addr_listunspent_requested != 0 && now > coin->lastpushtime+LP_ORDERBOOK_DURATION*.5) || now > coin->lastpushtime+LP_ORDERBOOK_DURATION*5 )
{
//printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested);
coin->lastpushtime = (uint32_t)now;
LP_smartutxos_push(coin);
coin->addr_listunspent_requested = 0;
}
}*/
if ( coin->electrum == 0 && coin->inactive == 0 && now > coin->lastgetinfo+LP_GETINFO_INCR )
{
nonz++;
if ( (height= LP_getheight(coin)) > coin->longestchain )
if ( (height= LP_getheight(&notarized,coin)) > coin->longestchain )
{
coin->longestchain = height;
if ( notarized != 0 && notarized > coin->notarized )
{
coin->notarized = notarized;
if ( IAMLP != 0 )
LP_dPoW_broadcast(coin);
}
if ( 0 && coin->firstrefht != 0 )
printf(">>>>>>>>>> set %s longestchain %d (ref.%d [%d, %d])\n",coin->symbol,height,coin->firstrefht,coin->firstscanht,coin->lastscanht);
} //else LP_mempoolscan(coin->symbol,zero);
@ -673,19 +712,25 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins)
{
int32_t i,n; cJSON *item; char *symbol; struct iguana_info *coin;
int32_t i,n,notarized; cJSON *item; char *symbol; struct iguana_info *coin;
for (i=0; i<sizeof(activecoins)/sizeof(*activecoins); i++)
{
printf("%s ",activecoins[i]);
printf("%s, ",activecoins[i]);
LP_coinfind(activecoins[i]);
LP_priceinfoadd(activecoins[i]);
//test_validate("02000000010e62f95ff5881de8853ce1a5ddbaad731a62879d719367f539103600f1895477010000006b483045022100c684a0871689519bd97f2e61275752124f0f1498360750c87cf99a8acf06fd8c022047e7e62a7bfd481599130e6f40c95833f6ed6f44aa8b6ead7b0ec86a738b98a041210361857e1ba609aadff520a2ca9886fe7548c7154fab2cbe108c3b0e1e7635eb1ffeffffff02a0860100000000001976a9146cfa0a987f4c8f2ffee7e9944ef0c86fcda9671d88ac1e6f0700000000001976a9147f4b7113f9e26d84b150f2cc6d219baaf27f884488ace6b00700");
//getchar();
if ( (coin= LP_coinfind(activecoins[i])) != 0 )
{
if ( LP_getheight(coin) <= 0 )
if ( LP_getheight(&notarized,coin) <= 0 )
coin->inactive = (uint32_t)time(NULL);
else LP_unspents_load(coin->symbol,coin->smartaddr);
else
{
LP_unspents_load(coin->symbol,coin->smartaddr);
if ( strcmp(coin->symbol,"KMD") == 0 )
{
LP_importaddress("KMD",BOTS_BONDADDRESS);
LP_dPoW_request(coin);
}
}
if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 )
coin->txfee = LP_MIN_TXFEE;
}
@ -697,12 +742,12 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins)
item = jitem(coins,i);
if ( (symbol= jstr(item,"coin")) != 0 )
{
printf("%s ",jstr(item,"coin"));
printf("%s, ",jstr(item,"coin"));
LP_coincreate(item);
LP_priceinfoadd(jstr(item,"coin"));
if ( (coin= LP_coinfind(symbol)) != 0 )
{
if ( LP_getheight(coin) <= 0 )
if ( LP_getheight(&notarized,coin) <= 0 )
coin->inactive = (uint32_t)time(NULL);
else LP_unspents_load(coin->symbol,coin->smartaddr);
if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 )
@ -710,6 +755,11 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins)
}
}
}
for (i=0; i<n; i++)
{
item = jitem(coins,i);
printf("\"%s\", ",jstr(item,"coin"));
}
}
printf("privkey updates\n");
}
@ -758,23 +808,13 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint
void LP_pubkeysloop(void *ctx)
{
static uint32_t lasttime; cJSON *retjson; struct iguana_info *coin,*tmp;
static uint32_t lasttime;
strcpy(LP_pubkeysloop_stats.name,"LP_pubkeysloop");
LP_pubkeysloop_stats.threshold = 15000.;
sleep(10);
while ( 1 )
{
LP_millistats_update(&LP_pubkeysloop_stats);
HASH_ITER(hh,LP_coins,coin,tmp) // firstrefht,firstscanht,lastscanht
{
if ( coin->electrum != 0 && time(NULL) > coin->lastunspent+30 )
{
//printf("call electrum listunspent.%s\n",coin->symbol);
if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,coin->smartaddr,2)) != 0 )
free_json(retjson);
coin->lastunspent = (uint32_t)time(NULL);
}
}
if ( time(NULL) > lasttime+LP_ORDERBOOK_DURATION*0.5 )
{
//printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL));
@ -785,22 +825,7 @@ void LP_pubkeysloop(void *ctx)
}
}
void LP_privkeysloop(void *ctx)
{
strcpy(LP_privkeysloop_stats.name,"LP_privkeysloop");
LP_privkeysloop_stats.threshold = (LP_ORDERBOOK_DURATION * .8 * 1000) + 10000;
sleep(20);
while ( 1 )
{
LP_millistats_update(&LP_privkeysloop_stats);
LP_counter += 1000;
//printf("LP_privkeysloop %u\n",LP_counter);
LP_privkey_updates(ctx,LP_mypubsock,0);
sleep(LP_ORDERBOOK_DURATION * .777);
}
}
void LP_swapsloop(void *ignore)
void LP_swapsloop(void *ctx)
{
char *retstr;
strcpy(LP_swapsloop_stats.name,"LP_swapsloop");
@ -809,14 +834,153 @@ void LP_swapsloop(void *ignore)
while ( 1 )
{
LP_millistats_update(&LP_swapsloop_stats);
LP_counter += 10000;
//printf("LP_swapsloop %u\n",LP_counter);
if ( (retstr= basilisk_swapentry(0,0)) != 0 )
if ( (retstr= basilisk_swapentry(0,0,0)) != 0 )
free(retstr);
sleep(600);
}
}
void gc_loop(void *ctx)
{
uint32_t now; struct LP_address_utxo *up,*utmp; struct rpcrequest_info *req,*rtmp; int32_t flag = 0;
strcpy(LP_gcloop_stats.name,"gc_loop");
LP_gcloop_stats.threshold = 11000.;
while ( 1 )
{
flag = 0;
LP_millistats_update(&LP_gcloop_stats);
portable_mutex_lock(&LP_gcmutex);
DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp)
{
DL_DELETE(LP_garbage_collector,req);
//printf("garbage collect ipbits.%x\n",req->ipbits);
free(req);
flag++;
}
now = (uint32_t)time(NULL);
DL_FOREACH_SAFE(LP_garbage_collector2,up,utmp)
{
if ( now > (uint32_t)up->spendheight+120 )
{
DL_DELETE(LP_garbage_collector2,up);
//char str[65]; printf("garbage collect %s/v%d lag.%d\n",bits256_str(str,up->U.txid),up->U.vout,now-up->spendheight);
free(up);
}
flag++;
}
portable_mutex_unlock(&LP_gcmutex);
if ( 0 && flag != 0 )
printf("gc_loop.%d\n",flag);
sleep(10);
}
}
void queue_loop(void *ctx)
{
struct LP_queue *ptr,*tmp; cJSON *json; uint8_t linebuf[32768]; int32_t k,sentbytes,nonz,flag,duplicate,n=0;
strcpy(queue_loop_stats.name,"queue_loop");
queue_loop_stats.threshold = 1000.;
while ( 1 )
{
LP_millistats_update(&queue_loop_stats);
//printf("LP_Q.%p next.%p prev.%p\n",LP_Q,LP_Q!=0?LP_Q->next:0,LP_Q!=0?LP_Q->prev:0);
n = nonz = flag = 0;
DL_FOREACH_SAFE(LP_Q,ptr,tmp)
{
n++;
flag = 0;
if ( ptr->sock >= 0 )
{
if ( ptr->notready == 0 || (LP_rand() % ptr->notready) == 0 )
{
if ( LP_sockcheck(ptr->sock) > 0 )
{
//bits256 magic;
//magic = LP_calc_magic(ptr->msg,(int32_t)(ptr->msglen - sizeof(bits256)));
//memcpy(&ptr->msg[ptr->msglen - sizeof(bits256)],&magic,sizeof(magic));
if ( 0 )
{
static FILE *fp;
if ( fp == 0 )
fp = fopen("packet.log","wb");
if ( fp != 0 )
{
fprintf(fp,"%s\n",(char *)ptr->msg);
fflush(fp);
}
}
if ( (json= cJSON_Parse((char *)ptr->msg)) != 0 )
{
if ( ptr->msglen < sizeof(linebuf) )
{
if ( (k= MMJSON_encode(linebuf,(char *)ptr->msg)) > 0 )
{
if ( (sentbytes= nn_send(ptr->sock,linebuf,k,0)) != k )
printf("%d LP_send mmjson sent %d instead of %d\n",n,sentbytes,k);
else flag++;
}
}
free_json(json);
}
if ( flag == 0 )
{
if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen )
printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen);
else flag++;
}
ptr->sock = -1;
if ( ptr->peerind > 0 )
ptr->starttime = (uint32_t)time(NULL);
}
else
{
if ( ptr->notready++ > 1000 )
flag = 1;
}
}
}
else if ( 0 && time(NULL) > ptr->starttime+13 )
{
LP_crc32find(&duplicate,-1,ptr->crc32);
if ( duplicate > 0 )
{
LP_Qfound++;
if ( (LP_Qfound % 100) == 0 )
printf("found.%u Q.%d err.%d match.%d\n",ptr->crc32,LP_Qenqueued,LP_Qerrors,LP_Qfound);
flag++;
}
else if ( 0 ) // too much beyond duplicate filter when network is busy
{
printf("couldnt find.%u peerind.%d Q.%d err.%d match.%d\n",ptr->crc32,ptr->peerind,LP_Qenqueued,LP_Qerrors,LP_Qfound);
ptr->peerind++;
if ( (ptr->sock= LP_peerindsock(&ptr->peerind)) < 0 )
{
printf("%d no more peers to try at peerind.%d %p Q_LP.%p\n",n,ptr->peerind,ptr,LP_Q);
flag++;
LP_Qerrors++;
}
}
}
if ( flag != 0 )
{
nonz++;
portable_mutex_lock(&LP_networkmutex);
DL_DELETE(LP_Q,ptr);
portable_mutex_unlock(&LP_networkmutex);
free(ptr);
ptr = 0;
break;
}
}
if ( nonz == 0 )
{
if ( IAMLP == 0 )
usleep(50000);
else usleep(10000);
}
}
}
void LP_reserved_msgs(void *ignore)
{
bits256 zero; int32_t flag,nonz; struct nn_pollfd pfd;
@ -875,7 +1039,7 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha
{
Reserved_msgs[priority][num_Reserved_msgs[priority]++] = msg;
n = num_Reserved_msgs[priority];
} else LP_broadcast_message(LP_mypubsock,base,rel,pubkey,msg);
} //else LP_broadcast_message(LP_mypubsock,base,rel,pubkey,msg);
if ( num_Reserved_msgs[priority] > max_Reserved_msgs[priority] )
{
max_Reserved_msgs[priority] = num_Reserved_msgs[priority];
@ -886,10 +1050,13 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha
return(n);
}
extern int32_t bitcoind_RPC_inittime;
void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybusport,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson)
{
char *myipaddr=0,version[64]; long filesize,n; int32_t valid,timeout,pubsock=-1; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128],*coins_str=0; cJSON *coinsjson=0; void *ctx = bitcoin_ctx();
sprintf(version,"Marketmaker %s.%s %s rsize.%ld",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER,sizeof(struct basilisk_request));
bitcoind_RPC_inittime = 1;
printf("%s %u\n",version,calc_crc32(0,version,(int32_t)strlen(version)));
if ( LP_MAXPRICEINFOS > 256 )
{
@ -960,6 +1127,9 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
portable_mutex_init(&LP_nanorecvsmutex);
portable_mutex_init(&LP_tradebotsmutex);
portable_mutex_init(&LP_cJSONmutex);
portable_mutex_init(&LP_logmutex);
portable_mutex_init(&LP_statslogmutex);
portable_mutex_init(&LP_tradesmutex);
myipaddr = clonestr("127.0.0.1");
#ifndef _WIN32
#ifndef FROM_JS
@ -1035,9 +1205,12 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
exit(-1);
}
LP_initcoins(ctx,pubsock,coinsjson);
G.waiting = 1;
LP_passphrase_init(passphrase,jstr(argjson,"gui"));
//char coinaddr[64]; bits256 zero;
//bitcoin_address(coinaddr,0,60,G.LP_myrmd160,20);
//memset(zero.bytes,0,sizeof(zero));
//LP_instantdex_depositadd(coinaddr,zero);
#ifndef FROM_JS
if ( IAMLP != 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_psockloop,(void *)myipaddr) != 0 )
{
@ -1049,11 +1222,6 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
printf("error launching LP_reserved_msgs for (%s)\n",myipaddr);
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 )
{
printf("error launching utxosQ_loop for (%s)\n",myipaddr);
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);
@ -1065,57 +1233,59 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
printf("error launching stats rpcloop for port.%u\n",myport);
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,(void *)myipaddr) != 0 )
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,ctx) != 0 )
{
printf("error launching command_rpcloop for port.%u\n",myport);
printf("error launching command_rpcloop for ctx.%p\n",ctx);
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,(void *)myipaddr) != 0 )
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,ctx) != 0 )
{
printf("error launching queue_loop for port.%u\n",myport);
printf("error launching queue_loop for ctx.%p\n",ctx);
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,(void *)myipaddr) != 0 )
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,ctx) != 0 )
{
printf("error launching gc_loop for port.%u\n",myport);
printf("error launching gc_loop for port.%p\n",ctx);
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 )
{
printf("error launching prices_loop for port.%u\n",myport);
printf("error launching prices_loop for ctx.%p\n",ctx);
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 )
{
printf("error launching LP_coinsloop for port.%u\n",myport);
printf("error launching LP_coinsloop for (%s)\n","");
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 )
{
printf("error launching BTC LP_coinsloop for port.%u\n",myport);
printf("error launching LP_coinsloop for (%s)\n","BTC");
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 )
{
printf("error launching KMD LP_coinsloop for port.%u\n",myport);
printf("error launching LP_coinsloop for (%s)\n","KMD");
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,(void *)myipaddr) != 0 )
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,ctx) != 0 )
{
printf("error launching LP_pubkeysloop for ctx.%p\n",ctx);
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_privkeysloop,(void *)myipaddr) != 0 )
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_tradesloop,ctx) != 0 )
{
printf("error launching LP_privkeysloop for ctx.%p\n",ctx);
printf("error launching LP_tradessloop for ctx.%p\n",ctx);
exit(-1);
}
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,(void *)myipaddr) != 0 )
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,ctx) != 0 )
{
printf("error launching LP_swapsloop for port.%u\n",myport);
printf("error launching LP_swapsloop for ctx.%p\n",ctx);
exit(-1);
}
int32_t nonz;
LP_statslog_parse();
bitcoind_RPC_inittime = 0;
while ( 1 )
{
nonz = 0;
@ -1182,8 +1352,6 @@ void LP_fromjs_iter()
}
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( 0 && (LP_counter % 100) == 0 )
printf("LP_fromjs_iter got called LP_counter.%d userpass.(%s) ctx.%p\n",LP_counter,G.USERPASS,ctx);
//if ( Nanomsg_threadarg != 0 )
// nn_thread_main_routine(Nanomsg_threadarg);
//LP_pubkeys_query();
@ -1191,18 +1359,17 @@ void LP_fromjs_iter()
//LP_nanomsg_recvs(ctx);
LP_mainloop_iter(ctx,LP_myipaddr,0,LP_mypubsock,LP_publicaddr,LP_RPCPORT);
//queue_loop(0);
if ( 0 && (LP_counter % 10) == 0 ) // 10 seconds
if ( 0 ) // 10 seconds
{
LP_coinsloop(0);
if ( (LP_counter % 100) == 0 ) // 100 seconds
if ( 0 ) // 100 seconds
{
LP_notify_pubkeys(ctx,LP_mypubsock);
LP_privkey_updates(ctx,LP_mypubsock,0);
if ( (retstr= basilisk_swapentry(0,0)) != 0 )
if ( (retstr= basilisk_swapentry(0,0,0)) != 0 )
free(retstr);
}
}
LP_counter++;
}
#endif

120
iguana/exchanges/LP_network.c

@ -152,7 +152,7 @@ void _LP_sendqueueadd(uint32_t crc32,int32_t sock,uint8_t *msg,int32_t msglen,in
ptr->crc32 = crc32;
ptr->sock = sock;
ptr->peerind = peerind;
ptr->msglen = (int32_t)(msglen + sizeof(bits256));
ptr->msglen = (int32_t)(msglen + 0*sizeof(bits256));
memcpy(ptr->msg,msg,msglen); // sizeof(bits256) at the end all zeroes
DL_APPEND(LP_Q,ptr);
LP_Qenqueued++;
@ -265,122 +265,6 @@ int32_t LP_peerindsock(int32_t *peerindp)
return(-1);
}
void gc_loop(void *arg)
{
uint32_t now; struct LP_address_utxo *up,*utmp; struct rpcrequest_info *req,*rtmp; int32_t flag = 0;
strcpy(LP_gcloop_stats.name,"gc_loop");
LP_gcloop_stats.threshold = 11000.;
while ( 1 )
{
flag = 0;
LP_millistats_update(&LP_gcloop_stats);
portable_mutex_lock(&LP_gcmutex);
DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp)
{
DL_DELETE(LP_garbage_collector,req);
//printf("garbage collect ipbits.%x\n",req->ipbits);
free(req);
flag++;
}
now = (uint32_t)time(NULL);
DL_FOREACH_SAFE(LP_garbage_collector2,up,utmp)
{
if ( now > (uint32_t)up->spendheight+120 )
{
DL_DELETE(LP_garbage_collector2,up);
//char str[65]; printf("garbage collect %s/v%d lag.%d\n",bits256_str(str,up->U.txid),up->U.vout,now-up->spendheight);
free(up);
}
flag++;
}
portable_mutex_unlock(&LP_gcmutex);
if ( 0 && flag != 0 )
printf("gc_loop.%d\n",flag);
sleep(10);
}
}
void queue_loop(void *arg)
{
struct LP_queue *ptr,*tmp; int32_t sentbytes,nonz,flag,duplicate,n=0;
strcpy(queue_loop_stats.name,"queue_loop");
queue_loop_stats.threshold = 1000.;
while ( 1 )
{
LP_millistats_update(&queue_loop_stats);
//printf("LP_Q.%p next.%p prev.%p\n",LP_Q,LP_Q!=0?LP_Q->next:0,LP_Q!=0?LP_Q->prev:0);
n = nonz = flag = 0;
DL_FOREACH_SAFE(LP_Q,ptr,tmp)
{
n++;
flag = 0;
if ( ptr->sock >= 0 )
{
if ( ptr->notready == 0 || (LP_rand() % ptr->notready) == 0 )
{
if ( LP_sockcheck(ptr->sock) > 0 )
{
bits256 magic;
magic = LP_calc_magic(ptr->msg,(int32_t)(ptr->msglen - sizeof(bits256)));
memcpy(&ptr->msg[ptr->msglen - sizeof(bits256)],&magic,sizeof(magic));
if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen )
printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen);
else flag++;
ptr->sock = -1;
if ( ptr->peerind > 0 )
ptr->starttime = (uint32_t)time(NULL);
}
else
{
if ( ptr->notready++ > 1000 )
flag = 1;
}
}
}
else if ( 0 && time(NULL) > ptr->starttime+13 )
{
LP_crc32find(&duplicate,-1,ptr->crc32);
if ( duplicate > 0 )
{
LP_Qfound++;
if ( (LP_Qfound % 100) == 0 )
printf("found.%u Q.%d err.%d match.%d\n",ptr->crc32,LP_Qenqueued,LP_Qerrors,LP_Qfound);
flag++;
}
else if ( 0 ) // too much beyond duplicate filter when network is busy
{
printf("couldnt find.%u peerind.%d Q.%d err.%d match.%d\n",ptr->crc32,ptr->peerind,LP_Qenqueued,LP_Qerrors,LP_Qfound);
ptr->peerind++;
if ( (ptr->sock= LP_peerindsock(&ptr->peerind)) < 0 )
{
printf("%d no more peers to try at peerind.%d %p Q_LP.%p\n",n,ptr->peerind,ptr,LP_Q);
flag++;
LP_Qerrors++;
}
}
}
if ( flag != 0 )
{
nonz++;
portable_mutex_lock(&LP_networkmutex);
DL_DELETE(LP_Q,ptr);
portable_mutex_unlock(&LP_networkmutex);
free(ptr);
ptr = 0;
break;
}
}
if ( arg == 0 )
break;
if ( nonz == 0 )
{
if ( IAMLP == 0 )
usleep(50000);
else usleep(10000);
}
}
}
void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32_t msglen,int32_t needack)
{
int32_t maxind,peerind = 0; //sentbytes,
@ -573,7 +457,7 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w
}
else if ( (pfds[n].revents & POLLIN) != 0 )
{
printf("publicsock.%d %s has pollin\n",ptr->publicsock,ptr->publicaddr);
//printf("publicsock.%d %s has pollin\n",ptr->publicsock,ptr->publicaddr);
buf = 0;
if ( (size= nn_recv(ptr->publicsock,&buf,NN_MSG,0)) > 0 )
{

1179
iguana/exchanges/LP_ordermatch.c

File diff suppressed because it is too large

6
iguana/exchanges/LP_peers.c

@ -212,8 +212,8 @@ void LP_peer_recv(char *ipaddr,int32_t ismine)
if ( (peer= LP_peerfind((uint32_t)calc_ipbits(ipaddr),RPC_port)) != 0 )
{
peer->numrecv++;
if ( ismine != 0 )
peer->recvtime = (uint32_t)time(NULL);
//if ( ismine != 0 )
peer->recvtime = (uint32_t)time(NULL);
}
}
@ -262,7 +262,7 @@ uint16_t LP_rarestpeer(char *destip)
{
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( iter == 0 && peer->recvtime < now-3600*24 )
if ( strcmp(peer->ipaddr,LP_myipaddr) != 0 && iter == 0 && peer->recvtime < now-3600 )
continue;
if ( peer->isLP != 0 )
{

425
iguana/exchanges/LP_portfolio.c

@ -18,9 +18,53 @@
// marketmaker
//
struct LP_portfoliotrade { double metric; char buycoin[65],sellcoin[65]; };
struct LP_autoprice_ref
{
char refbase[65],refrel[65],base[65],rel[65],fundbid[16],fundask[16];
double buymargin,sellmargin,factor,offset,lastbid,lastask;
cJSON *fundvalue;
uint32_t count;
} LP_autorefs[1024];
int32_t LP_autoprices,num_LP_autorefs;
char LP_portfolio_base[128],LP_portfolio_rel[128];
double LP_portfolio_relvolume;
void LP_portfolio_reset()
{
struct iguana_info *coin,*tmp; cJSON *fundjson; int32_t i; struct LP_autoprice_ref *ptr;
for (i=0; i<num_LP_autorefs; i++)
{
ptr = &LP_autorefs[i];
if ( (fundjson= ptr->fundvalue) != 0 )
{
ptr->fundvalue = 0;
free_json(fundjson);
}
}
memset(LP_autorefs,0,sizeof(LP_autorefs));
LP_autoprices = 0;
num_LP_autorefs = 0;
strcpy(LP_portfolio_base,"");
strcpy(LP_portfolio_rel,"");
LP_portfolio_relvolume = 0.;
HASH_ITER(hh,LP_coins,coin,tmp)
{
coin->maxamount = 0;
coin->perc = 0;
coin->goal = 0;
coin->goalperc = 0;
coin->relvolume = 0;
coin->force = 0;
coin->balanceA = 0;
coin->valuesumA = 0;
coin->balanceB = 0;
coin->valuesumB = 0;
}
}
cJSON *LP_portfolio_entry(struct iguana_info *coin)
{
cJSON *item = cJSON_CreateObject();
@ -48,9 +92,10 @@ cJSON *LP_portfolio_entry(struct iguana_info *coin)
uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr)
{
cJSON *array,*item; int32_t i,n; uint64_t valuesum,satoshisum,value;
cJSON *array,*item; bits256 zero; int32_t i,n; uint64_t valuesum,satoshisum,value;
valuesum = satoshisum = 0;
if ( (array= LP_listunspent(symbol,coinaddr)) != 0 )
memset(zero.bytes,0,sizeof(zero));
if ( (array= LP_listunspent(symbol,coinaddr,zero,zero)) != 0 )
{
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
@ -63,7 +108,7 @@ uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr)
}
free_json(array);
}
if ( (array= LP_inventory(symbol)) != 0 )
/*if ( (array= LP_inventory(symbol)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 && is_cJSON_Array(array) != 0 )
{
@ -75,8 +120,9 @@ uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr)
}
}
free_json(array);
}
}*/
*valuep = valuesum;
satoshisum = valuesum;
return(satoshisum);
}
@ -94,7 +140,7 @@ char *LP_portfolio()
if ( iter == 0 )
{
//printf("from portfolio\n");
LP_privkey_init(-1,coin,G.LP_privkey,G.LP_mypub25519);
//LP_privkey_init(-1,coin,G.LP_privkey,G.LP_mypub25519);
coin->balanceA = LP_balance(&coin->valuesumA,0,coin->symbol,coin->smartaddr);
coin->balanceB = LP_balance(&coin->valuesumB,1,coin->symbol,coin->smartaddr);
if ( strcmp(coin->symbol,"KMD") != 0 )
@ -199,13 +245,6 @@ char *LP_portfolio_goal(char *symbol,double goal)
} else return(clonestr("{\"error\":\"cant set goal for inactive coin\"}"));
}
int32_t LP_autoprices,num_LP_autorefs;
struct LP_autoprice_ref
{
char refbase[65],refrel[65],base[65],rel[65];
} LP_autorefs[100];
/*int32_t LP_autofill(char *base,char *rel,double maxprice,double totalrelvolume)
{
struct LP_priceinfo *basepp,*relpp;
@ -219,64 +258,12 @@ struct LP_autoprice_ref
return(-1);
}*/
int32_t LP_autoprice(char *base,char *rel,cJSON *argjson)
{
//curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.1,\"refbase\":\"KMD\",\refrel\":\"BTC\",\"factor\":15000,\"margin\":0.01}"
struct LP_priceinfo *basepp,*relpp; int32_t i; char *refbase="",*refrel=""; double minprice,margin,offset,factor,fixedprice;
//printf("autoprice.(%s %s) %s\n",base,rel,jprint(argjson,0));
if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{
if ( jobj(argjson,"minprice") != 0 )
minprice = jdouble(argjson,"minprice");
else minprice = 0.;
margin = jdouble(argjson,"margin");
offset = jdouble(argjson,"offset");
factor = jdouble(argjson,"factor");
fixedprice = jdouble(argjson,"fixed");
basepp->fixedprices[relpp->ind] = fixedprice;
basepp->minprices[relpp->ind] = minprice;
basepp->margins[relpp->ind] = margin;
basepp->offsets[relpp->ind] = offset;
basepp->factors[relpp->ind] = factor;
if ( fixedprice > SMALLVAL || ((refbase= jstr(argjson,"refbase")) != 0 && (refrel= jstr(argjson,"refrel")) != 0) )
{
if ( fixedprice > SMALLVAL )
{
refbase = base;
refrel = rel;
}
for (i=0; i<num_LP_autorefs; i++)
{
if ( strcmp(base,LP_autorefs[i].base) == 0 && strcmp(rel,LP_autorefs[i].rel) == 0 )
{
safecopy(LP_autorefs[i].refbase,refbase,sizeof(LP_autorefs[i].refbase));
safecopy(LP_autorefs[i].refrel,refrel,sizeof(LP_autorefs[i].refrel));
printf("%d Update ref %s/%s for %s/%s factor %.8f offset %.8f\n",i,refbase,refrel,base,rel,factor,offset);
break;
}
}
if ( i == num_LP_autorefs && num_LP_autorefs < sizeof(LP_autorefs)/sizeof(*LP_autorefs) )
{
safecopy(LP_autorefs[num_LP_autorefs].refbase,refbase,sizeof(LP_autorefs[num_LP_autorefs].refbase));
safecopy(LP_autorefs[num_LP_autorefs].refrel,refrel,sizeof(LP_autorefs[num_LP_autorefs].refrel));
safecopy(LP_autorefs[num_LP_autorefs].base,base,sizeof(LP_autorefs[num_LP_autorefs].base));
safecopy(LP_autorefs[num_LP_autorefs].rel,rel,sizeof(LP_autorefs[num_LP_autorefs].rel));
printf("%d Using ref %s/%s for %s/%s factor %.8f, offset %.8f, margin %.8f fixed %.8f\n",num_LP_autorefs,refbase,refrel,base,rel,factor,offset,margin,fixedprice);
num_LP_autorefs++;
}
}
LP_autoprices++;
return(0);
}
return(-1);
}
void LP_autopriceset(void *ctx,int32_t dir,struct LP_priceinfo *basepp,struct LP_priceinfo *relpp,double price,char *refbase,char *refrel)
void LP_autopriceset(int32_t ind,void *ctx,int32_t dir,struct LP_priceinfo *basepp,struct LP_priceinfo *relpp,double price,char *refbase,char *refrel)
{
static uint32_t lasttime;
double margin,minprice,newprice,oppomargin,fixedprice,factor,offset; double bid,ask; int32_t changed;
margin = basepp->margins[relpp->ind];
oppomargin = relpp->margins[basepp->ind];
margin = basepp->sellmargins[relpp->ind];
oppomargin = basepp->buymargins[relpp->ind];
if ( (fixedprice= basepp->fixedprices[relpp->ind]) > SMALLVAL )
{
LP_mypriceset(&changed,relpp->symbol,basepp->symbol,fixedprice);
@ -291,7 +278,7 @@ void LP_autopriceset(void *ctx,int32_t dir,struct LP_priceinfo *basepp,struct LP
if ( fabs(price) < SMALLVAL && refbase != 0 && refrel != 0 )
{
price = LP_myprice(&bid,&ask,refbase,refrel);
//printf("%s/%s USE ref %s/%s %.8f factor %.8f offset %.8f margin %.8f\n",basepp->symbol,relpp->symbol,refbase,refrel,price,factor,offset,margin);
//printf("%s/%s USE ref %s/%s %.8f factor %.8f offset %.8f margin %.8f/%.8f\n",basepp->symbol,relpp->symbol,refbase,refrel,price,factor,offset,oppomargin,margin);
}
if ( LP_pricevalid(price) > 0 )
{
@ -309,8 +296,15 @@ void LP_autopriceset(void *ctx,int32_t dir,struct LP_priceinfo *basepp,struct LP
else newprice = (price * (1. + margin));
if ( (minprice= basepp->minprices[relpp->ind]) == 0. || price >= minprice )
{
if ( ind >= 0 )
{
if ( LP_autorefs[ind].lastask < SMALLVAL )
LP_autorefs[ind].lastask = newprice;
else LP_autorefs[ind].lastask = (LP_autorefs[ind].lastask * 0.9) + (0.1 *newprice);
newprice = LP_autorefs[ind].lastask;
//printf("autopriceset %s/%s <- %.8f %.8f (%.8f %.8f)\n",basepp->symbol,relpp->symbol,price,newprice,LP_autorefs[ind].lastbid,LP_autorefs[ind].lastask);
}
LP_mypriceset(&changed,relpp->symbol,basepp->symbol,newprice);
//printf("autoprice changed.%d %s/%s <- %.8f\n",changed,basepp->symbol,relpp->symbol,price);
if ( changed != 0 || time(NULL) > lasttime+LP_ORDERBOOK_DURATION*.777)
{
lasttime = (uint32_t)time(NULL);
@ -397,8 +391,8 @@ double LP_pricesparse(void *ctx,int32_t trexflag,char *retstr,struct LP_priceinf
//printf("have trex: iter.%d trexflag.%d %s %.8f %.8f\n",iter,trexflag,symbol,coinpp->bid[1],coinpp->ask[1]);
continue;
}
LP_autopriceset(ctx,1,coinpp,refpp,price,0,0);
LP_autopriceset(ctx,-1,refpp,coinpp,price,0,0);
LP_autopriceset(-1,ctx,1,coinpp,refpp,price,0,0);
LP_autopriceset(-1,ctx,-1,refpp,coinpp,price,0,0);
}
}
}
@ -414,9 +408,49 @@ double LP_pricesparse(void *ctx,int32_t trexflag,char *retstr,struct LP_priceinf
return(nxtkmd);
}
double LP_autoprice_newprice(int32_t bidask,double price,double newprice)
{
double gap; int32_t r;
if ( (bidask == 0 && newprice < price) || (bidask != 0 && newprice > price) )
{
gap = fabs(newprice - price) * 2;
r = (rand() % 100);
if ( bidask == 0 )
price -= (gap * r) / 100.;
else price += (gap * r) / 100.;
}
else if ( price > SMALLVAL )
price = (price * 0.95) + (0.05 * newprice);
else price = newprice;
return(price);
}
double LP_tickered_price(int32_t bidask,char *base,char *rel,double price,cJSON *tickerjson)
{
int32_t i,n; cJSON *item; double basevol,relvol,itemprice;
//printf("%s %s/%s %.8f -> ",bidask == 0 ? "bid" : "ask",base,rel,price);
if ( (n= cJSON_GetArraySize(tickerjson)) > 0 )
{
for (i=n-1; i>=0; i--)
{
// {"timestamp":1513235320,"KMD":860.45202538,"SUPERNET":20.00010000,"price":0.02324371}
item = jitem(tickerjson,i);
if ( (basevol= jdouble(item,base)) > SMALLVAL && (relvol= jdouble(item,rel)) > SMALLVAL )
{
itemprice = (relvol / basevol);
//printf("%.8f ",itemprice);
price = LP_autoprice_newprice(bidask,price,itemprice);
}
}
}
//printf("-> %.8f\n",price);
return(price);
}
void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp)
{
char *retstr; cJSON *retjson,*bid,*ask; uint64_t bidsatoshis,asksatoshis; int32_t i; double nxtkmd,price; struct LP_priceinfo *kmdpp,*fiatpp,*nxtpp,*basepp,*relpp;
static cJSON *tickerjson; static uint32_t lasttime;
char *retstr,*base,*rel; cJSON *retjson,*bid,*ask,*fundjson,*argjson; uint64_t bidsatoshis,asksatoshis; int32_t i,changed; double bch_usd,bch_btc,nxtkmd,price,factor,offset,newprice,buymargin,sellmargin,price_btc,price_usd,kmd_btc,kmd_usd; struct LP_priceinfo *kmdpp,*fiatpp,*nxtpp,*basepp,*relpp;
if ( (retstr= issue_curlt("https://bittrex.com/api/v1.1/public/getmarketsummaries",LP_HTTP_TIMEOUT*10)) == 0 )
{
printf("trex error getting marketsummaries\n");
@ -436,21 +470,21 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp)
if ( (kmdpp= LP_priceinfofind("KMD")) != 0 )
{
for (i=0; i<32; i++)
{
{break;
if ( (fiatpp= LP_priceinfofind(CURRENCIES[i])) != 0 )
{
if ( (retjson= LP_paxprice(CURRENCIES[i])) != 0 )
{
//printf("(%s %.8f %.8f) ",CURRENCIES[i],jdouble(retjson,"price"),jdouble(retjson,"invprice"));
price = jdouble(retjson,"price");
LP_autopriceset(ctx,1,fiatpp,kmdpp,price,0,0);
LP_autopriceset(ctx,-1,kmdpp,fiatpp,price,0,0);
LP_autopriceset(-1,ctx,1,fiatpp,kmdpp,price,0,0);
LP_autopriceset(-1,ctx,-1,kmdpp,fiatpp,price,0,0);
free_json(retjson);
}
}
}
}
if ( nxtkmd > SMALLVAL )
if ( 0 && nxtkmd > SMALLVAL )
{
for (i=0; i<sizeof(assetids)/sizeof(*assetids); i++)
{
@ -467,29 +501,242 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp)
if ( bidsatoshis != 0 && asksatoshis != 0 )
price = 0.5 * dstr(bidsatoshis + asksatoshis) * nxtkmd;
}
LP_autopriceset(ctx,1,nxtpp,kmdpp,price,0,0);
LP_autopriceset(ctx,-1,kmdpp,nxtpp,price,0,0);
LP_autopriceset(-1,ctx,1,nxtpp,kmdpp,price,0,0);
LP_autopriceset(-1,ctx,-1,kmdpp,nxtpp,price,0,0);
//printf("%s %s -> (%s) nxtkmd %.8f %.8f %.8f\n",assetids[i][1],assetids[i][0],jprint(retjson,0),nxtkmd,0.5*dstr(bidsatoshis + asksatoshis),price);
free_json(retjson);
}
}
}
}
if ( time(NULL) > lasttime+60 )
{
if ( tickerjson != 0 )
free_json(tickerjson);
if ( (retstr= LP_ticker("","")) != 0 )
{
tickerjson = cJSON_Parse(retstr);
free(retstr);
}
}
kmd_btc = LP_CMCbtcprice(&kmd_usd,"komodo");
bch_btc = LP_CMCbtcprice(&bch_usd,"bitcoin-cash");
for (i=0; i<num_LP_autorefs; i++)
{
basepp = LP_priceinfofind(LP_autorefs[i].base);
relpp = LP_priceinfofind(LP_autorefs[i].rel);
if ( basepp != 0 && relpp != 0 )
rel = LP_autorefs[i].rel;
base = LP_autorefs[i].base;
buymargin = LP_autorefs[i].buymargin;
sellmargin = LP_autorefs[i].sellmargin;
offset = LP_autorefs[i].offset;
factor = LP_autorefs[i].factor;
if ( (argjson= LP_autorefs[i].fundvalue) != 0 )
{
if ( (fundjson= LP_fundvalue(argjson)) != 0 )
{
if ( jint(fundjson,"missing") == 0 )
{
if ( LP_autorefs[i].fundbid[0] != 0 && (price= jdouble(fundjson,LP_autorefs[i].fundbid)) > SMALLVAL )
{
if ( tickerjson != 0 && LP_autorefs[i].count == 0 )
price = LP_tickered_price(0,base,rel,price,tickerjson);
newprice = (1. / price) * (1. + buymargin);
if ( LP_autorefs[i].lastbid < SMALLVAL )
LP_autorefs[i].lastbid = newprice;
else LP_autorefs[i].lastbid = (LP_autorefs[i].lastbid * 0.9) + (0.1 *newprice);
newprice = LP_autorefs[i].lastbid;
LP_mypriceset(&changed,rel,base,newprice);
LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice);
//printf("fundbid %.8f margin %.8f newprice %.8f\n",price,margin,newprice);
}
if ( LP_autorefs[i].fundask[0] != 0 && (price= jdouble(fundjson,LP_autorefs[i].fundask)) > SMALLVAL )
{
if ( tickerjson != 0 && LP_autorefs[i].count == 0 )
price = LP_tickered_price(1,base,rel,price,tickerjson);
newprice = (price * (1. + sellmargin));
if ( LP_autorefs[i].lastask < SMALLVAL )
LP_autorefs[i].lastask = newprice;
else LP_autorefs[i].lastask = (LP_autorefs[i].lastask * 0.9) + (0.1 *newprice);
newprice = LP_autorefs[i].lastask;
LP_mypriceset(&changed,base,rel,newprice);
LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice);
//printf("fundask %.8f margin %.8f newprice %.8f\n",price,margin,newprice);
}
LP_autorefs[i].count++;
}
free_json(fundjson);
}
}
else if ( strcmp(LP_autorefs[i].refrel,"coinmarketcap") == 0 )
{
//printf("%s/%s for %s/%s margin %.8f/%.8f\n",base,rel,LP_autorefs[i].refbase,LP_autorefs[i].refrel,buymargin,sellmargin);
if ( (price_btc= LP_CMCbtcprice(&price_usd,LP_autorefs[i].refbase)) > SMALLVAL )
{
if ( strcmp(rel,"KMD") == 0 && kmd_btc > SMALLVAL )
price = kmd_btc / price_btc;
else if ( strcmp(rel,"BCH") == 0 && bch_btc > SMALLVAL )
price = bch_btc / price_btc;
else if ( strcmp(rel,"BTC") == 0 )
price = 1. / price_btc;
else continue;
if ( factor > 0. )
price = (price * factor) + offset;
newprice = (price * (1. + buymargin));
if ( LP_autorefs[i].lastbid < SMALLVAL )
LP_autorefs[i].lastbid = newprice;
else LP_autorefs[i].lastbid = (LP_autorefs[i].lastbid * 0.9) + (0.1 *newprice);
newprice = LP_autorefs[i].lastbid;
LP_mypriceset(&changed,rel,base,newprice);
LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice);
//printf("price %.8f margin %.8f/%.8f newprice %.8f %.8f\n",price,buymargin,sellmargin,newprice,(1. / price) * (1. + buymargin));
newprice = (1. / price) * (1. + sellmargin);
if ( LP_autorefs[i].lastask < SMALLVAL )
LP_autorefs[i].lastask = newprice;
else LP_autorefs[i].lastask = (LP_autorefs[i].lastask * 0.9) + (0.1 *newprice);
newprice = LP_autorefs[i].lastask;
LP_mypriceset(&changed,base,rel,newprice);
LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice);
}
}
else
{
basepp = LP_priceinfofind(base);
relpp = LP_priceinfofind(rel);
if ( basepp != 0 && relpp != 0 )
{
//printf("check ref-autoprice %s/%s %f %f (%.8f %.8f)\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel,relpp->fixedprices[basepp->ind],basepp->fixedprices[relpp->ind],LP_autorefs[i].lastbid,LP_autorefs[i].lastask);
LP_autopriceset(i,ctx,1,basepp,relpp,0.,LP_autorefs[i].refbase,LP_autorefs[i].refrel);
}
}
}
}
void LP_autoprices_update(char *method,char *base,double basevol,char *rel,double relvol)
{
int32_t i; double price,newprice;
if ( basevol > 0. && relvol > 0. )
{
price = relvol/basevol;
for (i=0; i<num_LP_autorefs; i++)
{
if ( strcmp(LP_autorefs[i].rel,rel) == 0 && strcmp(base,LP_autorefs[i].base) == 0 )
{
newprice = (LP_autorefs[i].lastask * 0.99) + (0.01 * price);
if ( LP_autorefs[i].lastask > 0 )
{
printf("%s: autoprice ask update %s/%s %.8f vs myprice %.8f/%.8f -> %.8f\n",method,base,rel,price,LP_autorefs[i].lastbid,LP_autorefs[i].lastask,newprice);
LP_autorefs[i].lastask = newprice;
} // else printf("%s: autoprice ask skip update %s/%s %.8f vs myprice %.8f/%.8f -> %.8f\n",method,base,rel,price,LP_autorefs[i].lastbid,LP_autorefs[i].lastask,newprice);
}
else if ( strcmp(LP_autorefs[i].rel,base) == 0 && strcmp(rel,LP_autorefs[i].base) == 0 )
{
newprice = (LP_autorefs[i].lastbid * 0.99) + (0.01 * price);
if ( LP_autorefs[i].lastbid > 0 )
{
printf("%s: autoprice bid update %s/%s %.8f vs myprice %.8f/%.8f -> %.8f\n",method,base,rel,price,LP_autorefs[i].lastbid,LP_autorefs[i].lastask,newprice);
LP_autorefs[i].lastbid = newprice;
} // else printf("%s: autoprice bid skip update %s/%s %.8f vs myprice %.8f/%.8f -> %.8f\n",method,base,rel,price,LP_autorefs[i].lastbid,LP_autorefs[i].lastask,newprice);
}
}
}
}
int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson)
{
//curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.1,\"refbase\":\"KMD\",\refrel\":\"BTC\",\"factor\":15000,\"margin\":0.01}"
struct LP_priceinfo *basepp,*relpp; int32_t i,retval = -1; char *fundvalue_bid,*fundvalue_ask,*refbase="",*refrel=""; double margin,minprice,buymargin,sellmargin,offset,factor,fixedprice; cJSON *fundvalue;
//printf("autoprice.(%s %s) %s\n",base,rel,jprint(argjson,0));
if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{
if ( jobj(argjson,"minprice") != 0 )
minprice = jdouble(argjson,"minprice");
else minprice = 0.;
if ( (margin= jdouble(argjson,"margin")) == 0. )
{
buymargin = jdouble(argjson,"buymargin");
sellmargin = jdouble(argjson,"sellmargin");
}
else
{
//printf("check ref-autoprice %s/%s %f %f\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel,relpp->fixedprices[basepp->ind],basepp->fixedprices[relpp->ind]);
LP_autopriceset(ctx,1,basepp,relpp,0.,LP_autorefs[i].refbase,LP_autorefs[i].refrel);
buymargin = margin;
sellmargin = margin;
}
offset = jdouble(argjson,"offset");
factor = jdouble(argjson,"factor");
fixedprice = jdouble(argjson,"fixed");
basepp->fixedprices[relpp->ind] = fixedprice;
basepp->minprices[relpp->ind] = minprice;
basepp->buymargins[relpp->ind] = buymargin;
basepp->sellmargins[relpp->ind] = sellmargin;
basepp->offsets[relpp->ind] = offset;
basepp->factors[relpp->ind] = factor;
refbase = jstr(argjson,"refbase");
refrel = jstr(argjson,"refrel");
fundvalue_bid = jstr(argjson,"fundvalue_bid");
fundvalue_ask = jstr(argjson,"fundvalue_ask");
if ( fundvalue_bid != 0 || fundvalue_ask != 0 || fixedprice > SMALLVAL || (refbase != 0 && refrel != 0) )
{
if ( fixedprice > SMALLVAL )
{
refbase = base;
refrel = rel;
}
for (i=0; i<num_LP_autorefs; i++)
{
if ( strcmp(base,LP_autorefs[i].base) == 0 && strcmp(rel,LP_autorefs[i].rel) == 0 )
{
if ( fundvalue_bid != 0 || fundvalue_ask != 0 )
{
fundvalue = jduplicate(argjson);
jdelete(fundvalue,"method");
jaddstr(fundvalue,"method","fundvalue");
LP_autorefs[i].fundvalue = fundvalue;
safecopy(LP_autorefs[i].fundbid,fundvalue_bid,sizeof(LP_autorefs[i].fundbid));
safecopy(LP_autorefs[i].fundask,fundvalue_ask,sizeof(LP_autorefs[i].fundask));
}
LP_autorefs[i].buymargin = buymargin;
LP_autorefs[i].sellmargin = sellmargin;
LP_autorefs[i].factor = factor;
LP_autorefs[i].offset = offset;
safecopy(LP_autorefs[i].refbase,refbase,sizeof(LP_autorefs[i].refbase));
safecopy(LP_autorefs[i].refrel,refrel,sizeof(LP_autorefs[i].refrel));
printf("%d Update ref %s/%s for %s/%s factor %.8f offset %.8f\n",i,refbase,refrel,base,rel,factor,offset);
break;
}
}
if ( i == num_LP_autorefs && num_LP_autorefs < sizeof(LP_autorefs)/sizeof(*LP_autorefs) )
{
if ( fundvalue_bid != 0 || fundvalue_ask != 0 )
{
fundvalue = jduplicate(argjson);
jdelete(fundvalue,"method");
jaddstr(fundvalue,"method","fundvalue");
LP_autorefs[num_LP_autorefs].fundvalue = fundvalue;
safecopy(LP_autorefs[num_LP_autorefs].fundbid,fundvalue_bid,sizeof(LP_autorefs[num_LP_autorefs].fundbid));
safecopy(LP_autorefs[num_LP_autorefs].fundask,fundvalue_ask,sizeof(LP_autorefs[num_LP_autorefs].fundask));
}
LP_autorefs[i].buymargin = buymargin;
LP_autorefs[i].sellmargin = sellmargin;
LP_autorefs[num_LP_autorefs].factor = factor;
LP_autorefs[num_LP_autorefs].offset = offset;
safecopy(LP_autorefs[num_LP_autorefs].refbase,refbase,sizeof(LP_autorefs[num_LP_autorefs].refbase));
safecopy(LP_autorefs[num_LP_autorefs].refrel,refrel,sizeof(LP_autorefs[num_LP_autorefs].refrel));
safecopy(LP_autorefs[num_LP_autorefs].base,base,sizeof(LP_autorefs[num_LP_autorefs].base));
safecopy(LP_autorefs[num_LP_autorefs].rel,rel,sizeof(LP_autorefs[num_LP_autorefs].rel));
printf("%d Using ref %s/%s for %s/%s factor %.8f, offset %.8f, margin %.8f/%.8f fixed %.8f\n",num_LP_autorefs,refbase,refrel,base,rel,factor,offset,buymargin,sellmargin,fixedprice);
num_LP_autorefs++;
}
}
LP_autoprices++;
retval = 0;
}
//LP_autoprice_iter(ctx,LP_priceinfofind("BTC"));
return(retval);
}
int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,struct iguana_info *buy,struct iguana_info *sell,double relvolume,int32_t setbaserel,char *gui)
{
char *retstr2; double bid,ask,maxprice; bits256 zero; uint32_t requestid,quoteid,iter,i; cJSON *retjson2;
char *retstr2; uint64_t txfee,desttxfee; double bid,ask,maxprice; bits256 zero; uint32_t requestid,quoteid,iter,i; cJSON *retjson2; struct LP_utxoinfo A; struct LP_address_utxo *utxos[1000]; int32_t max=(int32_t)(sizeof(utxos)/sizeof(*utxos));
LP_txfees(&txfee,&desttxfee,buy->symbol,sell->symbol);
requestid = quoteid = 0;
LP_myprice(&bid,&ask,buy->symbol,sell->symbol);
maxprice = ask;
@ -507,7 +754,8 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str
{
if ( relvolume < dstr(LP_MIN_TXFEE) )
break;
if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 )
if ( LP_address_myutxopair(&A,0,utxos,max,sell,sell->symbol,txfee,relvolume,maxprice,desttxfee) == 0 )
//if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 )
{
memset(zero.bytes,0,sizeof(zero));
if ( (retstr2= LP_autobuy(ctx,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1,zero,1)) != 0 )
@ -531,7 +779,8 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str
for (i=0; i<100; i++)
{
relvolume *= .99;
if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 )
if ( LP_address_myutxopair(&A,0,utxos,max,sell,sell->symbol,txfee,relvolume,maxprice,desttxfee) == 0 )
//if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 )
{
printf("i.%d relvolume %.8f from %.8f\n",i,relvolume,sell->relvolume);
break;
@ -553,8 +802,6 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str
else return(-1);
}
struct LP_portfoliotrade { double metric; char buycoin[65],sellcoin[65]; };
int32_t LP_portfolio_order(struct LP_portfoliotrade *trades,int32_t max,cJSON *array)
{
int32_t i,j,m,n = 0; cJSON *item; struct LP_portfoliotrade coins[256];
@ -605,7 +852,7 @@ void prices_loop(void *ctx)
{
char *retstr; cJSON *retjson,*array; char *buycoin,*sellcoin; struct iguana_info *buy,*sell; uint32_t requestid,quoteid; int32_t i,n,m; struct LP_portfoliotrade trades[256]; struct LP_priceinfo *btcpp;
strcpy(prices_loop_stats.name,"prices_loop");
prices_loop_stats.threshold = 91000.;
prices_loop_stats.threshold = 191000.;
while ( 1 )
{
//printf("prices loop autoprices.%d autorefs.%d\n",LP_autoprices,num_LP_autorefs);

366
iguana/exchanges/LP_prices.c

@ -18,24 +18,30 @@
// marketmaker
//
struct LP_orderbookentry { bits256 pubkey; double price; uint64_t avesatoshis,maxsatoshis,depth; uint32_t timestamp; int32_t numutxos; char coinaddr[64]; };
struct LP_orderbookentry
{
bits256 pubkey;
double price;
int64_t avesatoshis,maxsatoshis,depth,dynamictrust;
uint32_t timestamp;
int32_t numutxos;
char coinaddr[64];
};
struct LP_priceinfo
{
char symbol[68];
uint64_t coinbits;
int32_t ind,pad;
double diagval,high[2],low[2],last[2],bid[2],ask[2]; //volume,btcvolume,prevday; // mostly bittrex info
double diagval,high[2],low[2],last[2],bid[2],ask[2];
double relvals[LP_MAXPRICEINFOS];
double myprices[LP_MAXPRICEINFOS];
double minprices[LP_MAXPRICEINFOS]; // autoprice
double fixedprices[LP_MAXPRICEINFOS]; // fixedprices
double margins[LP_MAXPRICEINFOS];
double buymargins[LP_MAXPRICEINFOS];
double sellmargins[LP_MAXPRICEINFOS];
double offsets[LP_MAXPRICEINFOS];
double factors[LP_MAXPRICEINFOS];
//double maxprices[LP_MAXPRICEINFOS]; // autofill of base/rel
//double relvols[LP_MAXPRICEINFOS];
//FILE *fps[LP_MAXPRICEINFOS];
} LP_priceinfos[LP_MAXPRICEINFOS];
int32_t LP_numpriceinfos;
@ -48,8 +54,23 @@ struct LP_cacheinfo
uint32_t timestamp;
} *LP_cacheinfos;
void LP_priceinfos_clear()
{
int32_t i; struct LP_priceinfo *pp;
for (i=0; i<LP_numpriceinfos; i++)
{
pp = &LP_priceinfos[i];
memset(pp->myprices,0,sizeof(pp->myprices));
memset(pp->minprices,0,sizeof(pp->minprices));
memset(pp->fixedprices,0,sizeof(pp->fixedprices));
memset(pp->buymargins,0,sizeof(pp->buymargins));
memset(pp->sellmargins,0,sizeof(pp->sellmargins));
memset(pp->offsets,0,sizeof(pp->offsets));
memset(pp->factors,0,sizeof(pp->factors));
}
}
float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind)
float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t relind)
{
struct LP_pubkey_quote *pq,*tmp; int32_t scale; int64_t scale64;
*numutxosp = 0;
@ -75,7 +96,7 @@ float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatos
return(0);
}
void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind,float price,int64_t balance,char *utxocoin,int32_t numutxos,int64_t minutxo,int64_t maxutxo)
void LP_pubkey_update(struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t relind,float price,int64_t balance,char *utxocoin,int32_t numutxos,int64_t minutxo,int64_t maxutxo)
{
struct LP_pubkey_quote *pq,*tmp; int64_t aveutxo,scale64,ave64,max64; int32_t scale;
DL_FOREACH_SAFE(pubp->quotes,pq,tmp)
@ -91,7 +112,9 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin
pq->relind = relind;
pq->scale = 6; // millions of SATOSHIS, ie. 0.01
DL_APPEND(pubp->quotes,pq); // already serialized as only path is via stats_JSON()
//printf("create pubp quotes %d/%d\n",baseind,relind);
}
//printf("%d/%d price %.8f balance %.8f %s num.%d %.8f %.8f\n",baseind,relind,price,dstr(balance),utxocoin,numutxos,dstr(minutxo),dstr(maxutxo));
pq->price = price;
if ( utxocoin != 0 && utxocoin[0] != 0 )
{
@ -114,10 +137,13 @@ void LP_pubkey_update(struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relin
max64 = (1LL << 32) - 1;
pq->aveutxo = (uint32_t)ave64;
pq->maxutxo = (uint32_t)max64;
//printf("price %.8f base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",price,LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64);
//int64_t avesatoshis,maxsatoshis;
//price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseind,relind);
//printf("checkprice %.8f numutxos.%d ave %.8f max %.8f\n",price,numutxos,dstr(avesatoshis),dstr(maxsatoshis));
if ( 0 )
{
printf("price %.8f base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",price,LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64);
int64_t avesatoshis,maxsatoshis;
price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseind,relind);
printf("checkprice %.8f numutxos.%d ave %.8f max %.8f\n",price,numutxos,dstr(avesatoshis),dstr(maxsatoshis));
}
}
}
@ -214,9 +240,9 @@ struct LP_cacheinfo *LP_cachefind(char *base,char *rel,bits256 txid,int32_t vout
return(ptr);
}
struct LP_pubkeyinfo *LP_pubkey_rmd160find(uint8_t rmd160[20])
struct LP_pubkey_info *LP_pubkey_rmd160find(uint8_t rmd160[20])
{
struct LP_pubkeyinfo *pubp=0,*tmp;
struct LP_pubkey_info *pubp=0,*tmp;
portable_mutex_lock(&LP_pubkeymutex);
HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp)
{
@ -230,7 +256,7 @@ struct LP_pubkeyinfo *LP_pubkey_rmd160find(uint8_t rmd160[20])
struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr)
{
uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkeyinfo *pubp;
uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkey_info *pubp;
HASH_FIND(hh,coin->addresses,coinaddr,strlen(coinaddr),ap);
if ( ap != 0 && bits256_nonz(ap->pubkey) == 0 )
{
@ -246,7 +272,7 @@ struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr)
struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr)
{
uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkeyinfo *pubp;
uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkey_info *pubp;
ap = calloc(1,sizeof(*ap));
safecopy(ap->coinaddr,coinaddr,sizeof(ap->coinaddr));
bitcoin_addr2rmd160(coin->taddr,&addrtype,rmd160,coinaddr);
@ -260,18 +286,18 @@ struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr)
return(ap);
}
struct LP_pubkeyinfo *LP_pubkeyfind(bits256 pubkey)
struct LP_pubkey_info *LP_pubkeyfind(bits256 pubkey)
{
struct LP_pubkeyinfo *pubp=0;
struct LP_pubkey_info *pubp=0;
portable_mutex_lock(&LP_pubkeymutex);
HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp);
portable_mutex_unlock(&LP_pubkeymutex);
return(pubp);
}
struct LP_pubkeyinfo *LP_pubkeyadd(bits256 pubkey)
struct LP_pubkey_info *LP_pubkeyadd(bits256 pubkey)
{
char str[65]; struct LP_pubkeyinfo *pubp=0;
char str[65]; struct LP_pubkey_info *pubp=0;
portable_mutex_lock(&LP_pubkeymutex);
HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp);
if ( pubp == 0 )
@ -294,7 +320,7 @@ struct LP_pubkeyinfo *LP_pubkeyadd(bits256 pubkey)
int32_t LP_pubkey_istrusted(bits256 pubkey)
{
struct LP_pubkeyinfo *pubp;
struct LP_pubkey_info *pubp;
if ( (pubp= LP_pubkeyadd(pubkey)) != 0 )
return(pubp->istrusted != 0);
return(0);
@ -302,7 +328,7 @@ int32_t LP_pubkey_istrusted(bits256 pubkey)
char *LP_pubkey_trustset(bits256 pubkey,uint32_t trustval)
{
struct LP_pubkeyinfo *pubp;
struct LP_pubkey_info *pubp;
if ( (pubp= LP_pubkeyadd(pubkey)) != 0 )
{
pubp->istrusted = trustval;
@ -313,7 +339,7 @@ char *LP_pubkey_trustset(bits256 pubkey,uint32_t trustval)
char *LP_pubkey_trusted()
{
struct LP_pubkeyinfo *pubp,*tmp; cJSON *array = cJSON_CreateArray();
struct LP_pubkey_info *pubp,*tmp; cJSON *array = cJSON_CreateArray();
HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp)
{
if ( pubp->istrusted != 0 )
@ -322,10 +348,10 @@ char *LP_pubkey_trusted()
return(jprint(array,1));
}
uint64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr)
int64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr)
{
cJSON *array,*item; int32_t i,n; uint64_t metric=0,total;
LP_listunspent_both(coin->symbol,coinaddr,0);
cJSON *array,*item; int32_t i,n; int64_t metric=0,total;
//LP_listunspent_both(coin->symbol,coinaddr,0);
if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 )
{
total = 0;
@ -343,7 +369,7 @@ uint64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr)
return(metric);
}
cJSON *LP_pubkeyjson(struct LP_pubkeyinfo *pubp)
cJSON *LP_pubkeyjson(struct LP_pubkey_info *pubp)
{
int32_t baseid,relid,numutxos; int64_t avesatoshis,maxsatoshis; char *base,hexstr[67],hexstr2[67],sigstr[256]; double price; cJSON *item,*array,*obj;
obj = cJSON_CreateObject();
@ -380,7 +406,7 @@ cJSON *LP_pubkeyjson(struct LP_pubkeyinfo *pubp)
char *LP_prices()
{
struct LP_pubkeyinfo *pubp,*tmp; cJSON *array = cJSON_CreateArray();
struct LP_pubkey_info *pubp,*tmp; cJSON *array = cJSON_CreateArray();
HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp)
{
jaddi(array,LP_pubkeyjson(pubp));
@ -388,76 +414,6 @@ char *LP_prices()
return(jprint(array,1));
}
/*void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj)
{
struct LP_pubkeyinfo *pubp; struct LP_priceinfo *basepp,*relpp; uint32_t timestamp; bits256 pubkey; cJSON *asks,*item; uint8_t rmd160[20]; int32_t i,n,relid,mismatch; char *base,*rel,*hexstr; double askprice; uint32_t now;
now = (uint32_t)time(NULL);
pubkey = jbits256(obj,"pubkey");
if ( bits256_nonz(pubkey) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 )
{
if ( (hexstr= jstr(obj,"rmd160")) != 0 && strlen(hexstr) == 2*sizeof(rmd160) )
decode_hex(rmd160,sizeof(rmd160),hexstr);
if ( memcmp(pubp->rmd160,rmd160,sizeof(rmd160)) != 0 )
mismatch = 1;
else mismatch = 0;
if ( bits256_cmp(pubkey,G.LP_mypub25519) == 0 && mismatch == 0 )
peer->needping = 0;
LP_pubkey_sigcheck(pubp,obj);
timestamp = juint(obj,"timestamp");
if ( timestamp > now )
timestamp = now;
if ( timestamp >= pubp->timestamp && (asks= jarray(&n,obj,"asks")) != 0 )
{
for (i=0; i<n; i++)
{
item = jitem(asks,i);
base = jstri(item,0);
rel = jstri(item,1);
askprice = jdoublei(item,2);
if ( LP_pricevalid(askprice) > 0 )
{
if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 )
{
//char str[65]; printf("gotprice %s %s/%s (%d/%d) %.8f\n",bits256_str(str,pubkey),base,rel,basepp->ind,relid,askprice);
pubp->matrix[basepp->ind][relid] = askprice;
//pubp->timestamps[basepp->ind][relid] = timestamp;
if ( (relpp= LP_priceinfofind(rel)) != 0 )
{
dxblend(&basepp->relvals[relpp->ind],askprice,0.9);
dxblend(&relpp->relvals[basepp->ind],1. / askprice,0.9);
}
}
}
}
}
}
}
void LP_peer_pricesquery(struct LP_peerinfo *peer)
{
char *retstr; cJSON *array; int32_t i,n;
if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 )
return;
peer->needping = (uint32_t)time(NULL);
if ( (retstr= issue_LP_getprices(peer->ipaddr,peer->port)) != 0 )
{
if ( (array= cJSON_Parse(retstr)) != 0 )
{
if ( is_cJSON_Array(array) && (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
LP_prices_parse(peer,jitem(array,i));
}
free_json(array);
}
free(retstr);
}
if ( peer->needping != 0 )
{
//printf("%s needs ping\n",peer->ipaddr);
}
}*/
double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,int32_t vout)
{
struct LP_cacheinfo *ptr;
@ -465,14 +421,14 @@ double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,i
{
if ( qp != 0 )
(*qp) = ptr->Q;
if ( ptr->price == 0. && ptr->Q.satoshis != 0 )
if ( ptr->price == 0. && ptr->Q.satoshis > ptr->Q.txfee )
{
ptr->price = (double)ptr->Q.destsatoshis / ptr->Q.satoshis;
ptr->price = (double)ptr->Q.destsatoshis / (ptr->Q.satoshis - ptr->Q.txfee);
if ( LP_pricevalid(ptr->price) <= 0 )
ptr->price = 0.;
printf("LP_pricecache: set %s/%s ptr->price %.8f\n",base,rel,ptr->price);
}
printf(">>>>>>>>>> found %s/%s %.8f\n",base,rel,ptr->price);
//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);
@ -486,10 +442,10 @@ void LP_priceinfoupdate(char *base,char *rel,double price)
{
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);
basepp->relvals[relpp->ind] = price;
relpp->relvals[basepp->ind] = 1. / price;
dxblend(&basepp->relvals[relpp->ind],price,0.9);
dxblend(&relpp->relvals[basepp->ind],1. / price,0.9);
//basepp->relvals[relpp->ind] = price;
//relpp->relvals[basepp->ind] = 1. / price;
}
}
}
@ -555,13 +511,26 @@ char *LP_myprices()
int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price)
{
struct LP_priceinfo *basepp,*relpp; struct LP_pubkeyinfo *pubp;
struct LP_priceinfo *basepp,*relpp; struct LP_pubkey_info *pubp;
*changedp = 0;
if ( base != 0 && rel != 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{
if ( fabs(basepp->myprices[relpp->ind] - price)/price > 0.001 )
if ( price == 0. || fabs(basepp->myprices[relpp->ind] - price)/price > 0.001 )
*changedp = 1;
if ( price == 0. )
{
relpp->minprices[basepp->ind] = 0.;
relpp->fixedprices[basepp->ind] = 0.;
relpp->buymargins[basepp->ind] = 0.;
relpp->sellmargins[basepp->ind] = 0.;
relpp->offsets[basepp->ind] = 0.;
relpp->factors[basepp->ind] = 0.;
}
/*else if ( basepp->myprices[relpp->ind] > SMALLVAL )
{
price = (basepp->myprices[relpp->ind] * 0.9) + (0.1 * price);
}*/
basepp->myprices[relpp->ind] = price; // ask
//printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price);
//relpp->myprices[basepp->ind] = (1. / price); // bid
@ -583,7 +552,9 @@ double LP_price(char *base,char *rel)
if ( (basepp= LP_priceinfoptr(&relind,base,rel)) != 0 )
{
if ( (price= basepp->myprices[relind]) == 0. )
{
price = basepp->relvals[relind];
}
}
return(price);
}
@ -750,11 +721,12 @@ cJSON *LP_orderbookjson(char *symbol,struct LP_orderbookentry *op)
jaddnum(item,"depth",dstr(op->depth)*0.8);
jaddbits256(item,"pubkey",op->pubkey);
jaddnum(item,"age",time(NULL)-op->timestamp);
jaddnum(item,"zcredits",dstr(op->dynamictrust));
}
return(item);
}
struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,double price,int32_t numutxos,uint64_t avesatoshis,uint64_t maxsatoshis,bits256 pubkey,uint32_t timestamp,uint64_t balance)
struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,double price,int32_t numutxos,int64_t avesatoshis,int64_t maxsatoshis,bits256 pubkey,uint32_t timestamp,int64_t balance,int64_t dynamictrust)
{
struct LP_orderbookentry *op;
if ( (op= calloc(1,sizeof(*op))) != 0 )
@ -767,13 +739,14 @@ struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,d
op->pubkey = pubkey;
op->timestamp = timestamp;
op->depth = balance;
op->dynamictrust = dynamictrust;
}
return(op);
}
void LP_pubkeys_query()
{
uint8_t zeroes[20]; bits256 zero; cJSON *reqjson; struct LP_pubkeyinfo *pubp=0,*tmp;
uint8_t zeroes[20]; bits256 zero; cJSON *reqjson; struct LP_pubkey_info *pubp=0,*tmp;
memset(zero.bytes,0,sizeof(zero));
memset(zeroes,0,sizeof(zeroes));
HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp)
@ -792,7 +765,7 @@ void LP_pubkeys_query()
int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *rel,struct LP_orderbookentry *(**arrayp),int32_t num,int32_t cachednum,int32_t duration)
{
char coinaddr[64]; uint8_t zeroes[20]; struct LP_pubkeyinfo *pubp=0,*tmp; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; struct LP_address *ap; struct iguana_info *basecoin; uint32_t oldest; double price; int32_t baseid,relid,n; int64_t maxsatoshis,balance,avesatoshis;
char coinaddr[64]; uint8_t zeroes[20]; struct LP_pubkey_info *pubp=0,*tmp; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; struct LP_address *ap; struct iguana_info *basecoin; uint32_t oldest; double price; int32_t baseid,relid,n; int64_t maxsatoshis,balance,avesatoshis;
if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 )
baseid = basepp->ind;
else return(num);
@ -827,7 +800,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *
}
//printf("%s/%s %s n.%d ap->n.%d %.8f\n",base,rel,coinaddr,n,ap->n,dstr(ap->total));
}
if ( (op= LP_orderbookentry(coinaddr,base,rel,polarity > 0 ? price : 1./price,n,avesatoshis,maxsatoshis,pubp->pubkey,pubp->timestamp,balance)) != 0 )
if ( (op= LP_orderbookentry(coinaddr,base,rel,polarity > 0 ? price : 1./price,n,avesatoshis,maxsatoshis,pubp->pubkey,pubp->timestamp,balance,pubp->dynamictrust)) != 0 )
{
*arrayp = realloc(*arrayp,sizeof(*(*arrayp)) * (num+1));
(*arrayp)[num++] = op;
@ -840,7 +813,7 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *
char *LP_orderbook(char *base,char *rel,int32_t duration)
{
uint32_t now,i; uint64_t depth; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*array; struct iguana_info *basecoin,*relcoin; int32_t n,numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid,suppress_prefetch=0;
uint32_t now,i; int64_t depth,askdepth=0,biddepth=0; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*array; struct iguana_info *basecoin,*relcoin; int32_t n,numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid,suppress_prefetch=0;
basecoin = LP_coinfind(base);
relcoin = LP_coinfind(rel);
if ( basecoin == 0 || relcoin == 0 )
@ -887,20 +860,26 @@ char *LP_orderbook(char *base,char *rel,int32_t duration)
}
for (i=n=0; i<numbids; i++)
{
biddepth = bids[i]->depth;
jaddi(array,LP_orderbookjson(rel,bids[i]));
if ( suppress_prefetch == 0 && n < 3 && bids[i]->numutxos == 0 )
{
//printf("bid ping %s %s\n",rel,bids[i]->coinaddr);
LP_address(relcoin,bids[i]->coinaddr);
if ( 0 && relcoin->electrum == 0 )
/*if ( 0 && relcoin->electrum == 0 )
{
LP_listunspent_issue(rel,bids[i]->coinaddr,0);
//else if ( (tmpjson= LP_listunspent(rel,bids[i]->coinaddr)) != 0 )
// free_json(tmpjson);
LP_listunspent_query(rel,bids[i]->coinaddr);
}
}*/
n++;
}
if ( i == 0 )
{
LP_priceinfoupdate(rel,base,1. / bids[i]->price);
//printf("update %s/%s %.8f [%.8f]\n",rel,base,1./bids[i]->price,bids[i]->price);
}
free(bids[i]);
bids[i] = 0;
}
@ -908,23 +887,30 @@ char *LP_orderbook(char *base,char *rel,int32_t duration)
relcoin->lastmonitor -= 3600;
jadd(retjson,"bids",array);
jaddnum(retjson,"numbids",numbids);
jaddnum(retjson,"biddepth",dstr(biddepth));
array = cJSON_CreateArray();
for (i=n=0; i<numasks; i++)
{
askdepth = asks[i]->depth;
jaddi(array,LP_orderbookjson(base,asks[i]));
if ( suppress_prefetch == 0 && n < 3 && asks[i]->numutxos == 0 )
{
//printf("ask ping %s %s\n",base,asks[i]->coinaddr);
LP_address(basecoin,asks[i]->coinaddr);
if ( 0 && basecoin->electrum == 0 )
/*if ( 0 && basecoin->electrum == 0 )
{
LP_listunspent_issue(base,asks[i]->coinaddr,0);
//else if ( (tmpjson= LP_listunspent(base,asks[i]->coinaddr)) != 0 )
// free_json(tmpjson);
LP_listunspent_query(base,asks[i]->coinaddr);
}
}*/
n++;
}
if ( i == 0 )
{
LP_priceinfoupdate(base,rel,asks[i]->price);
//printf("update %s/%s %.8f [%.8f]\n",base,rel,asks[i]->price,1./asks[i]->price);
}
free(asks[i]);
asks[i] = 0;
}
@ -932,6 +918,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration)
basecoin->lastmonitor -= 3600;
jadd(retjson,"asks",array);
jaddnum(retjson,"numasks",numasks);
jaddnum(retjson,"askdepth",dstr(askdepth));
jaddstr(retjson,"base",base);
jaddstr(retjson,"rel",rel);
jaddnum(retjson,"timestamp",now);
@ -942,41 +929,32 @@ char *LP_orderbook(char *base,char *rel,int32_t duration)
return(jprint(retjson,1));
}
uint64_t LP_KMDvalue(struct iguana_info *coin,uint64_t balance)
int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance)
{
cJSON *bids,*asks,*orderbook,*item; double bid=0,ask=0,price = 0.; int32_t numasks,numbids; char *retstr; uint64_t KMDvalue=0;
double price = 0.; int64_t KMDvalue=0;
if ( balance != 0 )
{
if ( strcmp(coin->symbol,"KMD") == 0 )
KMDvalue = balance;
else if ( (retstr= LP_orderbook(coin->symbol,"KMD",-1)) != 0 )
else
{
if ( (orderbook= cJSON_Parse(retstr)) != 0 )
{
if ( (asks= jarray(&numasks,orderbook,"asks")) != 0 && numasks > 0 )
{
item = jitem(asks,0);
price = ask = jdouble(item,"price");
//printf("%s/%s ask %.8f\n",coin->symbol,"KMD",ask);
}
if ( (bids= jarray(&numbids,orderbook,"bids")) != 0 && numbids > 0 )
{
item = jitem(asks,0);
bid = jdouble(item,"price");
if ( price == 0. )
price = bid;
else price = (bid + ask) * 0.5;
//printf("%s/%s bid %.8f ask %.8f price %.8f\n",coin->symbol,"KMD",bid,ask,price);
}
if ( (price= LP_price(coin->symbol,"KMD")) > SMALLVAL )
KMDvalue = price * balance;
free_json(orderbook);
}
free(retstr);
}
}
return(KMDvalue);
}
int64_t LP_kmdvalue(char *symbol,int64_t satoshis)
{
struct iguana_info *coin; int64_t kmdvalue = 0;
if ( (coin= LP_coinfind(symbol)) != 0 )
kmdvalue = LP_KMDvalue(coin,satoshis);
if ( kmdvalue == 0 )
kmdvalue = satoshis;
return(kmdvalue);
}
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);
@ -1001,7 +979,7 @@ void LP_priceitemadd(cJSON *retarray,uint32_t timestamp,double avebid,double ave
cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,int32_t timescale)
{
cJSON *retarray; char askfname[1024],bidfname[1024]; uint64_t bidprice64,askprice64; uint32_t bidnow,asknow,bidi,aski,lastbidi,lastaski; int32_t numbids,numasks; double bidemit,askemit,bidsum,asksum,bid,ask,highbid,lowbid,highask,lowask,bidemit2,askemit2; FILE *askfp=0,*bidfp=0;
cJSON *retarray; char askfname[1024],bidfname[1024]; int64_t bidprice64,askprice64; uint32_t bidnow,asknow,bidi,aski,lastbidi,lastaski; int32_t numbids,numasks; double bidemit,askemit,bidsum,asksum,bid,ask,highbid,lowbid,highask,lowask,bidemit2,askemit2; FILE *askfp=0,*bidfp=0;
if ( timescale <= 0 )
timescale = 60;
if ( lasttime == 0 )
@ -1110,9 +1088,9 @@ cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,i
return(retarray);
}
void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *utxocoin,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo)
void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *utxocoin,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo,int64_t unconfcredits)
{
struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkeyinfo *pubp; char str[65],fname[512]; FILE *fp;
struct LP_priceinfo *basepp,*relpp; uint32_t now; int64_t price64; struct LP_pubkey_info *pubp; char str[65],fname[512]; FILE *fp;
//printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey));
if ( LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{
@ -1146,6 +1124,8 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *u
{
if ( (LP_rand() % 1000) == 0 )
printf("PRICEFEED UPDATE.(%-6s/%6s) %12.8f %s %12.8f\n",base,rel,price,bits256_str(str,pubkey),1./price);
if ( unconfcredits > pubp->unconfcredits )
pubp->unconfcredits = unconfcredits;
pubp->timestamp = (uint32_t)time(NULL);
LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,balance,utxocoin,numrelutxos,minutxo,maxutxo);
//pubp->depthinfo[basepp->ind][relpp->ind] = LP_depthinfo_compact();
@ -1162,3 +1142,105 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *u
// printf("error finding %s/%s %.8f\n",base,rel,price);
}
double LP_CMCbtcprice(double *price_usdp,char *symbol)
{
char *retstr; cJSON *ticker,*item; double price_btc = 0.;
*price_usdp = 0.;
if ( (retstr= cmc_ticker(symbol)) != 0 )
{
if ( (ticker= cJSON_Parse(retstr)) != 0 )
{
item = jitem(ticker,0);
price_btc = jdouble(item,"price_btc");
*price_usdp = jdouble(item,"price_usd");
//printf("%.8f item.(%s)\n",price_btc,jprint(item,0));
free_json(ticker);
}
free(retstr);
}
return(price_btc);
}
cJSON *LP_fundvalue(cJSON *argjson)
{
cJSON *holdings,*item,*newitem,*array,*retjson; int32_t i,iter,n,missing=0; double usdprice,divisor,btcprice,balance,btcsum,KMDholdings,numKMD; struct iguana_info *coin; char *symbol,*coinaddr; int64_t fundvalue,KMDvalue = 0;
fundvalue = 0;
KMDholdings = btcsum = 0.;
array = cJSON_CreateArray();
for (iter=0; iter<2; iter++)
{
if ( iter == 0 )
holdings = jarray(&n,argjson,"holdings");
else
{
if ( (coinaddr= jstr(argjson,"address")) != 0 )
{
holdings = LP_balances(coinaddr);
n = cJSON_GetArraySize(holdings);
} else break;
}
if ( holdings != 0 )
{
for (i=0; i<n; i++)
{
item = jitem(holdings,i);
if ( (symbol= jstr(item,"coin")) != 0 && (balance= jdouble(item,"balance")) > SMALLVAL )
{
newitem = cJSON_CreateObject();
jaddstr(newitem,"coin",symbol);
jaddnum(newitem,"balance",balance);
if ( (coin= LP_coinfind(symbol)) != 0 && (KMDvalue= LP_KMDvalue(coin,SATOSHIDEN * balance)) > 0 )
{
jaddnum(newitem,"KMD",dstr(KMDvalue));
fundvalue += KMDvalue;
if ( strcmp(symbol,"KMD") == 0 )
KMDholdings += dstr(KMDvalue);
}
else if ( iter == 0 && (btcprice= LP_CMCbtcprice(&usdprice,symbol)) > SMALLVAL )
{
btcsum += btcprice * balance;
jaddnum(newitem,"BTC",btcprice * balance);
}
else jaddstr(newitem,"error","no price source");
jaddi(array,newitem);
} else missing++;
}
}
}
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddnum(retjson,"missing",missing);
jadd(retjson,"holdings",array);
btcprice = LP_CMCbtcprice(&usdprice,"komodo");
divisor = jdouble(argjson,"divisor");
jaddnum(retjson,"KMDholdings",KMDholdings);
if ( btcsum != 0 )
{
if ( btcprice > SMALLVAL )
{
numKMD = (btcsum / btcprice);
fundvalue += numKMD * SATOSHIDEN;
jaddnum(retjson,"KMD_BTC",btcprice);
jaddnum(retjson,"btcsum",btcsum);
numKMD += KMDholdings;
jaddnum(retjson,"btc2kmd",numKMD);
if ( divisor != 0 )
{
jaddnum(retjson,"NAV_KMD",numKMD/divisor);
jaddnum(retjson,"NAV_BTC",(btcsum + (KMDholdings * btcprice))/divisor);
jaddnum(retjson,"NAV_USD",(usdprice * numKMD)/divisor);
}
}
}
jaddnum(retjson,"fundvalue",dstr(fundvalue));
if ( divisor != 0 )
{
jaddnum(retjson,"divisor",divisor);
numKMD = dstr(fundvalue);
jaddnum(retjson,"assetNAV_KMD",numKMD/divisor);
jaddnum(retjson,"assetNAV_BTC",(btcprice * numKMD)/divisor);
jaddnum(retjson,"assetNAV_USD",(usdprice * numKMD)/divisor);
}
return(retjson);
}

575
iguana/exchanges/LP_privkey.c

@ -0,0 +1,575 @@
/******************************************************************************
* 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
//
int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub)
{
int32_t enable_utxos = 0;
char *script,destaddr[64]; cJSON *array,*item; bits256 txid,deposittxid,zero; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,biggerval,value,total = 0; int64_t targetval; //struct LP_utxoinfo *utxo;
if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) )
{
//printf("coin not active\n");
return(0);
}
if ( coin->privkeydepth > 0 )
return(0);
coin->privkeydepth++;
LP_address(coin,coin->smartaddr);
//if ( coin->inactive == 0 )
// LP_listunspent_issue(coin->symbol,coin->smartaddr,0);
memset(zero.bytes,0,sizeof(zero));
array = LP_listunspent(coin->symbol,coin->smartaddr,zero,zero);
if ( array != 0 )
{
txfee = LP_txfeecalc(coin,0,0);
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
coin->numutxos = n;
//printf("LP_privkey_init %s %d\n",coin->symbol,n);
for (iambob=0; iambob<=1; iambob++)
{
if ( iambob == 0 )
values = calloc(n,sizeof(*values));
else memset(values,0,n * sizeof(*values));
used = 0;
for (i=0; i<n; i++)
{
item = jitem(array,i);
value = LP_listunspent_parseitem(coin,&txid,&vout,&height,item);
satoshis = LP_txvalue(destaddr,coin->symbol,txid,vout);
if ( satoshis != 0 && satoshis != value )
printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest"));
if ( coin->electrum != 0 || LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 )//&& height > 0 )
{
values[i] = satoshis;
//flag += LP_address_utxoadd(coin,destaddr,txid,vout,satoshis,height,-1);
} else used++;
}
//printf("array.%d\n",n);
while ( used < n-1 )
{
//for (i=0; i<n; i++)
// printf("%.8f ",dstr(values[i]));
//printf("used.%d of n.%d\n",used,n);
if ( (i= LP_maxvalue(values,n)) >= 0 )
{
item = jitem(array,i);
if ( coin->electrum == 0 )
{
deposittxid = jbits256(item,"txid");
depositvout = juint(item,"vout");
script = jstr(item,"scriptPubKey");
}
else
{
deposittxid = jbits256(item,"tx_hash");
depositvout = juint(item,"tx_pos");
script = coin->smartaddr;
}
biggerval = values[i];
values[i] = 0, used++;
if ( iambob == 0 )
targetval = (biggerval / 776) + txfee;
else targetval = (biggerval / 9) * 8 + 2*txfee;
if ( targetval < txfee*2 )
targetval = txfee*2;
//printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(biggerval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval));
if ( biggerval < (1+LP_MINSIZE_TXFEEMULT)*txfee )
continue;
i = -1;
if ( iambob != 0 )
{
if ( (i= LP_nearestvalue(iambob,values,n,targetval)) < 0 )
targetval /= 4;
if ( targetval < txfee*(1+LP_MINSIZE_TXFEEMULT) )
continue;
}
if ( i >= 0 || (i= LP_nearestvalue(iambob,values,n,targetval)) >= 0 )
{
//printf("iambob.%d i.%d %.8f target %.8f\n",iambob,i,dstr(biggerval),dstr(targetval));
item = jitem(array,i);
cmpflag = 0;
if ( coin->electrum == 0 )
{
txid = jbits256(item,"txid");
vout = juint(item,"vout");
if ( jstr(item,"scriptPubKey") != 0 && strcmp(script,jstr(item,"scriptPubKey")) == 0 )
cmpflag = 1;
}
else
{
txid = jbits256(item,"tx_hash");
vout = juint(item,"tx_pos");
cmpflag = 1;
}
if ( cmpflag != 0 )
{
value = values[i];
values[i] = 0, used++;
/*portable_mutex_lock(&LP_UTXOmutex);
if ( iambob != 0 )
{
if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,biggerval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 )
{
}
}
else
{
//printf("call utxoadd\n");
if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,biggerval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,biggerval)) != 0 )
{
}
}
portable_mutex_unlock(&LP_UTXOmutex);*/
total += value;
} // else printf("scriptmismatch.(%s) vs %s\n",script,jprint(item,0));
} //else printf("nothing near i.%d\n",i);
} else break;
}
if ( enable_utxos == 0 )
break;
}
}
free_json(array);
if ( 0 && flag != 0 )
LP_postutxos(coin->symbol,coin->smartaddr);
}
if ( values != 0 )
free(values);
if ( coin->privkeydepth > 0 )
coin->privkeydepth--;
//printf("privkey.%s %.8f\n",symbol,dstr(total));
return(flag);
}
char *LP_secretaddresses(void *ctx,char *prefix,char *passphrase,int32_t n,uint8_t taddr,uint8_t pubtype)
{
int32_t i; uint8_t tmptype,pubkey33[33],rmd160[20]; char output[777*45],str[65],str2[65],buf[8192],wifstr[128],coinaddr[64]; bits256 checkprivkey,privkey,pubkey; cJSON *retjson;
retjson = cJSON_CreateObject();
if ( prefix == 0 || prefix[0] == 0 )
prefix = "secretaddress";
if ( passphrase == 0 || passphrase[0] == 0 )
passphrase = "password";
if ( n <= 0 )
n = 16;
else if ( n > 777 )
n = 777;
conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,taddr,pubtype);
printf("generator (%s) secrets.[%d] <%s> t.%u p.%u\n",coinaddr,n,passphrase,taddr,pubtype);
sprintf(output,"\"addresses\":[");
for (i=0; i<n; i++)
{
sprintf(buf,"%s %s %03d",prefix,passphrase,i);
conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)buf,(int32_t)strlen(buf));
bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,taddr,pubtype);
bitcoin_priv2wif(0,wifstr,privkey,188);
bitcoin_wif2priv(0,&tmptype,&checkprivkey,wifstr);
bitcoin_addr2rmd160(taddr,&tmptype,rmd160,coinaddr);
if ( bits256_cmp(checkprivkey,privkey) != 0 )
{
printf("WIF.(%s) error -> %s vs %s?\n",wifstr,bits256_str(str,privkey),bits256_str(str2,checkprivkey));
free_json(retjson);
return(clonestr("{\"error\":\"couldnt validate wifstr\"}"));
}
else if ( tmptype != pubtype )
{
printf("checktype.%d != pubtype.%d\n",tmptype,pubtype);
free_json(retjson);
return(clonestr("{\"error\":\"couldnt validate pubtype\"}"));
}
jaddstr(retjson,coinaddr,wifstr);
sprintf(output+strlen(output),"\\\"%s\\\"%c ",coinaddr,i<n-1?',':' ');
printf("./komodo-cli jumblr_secret %s\n",coinaddr);
}
printf("%s]\n",output);
return(jprint(retjson,1));
}
static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
int32_t LP_wifstr_valid(char *wifstr)
{
bits256 privkey,cmpkey; uint8_t wiftype; char cmpstr[128],cmpstr2[128]; int32_t i;
memset(privkey.bytes,0,sizeof(privkey));
memset(cmpkey.bytes,0,sizeof(cmpkey));
for (i=0; wifstr[i]!=0; i++)
if ( strchr(base58_chars,wifstr[i]) == 0 )
return(0);
bitcoin_wif2priv(0,&wiftype,&privkey,wifstr);
bitcoin_priv2wif(0,cmpstr,privkey,wiftype);
if ( strcmp(cmpstr,wifstr) == 0 )
{
printf("%s is valid wif\n",wifstr);
return(1);
}
else if ( bits256_nonz(privkey) != 0 )
{
bitcoin_wif2priv(0,&wiftype,&cmpkey,cmpstr);
bitcoin_priv2wiflong(0,cmpstr2,privkey,wiftype);
char str[65],str2[65]; printf("mismatched wifstr %s -> %s -> %s %s %s\n",wifstr,bits256_str(str,privkey),cmpstr,bits256_str(str2,cmpkey),cmpstr2);
if ( bits256_cmp(privkey,cmpkey) == 0 )
return(1);
}
return(0);
}
bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguana_info *coin,char *passphrase,char *wifstr)
{
//static uint32_t counter;
bits256 privkey,userpub,zero,userpass,checkkey,tmpkey; char tmpstr[128]; cJSON *retjson; uint8_t tmptype; int32_t notarized; uint64_t nxtaddr;
if ( (wifstr == 0 || wifstr[0] == 0) && LP_wifstr_valid(passphrase) > 0 )
{
wifstr = passphrase;
passphrase = 0;
}
if ( passphrase != 0 && passphrase[0] != 0 )
{
calc_NXTaddr(G.LP_NXTaddr,userpub.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
conv_NXTpassword(privkey.bytes,pubkeyp->bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
privkey.bytes[0] &= 248, privkey.bytes[31] &= 127, privkey.bytes[31] |= 64;
//vcalc_sha256(0,checkkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
//printf("SHA256.(%s) ",bits256_str(pstr,checkkey));
//printf("privkey.(%s)\n",bits256_str(pstr,privkey));
bitcoin_priv2wif(coin->wiftaddr,tmpstr,privkey,coin->wiftype);
bitcoin_wif2priv(coin->wiftaddr,&tmptype,&checkkey,tmpstr);
if ( bits256_cmp(privkey,checkkey) != 0 )
{
char str[65],str2[65]; printf("mismatched privkeys from wif conversion: %s -> %s -> %s\n",bits256_str(str,privkey),tmpstr,bits256_str(str2,checkkey));
exit(1);
}
}
else
{
bitcoin_wif2priv(coin->wiftaddr,&tmptype,&privkey,wifstr);
bitcoin_priv2wif(coin->wiftaddr,tmpstr,privkey,tmptype);
if ( strcmp(tmpstr,wifstr) != 0 )
{
printf("error reproducing the wifstr, likely edge case like non-supported uncompressed pubkey\n");
exit(1);
}
tmpkey = privkey;
nxtaddr = conv_NXTpassword(tmpkey.bytes,pubkeyp->bytes,0,0);
RS_encode(G.LP_NXTaddr,nxtaddr);
}
bitcoin_priv2pub(ctx,coin->pubkey33,coin->smartaddr,privkey,coin->taddr,coin->pubtype);
if ( coin->counter == 0 )
{
coin->counter++;
memcpy(G.LP_pubsecp,coin->pubkey33,33);
bitcoin_priv2wif(coin->wiftaddr,tmpstr,privkey,coin->wiftype);
bitcoin_addr2rmd160(coin->taddr,&tmptype,G.LP_myrmd160,coin->smartaddr);
LP_privkeyadd(privkey,G.LP_myrmd160);
G.LP_privkey = privkey;
if ( G.counter++ == 0 )
{
bitcoin_priv2wif(coin->wiftaddr,G.USERPASS_WIFSTR,privkey,188);
bitcoin_wif2priv(coin->wiftaddr,&tmptype,&checkkey,G.USERPASS_WIFSTR);
if ( bits256_cmp(checkkey,privkey) != 0 )
{
char str[65],str2[65];
printf("FATAL ERROR converting USERPASS_WIFSTR %s -> %s != %s\n",G.USERPASS_WIFSTR,bits256_str(str,checkkey),bits256_str(str2,privkey));
exit(-1);
}
conv_NXTpassword(userpass.bytes,pubkeyp->bytes,(uint8_t *)G.USERPASS_WIFSTR,(int32_t)strlen(G.USERPASS_WIFSTR));
userpub = curve25519(userpass,curve25519_basepoint9());
printf("userpass.(%s)\n",bits256_str(G.USERPASS,userpub));
}
}
if ( coin->importedprivkey == 0 && coin->electrum == 0 && coin->userpass[0] != 0 && LP_getheight(&notarized,coin) > 0 )
{
memset(zero.bytes,0,sizeof(zero));
LP_listunspent_issue(coin->symbol,coin->smartaddr,0,zero,zero);
if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 )
{
if ( jobj(retjson,"error") != 0 )
{
printf("cant importprivkey.%s %s -> (%s), abort session\n",coin->symbol,coin->smartaddr,jprint(retjson,1));
exit(-1);
}
free_json(retjson);
}
coin->importedprivkey = (uint32_t)time(NULL);
}
vcalc_sha256(0,checkkey.bytes,privkey.bytes,sizeof(privkey));
checkkey.bytes[0] &= 248, checkkey.bytes[31] &= 127, checkkey.bytes[31] |= 64;
G.LP_mypub25519 = *pubkeyp = curve25519(checkkey,curve25519_basepoint9());
G.LP_mypriv25519 = checkkey;
LP_pubkeyadd(G.LP_mypub25519);
return(privkey);
}
void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase)
{
struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33]; int32_t initonly;
initonly = (passphrase != 0);
memset(privkey.bytes,0,sizeof(privkey));
memset(pubkey.bytes,0,sizeof(pubkey));
//printf("Total coins: %d\n", HASH_COUNT(LP_coins));
//int num_iter = 0;
HASH_ITER(hh,LP_coins,coin,tmp)
{
//printf("LP_privkey_updates [%02d / %02d]\n", num_iter++, HASH_COUNT(LP_coins));
if ( initonly != 0 )
{
coin->counter = 0;
memset(coin->smartaddr,0,sizeof(coin->smartaddr));
if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 )
privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,"");
}
//printf("i.%d of %d\n",i,LP_numcoins);
else if ( IAMLP == 0 || coin->inactive == 0 )
{
//printf("from updates %s\n",coin->symbol);
if ( 0 && LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (LP_rand() % 10) == 0 )
{
//LP_postutxos(coin->symbol,coin->smartaddr);
}
}
}
}
int32_t LP_passphrase_init(char *passphrase,char *gui)
{
static void *ctx; int32_t counter; //iambob,; struct LP_utxoinfo *utxo,*tmp;
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( G.LP_pendingswaps != 0 )
return(-1);
G.initializing = 1;
if ( gui == 0 )
gui = "cli";
counter = G.USERPASS_COUNTER;
while ( G.waiting == 0 )
{
printf("waiting for G.waiting\n");
sleep(5);
}
memset(&G,0,sizeof(G));
vcalc_sha256(0,G.LP_passhash.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
LP_privkey_updates(ctx,LP_mypubsock,passphrase);
init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20);
G.LP_sessionid = (uint32_t)time(NULL);
safecopy(G.gui,gui,sizeof(G.gui));
LP_tradebot_pauseall();
LP_portfolio_reset();
LP_priceinfos_clear();
G.USERPASS_COUNTER = counter;
G.initializing = 0;
return(0);
}
void LP_privkey_tests()
{
char wifstr[64],str[65],str2[65]; bits256 privkey,checkkey; int32_t i; uint8_t tmptype;
for (i=0; i<200000000; i++)
{
privkey = rand256(0);
bitcoin_priv2wif(0,wifstr,privkey,0xff);
bitcoin_wif2priv(0,&tmptype,&checkkey,wifstr);
if ( bits256_cmp(privkey,checkkey) != 0 )
{
printf("i.%d: %s vs %s\n",i,bits256_str(str,privkey),bits256_str(str2,checkkey));
exit(-1);
}
if ( (i % 1000000) == 0 )
fprintf(stderr,"%.1f%% ",100.*(double)i/200000000);
}
printf("%d privkeys checked\n",i);
}
// from https://github.com/owencm/C-Steganography-Framework
#include "../../crypto777/jpeg/cdjpeg.h" // Common decls for compressing and decompressing jpegs
int32_t LP_jpg_process(int32_t *capacityp,char *inputfname,char *outputfname,uint8_t *decoded,uint8_t *data,int32_t required,int32_t power2,char *passphrase)
{
struct jpeg_decompress_struct inputinfo;
struct jpeg_compress_struct outputinfo;
struct jpeg_error_mgr jerr;
jvirt_barray_ptr *coef_arrays;
JDIMENSION i,compnum,rownum,blocknum;
JBLOCKARRAY coef_buffers[MAX_COMPONENTS];
JBLOCKARRAY row_ptrs[MAX_COMPONENTS];
FILE *input_file,*output_file; int32_t val,modified,emit,totalrows,limit;
if ( power2 < 0 || power2 > 16 )
power2 = 4;
limit = 1;
while ( power2 > 0 )
{
limit <<= 1;
power2--;
}
if ((input_file = fopen(inputfname, READ_BINARY)) == NULL) {
fprintf(stderr, "Can't open %s\n", inputfname);
exit(EXIT_FAILURE);
}
// Initialize the JPEG compression and decompression objects with default error handling
inputinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&inputinfo);
// Specify data source for decompression and recompression
jpeg_stdio_src(&inputinfo, input_file);
(void) jpeg_read_header(&inputinfo, TRUE);
for (compnum=0; compnum<inputinfo.num_components; compnum++)
coef_buffers[compnum] = ((&inputinfo)->mem->alloc_barray)((j_common_ptr)&inputinfo,JPOOL_IMAGE,inputinfo.comp_info[compnum].width_in_blocks,inputinfo.comp_info[compnum].height_in_blocks);
coef_arrays = jpeg_read_coefficients(&inputinfo);
// Copy DCT coeffs to a new array
int num_components = inputinfo.num_components;
size_t block_row_size[num_components];
int width_in_blocks[num_components];
int height_in_blocks[num_components];
*capacityp = modified = emit = totalrows = 0;
if ( decoded != 0 )
memset(decoded,0,required/8+1);
for (compnum=0; compnum<num_components; compnum++)
{
height_in_blocks[compnum] = inputinfo.comp_info[compnum].height_in_blocks;
width_in_blocks[compnum] = inputinfo.comp_info[compnum].width_in_blocks;
block_row_size[compnum] = (size_t) SIZEOF(JCOEF)*DCTSIZE2*width_in_blocks[compnum];
for (rownum=0; rownum<height_in_blocks[compnum]; rownum++)
{
row_ptrs[compnum] = ((&inputinfo)->mem->access_virt_barray)((j_common_ptr)&inputinfo,coef_arrays[compnum],rownum,(JDIMENSION)1,FALSE);
for (blocknum=0; blocknum<width_in_blocks[compnum]; blocknum++)
{
for (i=0; i<DCTSIZE2; i++)
{
val = row_ptrs[compnum][0][blocknum][i];
if ( val < -power2 || val > power2 )
{
if ( decoded != 0 && (val & 1) != 0 && *capacityp < required )
decoded[*capacityp >> 3] |= (1 << (*capacityp & 7));
(*capacityp)++;
}
coef_buffers[compnum][rownum][blocknum][i] = val;
}
}
}
}
printf("capacity %d required.%d\n",*capacityp,required);
if ( *capacityp > required && outputfname != 0 && outputfname[0] != 0 )
{
if ((output_file = fopen(outputfname, WRITE_BINARY)) == NULL) {
fprintf(stderr, "Can't open %s\n", outputfname);
exit(EXIT_FAILURE);
}
outputinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&outputinfo);
jpeg_stdio_dest(&outputinfo, output_file);
jpeg_copy_critical_parameters(&inputinfo,&outputinfo);
// Print out or modify DCT coefficients
for (compnum=0; compnum<num_components; compnum++)
{
for (rownum=0; rownum<height_in_blocks[compnum]; rownum++)
{
for (blocknum=0; blocknum<width_in_blocks[compnum]; blocknum++)
{
//printf("\n\nComponent: %i, Row:%i, Column: %i\n", compnum, rownum, blocknum);
for (i=0; i<DCTSIZE2; i++)
{
val = coef_buffers[compnum][rownum][blocknum][i];
if ( val < -power2 || val > power2 )
{
val &= ~1;
if ( (data[emit >> 3] & (1 << (emit&7))) != 0 )
val |= 1;
emit++;
}
coef_buffers[compnum][rownum][blocknum][i] = val;
//printf("%i,", coef_buffers[compnum][rownum][blocknum][i]);
}
}
}
}
//printf("\n\n");
/* Output the new DCT coeffs to a JPEG file */
modified = 0;
for (compnum=0; compnum<num_components; compnum++)
{
for (rownum=0; rownum<height_in_blocks[compnum]; rownum++)
{
row_ptrs[compnum] = ((&outputinfo)->mem->access_virt_barray)((j_common_ptr)&outputinfo,coef_arrays[compnum],rownum,(JDIMENSION)1,TRUE);
if ( memcmp(row_ptrs[compnum][0][0],coef_buffers[compnum][rownum][0],block_row_size[compnum]) != 0 )
{
memcpy(row_ptrs[compnum][0][0],coef_buffers[compnum][rownum][0],block_row_size[compnum]);
modified++;
}
totalrows++;
}
}
// Write to the output file
jpeg_write_coefficients(&outputinfo, coef_arrays);
// Finish compression and release memory
jpeg_finish_compress(&outputinfo);
jpeg_destroy_compress(&outputinfo);
fclose(output_file);
}
jpeg_finish_decompress(&inputinfo);
jpeg_destroy_decompress(&inputinfo);
fclose(input_file);
if ( modified != 0 )
{
printf("New DCT coefficients successfully written to %s, capacity %d modifiedrows.%d/%d emit.%d\n",outputfname,*capacityp,modified,totalrows,emit);
}
return(modified);
}
char *LP_jpg(char *srcfile,char *destfile,int32_t power2,char *passphrase,char *datastr,int32_t required)
{
cJSON *retjson; int32_t len=0,modified,capacity; char *decodedstr; uint8_t *data=0,*decoded=0;
if ( srcfile != 0 && srcfile[0] != 0 )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
if ( datastr != 0 && datastr[0] != 0 )
{
if ( (len= is_hexstr(datastr,0)) > 0 )
{
len >>= 1;
data = calloc(1,len);
decode_hex(data,len,datastr);
required = len * 8;
}
}
if ( required > 0 )
decoded = calloc(1,len);
modified = LP_jpg_process(&capacity,srcfile,destfile,decoded,data,required,power2,passphrase);
jaddnum(retjson,"modifiedrows",modified);
if ( modified != 0 )
jaddstr(retjson,"outputfile",destfile);
jaddnum(retjson,"power2",power2);
jaddnum(retjson,"capacity",capacity);
jaddnum(retjson,"required",required);
if ( decoded != 0 )
{
decodedstr = calloc(1,len*2+1);
init_hexbytes_noT(decodedstr,decoded,len);
jaddstr(retjson,"decoded",decodedstr);
free(decodedstr);
free(decoded);
}
if ( data != 0 )
free(data);
return(jprint(retjson,1));
} else return(clonestr("{\"error\":\"no source file error\"}"));
}

245
iguana/exchanges/LP_remember.c

@ -243,6 +243,7 @@ bits256 basilisk_swap_privbob_extract(char *symbol,bits256 spendtxid,int32_t vin
bits256 basilisk_swap_privBn_extract(bits256 *bobrefundp,char *bobcoin,bits256 bobdeposit,bits256 privBn)
{
char destaddr[64];
destaddr[0] = 0;
if ( bits256_nonz(privBn) == 0 )
{
if ( bits256_nonz(bobdeposit) != 0 )
@ -253,23 +254,45 @@ bits256 basilisk_swap_privBn_extract(bits256 *bobrefundp,char *bobcoin,bits256 b
return(privBn);
}
bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t vout,char *aliceaddr,char *bobaddr,char *Adest,char *dest)
bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t utxovout,char *aliceaddr,char *bobaddr,char *Adest,char *dest)
{
bits256 spendtxid,txid; char destaddr[64],str[65]; struct iguana_info *coin; cJSON *histobj;
if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum != 0 )
bits256 spendtxid,txid; char destaddr[64],str[65]; int32_t i,n; struct iguana_info *coin; cJSON *array,*txobj;
memset(&spendtxid,0,sizeof(spendtxid));
destaddr[0] = 0;
if ( (coin= LP_coinfind(symbol)) == 0 )
return(spendtxid);
//printf("spentaddr.%s aliceaddr.%s bobaddr.%s Adest.%s Bdest.%s\n",spentaddr,aliceaddr,bobaddr,Adest,dest);
if ( coin->electrum != 0 )
{
if ( (histobj= electrum_address_gethistory(symbol,coin->electrum,&histobj,spentaddr)) != 0 )
if ( (array= electrum_address_gethistory(symbol,coin->electrum,&array,spentaddr,txids[utxoind])) != 0 )
{
//printf("processed history.(%s)\n",jprint(histobj,0));
free_json(histobj);
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
txid = jbits256(jitem(array,i),"tx_hash");
//printf("i.%d of %d: %s\n",i,n,bits256_str(str,txid));
if ( bits256_cmp(txid,txids[utxoind]) != 0 )
{
if ( (txobj= LP_gettx(symbol,txid,1)) != 0 ) // good side effects
free_json(txobj);
}
}
}
//printf("processed history.(%s) %s\n",jprint(array,0),bits256_str(str,txids[utxoind]));
free_json(array);
}
}
else
{
if ( iambob != 0 )
strcpy(destaddr,aliceaddr);
else strcpy(destaddr,bobaddr);
}
txid = txids[utxoind];
memset(&spendtxid,0,sizeof(spendtxid));
if ( bits256_nonz(txid) != 0 )//&& sentflags[utxoind] != 0 )
{
destaddr[0] = 0;
spendtxid = LP_swap_spendtxid(symbol,destaddr,txid,vout);
spendtxid = LP_swap_spendtxid(symbol,destaddr,txid,utxovout);
if ( bits256_nonz(spendtxid) != 0 )
{
sentflags[utxoind] = 1;
@ -305,7 +328,7 @@ bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,in
}
}
} //else printf("no spend of %s/v%d detected\n",bits256_str(str,txid),vout);
} else printf("utxoind.%d null txid\n",utxoind);
} //else printf("utxoind.%d null txid\n",utxoind);
return(spendtxid);
}
@ -352,11 +375,18 @@ int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflag
}
else if ( bits256_nonz(Apaymentspent) != 0 )
return(1);
else if ( bits256_nonz(paymentspent) != 0 && bits256_nonz(depositspent) != 0 )
return(1);
}
else
{
if ( bits256_nonz(txids[BASILISK_ALICEPAYMENT]) == 0 && sentflags[BASILISK_ALICEPAYMENT] == 0 )
return(1);
if ( sentflags[BASILISK_ALICEPAYMENT] == 0 )
{
if ( bits256_nonz(txids[BASILISK_ALICEPAYMENT]) == 0 )
return(1);
else if ( sentflags[BASILISK_BOBPAYMENT] != 0 && sentflags[BASILISK_BOBREFUND] != 0 )
return(1);
}
else
{
if ( sentflags[BASILISK_ALICERECLAIM] != 0 || sentflags[BASILISK_ALICESPEND] != 0 )
@ -389,6 +419,7 @@ uint32_t LP_extract(uint32_t requestid,uint32_t quoteid,char *rootfname,char *fi
t = (t << 8) | redeem[2];
//printf("extracted timestamp.%u\n",t);
}
free_json(json);
}
free(filestr);
}
@ -483,7 +514,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap)
if ( rswap->sentflags[i] != 0 )
jaddistr(array,txnames[i]);
if ( rswap->txbytes[i] != 0 )
free(rswap->txbytes[i]);
free(rswap->txbytes[i]), rswap->txbytes[i] = 0;
}
jadd(item,"sentflags",array);
array = cJSON_CreateArray();
@ -506,7 +537,7 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap)
return(item);
}
int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t quoteid)
int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t quoteid,int32_t forceflag)
{
char fname[1024],*fstr,*secretstr,*srcstr,*deststr,*dest33,*txname; long fsize; cJSON *item,*txobj,*array; bits256 privkey; struct iguana_info *coin; uint32_t r,q; int32_t i,j,n; uint8_t other33[33];
memset(rswap,0,sizeof(*rswap));
@ -637,9 +668,12 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t
}
}
}
free_json(txobj);
}
rswap->origfinishedflag = basilisk_swap_isfinished(rswap->iambob,rswap->txids,rswap->sentflags,rswap->paymentspent,rswap->Apaymentspent,rswap->depositspent);
rswap->finishedflag = rswap->origfinishedflag;
if ( forceflag != 0 )
rswap->finishedflag = rswap->origfinishedflag = 0;
free(fstr);
}
return(rswap->iambob);
@ -670,7 +704,7 @@ int32_t LP_refht_update(char *symbol,bits256 txid)
return(0);
}
int32_t LP_swap_load(struct LP_swap_remember *rswap)
int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag)
{
int32_t i,needflag,addflag; long fsize; char fname[1024],*fstr,*symbol,*rstr; cJSON *txobj,*sentobj,*fileobj; bits256 txid,checktxid; uint64_t value;
rswap->iambob = -1;
@ -680,7 +714,8 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap)
if ( (fileobj= cJSON_Parse(fstr)) != 0 )
{
rswap->finishtime = juint(fileobj,"finishtime");
rswap->origfinishedflag = rswap->finishedflag = 1;
if ( forceflag == 0 )
rswap->origfinishedflag = rswap->finishedflag = 1;
free_json(fileobj);
}
free(fstr);
@ -701,7 +736,11 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap)
rswap->iambob = jint(txobj,"iambob");
txid = jbits256(txobj,"txid");
if ( bits256_nonz(txid) == 0 )
{
free(fstr);
free_json(txobj);
continue;
}
rswap->txids[i] = txid;
if ( jstr(txobj,"Apayment") != 0 )
safecopy(rswap->alicepaymentaddr,jstr(txobj,"Apayment"),sizeof(rswap->alicepaymentaddr));
@ -753,7 +792,7 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap)
safecopy(rswap->alicecoin,symbol,sizeof(rswap->alicecoin));
if ( rswap->finishedflag == 0 )
{
if ( (sentobj= LP_gettx(symbol,txid)) == 0 )
if ( (sentobj= LP_gettx(symbol,txid,1)) == 0 )
{
char str2[65]; printf("%s %s ready to broadcast\n",symbol,bits256_str(str2,txid));
}
@ -773,6 +812,7 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap)
//printf("%s %s %.8f\n",txnames[i],bits256_str(str,txid),dstr(value));
}
}
free_json(txobj);
} //else printf("no symbol\n");
free(fstr);
} else if ( 0 && rswap->finishedflag == 0 )
@ -847,23 +887,30 @@ int32_t LP_spends_set(struct LP_swap_remember *rswap)
return(numspent);
}
cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid)
cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid,int32_t forceflag,int32_t pendingonly)
{
static void *ctx;
struct LP_swap_remember rswap; int32_t i,j,flag,numspent,len,secretstart,redeemlen; char str[65],*srcAdest,*srcBdest,*destAdest,*destBdest,otheraddr[64]; cJSON *item,*txoutobj; bits256 rev,signedtxid,zero,deadtxid; struct iguana_info *bob=0,*alice=0; uint8_t redeemscript[1024],userdata[1024];
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( (rswap.iambob= LP_rswap_init(&rswap,requestid,quoteid)) < 0 )
if ( requestid == 0 || quoteid == 0 )
return(cJSON_Parse("{\"error\":\"null requestid or quoteid\"}"));
if ( (rswap.iambob= LP_rswap_init(&rswap,requestid,quoteid,forceflag)) < 0 )
return(cJSON_Parse("{\"error\":\"couldnt initialize rswap, are all coins active?\"}"));
decode_hex(deadtxid.bytes,32,"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
LP_swap_load(&rswap);
LP_swap_load(&rswap,forceflag);
memset(zero.bytes,0,sizeof(zero));
otheraddr[0] = 0;
srcAdest = srcBdest = destAdest = destBdest = 0;
if ( rswap.bobcoin[0] == 0 || rswap.alicecoin[0] == 0 || strcmp(rswap.bobcoin,rswap.src) != 0 || strcmp(rswap.alicecoin,rswap.dest) != 0 )
{
//printf("legacy DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest);
return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}"));
//printf("legacy r%u-q%u DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",requestid,quoteid,rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest);
cJSON *retjson = cJSON_CreateObject();
jaddstr(retjson,"error","swap never started");
jaddnum(retjson,"requestid",requestid);
jaddnum(retjson,"quoteid",quoteid);
return(retjson);
//return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}"));
}
alice = LP_coinfind(rswap.alicecoin);
bob = LP_coinfind(rswap.bobcoin);
@ -876,6 +923,15 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
bitcoin_address(otheraddr,alice->taddr,alice->pubtype,rswap.other33,33);
destBdest = otheraddr;
destAdest = rswap.Adestaddr;
if ( strcmp(alice->smartaddr,rswap.Adestaddr) != 0 )
{
printf("this isnt my swap! alice.(%s vs %s)\n",alice->smartaddr,rswap.Adestaddr);
cJSON *retjson = cJSON_CreateObject();
jaddstr(retjson,"error","swap for different account");
jaddnum(retjson,"requestid",requestid);
jaddnum(retjson,"quoteid",quoteid);
return(retjson);
}
}
if ( (bob= LP_coinfind(rswap.bobcoin)) != 0 )
{
@ -891,6 +947,15 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
bitcoin_address(otheraddr,bob->taddr,bob->pubtype,rswap.other33,33);
srcAdest = otheraddr;
srcBdest = rswap.destaddr;
if ( strcmp(bob->smartaddr,rswap.destaddr) != 0 )
{
printf("this isnt my swap! bob.(%s vs %s)\n",bob->smartaddr,rswap.destaddr);
cJSON *retjson = cJSON_CreateObject();
jaddstr(retjson,"error","swap for different account");
jaddnum(retjson,"requestid",requestid);
jaddnum(retjson,"quoteid",quoteid);
return(retjson);
}
}
if ( (alice= LP_coinfind(rswap.alicecoin)) != 0 )
{
@ -969,7 +1034,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
}
if ( rswap.sentflags[BASILISK_ALICECLAIM] == 0 && rswap.sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(rswap.txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(rswap.depositspent) == 0 )
{
if ( time(NULL) > rswap.expiration )
if ( time(NULL) > rswap.expiration+777 )
{
flag = 0;
if ( bob->electrum == 0 )
@ -1058,7 +1123,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
free_json(txoutobj), flag = 0;
else flag = -1, rswap.paymentspent = deadtxid;
}
if ( flag == 0 && time(NULL) > rswap.expiration )
if ( flag == 0 && time(NULL) > rswap.expiration+777 )
{
// bobreclaim
redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,rswap.plocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,zero,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256);
@ -1087,7 +1152,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
free_json(txoutobj), flag = 0;
else flag = -1, rswap.depositspent = deadtxid;
}
if ( flag == 0 && (bits256_nonz(rswap.Apaymentspent) != 0 || time(NULL) > rswap.expiration) )
if ( flag == 0 && (bits256_nonz(rswap.Apaymentspent) != 0 || time(NULL) > rswap.expiration+777) )
{
printf("do the refund! paymentspent.%s now.%u vs expiration.%u\n",bits256_str(str,rswap.paymentspent),(uint32_t)time(NULL),rswap.expiration);
//if ( txbytes[BASILISK_BOBREFUND] == 0 )
@ -1101,7 +1166,7 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
}
LP_txbytes_update("bobrefund",rswap.bobcoin,rswap.txbytes[BASILISK_BOBREFUND],&rswap.txids[BASILISK_BOBREFUND],&rswap.depositspent,&rswap.sentflags[BASILISK_BOBREFUND]);
}
else if ( flag == 0 )
else if ( 0 && flag == 0 )
printf("bobrefund's time %u vs expiration %u\n",(uint32_t)time(NULL),rswap.expiration);
}
}
@ -1126,20 +1191,24 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
if ( (numspent= LP_spends_set(&rswap)) == 3 )
rswap.finishedflag = 1;
else rswap.finishedflag = basilisk_swap_isfinished(rswap.iambob,rswap.txids,rswap.sentflags,rswap.paymentspent,rswap.Apaymentspent,rswap.depositspent);
item = LP_swap_json(&rswap);
if ( rswap.origfinishedflag == 0 && rswap.finishedflag != 0 )
{
char fname[1024],*itemstr; FILE *fp;
LP_numfinished++;
printf("SWAP %u-%u finished LP_numfinished.%d !\n",requestid,quoteid,LP_numfinished);
if ( rswap.finishtime == 0 )
rswap.finishtime = (uint32_t)time(NULL);
if ( rswap.tradeid != 0 )
LP_tradebot_finished(rswap.tradeid,rswap.requestid,rswap.quoteid);
sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,rswap.requestid,rswap.quoteid), OS_compatible_path(fname);
item = LP_swap_json(&rswap);
if ( (fp= fopen(fname,"wb")) != 0 )
{
jaddstr(item,"method","tradestatus");
jaddnum(item,"finishtime",rswap.finishtime);
jaddstr(item,"gui",G.gui);
//jaddbits256(item,"srchash",rswap.Q.srchash);
//jaddbits256(item,"desthash",rswap.desthash);
itemstr = jprint(item,0);
fprintf(fp,"%s\n",itemstr);
LP_tradecommand_log(item);
@ -1149,11 +1218,41 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
//LP_broadcast_message(LP_mypubsock,rswap.src,rswap.dest,zero,itemstr);
fclose(fp);
}
} else item = LP_swap_json(&rswap);
for (i=0; i<sizeof(txnames)/sizeof(*txnames); i++)
if ( rswap.txbytes[i] != 0 )
free(rswap.txbytes[i]), rswap.txbytes[i] = 0;
if ( pendingonly != 0 && rswap.origfinishedflag != 0 )
{
free_json(item);
item = 0;
}
return(item);
}
char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid)
void for_satinder()
{
void *ctx; char *signedtx,*paymentaddr,*rscript; int32_t redeemlen,len; uint8_t pubkey33[33],redeemscript[512],userdata[512]; uint32_t expiration; bits256 zero,priv1,signedtxid,utxotxid; int64_t satoshis; struct iguana_info *coin;
ctx = bitcoin_ctx();
coin = LP_coinfind("ZEC");
expiration = 1511219708;
rscript = "63048543135ab1752103b1168377dec884dc7d615c64e0963a5efeaf3c34f8c88be04dec2ee5cc0608c0ac67a914fcfc9291cad04225e574b374516656f80b991c808821021a53a4a59017258f12b6a293fee7644dff98899d3e4a8917b4b3204ee50995a1ac68";
redeemlen = (int32_t)strlen(rscript)/2;
decode_hex(redeemscript,redeemlen,rscript);
decode_hex(utxotxid.bytes,32,"ef5b1d463715e6b5bd51c3161147f1aabebc7f3f88438cbdc744590c2b9856e6");
decode_hex(pubkey33,33,"02ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92");
paymentaddr = "t1Y9ukZMkNAYonCFVp3jSdx7NT8dEsXss7k";
satoshis = 1344 * SATOSHIDEN - 10000;
memset(zero.bytes,0,sizeof(zero));
decode_hex(priv1.bytes,32,"00000000000000000000000000000000bebc7f3f88438cbdc744590c2b9856e6"); // need to put the actual privkey here
len = basilisk_swapuserdata(userdata,zero,1,priv1,redeemscript,redeemlen);
if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,coin->txfee,"satinder",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,priv1,0,redeemscript,redeemlen,userdata,len,utxotxid,0,0,pubkey33,0,expiration,&satoshis,0,0,paymentaddr,1,coin->zcash)) != 0 )
{
char str[65]; printf("satinder %s signedtx.(%s)\n",bits256_str(str,signedtxid),signedtx);
} else printf("error with satinder tx\n");
}
char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid,int32_t forceflag,int32_t pendingonly)
{
uint64_t ridqids[4096],ridqid; char fname[512]; FILE *fp; cJSON *item,*retjson,*array,*totalsobj; uint32_t r,q,quoteid,requestid; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS],Btotal,Ktotal; int32_t i,j,count=0;
portable_mutex_lock(&LP_swaplistmutex);
@ -1166,7 +1265,7 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid)
if ( origrequestid != 0 && origquoteid != 0 )
{
//printf("orig req.%u q.%u\n",origrequestid,origquoteid);
if ( (item= basilisk_remember(KMDtotals,BTCtotals,origrequestid,origquoteid)) != 0 )
if ( (item= basilisk_remember(KMDtotals,BTCtotals,origrequestid,origquoteid,forceflag,0)) != 0 )
jaddi(array,item);
//printf("got.(%s)\n",jprint(item,0));
}
@ -1180,19 +1279,22 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid)
while ( fread(&requestid,1,sizeof(requestid),fp) == sizeof(requestid) && fread(&quoteid,1,sizeof(quoteid),fp) == sizeof(quoteid) )
{
flag = 0;
for (i=0; i<G.LP_numskips; i++)
if ( pendingonly == 0 )
{
r = (uint32_t)(G.LP_skipstatus[i] >> 32);
q = (uint32_t)G.LP_skipstatus[i];
if ( r == requestid && q == quoteid )
for (i=0; i<G.LP_numskips; i++)
{
item = cJSON_CreateObject();
jaddstr(item,"status","realtime");
jaddnum(item,"requestid",r);
jaddnum(item,"quoteid",q);
jaddi(array,item);
flag = 1;
break;
r = (uint32_t)(G.LP_skipstatus[i] >> 32);
q = (uint32_t)G.LP_skipstatus[i];
if ( r == requestid && q == quoteid )
{
item = cJSON_CreateObject();
jaddstr(item,"status","realtime");
jaddnum(item,"requestid",r);
jaddnum(item,"quoteid",q);
jaddi(array,item);
flag = 1;
break;
}
}
}
if ( flag == 0 )
@ -1205,7 +1307,7 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid)
{
if ( count < sizeof(ridqids)/sizeof(*ridqids) )
ridqids[count++] = ridqid;
if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid)) != 0 )
if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,0,pendingonly)) != 0 )
jaddi(array,item);
}
}
@ -1234,23 +1336,16 @@ char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid)
else if ( Ktotal < 0 && Btotal > 0 )
jaddnum(retjson,"avesell",(double)-Btotal/Ktotal);
}
/*array = cJSON_CreateArray();
for (i=0; i<sizeof(myinfo->linfos)/sizeof(*myinfo->linfos); i++)
{
if ( myinfo->linfos[i].base[0] != 0 && myinfo->linfos[i].rel[0] != 0 )
jaddi(array,linfo_json(&myinfo->linfos[i]));
}
jadd(retjson,"quotes",array);*/
portable_mutex_unlock(&LP_swaplistmutex);
return(jprint(retjson,1));
}
char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid)
char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid,int32_t forceflag)
{
cJSON *item; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS];
memset(KMDtotals,0,sizeof(KMDtotals));
memset(BTCtotals,0,sizeof(BTCtotals));
if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid)) != 0 )
if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,forceflag,0)) != 0 )
return(jprint(item,1));
else return(clonestr("{\"error\":\"cant find requestid-quoteid\"}"));
}
@ -1260,7 +1355,10 @@ extern uint32_t Alice_expiration;
char *LP_recent_swaps(int32_t limit)
{
char fname[512]; long fsize,offset; FILE *fp; int32_t i=0; uint32_t requestid,quoteid; cJSON *array,*item,*retjson;
char fname[512],*retstr,*base,*rel,*statusstr; long fsize,offset; FILE *fp; int32_t baseind,relind,i=0; uint32_t requestid,quoteid; cJSON *array,*item,*retjson,*subitem,*swapjson; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS]; double srcamount,destamount,netamounts[LP_MAXPRICEINFOS];
memset(KMDtotals,0,sizeof(KMDtotals));
memset(BTCtotals,0,sizeof(BTCtotals));
memset(netamounts,0,sizeof(netamounts));
if ( limit <= 0 )
limit = 3;
sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname);
@ -1282,6 +1380,36 @@ char *LP_recent_swaps(int32_t limit)
item = cJSON_CreateArray();
jaddinum(item,requestid);
jaddinum(item,quoteid);
if ( (retstr= basilisk_swapentry(requestid,quoteid,0)) != 0 )
{
if ( (swapjson= cJSON_Parse(retstr)) != 0 )
{
base = jstr(swapjson,"bob");
rel = jstr(swapjson,"alice");
statusstr = jstr(swapjson,"status");
baseind = relind = -1;
if ( base != 0 && rel != 0 && statusstr != 0 && strcmp(statusstr,"finished") == 0 && (baseind= LP_priceinfoind(base)) >= 0 && (relind= LP_priceinfoind(rel)) >= 0 )
{
srcamount = jdouble(swapjson,"srcamount");
destamount = jdouble(swapjson,"destamount");
if ( jint(swapjson,"iambob") != 0 )
srcamount = -srcamount;
else destamount = -destamount;
if ( srcamount != 0. && destamount != 0. )
{
netamounts[baseind] += srcamount;
netamounts[relind] += destamount;
subitem = cJSON_CreateObject();
jaddnum(subitem,base,srcamount);
jaddnum(subitem,rel,destamount);
jaddnum(subitem,"price",-destamount/srcamount);
jaddi(item,subitem);
}
} else printf("base.%p rel.%p statusstr.%p baseind.%d relind.%d\n",base,rel,statusstr,baseind,relind);
free_json(swapjson);
} else printf("error parsing.(%s)\n",retstr);
free(retstr);
}
jaddi(array,item);
} else break;
} else break;
@ -1291,6 +1419,17 @@ char *LP_recent_swaps(int32_t limit)
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jadd(retjson,"swaps",array);
array = cJSON_CreateArray();
for (i=0; i<LP_MAXPRICEINFOS; i++)
{
if ( netamounts[i] != 0. )
{
item = cJSON_CreateObject();
jaddnum(item,LP_priceinfostr(i),netamounts[i]);
jaddi(array,item);
}
}
jadd(retjson,"netamounts",array);
if ( time(NULL) < Alice_expiration )
{
item = cJSON_CreateObject();
@ -1340,7 +1479,7 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit)
limit = 10;
memset(ridqids,0,sizeof(ridqids));
retarray = cJSON_CreateArray();
if ( (liststr= basilisk_swaplist(0,0)) != 0 )
if ( (liststr= basilisk_swaplist(0,0,0,0)) != 0 )
{
//printf("swapentry.(%s)\n",liststr);
if ( (retjson= cJSON_Parse(liststr)) != 0 )
@ -1383,7 +1522,7 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit)
//printf("j.%d count.%d %u %u ridqid.%16llx\n",j,count,requestid,quoteid,(long long)ridqid);
if ( j == count )
{
if ( (retstr2= basilisk_swapentry(requestid,quoteid)) != 0 )
if ( (retstr2= basilisk_swapentry(requestid,quoteid,0)) != 0 )
{
if ( (swapjson= cJSON_Parse(retstr2)) != 0 )
{

628
iguana/exchanges/LP_rpc.c

@ -1,4 +1,3 @@
/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* *
@ -18,30 +17,6 @@
// marketmaker
//
/*char *LP_issue_curl(char *debugstr,char *destip,uint16_t port,char *url)
{
char *retstr = 0; int32_t maxerrs; struct LP_peerinfo *peer = 0;
peer = LP_peerfind((uint32_t)calc_ipbits(destip),port);
if ( strcmp(destip,"127.0.0.1") != 0 )
port--;
maxerrs = LP_MAXPEER_ERRORS;
if ( peer == 0 || (peer->errors < maxerrs || peer->good >= LP_MINPEER_GOOD) )
{
printf("issue.(%s)\n",url);
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) == 0 )
{
if ( peer != 0 )
{
peer->errors++;
peer->good *= LP_PEERGOOD_ERRORDECAY;
} else printf("%s error on (%s:%u) without peer\n",debugstr,destip,port);
}
else if ( peer != 0 )
peer->good++;
}
return(retstr);
}*/
char *LP_isitme(char *destip,uint16_t destport)
{
if ( LP_mypeer != 0 && strcmp(destip,LP_mypeer->ipaddr) == 0 && LP_mypeer->port == destport )
@ -77,7 +52,7 @@ cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params)
//printf("issue.(%s, %s, %s, %s, %s)\n",coin->symbol,coin->serverport,coin->userpass,method,params);
if ( coin->electrum != 0 && (strcmp(method,"getblock") == 0 || strcmp(method,"paxprice") == 0 || strcmp(method,"getrawmempool") == 0) )
return(cJSON_Parse("{\"error\":\"illegal electrum call\"}"));
if ( coin->inactive == 0 || strcmp(method,"importprivkey") == 0 || strcmp(method,"validateaddress") == 0 )
if ( coin->inactive == 0 || strcmp(method,"importprivkey") == 0 || strcmp(method,"validateaddress") == 0 || strcmp(method,"getrawtransaction") == 0 || strcmp(method,"getblock") == 0 || strcmp(method,"getinfo") == 0 )
{
if ( coin->electrum == 0 )
{
@ -99,13 +74,6 @@ cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params)
free_json(retjson);
retjson = 0;
}
//printf("electrum %s.%s -> (%s)\n",method,params,jprint(retjson,0));
/*if ( (resultjson= jobj(retjson,"result")) != 0 )
{
resultjson = jduplicate(resultjson);
free_json(retjson);
retjson = resultjson;
}*/
}
}
} else retjson = cJSON_Parse("{\"result\":\"disabled\"}");
@ -118,236 +86,14 @@ void LP_unspents_mark(char *symbol,cJSON *vins)
//printf("LOCK (%s)\n",jprint(vins,0));
}
char *NXTnodes[] = { "62.75.159.113", "91.44.203.238", "82.114.88.225", "78.63.207.76", "188.174.110.224", "91.235.72.49", "213.144.130.91", "209.222.98.250", "216.155.128.10", "178.33.203.157", "162.243.122.251", "69.163.47.173", "193.151.106.129", "78.94.2.74", "192.3.196.10", "173.33.112.87", "104.198.173.28", "35.184.154.126", "174.140.167.239", "23.88.113.131", "198.71.84.173", "178.150.207.53", "23.88.61.53", "192.157.233.106", "192.157.241.212", "23.89.192.88", "23.89.200.27", "192.157.241.139", "23.89.200.63", "23.89.192.98", "163.172.214.102", "176.9.85.5", "80.150.243.88", "80.150.243.92", "80.150.243.98", "109.70.186.198", "146.148.84.237", "104.155.56.82", "104.197.157.140", "37.48.73.249", "146.148.77.226", "84.57.170.200", "107.161.145.131", "80.150.243.97", "80.150.243.93", "80.150.243.100", "80.150.243.95", "80.150.243.91", "80.150.243.99", "80.150.243.96", "93.231.187.177", "212.237.23.85", "35.158.179.254", "46.36.66.41", "185.170.113.79", "163.172.68.112", "78.47.35.210", "77.90.90.75", "94.177.196.134", "212.237.22.215", "94.177.234.11", "167.160.180.199", "54.68.189.9", "94.159.62.14", "195.181.221.89", "185.33.145.94", "195.181.209.245", "195.181.221.38", "195.181.221.162", "185.33.145.12", "185.33.145.176", "178.79.128.235", "94.177.214.120", "94.177.199.41", "94.177.214.200", "94.177.213.201", "212.237.13.162", "195.181.221.236", "195.181.221.185", "185.28.103.187", "185.33.146.244", "217.61.123.71", "195.181.214.45", "195.181.212.99", "195.181.214.46", "195.181.214.215", "195.181.214.68", "217.61.123.118", "195.181.214.79", "217.61.123.14", "217.61.124.100", "195.181.214.111", "85.255.0.176", "81.2.254.116", "217.61.123.184", "195.181.212.231", "94.177.214.110", "195.181.209.164", "104.129.56.238", "85.255.13.64", "167.160.180.206", "217.61.123.226", "167.160.180.208", "93.186.253.127", "212.237.6.208", "94.177.207.190", "217.61.123.119", "85.255.1.245", "217.61.124.157", "37.59.57.141", "167.160.180.58", "104.223.53.14", "217.61.124.69", "195.181.212.103", "85.255.13.141", "104.207.133.204", "71.90.7.107", "107.150.18.108", "23.94.134.161", "80.150.243.13", "80.150.243.11", "185.81.165.52", "80.150.243.8" };
static char *assetids[][4] =
{
{ "13502152099823770958", "SUPERNETx2", "10000", "10000" },
{ "12071612744977229797", "SUPERNET", "10000", "10000" },
{ "12071612744977229797", "UNITY", "10000", "10000" },
{ "15344649963748848799", "DEX", "1", "100000000" },
{ "6883271355794806507", "PANGEA", "10000", "10000" },
{ "17911762572811467637", "JUMBLR", "10000", "10000" },
{ "17083334802666450484", "BET", "10000", "10000" },
{ "13476425053110940554", "CRYPTO", "1000", "100000" },
{ "6932037131189568014", "HODL", "1", "100000000" },
{ "3006420581923704757", "SHARK", "10000", "10000" },
{ "17571711292785902558", "BOTS", "1", "100000000" },
{ "10524562908394749924", "MGW", "1", "100000000" },
};
void LP_sendtoaddress_line(char *validaddress,char *assetname,uint64_t satoshis,uint64_t txnum)
{
char line[1024],lowerstr[64];
if ( strcmp(assetname,"SUPERNETx2") == 0 )
{
sprintf(line,"fiat/supernet sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long)txnum);
printf("%s\n",line);
sprintf(line,"fiat/revs sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long)txnum);
}
else
{
strcpy(lowerstr,assetname);
tolowercase(lowerstr);
sprintf(line,"fiat/%s sendtoaddress %s %.8f # txnum.%llu",lowerstr,validaddress,dstr(satoshis),(long long)txnum);
}
printf("%s\n",line);
}
uint64_t LP_assetid_mult(int32_t *assetindp,char *name,uint64_t assetid)
{
int32_t i; uint64_t mult = 0;
name[0] = 0;
*assetindp = -1;
for (i=0; i<sizeof(assetids)/sizeof(*assetids); i++)
{
if ( assetid == calc_nxt64bits(assetids[i][0]) )
{
*assetindp = i;
mult = atoi(assetids[i][3]);
strcpy(name,assetids[i][1]);
break;
}
}
return(mult);
}
cJSON *LP_NXT_message(char *method,uint64_t txnum,char *passphrase)
{
char url[1024],*retstr; cJSON *retjson = 0;
sprintf(url,"http://127.0.0.1:7876/nxt?requestType=%s&transaction=%llu&secretPhrase=%s",method,(long long)txnum,passphrase);
//printf("issue.(%s)\n",url);
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
}
free(retstr);
}
return(retjson);
}
cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char *passphrase)
{
char url[1024],*retstr; cJSON *retjson = 0;
if ( account != 0 && data != 0 && nonce != 0 && passphrase != 0 )
{
sprintf(url,"http://127.0.0.1:7876/nxt?requestType=readMessage&transaction=%llu&secretPhrase=%s",(long long)txnum,passphrase);
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
}
free(retstr);
}
}
return(retjson);
}
cJSON *LP_NXT_redeems()
{
char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[20],mult,txnum,assetid,qty; int32_t i,ind,numtx,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0;
uint64_t txnum_marker = calc_nxt64bits("0");
uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143");
char *passphrase = "";
char *account = "NXT-MRBN-8DFH-PFMK-A4DBM";
memset(totals,0,sizeof(totals));
sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getBlockchainTransactions&account=%s",account);
//printf("calling (%s)\n",url);
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (array= jarray(&numtx,retjson,"transactions")) != 0 )
{
for (i=0; i<numtx; i++)
{
msgjson = encjson = decjson = 0;
txnum = assetid = qty = 0;
item = jitem(array,i);
msgstr = jstr(item,"message");
txnum = j64bits(item,"transaction");
if ( txnum == txnum_marker )
past_marker = 1;
//printf("%d: %s\n",i,jprint(item,0));
if ( (recv= jstr(item,"recipientRS")) != 0 && strcmp(recv,"NXT-MRBN-8DFH-PFMK-A4DBM") == 0 )
{
if ( (attach= jobj(item,"attachment")) != 0 && jint(attach,"version.AssetTransfer") == 1 )
{
assetid = j64bits(attach,"asset");
qty = j64bits(attach,"quantityQNT");
//printf("txnum.%llu (%s)\n",(long long)txnum,jprint(attach,0));
if ( (msgstr == 0 || msgstr[0] == 0) && jint(attach,"version.PrunablePlainMessage") == 1 )
{
method = "getPrunableMessage";
if ( (msgjson= LP_NXT_message(method,txnum,"test")) != 0 )
{
msgstr = jstr(msgjson,"message");
//printf("%d method.(%s) (%s)\n",i,method,msgstr);
}
}
if ( msgstr == 0 || msgstr[0] == 0 )
msgstr = jstr(attach,"message");
if ( msgstr == 0 || msgstr[0] == 0 )
{
if ( (encjson= jobj(attach,"encryptedMessage")) != 0 )
{
msgstr = "encryptedMessage";//jstr(encjson,"data");
if ( (decjson= LP_NXT_decrypt(txnum,account,jstr(encjson,"data"),jstr(encjson,"nonce"),passphrase)) != 0 )
{
//printf("%s\n",jprint(decjson,0));
if ( jstr(decjson,"decryptedMessage") != 0 )
msgstr = jstr(decjson,"decryptedMessage");
}
}
}
}
mult = LP_assetid_mult(&ind,assetname,assetid);
if ( ind >= 0 )
totals[ind] += qty * mult;
if ( msgstr != 0 && assetname[0] != 0 && qty != 0 )
{
char validaddress[64]; int32_t z,n;
n = (int32_t)strlen(msgstr);
for (z=0; z<n; z++)
{
if ( msgstr[z] == 'R' )
break;
}
memset(validaddress,0,sizeof(validaddress));
if ( n-z >= 34 )
strncpy(validaddress,&msgstr[z],34);
if ( strlen(validaddress) == 34 || strlen(validaddress) == 33 )
{
//printf("%-4d: (%34s) <- %13.5f %10s tx.%llu past_marker.%d\n",i,validaddress,dstr(qty * mult),assetname,(long long)txnum,past_marker);
if ( past_marker == 0 )
{
LP_sendtoaddress_line(validaddress,assetname,(qty * mult),txnum);
}
} else printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum);
}
if ( msgjson != 0 )
free_json(msgjson);
if ( decjson != 0 )
free_json(decjson);
}
if ( txnum == txnum_marker2 )
break;
}
}
//free_json(retjson);
}
free(retstr);
}
printf("\nTotal redeemed\n");
for (i=0; i<sizeof(totals)/sizeof(*totals); i++)
{
if ( totals[i] != 0 )
printf("%-10s %13.5f\n",assetids[i][1],dstr(totals[i]));
}
return(retjson);
}
cJSON *LP_assethbla(char *assetid)
{
char url[1024],*retstr; int32_t n; cJSON *array,*bid=0,*ask=0,*retjson;
sprintf(url,"http://%s:7876/nxt?requestType=getBidOrders&asset=%s&firstIndex=0&lastIndex=0",NXTnodes[LP_rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid);
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 )
{
bid = cJSON_Parse(retstr);
free(retstr);
}
sprintf(url,"http://%s:7876/nxt?requestType=getAskOrders&asset=%s&firstIndex=0&lastIndex=0",NXTnodes[LP_rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid);
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 )
{
ask = cJSON_Parse(retstr);
free(retstr);
}
retjson = cJSON_CreateObject();
if ( bid != 0 && ask != 0 )
{
if ( (array= jarray(&n,bid,"bidOrders")) != 0 )
jadd(retjson,"bid",jduplicate(jitem(array,0)));
if ( (array= jarray(&n,ask,"askOrders")) != 0 )
jadd(retjson,"ask",jduplicate(jitem(array,0)));
}
if ( bid != 0 )
free_json(bid);
if ( ask != 0 )
free_json(ask);
return(retjson);
}
int32_t LP_getheight(struct iguana_info *coin)
int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin)
{
cJSON *retjson; char *retstr,*method = "getinfo"; int32_t height;
*notarizedp = 0;
if ( coin == 0 )
return(-1);
height = coin->height;
if ( coin->electrum == 0 && time(NULL) > coin->heighttime+60 )
if ( coin->electrum == 0 && time(NULL) > coin->heighttime+60 && coin->userpass[0] != 0 )
{
if ( strcmp(coin->symbol,"BTC") == 0 )
method = "getblockchaininfo";
@ -356,6 +102,13 @@ int32_t LP_getheight(struct iguana_info *coin)
{
retjson = cJSON_Parse(retstr);
coin->height = height = jint(retjson,"blocks");
if ( (*notarizedp= jint(retjson,"notarized")) != 0 && *notarizedp != coin->notarized )
{
printf("new notarized %s %d -> %d\n",coin->symbol,coin->notarized,*notarizedp);
coin->notarized = *notarizedp;
coin->notarizationtxid = jbits256(retjson,"notarizedtxid");
coin->notarizedhash = jbits256(retjson,"notarizedhash");
}
free_json(retjson);
if ( coin->height > 0 )
coin->heighttime = (uint32_t)time(NULL);
@ -388,7 +141,7 @@ uint64_t LP_RTsmartbalance(struct iguana_info *coin)
return(valuesum);
}
cJSON *LP_getmempool(char *symbol,char *coinaddr)
cJSON *LP_getmempool(char *symbol,char *coinaddr,bits256 txid,bits256 txid2)
{
cJSON *array; struct iguana_info *coin;
if ( symbol == 0 || symbol[0] == 0 )
@ -398,7 +151,7 @@ cJSON *LP_getmempool(char *symbol,char *coinaddr)
return(cJSON_Parse("{\"error\":\"no native coin\"}"));
if ( coin->electrum == 0 )
return(bitcoin_json(coin,"getrawmempool","[]"));
else return(electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr));
else return(electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr,txid,txid2));
}
cJSON *LP_paxprice(char *fiat)
@ -410,9 +163,9 @@ cJSON *LP_paxprice(char *fiat)
return(bitcoin_json(coin,"paxprice",buf));
}
cJSON *LP_gettx(char *symbol,bits256 txid)
cJSON *LP_gettx(char *symbol,bits256 txid,int32_t suppress_errors)
{
struct iguana_info *coin; char buf[512],str[65]; cJSON *retjson;
struct iguana_info *coin; char buf[512],str[65]; int32_t height; cJSON *retjson;
//printf("LP_gettx %s %s\n",symbol,bits256_str(str,txid));
if ( symbol == 0 || symbol[0] == 0 )
return(cJSON_Parse("{\"error\":\"null symbol\"}"));
@ -429,9 +182,10 @@ cJSON *LP_gettx(char *symbol,bits256 txid)
}
else
{
if ( (retjson= electrum_transaction(symbol,coin->electrum,&retjson,txid,0)) != 0 )
if ( (retjson= electrum_transaction(&height,symbol,coin->electrum,&retjson,txid,0)) != 0 )
return(retjson);
else printf("failed blockchain.transaction.get %s %s\n",coin->symbol,bits256_str(str,txid));
else if ( suppress_errors == 0 )
printf("failed blockchain.transaction.get %s %s\n",coin->symbol,bits256_str(str,txid));
return(cJSON_Parse("{\"error\":\"no transaction bytes\"}"));
}
}
@ -439,7 +193,7 @@ cJSON *LP_gettx(char *symbol,bits256 txid)
uint32_t LP_locktime(char *symbol,bits256 txid)
{
cJSON *txobj; uint32_t locktime = 0;
if ( (txobj= LP_gettx(symbol,txid)) != 0 )
if ( (txobj= LP_gettx(symbol,txid,0)) != 0 )
{
locktime = juint(txobj,"locktime");
free_json(txobj);
@ -447,23 +201,6 @@ uint32_t LP_locktime(char *symbol,bits256 txid)
return(locktime);
}
/*uint32_t LP_txtime(char *symbol,bits256 txid)
{
struct LP_transaction *tx; struct iguana_info *coin; int32_t timestamp=0,height = 0;
char str[65]; printf("LP_txtime (%s %s)\n",symbol,bits256_str(str,txid));
if ( (timestamp= LP_locktime(symbol,txid)) != 0 )
return(timestamp);
if ( (coin= LP_coinfind(symbol)) != 0 )
{
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
{
height = tx->height;
timestamp = LP_heighttime(symbol,height);
}
}
return(height);
}*/
cJSON *LP_gettxout_json(bits256 txid,int32_t vout,int32_t height,char *coinaddr,uint64_t value)
{
cJSON *retjson,*addresses,*sobj;
@ -485,7 +222,7 @@ cJSON *LP_gettxout_json(bits256 txid,int32_t vout,int32_t height,char *coinaddr,
cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
{
char buf[128],str[65]; cJSON *item,*array,*vouts,*txobj,*retjson=0; int32_t i,v,n; bits256 t; struct iguana_info *coin; struct LP_transaction *tx; struct LP_address_utxo *up;
char buf[128],str[65]; cJSON *item,*array,*vouts,*txobj,*retjson=0; int32_t i,v,height,n; bits256 t,zero; struct iguana_info *coin; struct LP_transaction *tx; struct LP_address_utxo *up;
if ( symbol == 0 || symbol[0] == 0 )
return(cJSON_Parse("{\"error\":\"null symbol\"}"));
if ( (coin= LP_coinfind(symbol)) == 0 )
@ -507,7 +244,7 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
}
if ( coinaddr[0] == 0 )
{
if ( (txobj= electrum_transaction(symbol,coin->electrum,&txobj,txid,0)) != 0 )
if ( (txobj= electrum_transaction(&height,symbol,coin->electrum,&txobj,txid,0)) != 0 )
{
if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n > 0 )
LP_destaddr(coinaddr,jitem(vouts,vout));
@ -522,7 +259,8 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
return(0);
//return(LP_gettxout_json(txid,vout,up->U.height,coinaddr,up->U.value));
}
if ( (array= electrum_address_listunspent(coin->symbol,0,&array,coinaddr,1)) != 0 )
memset(zero.bytes,0,sizeof(zero));
if ( (array= electrum_address_listunspent(coin->symbol,0,&array,coinaddr,1,txid,zero)) != 0 )
{
//printf("array.(%s)\n",jprint(array,0));
if ( array != 0 && (n= cJSON_GetArraySize(array)) > 0 )
@ -549,17 +287,6 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
}
}
/*cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t count,int32_t skip)
{
char buf[128]; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 )
return(cJSON_Parse("{\"error\":\"no coin\"}"));
if ( count == 0 )
count = 100;
sprintf(buf,"[\"%s\", %d, %d, true]",coinaddr,count,skip);
return(bitcoin_json(coin,"listtransactions",buf));
}*/
cJSON *LP_validateaddress(char *symbol,char *address)
{
char buf[512],coinaddr[64],checkaddr[64],script[128]; int32_t i; uint8_t rmd160[20],addrtype; cJSON *retjson; struct iguana_info *coin;
@ -574,7 +301,12 @@ cJSON *LP_validateaddress(char *symbol,char *address)
jaddstr(retjson,"address",address);
bitcoin_addr2rmd160(coin->taddr,&addrtype,rmd160,address);
bitcoin_address(checkaddr,coin->taddr,addrtype,rmd160,20);
jadd(retjson,"isvalid",strcmp(address,checkaddr)==0? cJSON_CreateTrue() : cJSON_CreateFalse());
if ( addrtype != coin->pubtype && addrtype != coin->p2shtype )
{
jadd(retjson,"isvalid",cJSON_CreateFalse());
return(retjson);
}
jadd(retjson,"isvalid",strcmp(address,checkaddr)==0 ? cJSON_CreateTrue() : cJSON_CreateFalse());
if ( addrtype == coin->pubtype )
{
strcpy(script,"76a914");
@ -585,8 +317,8 @@ cJSON *LP_validateaddress(char *symbol,char *address)
jaddstr(retjson,"scriptPubKey",script);
}
bitcoin_address(coinaddr,coin->taddr,coin->pubtype,G.LP_myrmd160,20);
jadd(retjson,"ismine",strcmp(address,coin->smartaddr) == 0 ? cJSON_CreateTrue() : cJSON_CreateFalse());
jadd(retjson,"iswatchonly",cJSON_CreateFalse());
jadd(retjson,"ismine",strcmp(coinaddr,coin->smartaddr) == 0 ? cJSON_CreateTrue() : cJSON_CreateFalse());
jadd(retjson,"iswatchonly",cJSON_CreateTrue());
jadd(retjson,"isscript",addrtype == coin->p2shtype ? cJSON_CreateTrue() : cJSON_CreateFalse());
return(retjson);
}
@ -599,12 +331,12 @@ cJSON *LP_validateaddress(char *symbol,char *address)
int32_t LP_address_ismine(char *symbol,char *address)
{
int32_t doneflag = 0; cJSON *retjson;
int32_t doneflag = 0; cJSON *retjson,*obj;
if ( symbol == 0 || symbol[0] == 0 )
return(0);
if ( (retjson= LP_validateaddress(symbol,address)) != 0 )
{
if ( jobj(retjson,"ismine") != 0 && is_cJSON_True(jobj(retjson,"ismine")) != 0 )
if ( (obj= jobj(retjson,"ismine")) != 0 && is_cJSON_True(obj) != 0 )
{
doneflag = 1;
//printf("%s ismine (%s)\n",address,jprint(retjson,0));
@ -615,6 +347,24 @@ int32_t LP_address_ismine(char *symbol,char *address)
return(doneflag);
}
int32_t LP_address_iswatchonly(char *symbol,char *address)
{
int32_t doneflag = 0; cJSON *retjson,*obj;
if ( symbol == 0 || symbol[0] == 0 )
return(0);
if ( (retjson= LP_validateaddress(symbol,address)) != 0 )
{
if ( (obj= jobj(retjson,"iswatchonly")) != 0 && is_cJSON_True(obj) != 0 )
{
doneflag = 1;
//printf("%s iswatchonly (%s)\n",address,jprint(retjson,0));
}
//printf("%s\n",jprint(retjson,0));
free_json(retjson);
}
return(doneflag);
}
int32_t LP_address_isvalid(char *symbol,char *address)
{
int32_t isvalid = 0; cJSON *retjson;
@ -633,38 +383,110 @@ int32_t LP_address_isvalid(char *symbol,char *address)
return(isvalid);
}
cJSON *LP_listunspent(char *symbol,char *coinaddr)
cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxid2)
{
char buf[128]; cJSON *retjson; int32_t numconfs; struct iguana_info *coin;
char buf[128],*retstr; struct LP_address *ap; cJSON *retjson; int32_t numconfs,usecache=1; struct iguana_info *coin;
if ( symbol == 0 || symbol[0] == 0 )
return(cJSON_Parse("{\"error\":\"null symbol\"}"));
coin = LP_coinfind(symbol);
//printf("LP_listunspent.(%s %s)\n",symbol,coinaddr);
if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) )
return(cJSON_Parse("{\"error\":\"no coin\"}"));
if ( coin->electrum == 0 )
{
if ( LP_address_ismine(symbol,coinaddr) > 0 )
if ( (ap= LP_addressfind(coin,coinaddr)) != 0 )
{
if ( ap->unspenttime == 0 )
usecache = 0;
else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+1 )
usecache = 0;
if ( usecache != 0 && (retstr= LP_unspents_filestr(symbol,coinaddr)) != 0 )
{
retjson = cJSON_Parse(retstr);
free(retstr);
return(retjson);
}
}
//printf("%s %s usecache.%d iswatched.%d\n",coin->symbol,coinaddr,usecache,LP_address_iswatchonly(symbol,coinaddr));
if ( LP_address_ismine(symbol,coinaddr) > 0 || LP_address_iswatchonly(symbol,coinaddr) > 0 )
{
if ( strcmp(symbol,"BTC") == 0 )
numconfs = 0;
else numconfs = 1;
sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr);
return(bitcoin_json(coin,"listunspent",buf));
//printf("LP_listunspent.(%s %s)\n",symbol,coinaddr);
retjson = bitcoin_json(coin,"listunspent",buf);
retstr = jprint(retjson,0);
LP_unspents_cache(coin->symbol,coinaddr,retstr,1);
free(retstr);
if ( ap != 0 )
ap->unspenttime = (uint32_t)time(NULL);
return(retjson);
} else return(LP_address_utxos(coin,coinaddr,0));
} else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1));
} else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1,reftxid,reftxid2));
}
cJSON *LP_listreceivedbyaddress(char *symbol,char *coinaddr)
{
char buf[128],*addr; bits256 zero; cJSON *retjson,*array,*item; int32_t i,n; struct iguana_info *coin;
if ( symbol == 0 || symbol[0] == 0 )
return(cJSON_Parse("{\"error\":\"null symbol\"}"));
coin = LP_coinfind(symbol);
if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) )
return(cJSON_Parse("{\"error\":\"no coin\"}"));
memset(zero.bytes,0,sizeof(zero));
if ( coin->electrum == 0 )
{
sprintf(buf,"[1, false, true]");
if ( (array= bitcoin_json(coin,"listreceivedbyaddress",buf)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
if ( (addr= jstr(item,"address")) != 0 && strcmp(addr,coinaddr) == 0 )
{
retjson = jduplicate(jobj(item,"txids"));
free_json(array);
return(retjson);
}
}
}
}
return(cJSON_Parse("[]"));
} else return(electrum_address_gethistory(symbol,coin->electrum,&retjson,coinaddr,zero));
}
int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item)
{
struct iguana_info *coin; int32_t n = 0; cJSON *retjson=0; char *retstr=0;
int64_t satoshis = 0;
if ( coin->electrum == 0 )
{
*txidp = jbits256(item,"txid");
*voutp = juint(item,"vout");
satoshis = LP_value_extract(item,0);
*heightp = LP_txheight(coin,*txidp);
}
else
{
*txidp = jbits256(item,"tx_hash");
*voutp = juint(item,"tx_pos");
satoshis = j64bits(item,"value");
*heightp = jint(item,"height");
}
return(satoshis);
}
int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag,bits256 reftxid,bits256 reftxid2)
{
struct iguana_info *coin; struct LP_address *ap; int32_t n = 0; cJSON *retjson=0; char *retstr=0;
if ( symbol == 0 || symbol[0] == 0 )
return(0);
if ( (coin= LP_coinfind(symbol)) != 0 )
{
if ( coin->electrum != 0 )
{
if ( (retjson= electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1)) != 0 )
if ( (retjson= electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,fullflag,reftxid,reftxid2)) != 0 )
{
n = cJSON_GetArraySize(retjson);
//printf("LP_listunspent_issue.%s %s.%d %s\n",symbol,coinaddr,n,jprint(retjson,0));
@ -672,21 +494,14 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
}
else
{
if ( strcmp(coin->smartaddr,coinaddr) == 0 )
{
retjson = LP_listunspent(symbol,coinaddr);
coin->numutxos = cJSON_GetArraySize(retjson);
//printf("SELF_LISTUNSPENT.(%s %s)\n",symbol,coinaddr);
}
else if ( IAMLP == 0 )
{
//printf("LP_listunspent_query.(%s %s)\n",symbol,coinaddr);
LP_listunspent_query(coin->symbol,coin->smartaddr);
}
if ( fullflag == 2 && (ap= LP_addressfind(coin,coinaddr)) != 0 )
ap->unspenttime = 0;
retjson = LP_listunspent(symbol,coinaddr,reftxid,reftxid2);
coin->numutxos = cJSON_GetArraySize(retjson);
if ( retjson != 0 )
{
n = cJSON_GetArraySize(retjson);
if ( electrum_process_array(coin,0,coinaddr,retjson,1) != 0 )
if ( electrum_process_array(coin,0,coinaddr,retjson,1,reftxid,reftxid2) != 0 )
{
//LP_postutxos(symbol,coinaddr); // might be good to not saturate
}
@ -701,39 +516,6 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
return(n);
}
cJSON *LP_importprivkey(char *symbol,char *wifstr,char *label,int32_t flag)
{
static void *ctx;
char buf[512],address[64]; cJSON *retjson; struct iguana_info *coin; int32_t doneflag = 0;
if ( symbol == 0 || symbol[0] == 0 )
return(cJSON_Parse("{\"error\":\"null symbol\"}"));
coin = LP_coinfind(symbol);
if ( coin == 0 )
return(cJSON_Parse("{\"error\":\"no coin\"}"));
if ( coin->electrum != 0 )
return(cJSON_Parse("{\"result\":\"electrum should have local wallet\"}"));
if ( ctx == 0 )
ctx = bitcoin_ctx();
bitcoin_wif2addr(ctx,coin->wiftaddr,coin->taddr,coin->pubtype,address,wifstr);
if ( (retjson= LP_validateaddress(symbol,address)) != 0 )
{
if ( jobj(retjson,"ismine") != 0 && is_cJSON_True(jobj(retjson,"ismine")) != 0 )
{
doneflag = 1;
//printf("%s already ismine\n",address);
}
//printf("%s\n",jprint(retjson,0));
free_json(retjson);
}
if ( doneflag == 0 )
{
if ( coin->noimportprivkey_flag != 0 )
sprintf(buf,"[\"%s\"]",wifstr);
else sprintf(buf,"\"%s\", \"%s\", %s",wifstr,label,flag < 0 ? "false" : "true");
return(bitcoin_json(coin,"importprivkey",buf));
} else return(cJSON_Parse("{\"result\":\"success\"}"));
}
int32_t LP_importaddress(char *symbol,char *address)
{
char buf[1024],*retstr; cJSON *validatejson; int32_t isvalid=0,doneflag = 0; struct iguana_info *coin;
@ -745,10 +527,10 @@ int32_t LP_importaddress(char *symbol,char *address)
if ( coin->electrum != 0 )
{
/*if ( (retjson= electrum_address_subscribe(symbol,coin->electrum,&retjson,address)) != 0 )
{
printf("importaddress.(%s) -> %s\n",address,jprint(retjson,0));
free_json(retjson);
}*/
{
printf("importaddress.(%s) -> %s\n",address,jprint(retjson,0));
free_json(retjson);
}*/
return(0);
}
else
@ -776,6 +558,45 @@ int32_t LP_importaddress(char *symbol,char *address)
}
}
cJSON *LP_importprivkey(char *symbol,char *wifstr,char *label,int32_t flag)
{
static void *ctx;
char buf[512],address[64]; cJSON *retjson; struct iguana_info *coin; int32_t doneflag = 0;
if ( symbol == 0 || symbol[0] == 0 )
return(cJSON_Parse("{\"error\":\"null symbol\"}"));
coin = LP_coinfind(symbol);
if ( coin == 0 )
return(cJSON_Parse("{\"error\":\"no coin\"}"));
if ( coin->electrum != 0 )
return(cJSON_Parse("{\"result\":\"electrum should have local wallet\"}"));
if ( ctx == 0 )
ctx = bitcoin_ctx();
bitcoin_wif2addr(ctx,coin->wiftaddr,coin->taddr,coin->pubtype,address,wifstr);
#ifdef LP_DONT_IMPORTPRIVKEY
bitcoin_wif2addr(ctx,coin->wiftaddr,coin->taddr,coin->pubtype,address,wifstr);
if ( LP_importaddress(symbol,address) < 0 )
return(cJSON_Parse("{\"error\":\"couldnt import\"}"));
else return(cJSON_Parse("{\"result\":\"success\"}"));
#endif
if ( (retjson= LP_validateaddress(symbol,address)) != 0 )
{
if ( jobj(retjson,"ismine") != 0 && is_cJSON_True(jobj(retjson,"ismine")) != 0 )
{
doneflag = 1;
//printf("%s already ismine\n",address);
}
//printf("%s\n",jprint(retjson,0));
free_json(retjson);
}
if ( doneflag == 0 )
{
if ( coin->noimportprivkey_flag != 0 )
sprintf(buf,"[\"%s\"]",wifstr);
else sprintf(buf,"\"%s\", \"%s\", %s",wifstr,label,flag < 0 ? "false" : "true");
return(bitcoin_json(coin,"importprivkey",buf));
} else return(cJSON_Parse("{\"result\":\"success\"}"));
}
double _LP_getestimatedrate(struct iguana_info *coin)
{
char buf[512],*retstr=0; int32_t numblocks; cJSON *errjson,*retjson; double rate = 0.00000020;
@ -805,9 +626,9 @@ double _LP_getestimatedrate(struct iguana_info *coin)
rate = atof(retstr) / 1024.;
if ( rate < 0.00000020 )
rate = 0.00000020;
rate *= 1.1;
rate *= 1.5;
if ( coin->electrum != 0 )
rate *= 1.667;
rate *= 1.5;
if ( fabs(rate - coin->rate) > SMALLVAL )
printf("t%u estimated rate.(%s) (%s) -> %.8f %.8f\n",coin->ratetime,coin->symbol,retstr,rate,coin->rate);
coin->rate = rate;
@ -998,17 +819,19 @@ bits256 LP_getbestblockhash(struct iguana_info *coin)
char *LP_blockhashstr(char *symbol,int32_t height)
{
cJSON *array; char *paramstr,*retstr; struct iguana_info *coin;
char params[64],*retstr; struct iguana_info *coin; //cJSON *array;
if ( symbol == 0 || symbol[0] == 0 )
return(0);
coin = LP_coinfind(symbol);
if ( coin == 0 || coin->electrum != 0 )
return(0);
array = cJSON_CreateArray();
jaddinum(array,height);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"getblockhash",paramstr);
free(paramstr);
//array = cJSON_CreateArray();
//jaddinum(array,height);
//paramstr = jprint(array,1);
sprintf(params,"[%d]",height);
retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"getblockhash",params);
//free(paramstr);
//printf("blockhashstr.(%s)\n",retstr);
return(retstr);
}
@ -1158,10 +981,11 @@ const char *Notaries_elected[][2] =
{ "xxspot2_XX", "03d85b221ea72ebcd25373e7961f4983d12add66a92f899deaf07bab1d8b6f5573" }
};
int32_t LP_txhasnotarization(struct iguana_info *coin,bits256 txid)
int32_t LP_txhasnotarization(bits256 *notarizedhashp,struct iguana_info *coin,bits256 txid)
{
cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[35]; bits256 spenttxid; uint64_t notarymask; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0;
if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 )
cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[1024]; bits256 spenttxid; uint64_t notarymask; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0;
memset(notarizedhashp,0,sizeof(*notarizedhashp));
if ( (txobj= LP_gettx(coin->symbol,txid,0)) != 0 )
{
if ( (vins= jarray(&numvins,txobj,"vin")) != 0 )
{
@ -1173,14 +997,14 @@ int32_t LP_txhasnotarization(struct iguana_info *coin,bits256 txid)
vin = jitem(vins,i);
spenttxid = jbits256(vin,"txid");
spentvout = jint(vin,"vout");
if ( (spentobj= LP_gettx(coin->symbol,spenttxid)) != 0 )
if ( (spentobj= LP_gettx(coin->symbol,spenttxid,0)) != 0 )
{
if ( (vouts= jarray(&numvouts,spentobj,"vout")) != 0 )
{
if ( spentvout < numvouts )
{
vout = jitem(vouts,spentvout);
if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) == sizeof(script)*2 )
if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) == 35*2 )
{
len >>= 1;
decode_hex(script,len,hexstr);
@ -1214,20 +1038,76 @@ int32_t LP_txhasnotarization(struct iguana_info *coin,bits256 txid)
}
}
}
if ( (vouts= jarray(&numvouts,txobj,"vout")) != 0 )
{
vout = jitem(vouts,1);
if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) >= 35 )
{
len >>= 1;
decode_hex(script,len,hexstr);
iguana_rwbignum(0,&script[2],32,(uint8_t *)notarizedhashp);
}
}
free_json(txobj);
}
return(hasnotarization);
}
int32_t LP_notarization_validate(char *symbol,int32_t notarized,bits256 notarizedhash,bits256 notarizationtxid)
{
struct iguana_info *coin; int32_t valid = 0; cJSON *blockjson; bits256 notarizedhash2; char str[65],str2[65];
if ( strcmp(symbol,"KMD") == 0 )
coin = LP_coinfind("BTC");
else coin = LP_coinfind("KMD");
if ( coin != 0 )
{
if (LP_txhasnotarization(&notarizedhash2,coin,notarizationtxid) == 0 )
{
printf("missing %s notarization txid %s\n",symbol,bits256_str(str,notarizationtxid));
return(-1);
}
else if ( bits256_cmp(notarizedhash,notarizedhash2) != 0 )
{
printf("mismatched %s notarizedhash %s vs %s\n",symbol,bits256_str(str,notarizedhash),bits256_str(str2,notarizedhash2));
return(-1);
}
}
if ( (coin= LP_coinfind(symbol)) != 0 )
{
if ( coin->electrum == 0 )
{
if ( (blockjson= LP_getblock(coin->symbol,notarizedhash)) != 0 )
{
if ( jint(blockjson,"height") != notarized )
valid = 1;
free_json(blockjson);
}
}
else
{
if ( (blockjson= electrum_getheader(symbol,coin->electrum,&blockjson,notarized+1)) != 0 )
{
notarizedhash2 = jbits256(blockjson,"prev_block_hash");
if ( bits256_cmp(notarizedhash,notarizedhash2) == 0 )
valid = 1;
free_json(blockjson);
}
}
}
if ( valid == 1 )
return(0);
else return(-1);
}
int32_t LP_hasnotarization(struct iguana_info *coin,cJSON *blockjson)
{
int32_t i,n,hasnotarization = 0; bits256 txid; cJSON *txarray;
int32_t i,n,hasnotarization = 0; bits256 txid,notarizedhash; cJSON *txarray;
if ( (txarray= jarray(&n,blockjson,"tx")) != 0 )
{
for (i=0; i<n; i++)
{
txid = jbits256i(txarray,i);
hasnotarization += LP_txhasnotarization(coin,txid);
hasnotarization += LP_txhasnotarization(&notarizedhash,coin,txid);
}
}
return(hasnotarization);

17
iguana/exchanges/LP_scan.c

@ -26,6 +26,7 @@ int32_t LP_blockinit(struct iguana_info *coin,int32_t height)
{
if ( (txs= jarray(&numtx,blockobj,"tx")) != 0 )
{
//printf("LP_blockinit %s ht.%d numtx.%d\n",coin->symbol,height,numtx);
for (iter=0; iter<2; iter++)
{
txobj = 0;
@ -413,10 +414,11 @@ int32_t LP_spendsearch(char *coinaddr,bits256 *spendtxidp,int32_t *indp,char *sy
int32_t LP_mempoolscan(char *symbol,bits256 searchtxid)
{
int32_t i,n; cJSON *array,*txobj; bits256 txid; struct iguana_info *coin; struct LP_transaction *tx;
int32_t i,n; cJSON *array,*txobj; bits256 txid,zero; struct iguana_info *coin; struct LP_transaction *tx;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 || coin->electrum != 0 )
return(-1);
if ( (array= LP_getmempool(symbol,0)) != 0 )
memset(zero.bytes,0,sizeof(zero));
if ( (array= LP_getmempool(symbol,0,searchtxid,zero)) != 0 )
{
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
@ -444,7 +446,7 @@ int32_t LP_mempoolscan(char *symbol,bits256 searchtxid)
int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration)
{
struct iguana_info *coin; cJSON *array,*item; uint32_t expiration,i,n; int32_t numconfirms = -1;
struct iguana_info *coin; bits256 zero; cJSON *array,*item; uint32_t expiration,i,n; int32_t numconfirms = -1;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
{
printf("LP_waitmempool missing coin.%p or inactive\n",coin);
@ -464,7 +466,8 @@ int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int
}
else
{
if ( (array= electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr)) != 0 )
memset(zero.bytes,0,sizeof(zero));
if ( (array= electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr,txid,zero)) != 0 )
{
//char str[65]; printf("check %s mempool.(%s)\n",bits256_str(str,txid),jprint(array,0));
if ( (n= cJSON_GetArraySize(array)) > 0 )
@ -482,12 +485,12 @@ int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int
}
free(array);
}
LP_listunspent_issue(coin->symbol,coinaddr,1);
LP_listunspent_issue(coin->symbol,coinaddr,1,txid,zero);
struct LP_address_utxo *up;
if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 )
{
char str[65]; printf("address_utxofind found confirmed %s %s %s ht.%d vs %d\n",symbol,coinaddr,bits256_str(str,txid),up->U.height,coin->height);
if ( coin->electrum != 0 && (array= electrum_address_gethistory(symbol,coin->electrum,&array,coinaddr)) != 0 )
if ( coin->electrum != 0 && (array= electrum_address_gethistory(symbol,coin->electrum,&array,coinaddr,txid)) != 0 )
free_json(array);
if ( coin->height >= up->U.height )
numconfirms = (coin->height - up->U.height + 1);
@ -512,7 +515,7 @@ int32_t LP_mempool_vinscan(bits256 *spendtxidp,int32_t *spendvinp,char *symbol,c
return(-1);
if ( time(NULL) > coin->lastmempool+LP_MEMPOOL_TIMEINCR )
{
if ( (array= LP_getmempool(symbol,coinaddr)) != 0 )
if ( (array= LP_getmempool(symbol,coinaddr,searchtxid,searchtxid2)) != 0 )
{
free_json(array);
coin->lastmempool = (uint32_t)time(NULL);

13
iguana/exchanges/LP_secp.c

@ -86,21 +86,28 @@ bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even)
int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag)
{
int32_t fCompressed = 1;
secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; int32_t recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB;
secp256k1_ecdsa_signature SIG; void *funcp; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; uint8_t *entropy; int32_t recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB;
seed = rand256(0);
extra_entropy = rand256(0);
SECP_ENSURE_CTX
{
funcp = secp256k1_nonce_function_rfc6979;
if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 )
{
//printf("bitcoin_sign illegal privkey\n");
return(-1);
}
if ( strcmp(symbol,"BCH") == 0 || strcmp(symbol,"BTG") == 0 )
{
char str[65]; printf("BCH/BTG deterministic signature %s\n",bits256_str(str,txhash2));
funcp = 0;
entropy = 0;
} else entropy = extra_entropy.bytes;
if ( secp256k1_context_randomize(ctx,seed.bytes) != 0 )
{
if ( recoverflag != 0 )
{
if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 )
if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,funcp,entropy) != 0 )
{
recid = -1;
secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx,sig+1,&recid,&rSIG);
@ -125,7 +132,7 @@ int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256
}
else
{
if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 )
if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,funcp,entropy) != 0 )
{
if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) != 0 )
retval = (int32_t)siglen;

154
iguana/exchanges/LP_signatures.c

@ -194,15 +194,15 @@ int32_t LP_quotedestinfo(struct LP_quoteinfo *qp,bits256 desttxid,int32_t destvo
return(0);
}
char *LP_quotereceived(cJSON *argjson)
char *LP_quotereceived(struct LP_quoteinfo *qp)
{
struct LP_cacheinfo *ptr; double price; struct LP_quoteinfo Q;
LP_quoteparse(&Q,argjson);
price = (double)Q.destsatoshis / (Q.satoshis - Q.txfee);
if ( (ptr= LP_cacheadd(Q.srccoin,Q.destcoin,Q.txid,Q.vout,price,&Q)) != 0 )
struct LP_cacheinfo *ptr; double price;
//LP_quoteparse(&Q,argjson);
price = (double)qp->destsatoshis / (qp->satoshis - qp->txfee);
if ( (ptr= LP_cacheadd(qp->srccoin,qp->destcoin,qp->txid,qp->vout,price,qp)) != 0 )
{
ptr->Q = Q;
printf(">>>>>>>>>> received quote %s/%s %.8f\n",Q.srccoin,Q.destcoin,price);
ptr->Q = *qp;
printf(">>>>>>>>>> received quote %s/%s %.8f\n",qp->srccoin,qp->destcoin,price);
return(clonestr("{\"result\":\"updated\"}"));
} else return(clonestr("{\"error\":\"nullptr\"}"));
}
@ -276,7 +276,7 @@ bits256 LP_utxos_sighash(uint32_t timestamp,uint8_t *pubsecp,bits256 pubkey,bits
int32_t LP_utxos_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,bits256 utxoshash)
{
static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; char str[65]; struct LP_pubkeyinfo *pubp;
static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; char str[65]; struct LP_pubkey_info *pubp;
if ( ctx == 0 )
ctx = bitcoin_ctx();
pubp = LP_pubkeyfind(pubkey);
@ -357,66 +357,9 @@ return;
}
}
queue_t utxosQ;
struct LP_utxos_qitem { struct queueitem DL; cJSON *argjson; };
char *LP_postutxos_recv(cJSON *argjson)
{
struct LP_utxos_qitem *uitem; struct iguana_info *coin; char *coinaddr,*symbol; bits256 utxoshash,pubkey; cJSON *obj; struct LP_pubkeyinfo *pubp;
printf("LP_postutxos_recv deprecated\n");
pubkey = jbits256(argjson,"pubkey");
pubp = LP_pubkeyfind(pubkey);
if ( pubp != 0 && pubp->numerrors > LP_MAXPUBKEY_ERRORS )
return(clonestr("{\"error\":\"blacklisted\"}"));
if ( (coinaddr= jstr(argjson,"coinaddr")) != 0 && (symbol= jstr(argjson,"coin")) != 0 && (coin= LP_coinfind(symbol)) != 0 )
{
if ( strcmp(coinaddr,coin->smartaddr) == 0 )
{
//printf("ignore my utxo from external source %s %s\n",symbol,coinaddr);
return(clonestr("{\"result\":\"success\"}"));
}
}
if ( (obj= jobj(argjson,"utxos")) != 0 )
{
utxoshash = LP_utxoshash_calc(obj);
//char str[65]; //printf("got utxoshash %s\n",bits256_str(str,utxoshash));
if ( LP_utxos_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,utxoshash) == 0 )
{
uitem = calloc(1,sizeof(*uitem));
uitem->argjson = jduplicate(argjson);
queue_enqueue("utxosQ",&utxosQ,&uitem->DL);
return(clonestr("{\"result\":\"success\"}"));
} //else printf("valid utxos sig %s\n",bits256_str(str,pubp->pubkey));
}
return(clonestr("{\"error\":\"sig failure\"}"));
}
int32_t LP_utxosQ_process()
{
struct LP_utxos_qitem *uitem; int32_t n; char *symbol,*coinaddr; struct LP_address *ap; struct iguana_info *coin; cJSON *array;
if ( (uitem= queue_dequeue(&utxosQ)) != 0 )
{
//printf("LP_utxosQ_process.(%s)\n",jprint(uitem->argjson,0));
if ( (coinaddr= jstr(uitem->argjson,"coinaddr")) != 0 && (symbol= jstr(uitem->argjson,"coin")) != 0 && (coin= LP_coinfind(symbol)) != 0 ) // addsig
{
if ( coin->electrum == 0 || (ap= LP_addressfind(coin,coinaddr)) != 0 )
{
if ( (array= jarray(&n,uitem->argjson,"utxos")) != 0 )
LP_unspents_array(coin,coinaddr,array);
}
else if ( (array= electrum_address_listunspent(symbol,coin->electrum,&array,coinaddr,1)) != 0 )
free_json(array);
}
free_json(uitem->argjson);
free(uitem);
return(1);
}
return(0);
}
int32_t LP_price_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,char *base,char *rel,uint64_t price64)
{
static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; struct LP_pubkeyinfo *pubp;
static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; struct LP_pubkey_info *pubp;
if ( ctx == 0 )
ctx = bitcoin_ctx();
pubp = LP_pubkeyfind(pubkey);
@ -451,10 +394,10 @@ int32_t LP_price_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,uint8_t *pub
char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price)
{
struct iguana_info *basecoin,*relcoin; struct LP_address *ap; char pubsecpstr[67]; uint32_t numutxos,timestamp; uint64_t price64,balance,minsize,maxsize; bits256 zero; cJSON *reqjson;
struct iguana_info *basecoin,*relcoin,*kmd; struct LP_address *ap; char pubsecpstr[67]; uint32_t numutxos,timestamp; uint64_t price64,balance,minsize,maxsize; bits256 zero; cJSON *reqjson;
reqjson = cJSON_CreateObject();
// LP_addsig
if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 && basecoin->electrum == 0 )//&& relcoin->electrum == 0 )
if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 )//&& basecoin->electrum == 0 )//&& relcoin->electrum == 0 )
{
memset(zero.bytes,0,sizeof(zero));
jaddbits256(reqjson,"pubkey",G.LP_mypub25519);
@ -468,17 +411,16 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re
jaddnum(reqjson,"timestamp",timestamp);
init_hexbytes_noT(pubsecpstr,G.LP_pubsecp,33);
jaddstr(reqjson,"pubsecp",pubsecpstr);
if ( (ap= LP_address(basecoin,basecoin->smartaddr)) != 0 )
if ( (kmd= LP_coinfind("KMD")) != 0 && (ap= LP_address(kmd,kmd->smartaddr)) != 0 && ap->instantdex_credits != 0 )
jaddnum(reqjson,"credits",dstr(ap->instantdex_credits));
if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,basecoin,basecoin->smartaddr)) != 0 )
{
if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,ap)) != 0 )
{
//printf("%s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize));
jaddstr(reqjson,"utxocoin",base);
jaddnum(reqjson,"n",numutxos);
jaddnum(reqjson,"bal",dstr(balance));
jaddnum(reqjson,"min",dstr(minsize));
jaddnum(reqjson,"max",dstr(maxsize));
}
//printf("send %s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize));
jaddstr(reqjson,"utxocoin",base);
jaddnum(reqjson,"n",numutxos);
jaddnum(reqjson,"bal",dstr(balance));
jaddnum(reqjson,"min",dstr(minsize));
jaddnum(reqjson,"max",dstr(maxsize));
}
LP_price_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_pubsecp,G.LP_mypub25519,base,rel,price64);
LP_reserved_msg(0,base,rel,zero,jprint(reqjson,1));
@ -497,9 +439,15 @@ char *LP_postprice_recv(cJSON *argjson)
{
if ( LP_price_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,base,rel,j64bits(argjson,"price64")) == 0 )
{
LP_pricefeedupdate(pubkey,base,rel,price,jstr(argjson,"utxocoin"),jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN);
//printf("call pricefeed update\n");
LP_pricefeedupdate(pubkey,base,rel,price,jstr(argjson,"utxocoin"),jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN,jdouble(argjson,"credits")*SATOSHIDEN);
return(clonestr("{\"result\":\"success\"}"));
} else return(clonestr("{\"error\":\"sig failure\"}"));
}
else
{
printf("sig failure\n");
return(clonestr("{\"error\":\"sig failure\"}"));
}
}
}
return(clonestr("{\"error\":\"missing fields in posted price\"}"));
@ -521,7 +469,7 @@ int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub
return(LP_bitcoinsig_add(item,priv,pubsecp,sighash));
}
int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item)
int32_t LP_pubkey_sigcheck(struct LP_pubkey_info *pubp,cJSON *item)
{
int32_t i,len,siglen,retval=-1; uint8_t rmd160[20],checkrmd160[20],pubsecp[33],sig[65],zeroes[20]; char *sigstr,*hexstr,*pubsecpstr;
if ( (hexstr= jstr(item,"rmd160")) != 0 && strlen(hexstr) == 2*sizeof(rmd160) )
@ -603,7 +551,7 @@ void LP_notify_pubkeys(void *ctx,int32_t pubsock)
char *LP_notify_recv(cJSON *argjson)
{
bits256 pub; struct LP_pubkeyinfo *pubp; char *ipaddr;
bits256 pub; struct LP_pubkey_info *pubp; char *ipaddr;
pub = jbits256(argjson,"pub");
if ( bits256_nonz(pub) != 0 )
{
@ -695,13 +643,13 @@ void LP_listunspent_query(char *symbol,char *coinaddr)
void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_quoteinfo *qp)
{
cJSON *reqjson; bits256 zero; char *msg,*msg2; int32_t flag = 0;
cJSON *reqjson; bits256 zero; char *msg; struct iguana_info *coin; int32_t flag = 0;
if ( strcmp(method,"request") == 0 )
{
if ( LP_allocated(qp->desttxid,qp->destvout) == 0 && LP_allocated(qp->feetxid,qp->feevout) == 0 )
{
LP_unavailableset(qp->desttxid,qp->destvout,qp->timestamp+LP_AUTOTRADE_TIMEOUT,qp->srchash);
LP_unavailableset(qp->feetxid,qp->feevout,qp->timestamp+LP_AUTOTRADE_TIMEOUT,qp->srchash);
LP_unavailableset(qp->desttxid,qp->destvout,qp->timestamp+LP_AUTOTRADE_TIMEOUT*4,qp->srchash);
LP_unavailableset(qp->feetxid,qp->feevout,qp->timestamp+LP_AUTOTRADE_TIMEOUT*4,qp->srchash);
}
else
{
@ -714,17 +662,33 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_
flag = 1;
jaddbits256(reqjson,"pubkey",qp->srchash);
jaddstr(reqjson,"method",method);
jaddnum(reqjson,"timestamp",time(NULL));
if ( jobj(reqjson,"timestamp") == 0 )
jaddnum(reqjson,"timestamp",time(NULL));
if ( strcmp(method,"connect") == 0 )
{
if ( (coin= LP_coinfind("KMD")) != 0 )
jadd(reqjson,"proof",LP_instantdex_txids(0,coin->smartaddr));
}
msg = jprint(reqjson,1);
msg2 = clonestr(msg);
printf("QUERY.(%s)\n",msg);
memset(&zero,0,sizeof(zero));
portable_mutex_lock(&LP_reservedmutex);
if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 )
Reserved_msgs[1][num_Reserved_msgs[1]++] = msg;
if ( num_Reserved_msgs[0] < sizeof(Reserved_msgs[0])/sizeof(*Reserved_msgs[0])-2 )
Reserved_msgs[0][num_Reserved_msgs[0]++] = msg2;
//LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,zero,msg2);
portable_mutex_unlock(&LP_reservedmutex);
//if ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 )
{
memset(&zero,0,sizeof(zero));
LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg));
if ( strcmp(method,"request") == 0 )
{
sleep(1);
LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg));
sleep(1);
LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg));
}
free(msg);
/*portable_mutex_lock(&LP_reservedmutex);
if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 )
Reserved_msgs[1][num_Reserved_msgs[1]++] = msg;
if ( num_Reserved_msgs[0] < sizeof(Reserved_msgs[0])/sizeof(*Reserved_msgs[0])-2 )
Reserved_msgs[0][num_Reserved_msgs[0]++] = msg2;
portable_mutex_unlock(&LP_reservedmutex);*/
} //else LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->srchash,msg);
}

142
iguana/exchanges/LP_socket.c

@ -283,7 +283,7 @@ struct electrum_info *electrum_server(char *symbol,struct electrum_info *ep)
return(ep);
}
int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep,char *coinaddr,cJSON *array,int32_t electrumflag)
int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep,char *coinaddr,cJSON *array,int32_t electrumflag,bits256 reftxid,bits256 reftxid2)
{
int32_t i,v,n,ht,flag = 0; char str[65]; uint64_t value; bits256 txid; cJSON *item,*retjson,*txobj; struct LP_transaction *tx;
if ( array != 0 && coin != 0 && (n= cJSON_GetArraySize(array)) > 0 )
@ -317,10 +317,13 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep
continue;
if ( (tx= LP_transactionfind(coin,txid)) == 0 )
{
txobj = LP_transactioninit(coin,txid,0,0);
LP_transactioninit(coin,txid,1,txobj);
free_json(txobj);
tx = LP_transactionfind(coin,txid);
if ( (bits256_nonz(reftxid) == 0 || bits256_cmp(reftxid,txid) == 0) && (bits256_nonz(reftxid2) == 0 || bits256_cmp(reftxid2,txid) == 0) )
{
txobj = LP_transactioninit(coin,txid,0,0);
LP_transactioninit(coin,txid,1,txobj);
free_json(txobj);
tx = LP_transactionfind(coin,txid);
}
}
if ( tx != 0 )
{
@ -401,6 +404,8 @@ int32_t electrum_kickstart(struct electrum_info *ep)
return(0);
}
int32_t zeroval();
cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,char *params,int32_t timeout)
{
// queue id and string and callback
@ -440,7 +445,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch
}
return(*retjsonp);
}
} else printf("couldnt find electrum server for (%s %s) or no retjsonp.%p\n",method,params,retjsonp);
} //else printf("couldnt find electrum server for (%s %s) or no retjsonp.%p\n",method,params,retjsonp);
ep = ep->prev;
//if ( ep != 0 )
// printf("using prev ep.%s\n",ep->symbol);
@ -518,7 +523,7 @@ cJSON *electrum_address_subscribe(char *symbol,struct electrum_info *ep,cJSON **
return(retjson);
}
cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr)
cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid)
{
char str[65]; struct LP_transaction *tx; cJSON *retjson,*txobj,*item; int32_t i,n,height; bits256 txid; struct iguana_info *coin = LP_coinfind(symbol);
retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_history",addr,ELECTRUM_TIMEOUT);
@ -530,7 +535,7 @@ cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON *
item = jitem(retjson,i);
txid = jbits256(item,"tx_hash");
height = jint(item,"height");
if ( (tx= LP_transactionfind(coin,txid)) == 0 )
if ( (tx= LP_transactionfind(coin,txid)) == 0 && (bits256_nonz(reftxid) == 0 || bits256_cmp(txid,reftxid) == 0) )
{
//char str[65]; printf("history txinit %s ht.%d\n",bits256_str(str,txid),height);
txobj = LP_transactioninit(coin,txid,0,0);
@ -553,27 +558,27 @@ cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON *
return(retjson);
}
int32_t LP_txheight_check(struct iguana_info *coin,char *coinaddr,struct LP_address_utxo *up)
int32_t LP_txheight_check(struct iguana_info *coin,char *coinaddr,bits256 txid)
{
cJSON *retjson;
if ( coin->electrum != 0 )
{
if ( (retjson= electrum_address_gethistory(coin->symbol,coin->electrum,&retjson,coinaddr)) != 0 )
if ( (retjson= electrum_address_gethistory(coin->symbol,coin->electrum,&retjson,coinaddr,txid)) != 0 )
free_json(retjson);
}
return(0);
}
cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr)
cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid,bits256 reftxid2)
{
cJSON *retjson; struct iguana_info *coin = LP_coinfind(symbol);
retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_mempool",addr,ELECTRUM_TIMEOUT);
//printf("MEMPOOL.(%s)\n",jprint(retjson,0));
electrum_process_array(coin,ep,addr,retjson,1);
electrum_process_array(coin,ep,addr,retjson,1,reftxid,reftxid2);
return(retjson);
}
cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,int32_t electrumflag)
cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,int32_t electrumflag,bits256 txid,bits256 txid2)
{
cJSON *retjson=0; char *retstr; struct LP_address *ap; struct iguana_info *coin; int32_t updatedflag,height,usecache=1;
if ( (coin= LP_coinfind(symbol)) == 0 )
@ -589,7 +594,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON
usecache = 0;
else if ( ap->unspentheight < height )
usecache = 0;
else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+30 )
else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+13 )
usecache = 0;
}
if ( usecache == 0 || electrumflag > 1 )
@ -601,17 +606,14 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON
if ( 0 && electrumflag > 1 )
printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0)));
updatedflag = 0;
if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 )
if ( electrum_process_array(coin,ep,addr,retjson,electrumflag,txid,txid2) != 0 )
{
//LP_postutxos(coin->symbol,addr);
updatedflag = 1;
}
if ( strcmp(addr,coin->smartaddr) == 0 )
{
retstr = jprint(retjson,0);
LP_unspents_cache(coin->symbol,coin->smartaddr,retstr,1);
free(retstr);
}
retstr = jprint(retjson,0);
LP_unspents_cache(coin->symbol,addr,retstr,1);
free(retstr);
if ( ap != 0 )
{
ap->unspenttime = (uint32_t)time(NULL);
@ -627,7 +629,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON
}
if ( retjson == 0 )
{
if ( strcmp(addr,coin->smartaddr) == 0 && (retstr= LP_unspents_filestr(symbol,coin->smartaddr)) != 0 )
if ( (retstr= LP_unspents_filestr(symbol,addr)) != 0 )
{
retjson = cJSON_Parse(retstr);
free(retstr);
@ -734,7 +736,7 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs
free_json(hexjson);
//printf("return from electrum_transaction\n");
return(*retjsonp);
} else printf("%s %s non-hex tx.(%s)\n",coin->symbol,bits256_str(str,txid),jprint(hexjson,0));
} //else printf("%s %s non-hex tx.(%s)\n",coin->symbol,bits256_str(str,txid),jprint(hexjson,0));
free(hexstr);
free_json(hexjson);
}
@ -742,27 +744,34 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs
return(*retjsonp);
}
cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,char *SPVcheck)
cJSON *electrum_transaction(int32_t *heightp,char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,char *SPVcheck)
{
cJSON *retjson,*array; struct LP_transaction *tx; struct iguana_info *coin;
cJSON *retjson,*array; bits256 zero; struct LP_transaction *tx=0; struct iguana_info *coin;
coin = LP_coinfind(symbol);
*heightp = 0;
if ( ep != 0 )
portable_mutex_lock(&ep->txmutex);
retjson = _electrum_transaction(symbol,ep,retjsonp,txid);
if ( ep != 0 && coin != 0 && SPVcheck != 0 && SPVcheck[0] != 0 && (tx= LP_transactionfind(coin,txid)) != 0 )
if ( (tx= LP_transactionfind(coin,txid)) != 0 && ep != 0 && coin != 0 && SPVcheck != 0 && SPVcheck[0] != 0 )
{
if ( tx->height <= 0 )
{
if ( (array= electrum_address_listunspent(symbol,ep,&array,SPVcheck,2)) != 0 )
memset(zero.bytes,0,sizeof(zero));
if ( (array= electrum_address_listunspent(symbol,ep,&array,SPVcheck,2,txid,zero)) != 0 )
{
printf("SPVcheck.%s got %d unspents\n",SPVcheck,cJSON_GetArraySize(array));
free_json(array);
}
}
if ( tx->height > 0 )
tx->SPV = LP_merkleproof(coin,SPVcheck,ep,txid,tx->height);
{
if ( tx->SPV == 0 )
tx->SPV = LP_merkleproof(coin,SPVcheck,ep,txid,tx->height);
*heightp = tx->height;
}
char str[65]; printf("%s %s %s SPV height %d SPV %d\n",coin->symbol,SPVcheck,bits256_str(str,txid),tx->height,tx->SPV);
}
} else if ( tx != 0 )
*heightp = tx->height;
if ( ep != 0 )
portable_mutex_unlock(&ep->txmutex);
return(retjson);
@ -779,12 +788,13 @@ cJSON *electrum_getmerkle(char *symbol,struct electrum_info *ep,cJSON **retjsonp
void electrum_test()
{
cJSON *retjson; bits256 hash; struct electrum_info *ep = 0; char *addr,*script,*symbol = "BTC";
cJSON *retjson; int32_t height; bits256 hash,zero; struct electrum_info *ep = 0; char *addr,*script,*symbol = "BTC";
while ( Num_electrums == 0 )
{
sleep(1);
printf("Num_electrums %p -> %d\n",&Num_electrums,Num_electrums);
}
memset(zero.bytes,0,sizeof(zero));
printf("found electrum server\n");
if ( (retjson= electrum_version(symbol,ep,0)) != 0 )
printf("electrum_version %s\n",jprint(retjson,1));
@ -804,16 +814,16 @@ void electrum_test()
decode_hex(hash.bytes,sizeof(hash),"b967a7d55889fe11e993430921574ec6379bc8ce712a652c3fcb66c6be6e925c");
if ( (retjson= electrum_getmerkle(symbol,ep,0,hash,403000)) != 0 )
printf("electrum_getmerkle %s\n",jprint(retjson,1));
if ( (retjson= electrum_transaction(symbol,ep,0,hash,0)) != 0 )
if ( (retjson= electrum_transaction(&height,symbol,ep,0,hash,0)) != 0 )
printf("electrum_transaction %s\n",jprint(retjson,1));
addr = "14NeevLME8UAANiTCVNgvDrynUPk1VcQKb";
if ( (retjson= electrum_address_gethistory(symbol,ep,0,addr)) != 0 )
if ( (retjson= electrum_address_gethistory(symbol,ep,0,addr,zero)) != 0 )
printf("electrum_address_gethistory %s\n",jprint(retjson,1));
if ( (retjson= electrum_address_getmempool(symbol,ep,0,addr)) != 0 )
if ( (retjson= electrum_address_getmempool(symbol,ep,0,addr,zero,zero)) != 0 )
printf("electrum_address_getmempool %s\n",jprint(retjson,1));
if ( (retjson= electrum_address_getbalance(symbol,ep,0,addr)) != 0 )
printf("electrum_address_getbalance %s\n",jprint(retjson,1));
if ( (retjson= electrum_address_listunspent(symbol,ep,0,addr,1)) != 0 )
if ( (retjson= electrum_address_listunspent(symbol,ep,0,addr,1,zero,zero)) != 0 )
printf("electrum_address_listunspent %s\n",jprint(retjson,1));
if ( (retjson= electrum_addpeer(symbol,ep,0,"electrum.be:50001")) != 0 )
printf("electrum_addpeer %s\n",jprint(retjson,1));
@ -898,7 +908,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len)
ep->lasttime = (uint32_t)time(NULL);
if ( (strjson= cJSON_Parse(str)) != 0 )
{
//printf("%s RECV.(%ld) id.%d\n",ep->symbol,strlen(str),jint(strjson,"id"));
//printf("%s RECV.(%ld) id.%d (%s)\n",ep->symbol,strlen(str),jint(strjson,"id"),jint(strjson,"id")==0?str:"");
resultjson = jobj(strjson,"result");
//printf("strjson.(%s)\n",jprint(strjson,0));
if ( (method= jstr(strjson,"method")) != 0 )
@ -972,7 +982,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len)
void LP_dedicatedloop(void *arg)
{
struct pollfd fds; int32_t i,len,flag,timeout = 10; struct iguana_info *coin; struct stritem *sitem; struct electrum_info *ep = arg;
struct pollfd fds; int32_t i,len,n,flag,timeout = 10; struct iguana_info *coin; struct stritem *sitem; struct electrum_info *ep = arg;
if ( (coin= LP_coinfind(ep->symbol)) != 0 )
ep->heightp = &coin->height, ep->heighttimep = &coin->heighttime;
electrum_initial_requests(ep);
@ -1004,7 +1014,34 @@ void LP_dedicatedloop(void *arg)
{
if ( (fds.revents & POLLIN) != 0 )
{
if ( (len= LP_socketrecv(ep->sock,ep->buf,ep->bufsize)) > 0 )
len = 0;
while ( len+65536 < ep->bufsize )
{
if ( (n= LP_socketrecv(ep->sock,&ep->buf[len],ep->bufsize-len)) > 0 )
{
len += n;
if ( ep->buf[len - 1] == '\n' )
break;
memset(&fds,0,sizeof(fds));
fds.fd = ep->sock;
fds.events = POLLIN;
if ( poll(&fds,1,1000) <= 0 )
{
printf("no more electrum data after a second\n");
electrum_kickstart(ep);
break;
}
}
else
{
#ifndef _WIN32
printf("no more electrum data when expected2\n");
electrum_kickstart(ep);
#endif
break;
}
}
if ( len > 0 )
{
ep->pending = 0;
LP_recvfunc(ep,(char *)ep->buf,len);
@ -1041,13 +1078,33 @@ void LP_dedicatedloop(void *arg)
cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port)
{
struct electrum_info *ep; int32_t kickval,already; cJSON *retjson;
struct electrum_info *ep,*prev; int32_t kickval,already; cJSON *retjson,*array,*item;
if ( ipaddr == 0 || ipaddr[0] == 0 || port == 0 )
{
ep = coin->electrum;
coin->electrum = 0;
coin->inactive = (uint32_t)time(NULL);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"status","electrum mode disabled, now in disabled native coin mode");
if ( ep != 0 )
{
array = cJSON_CreateArray();
while ( ep != 0 )
{
item = cJSON_CreateObject();
jaddstr(item,"ipaddr",ep->ipaddr);
jaddnum(item,"port",ep->port);
jaddnum(item,"kickstart",electrum_kickstart(ep));
jaddi(array,item);
prev = ep->prev;
ep->prev = 0;
ep = prev;
}
jadd(retjson,"electrums",array);
}
//printf("would have disabled %s electrum here\n",coin->symbol);
return(cJSON_Parse("{\"result\":\"success\",\"status\":\"electrum mode disabled, now in native coin mode\"}"));
return(retjson);
}
retjson = cJSON_CreateObject();
jaddstr(retjson,"ipaddr",ipaddr);
@ -1075,6 +1132,13 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port)
LP_cacheptrs_init(coin);
coin->loadedcache = (uint32_t)time(NULL);
}
if ( 0 && strcmp(coin->symbol,"ZEC") == 0 )
{
void for_satinder();
sleep(3);
for_satinder();
getchar();
}
}
}
else

2117
iguana/exchanges/LP_statemachine.c

File diff suppressed because it is too large

672
iguana/exchanges/LP_stats.c

@ -20,28 +20,81 @@
#define LP_STATSLOG_FNAME "stats.log"
struct LP_swapstats
{
UT_hash_handle hh;
struct LP_quoteinfo Q;
bits256 bobdeposit,alicepayment,bobpayment,paymentspent,Apaymentspent,depositspent;
double qprice;
uint64_t aliceid;
uint32_t ind,methodind,finished,expired;
char alicegui[32],bobgui[32];
} *LP_swapstats;
struct LP_swapstats *LP_swapstats,*LP_RTstats;
int32_t LP_statslog_parsequote(char *method,cJSON *lineobj);
char *LP_stats_methods[] = { "unknown", "request", "reserved", "connect", "connected", "tradestatus" };
#define LP_TRADESTATUS_METHODIND 5
static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatuses,LP_parse_errors,LP_unknowns,LP_duplicates,LP_aliceids;
uint32_t LP_atomic_locktime(char *base,char *rel)
void LP_dPoW_request(struct iguana_info *coin)
{
if ( strcmp(base,"BTC") != 0 && strcmp(rel,"BTC") != 0 )
return(INSTANTDEX_LOCKTIME);
else return(INSTANTDEX_LOCKTIME * 10);
bits256 zero; cJSON *reqjson;
reqjson = cJSON_CreateObject();
jaddstr(reqjson,"method","getdPoW");
jaddstr(reqjson,"coin",coin->symbol);
memset(zero.bytes,0,sizeof(zero));
//printf("request %s\n",jprint(reqjson,0));
LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1));
}
static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatuses,LP_parse_errors,LP_unknowns,LP_duplicates,LP_aliceids;
void LP_dPoW_broadcast(struct iguana_info *coin)
{
bits256 zero; cJSON *reqjson;
if ( time(NULL) > coin->dPoWtime+60 && (coin->isassetchain != 0 || strcmp(coin->symbol,"KMD") == 0) )
{
reqjson = cJSON_CreateObject();
jaddstr(reqjson,"method","dPoW");
jaddstr(reqjson,"coin",coin->symbol);
jaddnum(reqjson,"notarized",coin->notarized);
jaddbits256(reqjson,"notarizedhash",coin->notarizedhash);
jaddbits256(reqjson,"notarizationtxid",coin->notarizationtxid);
memset(zero.bytes,0,sizeof(zero));
//printf("broadcast %s\n",jprint(reqjson,0));
LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1));
coin->dPoWtime = (uint32_t)time(NULL);
}
}
char *LP_dPoW_recv(cJSON *argjson)
{
int32_t notarized; bits256 notarizedhash,notarizationtxid; char *symbol; struct iguana_info *coin;
if ( (symbol= jstr(argjson,"coin")) != 0 && (coin= LP_coinfind(symbol)) != 0 && coin->electrum != 0 )
{
notarized = jint(argjson,"notarized");
notarizedhash = jbits256(argjson,"notarizedhash");
notarizationtxid = jbits256(argjson,"notarizationtxid");
//printf("dPoW %s\n",jprint(argjson,0));
if ( notarized > coin->notarized && LP_notarization_validate(symbol,notarized,notarizedhash,notarizationtxid) == 0 )
{
coin->notarized = notarized;
coin->notarizedhash = notarizedhash;
coin->notarizationtxid = notarizationtxid;
printf("VALIDATED dPoW %s\n",jprint(argjson,0));
}
}
return(clonestr("{\"result\":\"success\"}"));
}
/*int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height
{
int32_t notarized,oldnotarized;
if ( coin->electrum == 0 )
{
coin->heighttime = (uint32_t)(time(NULL) - 61);
oldnotarized = coin->notarized;
LP_getheight(&notarized,coin);
if ( notarized != 0 && notarized != oldnotarized )
{
printf("dPoWheight.%s %d <- %d\n",coin->symbol,oldnotarized,notarized);
coin->notarized = notarized;
}
}
else if ( coin->notarized == 0 )
LP_dPoW_request(coin);
return(coin->notarized);
}*/
void LP_tradecommand_log(cJSON *argjson)
{
@ -97,13 +150,14 @@ void LP_statslog_parseline(cJSON *lineobj)
int32_t LP_statslog_parse()
{
static long lastpos; FILE *fp; char line[8192]; cJSON *lineobj; int32_t n = 0;
static long lastpos;
FILE *fp; long fpos; char line[8192]; cJSON *lineobj; int32_t c,n = 0;
if ( (fp= fopen(LP_STATSLOG_FNAME,"rb")) != 0 )
{
if ( lastpos > 0 )
{
fseek(fp,0,SEEK_END);
if ( ftell(fp) > lastpos )
if ( ftell(fp) >= lastpos )
fseek(fp,lastpos,SEEK_SET);
else
{
@ -111,6 +165,20 @@ int32_t LP_statslog_parse()
return(0);
}
}
else if ( 1 )
{
if ( IAMLP == 0 )
{
fseek(fp,0,SEEK_END);
if ( (fpos= ftell(fp)) > LP_CLIENT_STATSPARSE )
{
fseek(fp,fpos-LP_CLIENT_STATSPARSE,SEEK_SET);
while ( (c= fgetc(fp)) >= 0 && c != '\n' )
;
printf("start scanning %s from %ld, found boundary %ld\n",LP_STATSLOG_FNAME,fpos-LP_CLIENT_STATSPARSE,ftell(fp));
} else rewind(fp);
}
}
while ( fgets(line,sizeof(line),fp) > 0 )
{
lastpos = ftell(fp);
@ -130,18 +198,22 @@ int32_t LP_statslog_parse()
struct LP_swapstats *LP_swapstats_find(uint64_t aliceid)
{
struct LP_swapstats *sp;
HASH_FIND(hh,LP_swapstats,&aliceid,sizeof(aliceid),sp);
HASH_FIND(hh,LP_RTstats,&aliceid,sizeof(aliceid),sp);
if ( sp == 0 )
HASH_FIND(hh,LP_swapstats,&aliceid,sizeof(aliceid),sp);
return(sp);
}
struct LP_swapstats *LP_swapstats_add(uint64_t aliceid)
struct LP_swapstats *LP_swapstats_add(uint64_t aliceid,int32_t RTflag)
{
struct LP_swapstats *sp;
if ( (sp= LP_swapstats_find(aliceid)) == 0 )
{
sp = calloc(1,sizeof(*sp));
sp->aliceid = aliceid;
HASH_ADD(hh,LP_swapstats,aliceid,sizeof(aliceid),sp);
if ( RTflag != 0 )
HASH_ADD(hh,LP_RTstats,aliceid,sizeof(aliceid),sp);
else HASH_ADD(hh,LP_swapstats,aliceid,sizeof(aliceid),sp);
}
return(LP_swapstats_find(aliceid));
}
@ -180,6 +252,7 @@ bits256 LP_swapstats_txid(cJSON *argjson,char *name,bits256 oldtxid)
int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSON *lineobj)
{
char *statusstr,*base,*rel,gui[64]; uint32_t requestid,quoteid; uint64_t satoshis,destsatoshis;
sp->lasttime = (uint32_t)time(NULL);
safecopy(gui,sp->Q.gui,sizeof(gui));
if ( strcmp(LP_stats_methods[sp->methodind],"tradestatus") == 0 )
{
@ -189,7 +262,7 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO
quoteid = juint(lineobj,"quoteid");
satoshis = jdouble(lineobj,"srcamount") * SATOSHIDEN;
destsatoshis = jdouble(lineobj,"destamount") * SATOSHIDEN;
if ( base != 0 && strcmp(base,sp->Q.srccoin) == 0 && rel != 0 && strcmp(rel,sp->Q.destcoin) == 0 && requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid && ((satoshis+2*sp->Q.txfee)|1) == (sp->Q.satoshis|1) && ((destsatoshis+2*sp->Q.desttxfee)|1) == (sp->Q.destsatoshis|1) )
if ( base != 0 && strcmp(base,sp->Q.srccoin) == 0 && rel != 0 && strcmp(rel,sp->Q.destcoin) == 0 && requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid && llabs((int64_t)(satoshis+2*sp->Q.txfee) - (int64_t)sp->Q.satoshis) <= sp->Q.txfee && llabs((int64_t)(destsatoshis+2*sp->Q.desttxfee) - (int64_t)sp->Q.destsatoshis) <= sp->Q.desttxfee )
{
sp->bobdeposit = LP_swapstats_txid(lineobj,"bobdeposit",sp->bobdeposit);
sp->alicepayment = LP_swapstats_txid(lineobj,"alicepayment",sp->alicepayment);
@ -208,7 +281,7 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO
}
else
{
if ( requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid )
if ( 0 && requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid )
printf("mismatched tradestatus aliceid.%22llu b%s/%s r%s/%s r%u/%u q%u/%u %.8f/%.8f -> %.8f/%.8f\n",(long long)sp->aliceid,base,sp->Q.srccoin,rel,sp->Q.destcoin,requestid,sp->Q.R.requestid,quoteid,sp->Q.R.quoteid,dstr(satoshis+2*sp->Q.txfee),dstr(sp->Q.satoshis),dstr(destsatoshis+2*sp->Q.desttxfee),dstr(sp->Q.destsatoshis));
return(-1);
}
@ -219,10 +292,140 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO
return(0);
}
int32_t LP_finished_lastheight(struct LP_swapstats *sp)
{
int32_t height = 1; struct iguana_info *bob,*alice; //char str[65];
if ( (bob= LP_coinfind(sp->Q.srccoin)) != 0 && (alice= LP_coinfind(sp->Q.destcoin)) != 0 )
{
if ( strcmp(bob->symbol,"BTC") == 0 )
sp->bobneeds_dPoW = 0;
if ( strcmp(alice->symbol,"BTC") == 0 )
sp->aliceneeds_dPoW = 0;
if ( sp->bobneeds_dPoW != 0 )
{
if ( bits256_nonz(sp->bobdeposit) != 0 && sp->bobdeposit_ht == 0 )
{
if ( (sp->bobdeposit_ht= LP_txheight(bob,sp->bobdeposit)) > sp->bobneeds_dPoW )
sp->bobneeds_dPoW = sp->bobdeposit_ht;
//printf("%s bobdeposit.%d height.%d\n",bits256_str(str,sp->bobdeposit),ht,sp->bobneeds_dPoW);
}
if ( bits256_nonz(sp->bobpayment) != 0 && sp->bobpayment_ht == 0 )
{
if ( (sp->bobpayment_ht= LP_txheight(bob,sp->bobpayment)) > sp->bobneeds_dPoW )
sp->bobneeds_dPoW = sp->bobpayment_ht;
//printf("%s bobpayment.%d height.%d\n",bits256_str(str,sp->bobpayment),ht,sp->bobneeds_dPoW);
}
if ( bits256_nonz(sp->paymentspent) != 0 && sp->paymentspent_ht == 0 )
{
if ( (sp->paymentspent_ht= LP_txheight(bob,sp->paymentspent)) > sp->bobneeds_dPoW )
sp->bobneeds_dPoW = sp->paymentspent_ht;
//printf("%s paymentspent.%d height.%d\n",bits256_str(str,sp->paymentspent),ht,sp->bobneeds_dPoW);
}
if ( bits256_nonz(sp->depositspent) != 0 && sp->depositspent_ht == 0 )
{
if ( (sp->depositspent_ht= LP_txheight(bob,sp->depositspent)) > sp->bobneeds_dPoW )
sp->bobneeds_dPoW = sp->depositspent_ht;
//printf("%s depositspent.%d height.%d\n",bits256_str(str,sp->depositspent),ht,sp->bobneeds_dPoW);
}
}
if ( sp->aliceneeds_dPoW != 0 )
{
if ( bits256_nonz(sp->alicepayment) != 0 && sp->alicepayment_ht == 0 )
{
if ( (sp->alicepayment_ht= LP_txheight(alice,sp->alicepayment)) > sp->aliceneeds_dPoW )
sp->aliceneeds_dPoW = sp->alicepayment_ht;
//printf("%s alicepayment.%d height.%d\n",bits256_str(str,sp->alicepayment),ht,sp->aliceneeds_dPoW);
}
if ( bits256_nonz(sp->Apaymentspent) != 0 && sp->Apaymentspent_ht == 0 )
{
if ( (sp->Apaymentspent_ht= LP_txheight(alice,sp->Apaymentspent)) > sp->aliceneeds_dPoW )
sp->aliceneeds_dPoW = sp->Apaymentspent_ht;
//printf("%s Apaymentspent.%d height.%d\n",bits256_str(str,sp->Apaymentspent),ht,sp->aliceneeds_dPoW);
}
}
}
return(height);
}
int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag)
{
struct iguana_info *bob,*alice;
if ( sp->dPoWfinished != 0 || sp->expired != 0 )
return(1);
else if ( dPoWflag == 0 && sp->finished != 0 )
return(1);
if ( (bob= LP_coinfind(sp->Q.srccoin)) == 0 )
{
//printf("no bobcoin.%s\n",sp->Q.srccoin);
return(0);
}
if ( (alice= LP_coinfind(sp->Q.destcoin)) == 0 )
{
//printf("no alicecoin.%s\n",sp->Q.destcoin);
return(0);
}
if ( dPoWflag != 0 )
{
if ( sp->finished != 0 )
{
LP_finished_lastheight(sp);
if ( 0 && IAMLP == 0 )
printf("bob needs %d @ %d, alice needs %d @ %d\n",sp->bobneeds_dPoW,bob->notarized,sp->aliceneeds_dPoW,alice->notarized);
}
if ( (sp->bobneeds_dPoW == 0 || (sp->bobneeds_dPoW > 1 && bob->notarized >= sp->bobneeds_dPoW)) && (sp->aliceneeds_dPoW == 0 || (sp->aliceneeds_dPoW > 1 && alice->notarized >= sp->aliceneeds_dPoW)) )
{
sp->dPoWfinished = (uint32_t)time(NULL);
return(1);
}
}
return(0);
}
struct LP_swapstats *LP_swapstats_create(uint64_t aliceid,int32_t RTflag,struct LP_quoteinfo *qp,double qprice,int32_t methodind)
{
struct LP_pubswap *ptr; struct iguana_info *alice,*bob; struct LP_pubkey_info *pubp; char *base,*rel; struct LP_swapstats *sp = 0;
base = qp->srccoin, rel = qp->destcoin;
if ( (sp= LP_swapstats_add(aliceid,RTflag)) != 0 )
{
sp->Q = *qp;
sp->qprice = qprice;
sp->methodind = methodind;
sp->ind = LP_aliceids++;
sp->lasttime = (uint32_t)time(NULL);
if ( sp->lasttime > sp->Q.timestamp+LP_atomic_locktime(base,rel)*2 )
sp->expired = sp->lasttime;
else
{
if ( (alice= LP_coinfind(rel)) != 0 && (alice->isassetchain != 0 || strcmp("KMD",alice->symbol) == 0) )
sp->aliceneeds_dPoW = 1;
if ( (bob= LP_coinfind(rel)) != 0 && (bob->isassetchain != 0 || strcmp(bob->symbol,"KMD") == 0) )
sp->bobneeds_dPoW = 1;
}
strcpy(sp->bobgui,"nogui");
strcpy(sp->alicegui,"nogui");
if ( LP_swap_finished(sp,1) == 0 ) //sp->finished == 0 && sp->expired == 0 )
{
if ( (pubp= LP_pubkeyadd(qp->srchash)) != 0 )
{
ptr = calloc(1,sizeof(*ptr));
ptr->swap = sp;
DL_APPEND(pubp->bobswaps,ptr);
}
if ( (pubp= LP_pubkeyadd(qp->desthash)) != 0 )
{
ptr = calloc(1,sizeof(*ptr));
ptr->swap = sp;
DL_APPEND(pubp->aliceswaps,ptr);
}
}
} else printf("unexpected LP_swapstats_add failure\n");
return(sp);
}
int32_t LP_statslog_parsequote(char *method,cJSON *lineobj)
{
static uint32_t unexpected;
struct LP_swapstats *sp,*tmp; double qprice; uint32_t requestid,quoteid,timestamp; int32_t i,flag,numtrades[LP_MAXPRICEINFOS],methodind,destvout,feevout,duplicate=0; char *gui,*base,*rel; uint64_t aliceid,txfee,satoshis,destsatoshis; bits256 desttxid,feetxid; struct LP_quoteinfo Q; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS];
struct LP_swapstats *sp,*tmp; double qprice; uint32_t requestid,quoteid,timestamp; int32_t i,RTflag,flag,numtrades[LP_MAXPRICEINFOS],methodind,destvout,feevout,duplicate=0; char *statusstr,*gui,*base,*rel; uint64_t aliceid,txfee,satoshis,destsatoshis; bits256 desttxid,feetxid; struct LP_quoteinfo Q; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS];
memset(numtrades,0,sizeof(numtrades));
memset(basevols,0,sizeof(basevols));
memset(relvols,0,sizeof(relvols));
@ -242,25 +445,36 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj)
if ( (sp= LP_swapstats_find(aliceid)) != 0 )
{
sp->methodind = methodind;
sp->Q.R.requestid = requestid;
sp->Q.R.quoteid = quoteid;
if ( LP_swapstats_update(sp,&Q,lineobj) == 0 )
flag = 1;
//else printf("LP_swapstats_update error\n");
}
if ( flag == 0 )
{
HASH_ITER(hh,LP_swapstats,sp,tmp)
{
static uint32_t counter;
if ( sp->Q.R.requestid == requestid && sp->Q.R.quoteid == quoteid )
{
sp->methodind = methodind;
if ( LP_swapstats_update(sp,&Q,lineobj) == 0 )
{
flag = 1;
else printf("error after delayed match\n");
break;
break;
}
if ( counter++ < 10 )
printf("error after delayed match\n");
}
}
}
if ( flag == 0 )
printf("unexpected.%d tradestatus.(%s)\n",unexpected++,jprint(lineobj,0));
{
static uint32_t counter;
if ( counter++ < 3 )
printf("unexpected.%d tradestatus aliceid.%llu requestid.%u quoteid.%u\n",unexpected++,(long long)aliceid,requestid,quoteid);//,jprint(lineobj,0));
}
return(0);
}
if ( LP_quoteparse(&Q,lineobj) < 0 )
@ -290,6 +504,9 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj)
destvout = jint(lineobj,"destvout");
feetxid = jbits256(lineobj,"feetxid");
feevout = jint(lineobj,"feevout");
if ( (statusstr= jstr(lineobj,"status")) != 0 && strcmp(statusstr,"finished") == 0 )
RTflag = 0;
else RTflag = 1;
qprice = ((double)destsatoshis / (satoshis - txfee));
//printf("%s/v%d %s/v%d\n",bits256_str(str,desttxid),destvout,bits256_str(str2,feetxid),feevout);
aliceid = LP_aliceid_calc(desttxid,destvout,feetxid,feevout);
@ -305,17 +522,8 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj)
}
else
{
if ( (sp= LP_swapstats_add(aliceid)) != 0 )
{
sp->Q = Q;
sp->qprice = qprice;
sp->methodind = methodind;
sp->ind = LP_aliceids++;
strcpy(sp->bobgui,"nogui");
strcpy(sp->alicegui,"nogui");
//LP_swapstats_line(numtrades,basevols,relvols,line,sp);
//printf("%s\n",line);
} else printf("unexpected LP_swapstats_add failure\n");
sp = LP_swapstats_create(aliceid,RTflag,&Q,qprice,methodind);
//printf("create aliceid.%llu\n",(long long)aliceid);
}
if ( sp != 0 )
{
@ -330,11 +538,194 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj)
return(duplicate == 0);
}
char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey)
cJSON *LP_swapstats_json(struct LP_swapstats *sp)
{
cJSON *item = cJSON_CreateObject();
jaddnum(item,"timestamp",sp->Q.timestamp);
jadd64bits(item,"aliceid",sp->aliceid);
jaddbits256(item,"src",sp->Q.srchash);
jaddstr(item,"base",sp->Q.srccoin);
jaddnum(item,"basevol",dstr(sp->Q.satoshis));
jaddbits256(item,"dest",sp->Q.desthash);
jaddstr(item,"rel",sp->Q.destcoin);
jaddnum(item,"relvol",dstr(sp->Q.destsatoshis));
jaddnum(item,"price",sp->qprice);
jaddnum(item,"requestid",sp->Q.R.requestid);
jaddnum(item,"quoteid",sp->Q.R.quoteid);
jaddnum(item,"finished",sp->finished);
jaddnum(item,"expired",sp->expired);
if ( bits256_nonz(sp->bobdeposit) != 0 )
jaddbits256(item,"bobdeposit",sp->bobdeposit);
if ( bits256_nonz(sp->alicepayment) != 0 )
jaddbits256(item,"alicepayment",sp->alicepayment);
if ( bits256_nonz(sp->bobpayment) != 0 )
jaddbits256(item,"bobpayment",sp->bobpayment);
if ( bits256_nonz(sp->paymentspent) != 0 )
jaddbits256(item,"paymentspent",sp->paymentspent);
if ( bits256_nonz(sp->Apaymentspent) != 0 )
jaddbits256(item,"Apaymentspent",sp->Apaymentspent);
if ( bits256_nonz(sp->depositspent) != 0 )
jaddbits256(item,"depositspent",sp->depositspent);
if ( sp->finished == 0 && sp->expired == 0 )
jaddnum(item,"expires",sp->Q.timestamp + LP_atomic_locktime(sp->Q.srccoin,sp->Q.destcoin)*2 - time(NULL));
jaddnum(item,"ind",sp->methodind);
//jaddstr(item,"line",line);
return(item);
}
char *LP_swapstatus_recv(cJSON *argjson)
{
cJSON *retjson,*array,*item; struct LP_swapstats *sp,*tmp; int32_t i,dispflag,numtrades[LP_MAXPRICEINFOS]; char line[1024]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS];
struct LP_swapstats *sp; char *statusstr; uint64_t aliceid; double qprice; struct LP_quoteinfo Q; int32_t methodind,RTflag; bits256 txid; //char str[65];
if ( (aliceid= j64bits(argjson,"aliceid")) == 0 )
return(clonestr("{\"error\":\"LP_swapstatus_recv null aliceid\"}"));
if ( (sp= LP_swapstats_find(aliceid)) == 0 )
{
LP_quoteparse(&Q,argjson);
if ( Q.satoshis > Q.txfee )
return(clonestr("{\"error\":\"LP_swapstatus_recv null satoshis\"}"));
qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee);
if ( (statusstr= jstr(argjson,"status")) != 0 && strcmp(statusstr,"finished") == 0 )
RTflag = 0;
else RTflag = 1;
sp = LP_swapstats_create(aliceid,RTflag,&Q,qprice,LP_TRADESTATUS_METHODIND);
//printf("create swapstatus from recv\n");
}
if ( sp != 0 )
{
if ( 0 && IAMLP == 0 )
printf("swapstatus.(%s)\n",jprint(argjson,0));
sp->lasttime = (uint32_t)time(NULL);
if ( (methodind= jint(argjson,"ind")) > sp->methodind && methodind < sizeof(LP_stats_methods)/sizeof(*LP_stats_methods) )
{
if ( 0 && sp->finished == 0 && sp->expired == 0 )
printf("SWAPSTATUS updated %llu %s %u %u\n",(long long)sp->aliceid,LP_stats_methods[sp->methodind],juint(argjson,"finished"),juint(argjson,"expired"));
sp->methodind = methodind;
sp->finished = juint(argjson,"finished");
sp->expired = juint(argjson,"expired");
txid = jbits256(argjson,"bobdeposit");
if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->bobdeposit) == 0 )
{
sp->bobdeposit = txid;
//printf("set aliceid.%llu bobdeposit %s\n",(long long)sp->aliceid,bits256_str(str,txid));
}
txid = jbits256(argjson,"alicepayment");
if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->alicepayment) == 0 )
{
sp->alicepayment = txid;
//printf("set aliceid.%llu alicepayment %s\n",(long long)sp->aliceid,bits256_str(str,txid));
}
txid = jbits256(argjson,"bobpayment");
if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->bobpayment) == 0 )
{
sp->bobpayment = txid;
//printf("set aliceid.%llu bobpayment %s\n",(long long)sp->aliceid,bits256_str(str,txid));
}
txid = jbits256(argjson,"paymentspent");
if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->paymentspent) == 0 )
{
sp->paymentspent = txid;
//printf("set aliceid.%llu paymentspent %s\n",(long long)sp->aliceid,bits256_str(str,txid));
}
txid = jbits256(argjson,"Apaymentspent");
if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->Apaymentspent) == 0 )
{
sp->Apaymentspent = txid;
//printf("set aliceid.%llu Apaymentspent %s\n",(long long)sp->aliceid,bits256_str(str,txid));
}
txid = jbits256(argjson,"depositspent");
if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->depositspent) == 0 )
{
sp->depositspent = txid;
//printf("set aliceid.%llu depositspent %s\n",(long long)sp->aliceid,bits256_str(str,txid));
}
}
}
return(clonestr("{\"result\":\"success\"}"));
}
char *LP_gettradestatus(uint64_t aliceid,uint32_t requestid,uint32_t quoteid)
{
struct LP_swapstats *sp; struct iguana_info *bob,*alice; char *swapstr,*statusstr; cJSON *reqjson,*swapjson; bits256 zero;
//printf("gettradestatus.(%llu)\n",(long long)aliceid);
if ( IAMLP != 0 )
{
if ( (sp= LP_swapstats_find(aliceid)) != 0 && sp->Q.satoshis != 0 && sp->Q.destsatoshis != 0 && bits256_nonz(sp->bobdeposit) != 0 )
{
if ( time(NULL) > sp->lasttime+60 )
{
if ( (reqjson= LP_swapstats_json(sp)) != 0 )
{
jaddstr(reqjson,"method","swapstatus");
memset(zero.bytes,0,sizeof(zero));
LP_reserved_msg(0,"","",zero,jprint(reqjson,1));
}
if ( (bob= LP_coinfind(sp->Q.srccoin)) != 0 )
LP_dPoW_broadcast(bob);
if ( (alice= LP_coinfind(sp->Q.destcoin)) != 0 )
LP_dPoW_broadcast(alice);
}
return(clonestr("{\"result\":\"success\"}"));
}
}
if ( (swapstr= basilisk_swapentry(requestid,quoteid,0)) != 0 )
{
if ( (swapjson= cJSON_Parse(swapstr)) != 0 )
{
if ( (statusstr= jstr(swapjson,"status")) != 0 && strcmp(statusstr,"finished") == 0 )
{
jaddstr(swapjson,"method","swapstatus");
memset(zero.bytes,0,sizeof(zero));
printf("send local swapstatus\n");
LP_reserved_msg(0,"","",zero,jprint(swapjson,0));
}
free_json(swapjson);
}
free(swapstr);
}
return(clonestr("{\"result\":\"success\"}"));
}
int32_t LP_stats_dispiter(cJSON *array,struct LP_swapstats *sp,uint32_t starttime,uint32_t endtime,char *refbase,char *refrel,char *refgui,bits256 refpubkey)
{
int32_t dispflag,retval = 0;
if ( sp->finished == 0 && sp->expired == 0 && time(NULL) > sp->Q.timestamp+LP_atomic_locktime(sp->Q.srccoin,sp->Q.destcoin)*2 )
sp->expired = (uint32_t)time(NULL);
if ( LP_swap_finished(sp,1) > 0 )
retval = 1;
dispflag = 0;
if ( starttime == 0 && endtime == 0 )
dispflag = 1;
else if ( starttime > time(NULL) && endtime == starttime && sp->finished == 0 && sp->expired == 0 )
dispflag = 1;
else if ( sp->Q.timestamp >= starttime && sp->Q.timestamp <= endtime )
dispflag = 1;
if ( refbase != 0 && refbase[0] != 0 && strcmp(refbase,sp->Q.srccoin) != 0 && strcmp(refbase,sp->Q.destcoin) != 0 )
dispflag = 0;
if ( refrel != 0 && refrel[0] != 0 && strcmp(refrel,sp->Q.srccoin) != 0 && strcmp(refrel,sp->Q.destcoin) != 0 )
dispflag = 0;
if ( dispflag != 0 )
{
dispflag = 0;
if ( refgui == 0 || refgui[0] == 0 || strcmp(refgui,sp->bobgui) == 0 || strcmp(refgui,sp->alicegui) == 0 )
{
if ( bits256_nonz(refpubkey) == 0 || bits256_cmp(refpubkey,sp->Q.srchash) == 0 || bits256_cmp(refpubkey,sp->Q.desthash) == 0 )
dispflag = 1;
}
}
if ( dispflag != 0 )
jaddi(array,LP_swapstats_json(sp));
return(retval);
}
cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel)
{
static int32_t rval;
cJSON *retjson,*array,*item,*reqjson; struct LP_pubkey_info *pubp,*ptmp; bits256 zero; uint32_t now; struct LP_swapstats *sp,*tmp; int32_t i,n,numtrades[LP_MAXPRICEINFOS]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS];
if ( rval == 0 )
rval = (LP_rand() % 300) + 60;
if ( starttime > endtime )
starttime = endtime;
n = LP_statslog_parse();
memset(basevols,0,sizeof(basevols));
memset(relvols,0,sizeof(relvols));
memset(numtrades,0,sizeof(numtrades));
@ -342,45 +733,41 @@ char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgu
jaddstr(retjson,"result","success");
jaddnum(retjson,"newlines",n);
array = cJSON_CreateArray();
HASH_ITER(hh,LP_swapstats,sp,tmp)
LP_RTcount = LP_swapscount = 0;
now = (uint32_t)time(NULL);
HASH_ITER(hh,LP_RTstats,sp,tmp)
{
if ( sp->finished == 0 && time(NULL) > sp->Q.timestamp+LP_atomic_locktime(sp->Q.srccoin,sp->Q.destcoin)*2 )
sp->expired = (uint32_t)time(NULL);
dispflag = 0;
if ( starttime == 0 && endtime == 0 )
dispflag = 1;
else if ( starttime > time(NULL) && endtime == starttime && sp->finished == 0 && sp->expired == 0 )
dispflag = 1;
else if ( sp->Q.timestamp >= starttime && sp->Q.timestamp <= endtime )
dispflag = 1;
if ( dispflag != 0 )
{
dispflag = 0;
if ( refgui == 0 || refgui[0] == 0 || strcmp(refgui,sp->bobgui) == 0 || strcmp(refgui,sp->alicegui) == 0 )
{
if ( bits256_nonz(refpubkey) == 0 || bits256_cmp(refpubkey,sp->Q.srchash) == 0 || bits256_cmp(refpubkey,sp->Q.desthash) == 0 )
dispflag = 1;
}
if ( LP_stats_dispiter(array,sp,starttime,endtime,refbase,refrel,refgui,refpubkey) > 0 )
{
HASH_DELETE(hh,LP_RTstats,sp);
HASH_ADD(hh,LP_swapstats,aliceid,sizeof(sp->aliceid),sp);
}
if ( dispflag != 0 )
else
{
LP_swapstats_line(numtrades,basevols,relvols,line,sp);
item = cJSON_CreateObject();
jadd64bits(item,"aliceid",sp->aliceid);
jaddbits256(item,"src",sp->Q.srchash);
jaddstr(item,"base",sp->Q.srccoin);
jaddnum(item,"basevol",dstr(sp->Q.satoshis));
jaddbits256(item,"dest",sp->Q.desthash);
jaddstr(item,"rel",sp->Q.destcoin);
jaddnum(item,"relvol",dstr(sp->Q.destsatoshis));
jaddnum(item,"price",sp->qprice);
jaddnum(item,"requestid",sp->Q.R.requestid);
jaddnum(item,"quoteid",sp->Q.R.quoteid);
jaddstr(item,"line",line);
jaddi(array,item);
LP_RTcount++;
if ( now > sp->lasttime+rval )
{
reqjson = cJSON_CreateObject();
jaddstr(reqjson,"method","gettradestatus");
jadd64bits(reqjson,"aliceid",sp->aliceid);
memset(zero.bytes,0,sizeof(zero));
LP_reserved_msg(0,"","",zero,jprint(reqjson,1));
}
}
}
HASH_ITER(hh,LP_swapstats,sp,tmp)
{
LP_stats_dispiter(array,sp,starttime,endtime,refbase,refrel,refgui,refpubkey);
LP_swapscount++;
}
HASH_ITER(hh,LP_pubkeyinfos,pubp,ptmp)
{
pubp->dynamictrust = LP_dynamictrust(0,pubp->pubkey,0);
}
//printf("RT.%d completed.%d\n",LP_RTcount,LP_swapscount);
jadd(retjson,"swaps",array);
jaddnum(retjson,"RTcount",LP_RTcount);
jaddnum(retjson,"swapscount",LP_swapscount);
array = cJSON_CreateArray();
for (i=0; i<LP_MAXPRICEINFOS; i++)
{
@ -405,7 +792,146 @@ char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgu
jaddnum(retjson,"uniques",LP_aliceids);
jaddnum(retjson,"tradestatus",LP_tradestatuses);
jaddnum(retjson,"unknown",LP_unknowns);
return(jprint(retjson,1));
return(retjson);
}
char *LP_ticker(char *refbase,char *refrel)
{
cJSON *logjson,*retjson,*item,*retitem,*swapsjson; double basevol,relvol; char *base,*rel; int32_t i,n; bits256 zero; uint32_t now = (uint32_t)time(NULL);
memset(zero.bytes,0,sizeof(zero));
if ( (logjson= LP_statslog_disp(now - 3600*24,now,"",zero,refbase,refrel)) != 0 )
{
retjson = cJSON_CreateArray();
if ( (swapsjson= jarray(&n,logjson,"swaps")) != 0 )
{
for (i=n-1; i>=0; i--)
{
item = jitem(swapsjson,i);
retitem = cJSON_CreateObject();
if ( (base= jstr(item,"base")) != 0 && (rel= jstr(item,"rel")) != 0 && (basevol= jdouble(item,"basevol")) > SMALLVAL )
{
relvol = jdouble(item,"relvol");
jaddnum(retitem,"timestamp",juint(item,"timestamp"));
jaddnum(retitem,base,basevol);
jaddnum(retitem,rel,relvol);
jaddnum(retitem,"price",relvol/basevol);
}
jaddi(retjson,retitem);
}
}
free_json(logjson);
return(jprint(retjson,1));
} else return(clonestr("{\"error\":\"couldnt get logjson\"}"));
}
struct LP_ohlc
{
uint32_t timestamp,firsttime,lasttime,numtrades;
double high,low,open,close,relsum,basesum;
};
cJSON *LP_ohlc_json(struct LP_ohlc *bar,struct LP_ohlc *prevbar)
{
cJSON *item; struct LP_ohlc tmp;
memset(&tmp,0,sizeof(tmp));
if ( bar->numtrades == 0 )
{
memset(&tmp,0,sizeof(tmp));
tmp.timestamp = bar->timestamp;
tmp.open = tmp.high = tmp.low = tmp.close = prevbar->close;
tmp.numtrades = 0;
tmp.relsum = tmp.basesum = 0.;
} else tmp = *bar;
bar = &tmp;
item = cJSON_CreateArray();
jaddinum(item,bar->timestamp);
jaddinum(item,bar->high);
jaddinum(item,bar->low);
jaddinum(item,bar->open);
jaddinum(item,bar->close);
jaddinum(item,bar->relsum);
jaddinum(item,bar->basesum);
if ( bar->basesum != 0 )
jaddinum(item,bar->relsum / bar->basesum);
else jaddinum(item,0);
jaddinum(item,bar->numtrades);
return(item);
}
void LP_ohlc_update(struct LP_ohlc *bar,uint32_t timestamp,double basevol,double relvol)
{
double price;
if ( basevol > SMALLVAL && relvol > SMALLVAL )
{
price = relvol / basevol;
if ( bar->firsttime == 0 || timestamp < bar->firsttime )
{
bar->firsttime = timestamp;
bar->open = price;
}
if ( bar->lasttime == 0 || timestamp > bar->lasttime )
{
bar->lasttime = timestamp;
bar->close = price;
}
if ( bar->low == 0. || price < bar->low )
bar->low = price;
if ( bar->high == 0. || price > bar->high )
bar->high = price;
bar->basesum += basevol;
bar->relsum += relvol;
bar->numtrades++;
//printf("%d %.8f/%.8f -> %.8f\n",bar->numtrades,basevol,relvol,price);
}
}
cJSON *LP_tradesarray(char *refbase,char *refrel,uint32_t starttime,uint32_t endtime,int32_t timescale)
{
struct LP_ohlc *bars,nonz; cJSON *array,*item,*statsjson,*swaps; uint32_t timestamp; bits256 zero; char *base,*rel; int32_t i,n,numbars,bari;
if ( timescale < 60 )
return(cJSON_Parse("{\"error\":\"one minute is shortest timescale\"}"));
memset(zero.bytes,0,sizeof(zero));
if ( endtime == 0 )
endtime = (((uint32_t)time(NULL) / timescale) * timescale);
if ( starttime == 0 || starttime >= endtime )
starttime = (endtime - LP_SCREENWIDTH*timescale);
numbars = ((endtime - starttime) / timescale) + 1;
bars = calloc(numbars,sizeof(*bars));
for (bari=0; bari<numbars; bari++)
bars[bari].timestamp = starttime + bari*timescale;
if ( (statsjson= LP_statslog_disp(starttime,endtime,"",zero,refbase,refrel)) != 0 )
{
if ( (swaps= jarray(&n,statsjson,"swaps")) != 0 )
{
for (i=0; i<n; i++)
{
item = jitem(swaps,i);
if ( (timestamp= juint(item,"timestamp")) != 0 && timestamp >= starttime && timestamp <= endtime )
{
bari = (timestamp - starttime) / timescale;
base = jstr(item,"base");
rel = jstr(item,"rel");
if ( strcmp(base,refbase) == 0 && strcmp(rel,refrel) == 0 )
LP_ohlc_update(&bars[bari],timestamp,jdouble(item,"basevol"),jdouble(item,"relvol"));
else if ( strcmp(rel,refbase) == 0 && strcmp(base,refrel) == 0 )
LP_ohlc_update(&bars[bari],timestamp,jdouble(item,"relvol"),jdouble(item,"basevol"));
} else printf("skip.(%s)\n",jprint(item,0));
}
}
free_json(statsjson);
}
array = cJSON_CreateArray();
memset(&nonz,0,sizeof(nonz));
for (bari=0; bari<numbars; bari++)
{
if ( (item= LP_ohlc_json(&bars[bari],&nonz)) != 0 )
{
jaddi(array,item);
if ( bars[bari].numtrades > 0 )
nonz = bars[bari];
}
}
free(bars);
return(array);
}

159
iguana/exchanges/LP_swap.c

@ -109,6 +109,13 @@
*/
uint32_t LP_atomic_locktime(char *base,char *rel)
{
if ( strcmp(base,"BTC") != 0 && strcmp(rel,"BTC") != 0 )
return(INSTANTDEX_LOCKTIME);
else return(INSTANTDEX_LOCKTIME * 10);
}
void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx)
{
if ( rawtx->vins != 0 )
@ -119,24 +126,27 @@ void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx)
void basilisk_swap_finished(struct basilisk_swap *swap)
{
int32_t i;
/*if ( swap->utxo != 0 && swap->sentflag == 0 )
/*int32_t i;
if ( swap->utxo != 0 && swap->sentflag == 0 )
{
LP_availableset(swap->utxo);
swap->utxo = 0;
//LP_butxo_swapfields_set(swap->utxo);
}*/
if ( swap->I.iambob != 0 )
{
LP_availableset(swap->bobdeposit.utxotxid,swap->bobdeposit.utxovout);
LP_availableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout);
}
else
swap->I.finished = (uint32_t)time(NULL);*/
if ( swap->I.finished == 0 )
{
LP_availableset(swap->alicepayment.utxotxid,swap->alicepayment.utxovout);
LP_availableset(swap->myfee.utxotxid,swap->myfee.utxovout);
if ( swap->I.iambob != 0 )
{
LP_availableset(swap->bobdeposit.utxotxid,swap->bobdeposit.utxovout);
LP_availableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout);
}
else
{
LP_availableset(swap->alicepayment.utxotxid,swap->alicepayment.utxovout);
LP_availableset(swap->myfee.utxotxid,swap->myfee.utxovout);
}
}
swap->I.finished = (uint32_t)time(NULL);
// save to permanent storage
basilisk_rawtx_purge(&swap->bobdeposit);
basilisk_rawtx_purge(&swap->bobpayment);
@ -149,11 +159,11 @@ void basilisk_swap_finished(struct basilisk_swap *swap)
basilisk_rawtx_purge(&swap->bobspend);
basilisk_rawtx_purge(&swap->bobrefund);
basilisk_rawtx_purge(&swap->alicereclaim);
for (i=0; i<swap->nummessages; i++)
/*for (i=0; i<swap->nummessages; i++)
if ( swap->messages[i].data != 0 )
free(swap->messages[i].data), swap->messages[i].data = 0;
free(swap->messages), swap->messages = 0;
swap->nummessages = 0;
swap->nummessages = 0;*/
if ( swap->N.pair >= 0 )
nn_close(swap->N.pair), swap->N.pair = -1;
}
@ -240,7 +250,7 @@ int32_t LP_pubkeys_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datal
if ( swap->I.otheristrusted != 0 )
{
swap->I.aliceconfirms = swap->I.bobconfirms = 0;
printf("Otherside trusts us, adjust required confirms to: alice.%d bob.%d\n",swap->I.aliceconfirms,swap->I.bobconfirms);
printf("mutually trusted swap, adjust required confirms to: alice.%d bob.%d\n",swap->I.aliceconfirms,swap->I.bobconfirms);
}
}
printf("NUMCONFIRMS for SWAP alice.%d bob.%d, otheristrusted.%d othertrusts.%d\n",swap->I.aliceconfirms,swap->I.bobconfirms,swap->I.otheristrusted,swap->I.otherstrust);
@ -634,7 +644,7 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba
char str[65]; printf("rawtx.%s txid %s\n",rawtx->name,bits256_str(str,txid));
if ( bits256_cmp(txid,rawtx->I.actualtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 )
rawtx->I.actualtxid = txid;
if ( (txobj= bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,height,&rawtx->I.signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),data,datalen,0,suppress_pubkeys,coin->zcash)) != 0 )
if ( (txobj= bitcoin_data2json(coin->symbol,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,height,&rawtx->I.signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),data,datalen,0,suppress_pubkeys,coin->zcash)) != 0 )
{
rawtx->I.actualtxid = rawtx->I.signedtxid;
rawtx->I.locktime = rawtx->msgtx.lock_time;
@ -732,22 +742,25 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3
return(0);
}
int32_t LP_swapwait(uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t sleeptime)
int32_t LP_swapwait(struct basilisk_swap *swap,uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t sleeptime)
{
char *retstr; cJSON *retjson=0; uint32_t expiration = (uint32_t)(time(NULL) + duration);
printf("wait %d:%d for SWAP.(r%u/q%u) to complete\n",duration,sleeptime,requestid,quoteid);
sleep(10);
sleep(sleeptime/3);
//if ( sleeptime < divisor*60 )
// sleeptime = divisor * 60;
while ( time(NULL) < expiration )
{
if ( (retstr= basilisk_swapentry(requestid,quoteid)) != 0 )
if ( (retstr= basilisk_swapentry(requestid,quoteid,1)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( jstr(retjson,"status") != 0 && strcmp(jstr(retjson,"status"),"finished") == 0 )
{
swap->I.finished = (uint32_t)time(NULL);
break;
else printf("NOT FINISHED.(%s)\n",jprint(retjson,0));
}
//else printf("NOT FINISHED.(%s)\n",jprint(retjson,0));
free_json(retjson);
retjson = 0;
}
@ -762,7 +775,7 @@ int32_t LP_swapwait(uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t
{
printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>\nSWAP completed! %u-%u %s\n",requestid,quoteid,jprint(retjson,0));
free_json(retjson);
if ( (retstr= basilisk_swapentry(requestid,quoteid)) != 0 )
if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid,1)) != 0 )
{
printf("second call.(%s)\n",retstr);
free(retstr);
@ -781,7 +794,7 @@ void LP_bobloop(void *_swap)
expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT;
if ( swap != 0 )
{
if ( LP_waitsend("pubkeys",60,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 )
if ( LP_waitsend("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 )
printf("error waitsend pubkeys\n");
else if ( LP_waitsend("choosei",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 )
printf("error waitsend choosei\n");
@ -810,9 +823,9 @@ void LP_bobloop(void *_swap)
printf("error bobscripts payment\n");
else
{
if ( strcmp(swap->I.alicestr,"BTC") == 0 )
/*if ( strcmp(swap->I.alicestr,"BTC") == 0 )
m = 0;
else m = swap->I.aliceconfirms;
else*/ m = swap->I.aliceconfirms;
while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) // sync with alice
{
LP_swap_critical = (uint32_t)time(NULL);
@ -824,21 +837,22 @@ void LP_bobloop(void *_swap)
printf("error sending bobpayment\n");
//if ( LP_waitfor(swap->N.pair,swap,10,LP_verify_alicespend) < 0 )
// printf("error waiting for alicespend\n");
swap->sentflag = 1;
//swap->sentflag = 1;
swap->bobreclaim.utxovout = 0;
swap->bobreclaim.utxotxid = swap->bobpayment.I.signedtxid;
basilisk_bobpayment_reclaim(swap,swap->I.callduration);
if ( swap->N.pair >= 0 )
nn_close(swap->N.pair), swap->N.pair = -1;
LP_swap_endcritical = (uint32_t)time(NULL);
LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,30);
LP_swapwait(swap,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30);
}
}
}
basilisk_swap_finished(swap);
free(swap);
} else printf("swap timed out\n");
G.LP_pendingswaps--;
basilisk_swap_finished(swap);
free(swap);
free(data);
}
void LP_aliceloop(void *_swap)
@ -851,7 +865,7 @@ void LP_aliceloop(void *_swap)
if ( swap != 0 )
{
printf("start swap iamalice pair.%d\n",swap->N.pair);
if ( LP_sendwait("pubkeys",60,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 )
if ( LP_sendwait("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 )
printf("error LP_sendwait pubkeys\n");
else if ( LP_sendwait("choosei",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 )
printf("error LP_sendwait choosei\n");
@ -867,53 +881,60 @@ void LP_aliceloop(void *_swap)
printf("error sending alicefee\n");
else if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobdeposit) < 0 )
printf("error waiting for bobdeposit\n");
else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0) == 0 )
printf("error sending alicepayment\n");
else
{
if ( strcmp(swap->I.alicestr,"BTC") == 0 )
/*if ( strcmp(swap->I.bobstr,"BTC") == 0 )
m = 0;
else m = swap->I.aliceconfirms;
while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m )
else*/ m = swap->I.bobconfirms;
while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,1)) < m )
{
LP_swap_critical = (uint32_t)time(NULL);
char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid));
char str[65];printf("%d wait for bobdeposit %s numconfs.%d %s %s\n",n,swap->bobdeposit.I.destaddr,m,swap->I.bobstr,bits256_str(str,swap->bobdeposit.I.signedtxid));
sleep(10);
}
swap->sentflag = 1;
LP_swap_critical = (uint32_t)time(NULL);
if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobpayment) < 0 )
printf("error waiting for bobpayment\n");
if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0) == 0 )
printf("error sending alicepayment\n");
else
{
LP_swap_endcritical = (uint32_t)time(NULL);
while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms )
/*if ( strcmp(swap->I.alicestr,"BTC") == 0 )
m = 0;
else*/ m = swap->I.aliceconfirms;
while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m )
{
char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->I.bobstr,bits256_str(str,swap->bobpayment.I.signedtxid));
LP_swap_critical = (uint32_t)time(NULL);
char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid));
sleep(10);
}
/*if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x20000,data,maxlen,&swap->alicespend,0x40000,0) == 0 )
printf("error sending alicespend\n");
while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicespend.I.destaddr,swap->alicespend.I.signedtxid,0,1)) < swap->I.aliceconfirms )
//swap->sentflag = 1;
LP_swap_critical = (uint32_t)time(NULL);
if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobpayment) < 0 )
printf("error waiting for bobpayment\n");
else
{
char str[65];printf("%d wait for alicespend %s numconfs.%d %s %s\n",n,swap->alicespend.I.destaddr,swap->I.aliceconfirms,swap->I.bobstr,bits256_str(str,swap->alicespend.I.signedtxid));
sleep(LP_SWAPSTEP_TIMEOUT);
}*/
if ( swap->N.pair >= 0 )
nn_close(swap->N.pair), swap->N.pair = -1;
LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,30);
LP_swap_endcritical = (uint32_t)time(NULL);
while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms )
{
char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->I.bobstr,bits256_str(str,swap->bobpayment.I.signedtxid));
sleep(10);
}
/*if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x20000,data,maxlen,&swap->alicespend,0x40000,0) == 0 )
printf("error sending alicespend\n");
while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicespend.I.destaddr,swap->alicespend.I.signedtxid,0,1)) < swap->I.aliceconfirms )
{
char str[65];printf("%d wait for alicespend %s numconfs.%d %s %s\n",n,swap->alicespend.I.destaddr,swap->I.aliceconfirms,swap->I.bobstr,bits256_str(str,swap->alicespend.I.signedtxid));
sleep(LP_SWAPSTEP_TIMEOUT);
}*/
if ( swap->N.pair >= 0 )
nn_close(swap->N.pair), swap->N.pair = -1;
LP_swap_endcritical = (uint32_t)time(NULL);
LP_swapwait(swap,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30);
}
}
}
}
}
free(data);
if ( swap->N.pair >= 0 )
{
nn_close(swap->N.pair);
swap->N.pair = -1;
}
basilisk_swap_finished(swap);
printf("finish swap.%p\n",swap);
free(swap);
G.LP_pendingswaps--;
}
@ -1029,7 +1050,7 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx *
} else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->I.vouttype,rawtx->I.destaddr);
}
struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 pubkey25519,struct basilisk_swap *swap,int32_t optionduration,uint32_t statebits,struct LP_quoteinfo *qp)
struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 pubkey25519,struct basilisk_swap *swap,int32_t optionduration,uint32_t statebits,struct LP_quoteinfo *qp,int32_t dynamictrust)
{
//FILE *fp; char fname[512];
uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag=-2,x = -1; struct iguana_info *bobcoin,*alicecoin;
@ -1076,7 +1097,7 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
swap->I.bobinsurance = LP_MIN_TXFEE;
if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE )
swap->I.aliceinsurance = LP_MIN_TXFEE;
swap->I.started = (uint32_t)time(NULL);
swap->I.started = qp->timestamp;//(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));
if ( swap->I.choosei < 0 )
@ -1089,14 +1110,18 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
swap->I.iambob = 0;
swap->I.otherhash = swap->I.req.desthash;
swap->I.aliceistrusted = 1;
swap->I.otheristrusted = swap->I.bobistrusted = LP_pubkey_istrusted(swap->I.req.srchash);
if ( dynamictrust == 0 && LP_pubkey_istrusted(swap->I.req.srchash) != 0 )
dynamictrust = 1;
swap->I.otheristrusted = swap->I.bobistrusted = dynamictrust;
}
else
{
swap->I.iambob = 1;
swap->I.otherhash = swap->I.req.srchash;
swap->I.bobistrusted = 1;
swap->I.otheristrusted = swap->I.aliceistrusted = LP_pubkey_istrusted(swap->I.req.desthash);
if ( dynamictrust == 0 && LP_pubkey_istrusted(swap->I.req.desthash) != 0 )
dynamictrust = 1;
swap->I.otheristrusted = swap->I.aliceistrusted = dynamictrust;
}
if ( bits256_nonz(privkey) == 0 || (x= instantdex_pubkeyargs(swap,2 + INSTANTDEX_DECKSIZE,privkey,swap->I.orderhash,0x02+swap->I.iambob)) != 2 + INSTANTDEX_DECKSIZE )
{
@ -1105,12 +1130,12 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
}
if ( strcmp("BTC",swap->I.bobstr) == 0 )
{
swap->I.bobconfirms = (1 + sqrt(dstr(swap->I.bobsatoshis) * .1));
swap->I.bobconfirms = 1;//(1 + sqrt(dstr(swap->I.bobsatoshis) * .1));
swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS;
}
else if ( strcmp("BTC",swap->I.alicestr) == 0 )
{
swap->I.aliceconfirms = (1 + sqrt(dstr(swap->I.alicesatoshis) * .1));
swap->I.aliceconfirms = 1;//(1 + sqrt(dstr(swap->I.alicesatoshis) * .1));
swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS;
}
else
@ -1151,20 +1176,20 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
}
swap->myfee.I.locktime = swap->I.started + 1;
swap->otherfee.I.locktime = swap->I.started + 1;
basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + bobcoin->txfee,4,0,jumblrflag);
basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + 2*bobcoin->txfee,4,0,jumblrflag);
basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,bobpub33,jumblrflag);
swap->bobrefund.I.suppress_pubkeys = 1;
basilisk_rawtx_setparms("aliceclaim",swap->I.req.quoteid,&swap->aliceclaim,bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,alicepub33,jumblrflag);
swap->aliceclaim.I.suppress_pubkeys = 1;
swap->aliceclaim.I.locktime = swap->I.started + swap->I.putduration+swap->I.callduration + 1;
basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + bobcoin->txfee,3,0,jumblrflag);
basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + 2*bobcoin->txfee,3,0,jumblrflag);
basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag);
swap->alicespend.I.suppress_pubkeys = 1;
basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag);
swap->bobreclaim.I.suppress_pubkeys = 1;
swap->bobreclaim.I.locktime = swap->I.started + swap->I.putduration + 1;
basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + alicecoin->txfee,2,0,jumblrflag);
basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + 2*alicecoin->txfee,2,0,jumblrflag);
basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag);
swap->bobspend.I.suppress_pubkeys = 1;
basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag);
@ -1186,7 +1211,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 LP_quoteinfo *qp)
struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp,int32_t dynamictrust)
{
struct basilisk_swap *swap; bits256 pubkey25519; uint8_t pubkey33[33];
swap = calloc(1,sizeof(*swap));
@ -1205,7 +1230,7 @@ struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256
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,qp) == 0 )
if ( bitcoin_swapinit(privkey,pubkey33,pubkey25519,swap,optionduration,!iambob,qp,dynamictrust) == 0 )
{
printf("error doing swapinit\n");
free(swap);

32
iguana/exchanges/LP_tradebots.c

@ -40,10 +40,19 @@ struct LP_tradebot
struct LP_tradebot_trade *trades[LP_TRADEBOTS_MAXTRADES];
} *LP_tradebots;
void LP_tradebot_pauseall()
{
struct LP_tradebot *bot,*tmp;
DL_FOREACH_SAFE(LP_tradebots,bot,tmp)
{
bot->userpause = bot->pause = (uint32_t)time(NULL);
}
}
void LP_tradebot_updatestats(struct LP_tradebot *bot,struct LP_tradebot_trade *tp)
{
char *swapstr,*status; int32_t flag; cJSON *swapjson;
if ( (swapstr= basilisk_swapentry(tp->requestid,tp->quoteid)) != 0 )
if ( (swapstr= basilisk_swapentry(tp->requestid,tp->quoteid,1)) != 0 )
{
flag = 0;
if ( (swapjson= cJSON_Parse(swapstr)) != 0 )
@ -195,7 +204,7 @@ cJSON *LP_tradebot_json(struct LP_tradebot *bot)
jadd(json,"trades",array);
if ( bot->basesum > SMALLVAL && bot->relsum > SMALLVAL && bot->completed > 0 )
{
jaddnum(json,"completed",bot->completed);
jadd(json,"complete",bot->completed!=0?jtrue():jfalse());
jaddnum(json,"percentage",100. * (bot->relsum / bot->totalrelvolume));
if ( bot->dispdir > 0 )
{
@ -413,11 +422,12 @@ void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid)
void LP_tradebots_timeslice(void *ctx)
{
static uint32_t lastnumfinished = 0;
struct iguana_info *relcoin; struct LP_tradebot *bot,*tmp;
struct iguana_info *relcoin; bits256 zero; struct LP_tradebot *bot,*tmp;
DL_FOREACH_SAFE(LP_tradebots,bot,tmp)
{
memset(zero.bytes,0,sizeof(zero));
if ( (relcoin= LP_coinfind(bot->rel)) != 0 )
LP_listunspent_issue(bot->rel,relcoin->smartaddr,1);
LP_listunspent_issue(bot->rel,relcoin->smartaddr,1,zero,zero);
if ( bot->relsum >= 0.99*bot->totalrelvolume-SMALLVAL || bot->basesum >= 0.99*bot->totalbasevolume-SMALLVAL )
bot->dead = (uint32_t)time(NULL);
else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL )
@ -455,12 +465,12 @@ char *LP_tradebot_statuslist(void *ctx,int32_t pubsock,cJSON *argjson)
char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume)
{
struct LP_tradebot *bot; char *retstr; double shortfall; int32_t i,n; cJSON *array,*item,*retjson; uint64_t sum,txfee,txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin;
struct LP_tradebot *bot; char *retstr; double shortfall; cJSON *retjson; uint64_t sum,txfee,txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin;
basecoin = LP_coinfind(base);
relcoin = LP_coinfind(rel);
if ( basecoin == 0 || relcoin == 0 || basecoin->inactive != 0 || relcoin->inactive != 0 )
return(clonestr("{\"error\":\"one or more coins inactive\"}"));
if ( (array= LP_inventory(rel)) != 0 )
/*if ( (array= LP_inventory(rel)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 && is_cJSON_Array(array) != 0 )
{
@ -471,7 +481,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl
}
}
free_json(array);
}
}*/
if ( (retstr= LP_orderbook(base,rel,0)) != 0 )
free(retstr);
txfee = LP_txfeecalc(relcoin,0,0);
@ -481,8 +491,8 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl
else balance = LP_RTsmartbalance(relcoin);
sum = (SATOSHIDEN*relvolume+2*dstr(txfees)) + 3 * ((SATOSHIDEN*relvolume+2*dstr(txfees))/777);
printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f, utxobal %.8f sum %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees),dstr(balance),dstr(sum));
if ( (abalance < SATOSHIDEN*relvolume + txfees) || ((balance-abalance) < (uint64_t)(SATOSHIDEN*relvolume)/777 + txfees) )
//if ( dstr(abalance) < relvolume && balance > sum+2*txfee )
//if ( (abalance < SATOSHIDEN*relvolume + txfees) || ((balance-abalance) < (uint64_t)(SATOSHIDEN*relvolume)/777 + txfees) )
if ( balance < sum+2*txfee )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"error","not enough funds");
@ -493,7 +503,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl
jaddnum(retjson,"txfees",dstr(txfees));
shortfall = (relvolume + dstr(txfees)) - dstr(balance);
jaddnum(retjson,"shortfall",shortfall);
if ( balance > sum+2*txfee )
/*if ( balance > sum+2*txfee )
{
char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item;
outputjson = cJSON_CreateObject();
@ -518,7 +528,7 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl
free(withdrawstr);
}
free_json(outputjson);
}
}*/
return(jprint(retjson,1));
}
printf("disp.%d tradebot_buy(%s / %s) maxprice %.8f relvolume %.8f\n",dispdir,base,rel,maxprice,relvolume);

309
iguana/exchanges/LP_transaction.c

@ -63,7 +63,7 @@ bits256 LP_pubkey(bits256 privkey)
int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid)
{
cJSON *txobj; bits256 txid; int32_t flag = 0;
if ( (txobj= LP_gettx(symbol,expectedtxid)) != 0 )
if ( (txobj= LP_gettx(symbol,expectedtxid,0)) != 0 )
{
txid = jbits256(txobj,"txid");
if ( jobj(txobj,"error") == 0 && bits256_cmp(txid,expectedtxid) == 0 )
@ -397,29 +397,26 @@ int32_t iguana_vininfo_create(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uin
int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxlen,struct vin_info *V,uint32_t sighash,int32_t signtx,int32_t suppress_pubkeys,int32_t zcash)
{
bits256 sigtxid; uint8_t *sig,*script; struct vin_info *vp; char vpnstr[64]; int32_t scriptlen,complete=0,j,vini=0,flag=0,siglen,numvouts,numsigs;
bits256 sigtxid; int64_t spendamount; uint8_t *sig,*script; struct vin_info *vp; char vpnstr[64]; int32_t scriptlen,complete=0,j,vini=0,flag=0,siglen,numvouts,numsigs;
numvouts = msgtx->tx_out;
vpnstr[0] = 0;
*signedtx = 0;
memset(signedtxidp,0,sizeof(*signedtxidp));
//printf("bitcoin_verifyvins numvins.%d numvouts.%d signtx.%d privkey.%d M.%d N.%d\n",msgtx->tx_in,numvouts,signtx,bits256_nonz(V[0].signers[0].privkey),V[0].M,V[0].N);
for (vini=0; vini<msgtx->tx_in; vini++)
{
if ( V->p2shscript[0] != 0 && V->p2shlen != 0 )
{
script = V->p2shscript;
scriptlen = V->p2shlen;
//for (j=0; j<scriptlen; j++)
// printf("%02x",script[j]);
//printf(" V->p2shlen.%d\n",V->p2shlen);
}
else
{
script = msgtx->vins[vini].spendscript;
scriptlen = msgtx->vins[vini].spendlen;
}
if ( zcash == LP_IS_BITCOINCASH )
sighash |= SIGHASH_FORKID;
sigtxid = bitcoin_sigtxid(taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys,zcash);
spendamount = LP_outpoint_amount(symbol,msgtx->vins[vini].prev_hash,msgtx->vins[vini].prev_vout);
sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,spendamount,sighash,vpnstr,suppress_pubkeys,zcash);
if ( bits256_nonz(sigtxid) != 0 )
{
vp = &V[vini];
@ -439,7 +436,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype,
int32_t i; for (i=0; i<siglen; i++)
printf("%02x",sig[i]);
printf(" sig, ");
for (i=0; i<plen; i++)
for (i=0; i<33; i++)
printf("%02x",vp->signers[j].pubkey[i]);
// s2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1;
printf(" SIGNEDTX.[%02x] siglen.%d priv.%s\n",sig[siglen-1],siglen,bits256_str(str,vp->signers[j].privkey));*/
@ -447,6 +444,7 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype,
if ( sig == 0 || siglen == 0 )
{
memset(vp->signers[j].pubkey,0,sizeof(vp->signers[j].pubkey));
printf("no sig.%p or siglen.%d zero\n",sig,siglen);
continue;
}
if ( bitcoin_verify(ctx,sig,siglen-1,sigtxid,vp->signers[j].pubkey,bitcoin_pubkeylen(vp->signers[j].pubkey)) < 0 )
@ -465,17 +463,18 @@ int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype,
printf(" <- sig[%d]\n",j);
for (z=0; z<33; z++)
printf("%02x",vp->signers[j].pubkey[z]);
bitcoin_address(tmpaddr,60,vp->signers[j].pubkey,33);
bitcoin_address(tmpaddr,0,0,vp->signers[j].pubkey,33);
printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr);*/
}
}
if ( numsigs >= vp->M )
complete = 1;
}
} else if ( signtx != 0 )
printf("bitcoin_verifyvins cant without privkey\n");
}
iguana_msgtx_Vset(serialized,maxlen,msgtx,V);
cJSON *txobj = cJSON_CreateObject();
*signedtx = iguana_rawtxbytes(taddr,pubtype,p2shtype,isPoS,height,txobj,msgtx,suppress_pubkeys,zcash);
cJSON *txobj = 0;//cJSON_CreateObject();
*signedtx = iguana_rawtxbytes(symbol,taddr,pubtype,p2shtype,isPoS,height,txobj,msgtx,suppress_pubkeys,zcash);
//printf("SIGNEDTX.(%s)\n",jprint(txobj,1));
*signedtxidp = msgtx->txid;
return(complete);
@ -491,7 +490,7 @@ int64_t iguana_lockval(int32_t finalized,int64_t locktime)
int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson,int32_t zcash)
{
uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; bits256 privkeys[LP_MAXVINS],privkey,txid; cJSON *item; cJSON *txobj = 0;
uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; uint32_t sighash; bits256 privkeys[LP_MAXVINS],privkey,txid; cJSON *item; cJSON *txobj = 0;
maxsize = 1000000;
memset(privkey.bytes,0,sizeof(privkey));
if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize )
@ -503,7 +502,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_
extraspace = malloc(extralen);
memset(msgtx,0,sizeof(*msgtx));
decode_hex(serialized,len,rawtx);
if ( (txobj= bitcoin_hex2json(taddr,pubtype,p2shtype,isPoS,height,&txid,msgtx,rawtx,extraspace,extralen,serialized4,vins,V->suppress_pubkeys,zcash)) != 0 )
if ( (txobj= bitcoin_hex2json(symbol,taddr,pubtype,p2shtype,isPoS,height,&txid,msgtx,rawtx,extraspace,extralen,serialized4,vins,V->suppress_pubkeys,zcash)) != 0 )
{
//printf("back from bitcoin_hex2json (%s)\n",jprint(vins,0));
} else printf("no txobj from bitcoin_hex2json\n");
@ -512,7 +511,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_
{
//printf("numinputs.%d (%s) msgtx.%d\n",numinputs,jprint(vins,0),msgtx->tx_in);
memset(msgtx,0,sizeof(*msgtx));
if ( iguana_rwmsgtx(taddr,pubtype,p2shtype,isPoS,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,extralen,vins,V->suppress_pubkeys,zcash) > 0 && numinputs == msgtx->tx_in )
if ( iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,extralen,vins,V->suppress_pubkeys,zcash) > 0 && numinputs == msgtx->tx_in )
{
memset(pubkeys,0,sizeof(pubkeys));
memset(privkeys,0,sizeof(privkeys));
@ -540,7 +539,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_
coinaddr[0] = 0;
sigsize = 0;
flag = (msgtx->vins[i].vinscript[0] == 0);
type = bitcoin_scriptget(taddr,pubtype,p2shtype,&hashtype,&sigsize,&pubkeysize,&userdata,&userdatalen,&mainvin,msgtx->vins[i].vinscript+flag,msgtx->vins[i].scriptlen-flag,0);
type = bitcoin_scriptget(symbol,taddr,pubtype,p2shtype,&hashtype,&sigsize,&pubkeysize,&userdata,&userdatalen,&mainvin,msgtx->vins[i].vinscript+flag,msgtx->vins[i].scriptlen-flag,0,zcash);
//printf("i.%d flag.%d type.%d scriptlen.%d\n",i,flag,type,msgtx->vins[i].scriptlen);
if ( msgtx->vins[i].redeemscript != 0 )
{
@ -599,7 +598,8 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_
}
finalized = iguana_vininfo_create(taddr,pubtype,p2shtype,isPoS,serialized2,maxsize,msgtx,vins,numinputs,V);
//printf("finalized.%d ignore_cltverr.%d suppress.%d\n",finalized,V[0].ignore_cltverr,V[0].suppress_pubkeys);
if ( (complete= bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys,zcash)) > 0 && signedtx != 0 )
sighash = LP_sighash(symbol,zcash);
if ( (complete= bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,sighash,1,V->suppress_pubkeys,zcash)) > 0 && signedtx != 0 )
{
/*int32_t tmp; //char str[65];
if ( (tmp= iguana_interpreter(ctx,cJSON_CreateArray(),iguana_lockval(finalized,jint(txobj,"locktime")),V,numinputs)) < 0 )
@ -621,7 +621,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_
char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys,int32_t zcash)
{
bits256 signedtxid; struct iguana_msgvin vin; cJSON *log,*vins,*vouts,*txobj,*retjson; char *signedtx; int32_t plen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum; struct iguana_msgvout vout;
bits256 signedtxid; cJSON *item,*vins,*vouts,*txobj,*retjson,*sobj; char *scriptsig,*signedtx; uint32_t sighash; int32_t sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout;
char *symbol; uint8_t wiftaddr,taddr,pubtype,p2shtype,isPoS;
height = coin->longestchain;
symbol = coin->symbol;
@ -637,12 +637,11 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt
if ( (strlen(rawtx) & 1) != 0 )
return(clonestr("{\"error\":\"rawtx hex has odd length\"}"));
memset(msgtx,0,sizeof(*msgtx));
if ( (txobj= bitcoin_hex2json(taddr,pubtype,p2shtype,isPoS,height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys,zcash)) != 0 )
if ( (txobj= bitcoin_hex2json(symbol,taddr,pubtype,p2shtype,isPoS,height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys,zcash)) != 0 )
{
maxsize = (int32_t)strlen(rawtx);
serialized = malloc(maxsize);
serialized2 = malloc(maxsize);
V = calloc(numinputs,sizeof(*V));
if ( (vouts= jarray(&numoutputs,txobj,"vout")) > 0 )
{
for (i=0; i<numoutputs; i++)
@ -653,48 +652,78 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt
}
if ( (vins= jarray(&numinputs,txobj,"vin")) > 0 )
{
V = calloc(numinputs,sizeof(*V));
len = 0;
for (i=0; i<numinputs; i++)
{
len += iguana_parsevinobj(&serialized[len],maxsize-len,&vin,jitem(vins,i),&V[i]);
V[i].suppress_pubkeys = suppress_pubkeys;
inputsum += V[i].amount;
if ( V[i].M == 0 )
V[i].M = 1;
if ( V[i].N < V[i].M )
V[i].N = V[i].M;
item = jitem(vins,i);
if ( strcmp(jstr(item,"txid"),"b19ce2c564f7dc57b3f95593e2b287c72d388e86de12dc562d9f8a6bea65b310") == 0 && jint(item,"vout") == 1 )
{
V[i].spendlen = 25;
decode_hex(V[i].spendscript,V[i].spendlen,"76a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688ac");
msgtx->lock_time = 0;
V[i].amount = 2746715;
strcpy(V[i].coinaddr,"19Cq6MBaD8LY7trqs99ypqKAms3GcLs6J9");
V[i].suppress_pubkeys = 0;
decode_hex(msgtx->vins[i].prev_hash.bytes,32,"b19ce2c564f7dc57b3f95593e2b287c72d388e86de12dc562d9f8a6bea65b310");
msgtx->vins[i].prev_vout = 1;
msgtx->vins[i].sequence = 0xffffffff;
sobj = cJSON_CreateObject();
jaddstr(sobj,"hex","76a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688ac");
jadd(item,"scriptPubKey",sobj);
printf("match special txid B\n");
V[i].signers[0].privkey = G.LP_privkey;
}
msgtx->vins[i].spendscript = V[i].spendscript;
if ( (msgtx->vins[i].spendlen= V[i].spendlen) == 35 )
msgtx->vins[i].spendlen = V[i].spendlen;
if ( (sobj= jobj(item,"scriptSig")) != 0 )
{
if ( (plen= bitcoin_pubkeylen(msgtx->vins[i].spendscript+1)) > 0 )
if ( (scriptsig= jstr(sobj,"hex")) != 0 )
{
memcpy(V[i].signers[0].pubkey,msgtx->vins[i].spendscript+1,plen);
V[i].suppress_pubkeys = 1;
slen = (int32_t)strlen(scriptsig) >> 1;
if ( slen <= sizeof(scriptbuf) )
{
msgtx->vins[i].scriptlen = slen;
msgtx->vins[i].vinscript = scriptbuf;
decode_hex(scriptbuf,slen,scriptsig);
if ( (sigsize= scriptbuf[0]) >= 70 && sigsize < 76 )
{
memcpy(V[i].signers[0].sig,scriptbuf+1,sigsize-1);
V[i].signers[0].siglen = sigsize - 1;
V[i].hashtype = scriptbuf[1 + sigsize-1];
if ( scriptbuf[sigsize+1] == 33 )
{
memcpy(V[i].signers[0].pubkey,&scriptbuf[sigsize+2],33);
uint8_t rmd160[20]; char rmdstr[42];
calc_rmd160(rmdstr,rmd160,V[i].signers[0].pubkey,33);
printf("RMD160.%s\n",rmdstr);
}
} else printf("sigsize.%d unexpected\n",sigsize);
}
}
}
V[i].hashtype = iguana_vinscriptparse(taddr,pubtype,p2shtype,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen);
if ( (V[i].signers[0].siglen= sigsize) > 0 )
memcpy(V[i].signers[0].sig,msgtx->vins[i].vinscript+1,sigsize);
V[i].userdatalen = suffixlen;
memcpy(V[i].spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen);
V[i].spendlen = msgtx->vins[i].spendlen;
inputsum += V[i].amount;
if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL )
finalized = 0;
if ( V[i].M == 0 )
V[i].M = 1;
if ( V[i].N < V[i].M )
V[i].N = V[i].M;
printf("V %dof%d %.8f (%s) spendscript.[%d] scriptlen.%d\n",V[i].M,V[i].N,dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen);
}
complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys,LP_IS_BITCOINCASH);
sighash = LP_sighash(symbol,zcash);
complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,0,V[0].suppress_pubkeys,zcash);
msgtx->txid = signedtxid;
log = cJSON_CreateArray();
/*cJSON *log = cJSON_CreateArray();
if ( iguana_interpreter(ctx,log,0,V,numinputs) < 0 )
jaddstr(retjson,"error","interpreter rejects tx");
else complete = 1;
jadd(retjson,"interpreter",log);
jaddnum(retjson,"complete",complete);
free(serialized), free(serialized2);
jadd(retjson,"interpreter",log);*/
jadd(retjson,"complete",complete!=0?jtrue():jfalse());
if ( signedtx != 0 )
free(signedtx);
free(V);
}
free(serialized), free(serialized2);
}
//char str[65]; printf("got txid.(%s)\n",bits256_str(str,txid));
}
@ -706,9 +735,9 @@ char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgt
return(jprint(retjson,1));
}
void test_validate(char *signedtx)
void test_validate(struct iguana_info *coin,char *signedtx)
{
char *retstr; uint8_t extraspace[8192]; int32_t mempool=0; struct iguana_msgtx msgtx; struct iguana_info *coin = LP_coinfind("BTC");
char *retstr; uint8_t extraspace[8192]; int32_t mempool=0; struct iguana_msgtx msgtx;
retstr = iguana_validaterawtx(bitcoin_ctx(),coin,&msgtx,extraspace,sizeof(extraspace),signedtx,mempool,0,coin->zcash);
printf("validate test.(%s)\n",retstr);
}
@ -730,7 +759,7 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch
if ( (coin= LP_coinfind(symbol)) != 0 )
{
#ifndef BASILISK_DISABLESENDTX
if ( (txobj= LP_gettx(symbol,utxotxid)) != 0 )
if ( (txobj= LP_gettx(symbol,utxotxid,0)) != 0 )
{
if ( (vouts= jarray(&n,txobj,"vout")) != 0 && utxovout < n )
{
@ -806,7 +835,7 @@ char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,ch
V[0].ignore_cltverr = ignore_cltverr;
if ( redeemlen != 0 )
memcpy(V[0].p2shscript,redeemscript,redeemlen), V[0].p2shlen = redeemlen;
txobj = bitcoin_txcreate(symbol,isPoS,locktime,1,timestamp);
txobj = bitcoin_txcreate(symbol,isPoS,locktime,coin->txversion,timestamp);
vins = cJSON_CreateArray();
item = cJSON_CreateObject();
if ( userdata != 0 && userdatalen > 0 )
@ -908,19 +937,33 @@ int32_t LP_vin_select(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t
above = gap;
abovei = i;
}
} else gap = (value - atx_value);
if ( below == 0 || gap < below )
}
else
{
below = gap;
belowi = i;
gap = (value - atx_value);
if ( below == 0 || gap < below )
{
below = gap;
belowi = i;
}
}
//printf("value %.8f gap %.8f abovei.%d %.8f belowi.%d %.8f\n",dstr(value),dstr(gap),abovei,dstr(above),belowi,dstr(below));
}
*aboveip = abovei;
*abovep = above;
*belowip = belowi;
*belowp = below;
//printf("above.%d below.%d\n",abovei,belowi);
return(abovei >= 0 && above < (below>>1) ? abovei : belowi);
if ( abovei >= 0 && belowi >= 0 )
{
if ( above < (below >> 1) )
return(abovei);
else return(belowi);
}
else if ( abovei >= 0 )
return(abovei);
else return(belowi);
//return(abovei >= 0 && above < (below>>1) ? abovei : belowi);
}
cJSON *LP_inputjson(bits256 txid,int32_t vout,char *spendscriptstr)
@ -938,8 +981,10 @@ cJSON *LP_inputjson(bits256 txid,int32_t vout,char *spendscriptstr)
uint64_t _komodo_interestnew(uint64_t nValue,uint32_t nLockTime,uint32_t tiptime)
{
int32_t minutes; uint64_t interest = 0;
if ( (minutes= (tiptime - nLockTime) / 60) >= 60 )
if ( tiptime > nLockTime && (minutes= (tiptime - nLockTime) / 60) >= 60 )
{
//minutes.71582779 tiptime.1511292969 locktime.1511293505
printf("minutes.%d tiptime.%u locktime.%u\n",minutes,tiptime,nLockTime);
if ( minutes > 365 * 24 * 60 )
minutes = 365 * 24 * 60;
minutes -= 59;
@ -1082,20 +1127,21 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
if ( LP_validSPV(coin->symbol,coin->smartaddr,up->U.txid,up->U.vout) < 0 )
continue;
}
if ( bits256_cmp(utxotxid,up->U.txid) != 0 && LP_allocated(up->U.txid,up->U.vout) != 0 )
continue;
up->spendheight = 1;
total += up->U.value;
remains -= up->U.value;
interest = 0;
if ( up->U.height < 7777777 && strcmp(coin->symbol,"KMD") == 0 )
{
if ( 0 && (interest= LP_komodo_interest(up->U.txid,up->U.value)) > 0 )
if ( (interest= LP_komodo_interest(up->U.txid,up->U.value)) > 0 )
{
interestsum += interest;
char str[65]; printf("%s/%d %.8f interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum));
}
}
//printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f %s/v%d\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum),bits256_str(str,up->U.txid),up->U.vout);
printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f %s/v%d\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum),bits256_str(str,up->U.txid),up->U.vout);
vp = &V[n++];
vp->N = vp->M = 1;
vp->signers[0].privkey = privkey;
@ -1104,10 +1150,10 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
vp->suppress_pubkeys = suppress_pubkeys;
vp->ignore_cltverr = ignore_cltverr;
jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr));
LP_unavailableset(up->U.txid,up->U.vout,(uint32_t)time(NULL)+600,G.LP_mypub25519);
LP_unavailableset(up->U.txid,up->U.vout,(uint32_t)time(NULL)+LP_RESERVETIME,G.LP_mypub25519);
if ( remains <= 0 && i >= numpre-1 )
break;
if ( numunspents < 0 )
if ( numunspents < 0 || n >= LP_MAXVINS )
{
printf("total %.8f not enough for amount %.8f\n",dstr(total),dstr(amount));
return(0);
@ -1120,16 +1166,16 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_info *coin,struct vin_info *V,int32_t max,bits256 privkey,cJSON *outputs,cJSON *vins,cJSON *privkeys,int64_t txfee,bits256 utxotxid,int32_t utxovout,uint32_t locktime)
{
static void *ctx;
cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS]; struct LP_address *ap;
cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS*256]; struct LP_address *ap;
if ( ctx == 0 )
ctx = bitcoin_ctx();
*numvinsp = 0;
*txobjp = 0;
if ( sizeof(utxos)/sizeof(*utxos) != max )
/*if ( sizeof(utxos)/sizeof(*utxos) != max )
{
printf("LP_createrawtransaction: internal error %d != max.%d\n",(int32_t)(sizeof(utxos)/sizeof(*utxos)),max);
return(0);
}
}*/
if ( coin == 0 || outputs == 0 || (numvouts= cJSON_GetArraySize(outputs)) <= 0 )
{
printf("LP_createrawtransaction: illegal coin.%p outputs.%p or arraysize.%d, error\n",coin,outputs,numvouts);
@ -1148,7 +1194,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
{
if ( LP_address_isvalid(coin->symbol,coinaddr) <= 0 )
{
printf("LP_createrawtransaction %s i.%d of %d is invalid\n",coinaddr,i,numvouts);
printf("%s LP_createrawtransaction %s i.%d of %d is invalid\n",coin->symbol,coinaddr,i,numvouts);
return(0);
}
if ( (value= SATOSHIDEN * jdouble(item,coinaddr)) <= 0 )
@ -1165,15 +1211,13 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
return(0);
}
}
//if ( bits256_nonz(utxotxid) == 0 )
if ( (ap= LP_address(coin,coin->smartaddr)) == 0 )
{
if ( (ap= LP_address_utxo_reset(coin)) == 0 )
return(0);
printf("LP_createrawtransaction LP_address null?\n");
return(0);
}
//else if ( (ap= LP_address(coin,coin->smartaddr)) == 0 )
// return(0);
memset(utxos,0,sizeof(utxos));
if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,max,ap,coin->smartaddr)) <= 0 )
if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,(int32_t)(sizeof(utxos)/sizeof(*utxos)),ap,coin->smartaddr)) <= 0 )
{
if ( bits256_nonz(utxotxid) == 0 )
{
@ -1199,14 +1243,9 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
timestamp = (uint32_t)time(NULL);
if ( locktime == 0 && strcmp("KMD",coin->symbol) == 0 )
locktime = timestamp - 777;
txobj = bitcoin_txcreate(coin->symbol,coin->isPoS,locktime,1,timestamp);
txobj = bitcoin_txcreate(coin->symbol,coin->isPoS,locktime,coin->txversion,timestamp);
jdelete(txobj,"vin");
jadd(txobj,"vin",jduplicate(vins));
if ( change < 6000 )
{
adjust = change / numvouts;
change = 0;
}
printf("change %.8f = total %.8f - amount %.8f, adjust %.8f numvouts.%d\n",dstr(change),dstr(total),dstr(amount),dstr(adjust),numvouts);
for (i=0; i<numvouts; i++)
{
@ -1216,33 +1255,47 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
if ( (value= SATOSHIDEN * jdouble(item,coinaddr)) <= 0 )
{
printf("cant get value i.%d of %d %s\n",i,numvouts,jprint(outputs,0));
free_json(txobj);
return(0);
}
bitcoin_addr2rmd160(coin->taddr,&addrtype,rmd160,coinaddr);
if ( addrtype == coin->pubtype )
spendlen = bitcoin_standardspend(spendscript,0,rmd160);
else spendlen = bitcoin_p2shspend(spendscript,0,rmd160);
if ( i == numvouts-1 && strcmp(coinaddr,coin->smartaddr) == 0 && change != 0 )
{
printf("combine last vout %.8f with change %.8f\n",dstr(value+adjust),dstr(change));
value += change;
change = 0;
}
txobj = bitcoin_txoutput(txobj,spendscript,spendlen,value + adjust);
}
else
{
printf("cant get fieldname.%d of %d %s\n",i,numvouts,jprint(outputs,0));
free_json(txobj);
return(0);
}
}
if ( change < 6000 )
{
//adjust = change / numvouts; adjust messes up vout encoding!
change = 0;
}
if ( change != 0 )
txobj = bitcoin_txoutput(txobj,script,scriptlen,change);
if ( (rawtxbytes= bitcoin_json2hex(coin->isPoS,&txid,txobj,V)) != 0 )
{
} else printf("error making rawtx suppress.%d\n",suppress_pubkeys);
*txobjp = txobj;
*numvinsp = numvins;
return(rawtxbytes);
}
char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
{
static void *ctx;
int32_t iter,utxovout,autofee,completed=0,maxV,numvins,numvouts,datalen,suppress_pubkeys; bits256 privkey; char changeaddr[64],vinaddr[64],str[65],*signedtx=0,*rawtx=0; struct vin_info *V; uint32_t locktime; cJSON *retjson,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 utxotxid,signedtxid; uint64_t txfee,newtxfee=10000;
int32_t iter,i,utxovout,autofee,completed=0,maxV,numvins,numvouts,datalen,suppress_pubkeys; bits256 privkey; struct LP_address *ap; char changeaddr[64],vinaddr[64],str[65],*signedtx=0,*rawtx=0; struct vin_info *V; uint32_t locktime; cJSON *retjson,*item,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 utxotxid,signedtxid; uint64_t txfee,newtxfee=10000;
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( (outputs= jarray(&numvouts,argjson,"outputs")) == 0 )
@ -1271,9 +1324,16 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
V = malloc(maxV * sizeof(*V));
for (iter=0; iter<2; iter++)
{
if ( (ap= LP_address_utxo_reset(coin)) == 0 )
{
printf("LP_withdraw error utxo reset %s\n",coin->symbol);
free(V);
return(0);
}
privkeys = cJSON_CreateArray();
vins = cJSON_CreateArray();
memset(V,0,sizeof(*V) * maxV);
numvins = 0;
if ( (rawtx= LP_createrawtransaction(&txobj,&numvins,coin,V,maxV,privkey,outputs,vins,privkeys,iter == 0 ? txfee : newtxfee,utxotxid,utxovout,locktime)) != 0 )
{
completed = 0;
@ -1286,25 +1346,44 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
printf("incomplete signing withdraw (%s)\n",jprint(vins,0));
if ( signedtx != 0 )
free(signedtx), signedtx = 0;
} else printf("LP_withdraw %s -> %s\n",jprint(argjson,0),bits256_str(str,signedtxid));
} else printf("LP_withdraw.%s %s -> %s\n",coin->symbol,jprint(argjson,0),bits256_str(str,signedtxid));
if ( signedtx == 0 )
break;
datalen = (int32_t)strlen(signedtx) / 2;
if ( strcmp(coin->symbol,"BTC") == 0 )
if ( iter == 0 && strcmp(coin->symbol,"BTC") == 0 )
{
newtxfee = LP_txfeecalc(coin,0,datalen);
printf("txfee %.8f -> newtxfee %.8f\n",dstr(txfee),dstr(newtxfee));
printf("txfee %.8f -> newtxfee %.8f, numvins.%d\n",dstr(txfee),dstr(newtxfee),numvins);
for (i=0; i<numvins; i++)
{
item = jitem(vins,i);
//printf("set available %s\n",jprint(item,0));
LP_availableset(jbits256(item,"txid"),jint(item,"vout"));
}
free_json(vins), vins = 0;
free_json(txobj), txobj = 0;
free_json(privkeys), privkeys = 0;
if ( rawtx != 0 )
free(rawtx), rawtx = 0;
if ( signedtx != 0 )
free(signedtx), signedtx = 0;
} else break;
} else break;
free_json(vins), vins = 0;
free_json(txobj), txobj = 0;
free_json(privkeys), privkeys = 0;
if ( rawtx != 0 )
free(rawtx), rawtx = 0;
}
free(V);
if ( vins != 0 )
{
if ( completed == 0 && (numvins= cJSON_GetArraySize(vins)) > 0 )
{
for (i=0; i<numvins; i++)
{
item = jitem(vins,i);
LP_availableset(jbits256(item,"txid"),jint(item,"vout"));
}
}
free_json(vins);
}
if ( privkeys != 0 )
free_json(privkeys);
retjson = cJSON_CreateObject();
@ -1339,6 +1418,7 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub
jaddnum(item,rawtx->I.destaddr,dstr(rawtx->I.amount));
jaddi(outputs,item);
jadd(argjson,"outputs",outputs);
//printf("call LP_withdraw.(%s)\n",jprint(argjson,0));
if ( (retstr= LP_withdraw(coin,argjson)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
@ -1350,7 +1430,7 @@ int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pub
rawtx->I.completed = 1;
rawtx->I.signedtxid = jbits256(retjson,"txid");
retval = 0;
}
} else printf("rawtx withdraw error? (%s)\n",retstr);
free_json(retjson);
}
free(retstr);
@ -1475,7 +1555,7 @@ int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vou
{
cJSON *retjson;
coinaddr[0] = 0;
if ( (retjson= LP_gettx(symbol,txid)) != 0 )
if ( (retjson= LP_gettx(symbol,txid,0)) != 0 )
{
LP_txdestaddr(coinaddr,txid,vout,retjson);
free_json(retjson);
@ -1486,7 +1566,7 @@ int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vou
int32_t basilisk_swap_getsigscript(char *symbol,uint8_t *script,int32_t maxlen,bits256 txid,int32_t vini)
{
cJSON *retjson,*vins,*item,*skey; int32_t n,scriptlen = 0; char *hexstr;
if ( (retjson= LP_gettx(symbol,txid)) != 0 )
if ( (retjson= LP_gettx(symbol,txid,0)) != 0 )
{
if ( (vins= jarray(&n,retjson,"vin")) != 0 && vini < n )
{
@ -1558,25 +1638,56 @@ bits256 _LP_swap_spendtxid(char *symbol,char *destaddr,char *coinaddr,bits256 ut
}
#endif
bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t vout)
bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t utxovout)
{
bits256 spendtxid; int32_t spendvin; char coinaddr[64],str[65]; cJSON *retjson; struct iguana_info *coin;
bits256 spendtxid,txid,vintxid; int32_t spendvin,i,m,n; char coinaddr[64]; cJSON *array,*vins,*vin,*txobj; struct iguana_info *coin;
// listtransactions or listspents
destaddr[0] = 0;
coinaddr[0] = 0;
memset(&spendtxid,0,sizeof(spendtxid));
if ( LP_spendsearch(destaddr,&spendtxid,&spendvin,symbol,utxotxid,vout) > 0 )
if ( LP_spendsearch(destaddr,&spendtxid,&spendvin,symbol,utxotxid,utxovout) > 0 )
{
//printf("spend of %s/v%d detected\n",bits256_str(str,utxotxid),vout);
//char str[65]; printf("spend of %s/v%d detected\n",bits256_str(str,utxotxid),utxovout);
}
else if ( 0 && (coin= LP_coinfind(symbol)) != 0 && coin->electrum == 0 )
else if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum == 0 )
{
if ( (retjson= LP_gettxout(symbol,coinaddr,utxotxid,vout)) == 0 )
if ( (array= LP_listreceivedbyaddress(symbol,destaddr)) != 0 )
{
decode_hex(spendtxid.bytes,32,"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
printf("couldnt find spend of %s/v%d, but no gettxout\n",bits256_str(str,utxotxid),vout);
} else free_json(retjson);
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
txid = jbits256i(array,i);
if ( (txobj= LP_gettx(symbol,txid,1)) != 0 )
{
if ( (vins= jarray(&m,txobj,"vin")) != 0 )
{
//printf("vins.(%s)\n",jprint(vins,0));
if ( utxovout < m )
{
vin = jitem(vins,utxovout);
vintxid = jbits256(vin,"txid");
if ( bits256_cmp(vintxid,utxotxid) == 0 )
{
LP_txdestaddr(destaddr,txid,0,txobj);
char str[65],str2[65],str3[65]; printf("LP_swap_spendtxid: found %s/v%d spends %s vs %s found.%d destaddr.(%s)\n",bits256_str(str,txid),utxovout,bits256_str(str2,vintxid),bits256_str(str3,utxotxid),bits256_cmp(vintxid,utxotxid) == 0,destaddr);
spendtxid = txid;
break;
}
}
}
free_json(txobj);
}
}
}
free_json(array);
}
}
/* if ( (retjson= LP_gettxout(symbol,coinaddr,utxotxid,vout)) == 0 )
{
decode_hex(spendtxid.bytes,32,"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
printf("couldnt find spend of %s/v%d, but no gettxout\n",bits256_str(str,utxotxid),vout);
} else free_json(retjson);
*/
return(spendtxid);
//char str[65]; printf("swap %s spendtxid.(%s)\n",symbol,bits256_str(str,utxotxid));
}
@ -1750,7 +1861,7 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u
cJSON *txobj,*vouts,*vout; uint8_t extraspace[32768]; bits256 signedtxid; struct iguana_msgtx msgtx; int32_t n,suppress_pubkeys = 0;
if ( valuep != 0 )
*valuep = 0;
if ( (txobj= bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&signedtxid,&msgtx,extraspace,sizeof(extraspace),data,datalen,0,suppress_pubkeys,coin->zcash)) != 0 )
if ( (txobj= bitcoin_data2json(coin->symbol,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&signedtxid,&msgtx,extraspace,sizeof(extraspace),data,datalen,0,suppress_pubkeys,coin->zcash)) != 0 )
{
//char str[65]; printf("got txid.%s (%s)\n",bits256_str(str,signedtxid),jprint(txobj,0));
if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n > 0 )
@ -1954,7 +2065,7 @@ int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t data
diff = swap->otherfee.I.locktime - (swap->I.started+1);
if ( diff < 0 )
diff = -diff;
if ( diff < 10 )
if ( diff < LP_AUTOTRADE_TIMEOUT )
printf("dexfee verified\n");
else printf("locktime mismatch in otherfee, reject %u vs %u\n",swap->otherfee.I.locktime,swap->I.started+1);
return(0);

371
iguana/exchanges/LP_utxo.c

@ -41,18 +41,19 @@ struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout)
int32_t _LP_inuse_delete(bits256 txid,int32_t vout)
{
struct LP_inuse_info *lp; int32_t ind;
struct LP_inuse_info *lp; int32_t ind; char str[65];
if ( (lp= _LP_inuse_find(txid,vout)) != 0 )
{
ind = lp->ind;
*lp = LP_inuse[--LP_numinuse];
if ( LP_numinuse > 0 )
*lp = LP_inuse[--LP_numinuse];
lp->ind = ind;
memset(&LP_inuse[LP_numinuse],0,sizeof(struct LP_inuse_info));
//printf("_LP_inuse_delete mark as free %s/v%d find.%p\n",bits256_str(str,txid),vout,_LP_inuse_find(txid,vout));
for (ind=0; ind<LP_numinuse; ind++)
if ( LP_inuse[ind].ind != ind )
printf("ind.%d of %d: mismatched ind.%d\n",ind,LP_numinuse,LP_inuse[ind].ind);
}
//char str[65]; printf("_LP_inuse_delete cant find %s/v%d\n",bits256_str(str,txid),vout);
} else printf("_LP_inuse_delete couldnt find %s/v%d\n",bits256_str(str,txid),vout);
return(-1);
}
@ -99,9 +100,10 @@ struct LP_inuse_info *_LP_inuse_add(uint32_t expiration,bits256 otherpub,bits256
{
if ( bits256_nonz(otherpub) != 0 )
lp->otherpub = otherpub;
if ( expiration > lp->expiration || expiration == 0 )
//if ( expiration > lp->expiration || expiration == 0 )
lp->expiration = expiration;
}
char str[65]; printf("set inuse until %u lag.%d for %s/v%d\n",expiration,(int32_t)(expiration-(uint32_t)time(NULL)),bits256_str(str,txid),vout);
return(lp);
} else printf("_LP_inuse_add [%d] overflow\n",LP_numinuse);
return(0);
@ -151,13 +153,34 @@ void LP_availableset(bits256 txid,int32_t vout)
portable_mutex_unlock(&LP_inusemutex);
}
int32_t LP_isavailable(struct LP_utxoinfo *utxo)
int32_t LP_maxvalue(uint64_t *values,int32_t n)
{
struct _LP_utxoinfo u;
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
if ( LP_allocated(utxo->payment.txid,utxo->payment.vout) == 0 && LP_allocated(u.txid,u.vout) == 0 )
return(1);
else return(0);
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(int32_t iambob,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 ( iambob != 0 && dist < 0 && -dist < values[i]/10 )
dist = -dist;
//printf("(%.8f %.8f %.8f).%d ",dstr(values[i]),dstr(dist),dstr(mindist),mini);
if ( dist >= 0 && dist < mindist )
{
mini = i;
mindist = dist;
}
}
return(mini);
}
uint64_t LP_value_extract(cJSON *obj,int32_t addinterest)
@ -237,24 +260,29 @@ struct LP_address *LP_address(struct iguana_info *coin,char *coinaddr)
return(ap);
}
int32_t LP_address_minmax(uint64_t *balancep,uint64_t *minp,uint64_t *maxp,struct LP_address *ap)
int32_t LP_address_minmax(uint64_t *balancep,uint64_t *minp,uint64_t *maxp,struct iguana_info *coin,char *coinaddr)
{
struct LP_address_utxo *up,*tmp; int32_t n = 0;
cJSON *array,*item; bits256 txid,zero; int64_t value; int32_t i,vout,height,n = 0;
*minp = *maxp = *balancep = 0;
DL_FOREACH_SAFE(ap->utxos,up,tmp)
memset(zero.bytes,0,sizeof(zero));
if ( (array= LP_listunspent(coin->symbol,coinaddr,zero,zero)) != 0 )
{
if ( up->spendheight <= 0 )
//printf("address minmax.(%s)\n",jprint(array,0));
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
if ( up->U.value > *maxp )
*maxp = up->U.value;
if ( *minp == 0 || up->U.value < *minp )
*minp = up->U.value;
*balancep += up->U.value;
n++;
for (i=0; i<n; i++)
{
item = jitem(array,i);
value = LP_listunspent_parseitem(coin,&txid,&vout,&height,item);
if ( value > *maxp )
*maxp = value;
if ( *minp == 0 || value < *minp )
*minp = value;
*balancep += value;
}
}
free_json(array);
}
if ( 0 && n > 0 )
printf("n.%d %s min %.8f max %.8f\n",n,ap->coinaddr,dstr(*minp),dstr(*maxp));
return(n);
}
@ -263,7 +291,6 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a
struct LP_address_utxo *up,*tmp; struct LP_transaction *tx; cJSON *txout; int32_t n = 0;
if ( strcmp(ap->coinaddr,coinaddr) != 0 )
printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr);
//LP_listunspent_issue(coin->symbol,coin->smartaddr,2);
//portable_mutex_lock(&LP_utxomutex);
DL_FOREACH_SAFE(ap->utxos,up,tmp)
{
@ -309,7 +336,7 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a
utxos[n++] = up;
if ( n >= max )
break;
} //else printf("LP_allocated skip\n");
} //else printf("LP_allocated skip %u\n",LP_allocated(up->U.txid,up->U.vout));
}
else
{
@ -418,15 +445,17 @@ int32_t LP_address_utxoadd(uint32_t timestamp,char *debug,struct iguana_info *co
struct LP_address *LP_address_utxo_reset(struct iguana_info *coin)
{
struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,vout,height; cJSON *array,*item; int64_t value; bits256 txid; uint32_t now;
struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,m,vout,height; cJSON *array,*item,*txobj; bits256 zero; int64_t value; bits256 txid; uint32_t now;
LP_address(coin,coin->smartaddr);
LP_listunspent_issue(coin->symbol,coin->smartaddr,2);
//printf("call listunspent issue %s (%s)\n",coin->symbol,coin->smartaddr);
memset(zero.bytes,0,sizeof(zero));
LP_listunspent_issue(coin->symbol,coin->smartaddr,2,zero,zero);
if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 )
{
printf("LP_address_utxo_reset: cant find address data\n");
return(0);
}
if ( (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 )
if ( (array= LP_listunspent(coin->symbol,coin->smartaddr,zero,zero)) != 0 )
{
DL_FOREACH_SAFE(ap->utxos,up,tmp)
{
@ -442,29 +471,26 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin)
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
char str[65];
for (i=0; i<n; i++)
for (i=m=0; i<n; i++)
{
//{"tx_hash":"38d1b7c73015e1b1d6cb7fc314cae402a635b7d7ea294970ab857df8777a66f4","tx_pos":0,"height":577975,"value":238700}
item = jitem(array,i);
if ( coin->electrum != 0 )
{
txid = jbits256(item,"tx_hash");
vout = juint(item,"tx_pos");
value = j64bits(item,"value");
height = jint(item,"height");
}
else
{
txid = jbits256(item,"txid");
vout = juint(item,"vout");
value = LP_value_extract(item,0);
height = LP_txheight(coin,txid);
}
value = LP_listunspent_parseitem(coin,&txid,&vout,&height,item);
if ( (txobj= LP_gettxout(coin->symbol,coin->smartaddr,txid,vout)) == 0 )
continue;
else free_json(txobj);
if ( LP_numconfirms(coin->symbol,coin->smartaddr,txid,vout,0) <= 0 )
continue;
LP_address_utxoadd(now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1);
if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 )
printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value));
else
{
m++;
//printf("%.8f ",dstr(value));
}
}
printf("added %d from listunspents\n",n);
//printf("added %d from listunspents\n",m);
}
free_json(array);
}
@ -473,13 +499,13 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin)
cJSON *LP_address_item(struct iguana_info *coin,struct LP_address_utxo *up,int32_t electrumret)
{
cJSON *item = cJSON_CreateObject();
int32_t notarized; cJSON *item = cJSON_CreateObject();
if ( electrumret == 0 )
{
jaddbits256(item,"txid",up->U.txid);
jaddnum(item,"vout",up->U.vout);
if ( up->U.height > 0 )
jaddnum(item,"confirmations",LP_getheight(coin) - up->U.height + 1);
jaddnum(item,"confirmations",LP_getheight(&notarized,coin) - up->U.height + 1);
jaddnum(item,"amount",dstr(up->U.value));
jaddstr(item,"scriptPubKey","");
}
@ -555,10 +581,11 @@ cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrum
cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electrumret)
{
cJSON *array,*retjson,*item; int32_t i,n; uint64_t balance = 0;
cJSON *array,*retjson,*item; bits256 zero; int32_t i,n; uint64_t balance = 0;
memset(zero.bytes,0,sizeof(zero));
if ( coin->electrum == 0 )
{
if ( (array= LP_listunspent(coin->symbol,coinaddr)) != 0 )
if ( (array= LP_listunspent(coin->symbol,coinaddr,zero,zero)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
@ -573,32 +600,98 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
}
else
{
if ( strcmp(coin->smartaddr,coinaddr) == 0 )
balance = LP_unspents_load(coin->symbol,coinaddr);
else
if ( strcmp(coin->smartaddr,coinaddr) != 0 )
{
if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
balance += j64bits(item,"value");
}
}
free_json(array);
}
if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,coinaddr,2,zero,zero)) != 0 )
free_json(retjson);
}
balance = LP_unspents_load(coin->symbol,coinaddr);
}
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jaddstr(retjson,"coin",coin->symbol);
jaddstr(retjson,"address",coinaddr);
jaddnum(retjson,"balance",dstr(balance));
if ( strcmp(coin->symbol,"KMD") == 0 && strcmp(coin->smartaddr,coinaddr) == 0 )
{
jaddnum(retjson,"zcredits",dstr(LP_myzcredits()));
jadd(retjson,"zdebits",LP_myzdebits());
}
return(retjson);
}
cJSON *LP_balances(char *coinaddr)
{
struct iguana_info *coin,*tmp; char address[64]; uint8_t taddr,addrtype,rmd160[20]; uint64_t balance,KMDvalue,sum = 0; cJSON *array,*item,*retjson;
if ( coinaddr != 0 && coinaddr[0] == 't' && (coinaddr[1] == '1' || coinaddr[1] == '3') )
taddr = 1;
else taddr = 0;
array = cJSON_CreateArray();
HASH_ITER(hh,LP_coins,coin,tmp)
{
if ( coin->electrum != 0 || (coinaddr != 0 && coinaddr[0] != 0 && strcmp(coinaddr,coin->smartaddr) != 0) )
{
if ( coinaddr == 0 || coinaddr[0] == 0 )
strcpy(address,coin->smartaddr);
else
{
bitcoin_addr2rmd160(taddr,&addrtype,rmd160,coinaddr);
bitcoin_address(address,coin->taddr,coin->pubtype,rmd160,20);
//printf("%s taddr.%d addrtype.%u %s -> %s [%c %c].%d\n",coin->symbol,taddr,addrtype,coinaddr,address,coinaddr[0],coinaddr[1],coinaddr[0] == 't' && (coinaddr[1] == '1' || coinaddr[1] == '3'));
}
if ( (retjson= LP_address_balance(coin,address,1)) != 0 )
{
if ( (balance= jdouble(retjson,"balance")*SATOSHIDEN) > 0 )
{
item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol);
jaddnum(item,"balance",dstr(balance));
if ( (KMDvalue= LP_KMDvalue(coin,balance)) != 0 )
{
jaddnum(item,"KMDvalue",dstr(KMDvalue));
sum += KMDvalue;
}
if ( coin->electrum != 0 && strcmp(address,coin->smartaddr) == 0 && strcmp(coin->symbol,"KMD") == 0 )
{
jaddnum(item,"zcredits",dstr(LP_myzcredits()));
//jadd(item,"zdebits",LP_myzdebits());
}
jaddi(array,item);
}
free_json(retjson);
}
}
else
{
if ( (balance= LP_RTsmartbalance(coin)) != 0 )
{
item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol);
jaddnum(item,"balance",dstr(balance));
if ( (KMDvalue= LP_KMDvalue(coin,balance)) != 0 )
{
jaddnum(item,"KMDvalue",dstr(KMDvalue));
sum += KMDvalue;
}
if ( strcmp(coin->symbol,"KMD") == 0 )
{
jaddnum(item,"zcredits",dstr(LP_myzcredits()));
//jadd(item,"zdebits",LP_myzdebits());
}
jaddi(array,item);
}
}
}
if ( sum != 0 )
{
item = cJSON_CreateObject();
jaddstr(item,"coin","total");
jaddnum(item,"balance",dstr(sum));
jaddi(array,item);
}
return(array);
}
int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array)
{
int32_t i,n,v,errs,height,count=0; uint64_t value,val; cJSON *item,*txobj; bits256 txid;
@ -642,66 +735,6 @@ int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array)
return(count);
}
void LP_utxosetkey(uint8_t *key,bits256 txid,int32_t vout)
{
memcpy(key,txid.bytes,sizeof(txid));
memcpy(&key[sizeof(txid)],&vout,sizeof(vout));
}
struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout)
{
struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)];
LP_utxosetkey(key,txid,vout);
HASH_FIND(hh,G.LP_utxoinfos[iambob!=0],key,sizeof(key),utxo);
return(utxo);
}
void _LP_utxo_delete(int32_t iambob,struct LP_utxoinfo *utxo)
{
HASH_DELETE(hh,G.LP_utxoinfos[iambob],utxo);
}
void _LP_utxo2_delete(int32_t iambob,struct LP_utxoinfo *utxo)
{
HASH_DELETE(hh,G.LP_utxoinfos2[iambob],utxo);
}
struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2)
{
struct LP_utxoinfo *utxo=0; uint8_t key2[sizeof(txid2) + sizeof(vout2)];
LP_utxosetkey(key2,txid2,vout2);
HASH_FIND(hh2,G.LP_utxoinfos2[iambob],key2,sizeof(key2),utxo);
return(utxo);
}
struct LP_utxoinfo *LP_utxofind(int32_t iambob,bits256 txid,int32_t vout)
{
struct LP_utxoinfo *utxo=0;
/*if ( iambob != 0 )
{
printf("LP_utxofind deprecated iambob\n");
return(0);
}*/
portable_mutex_lock(&LP_utxomutex);
utxo = _LP_utxofind(iambob,txid,vout);
portable_mutex_unlock(&LP_utxomutex);
return(utxo);
}
struct LP_utxoinfo *LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2)
{
struct LP_utxoinfo *utxo=0;
/*if ( iambob != 0 )
{
printf("LP_utxo2find deprecated iambob\n");
return(0);
}*/
portable_mutex_lock(&LP_utxomutex);
utxo = _LP_utxo2find(iambob,txid2,vout2);
portable_mutex_unlock(&LP_utxomutex);
return(utxo);
}
struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid)
{
struct LP_transaction *tx;
@ -741,7 +774,7 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS
struct LP_transaction *tx; int32_t i,height,numvouts,numvins,spentvout; cJSON *vins,*vouts,*vout,*vin; bits256 spenttxid; char str[65];
if ( coin->inactive != 0 )
return(0);
if ( txobj != 0 || (txobj= LP_gettx(coin->symbol,txid)) != 0 )
if ( txobj != 0 || (txobj= LP_gettx(coin->symbol,txid,0)) != 0 )
{
if ( coin->electrum == 0 )
height = LP_txheight(coin,txid);
@ -798,12 +831,12 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS
int32_t LP_txheight(struct iguana_info *coin,bits256 txid)
{
bits256 blockhash; struct LP_transaction *tx; cJSON *blockobj,*txobj; int32_t height = 0;
bits256 blockhash; struct LP_transaction *tx; cJSON *blockobj,*retjson,*txobj; int32_t height = 0;
if ( coin == 0 )
return(-1);
if ( coin->electrum == 0 )
{
if ( (txobj= LP_gettx(coin->symbol,txid)) != 0 )
if ( (txobj= LP_gettx(coin->symbol,txid,0)) != 0 )
{
//*timestampp = juint(txobj,"locktime");
//*blocktimep = juint(txobj,"blocktime");
@ -823,13 +856,23 @@ int32_t LP_txheight(struct iguana_info *coin,bits256 txid)
{
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
height = tx->height;
if ( height == 0 )
{
if ( (retjson= electrum_transaction(&height,coin->symbol,coin->electrum,&retjson,txid,0)) != 0 )
{
//printf("process %s\n",jprint(retjson,0));
free_json(retjson);
}
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
height = tx->height;
}
}
return(height);
}
int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool)
{
struct iguana_info *coin; int32_t ht,numconfirms = 100;
struct iguana_info *coin; bits256 zero; int32_t ht,notarized,numconfirms = 100;
cJSON *txobj;
if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 )
return(-1);
@ -843,7 +886,7 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int
}
else if ( mempool != 0 && LP_mempoolscan(symbol,txid) >= 0 )
numconfirms = 0;
else if ( (txobj= LP_gettx(symbol,txid)) != 0 )
else if ( (txobj= LP_gettx(symbol,txid,1)) != 0 )
{
numconfirms = jint(txobj,"confirmations");
free_json(txobj);
@ -851,9 +894,10 @@ int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int
}
else
{
LP_listunspent_issue(symbol,coinaddr,1);
memset(zero.bytes,0,sizeof(zero));
LP_listunspent_issue(symbol,coinaddr,1,txid,zero);
if ( (ht= LP_txheight(coin,txid)) > 0 && ht <= coin->height )
numconfirms = (LP_getheight(coin) - ht + 1);
numconfirms = (LP_getheight(&notarized,coin) - ht + 1);
else if ( mempool != 0 )
{
if ( LP_waitmempool(symbol,coinaddr,txid,vout,30) >= 0 )
@ -964,6 +1008,23 @@ uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout)
return(0);
}
int64_t LP_outpoint_amount(char *symbol,bits256 txid,int32_t vout)
{
int64_t amount=0; int32_t numvouts; char coinaddr[64]; cJSON *vouts,*txjson;
if ( (amount= LP_txvalue(coinaddr,symbol,txid,vout)) != 0 )
return(amount);
else
{
if ( (txjson= LP_gettx(symbol,txid,1)) != 0 )
{
if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && vout < numvouts )
amount = LP_value_extract(jitem(vouts,vout),0);
free_json(txjson);
}
}
return(amount);
}
int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol,bits256 txid,int32_t vout,uint64_t satoshis,bits256 txid2,int32_t vout2)
{
uint64_t val,val2=0,txfee,threshold=0; cJSON *txobj; int32_t bypass = 0; char destaddr[64],destaddr2[64]; struct iguana_info *coin = LP_coinfind(symbol);
@ -989,8 +1050,6 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
{
if ( bypass == 0 && strcmp(destaddr,destaddr2) != 0 )
printf("mismatched %s destaddr (%s) vs (%s)\n",symbol,destaddr,destaddr2);
else if ( bypass == 0 && ((iambob == 0 && val2 > val) || (iambob != 0 && val2 <= satoshis)) )
printf("iambob.%d ineligible due to offsides: val %.8f and val2 %.8f vs %.8f diff %lld\n",iambob,dstr(val),dstr(val2),dstr(satoshis),(long long)(val2 - val));
else
{
*valp = val;
@ -999,38 +1058,16 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
strcpy(destaddr,destaddr2);
if ( coin != 0 )
{
/*if ( coin->electrum != 0 )
{
if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts && tx->outpoints[vout].spendheight > 0 )
{
//printf("txid spent\n");
return(0);
}
if ( (tx= LP_transactionfind(coin,txid2)) != 0 && vout2 < tx->numvouts && tx->outpoints[vout2].spendheight > 0 )
{
//printf("txid2 spent\n");
return(0);
}
if ( (up= LP_address_utxofind(coin,destaddr,txid,vout)) != 0 && up->spendheight > 0 )
{
//printf("txid %s spentB\n",destaddr);
return(0);
}
if ( (up= LP_address_utxofind(coin,destaddr,txid2,vout2)) != 0 && up->spendheight > 0 )
{
//printf("txid2 %s spentB\n",destaddr);
return(0);
}
}
else*/
{
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 )
return(0);
else free_json(txobj);
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 )
return(0);
else free_json(txobj);
}
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 )
return(0);
else free_json(txobj);
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 )
return(0);
else free_json(txobj);
if ( LP_numconfirms(coin->symbol,destaddr,txid,vout,0) <= 0 )
return(0);
if ( LP_numconfirms(coin->symbol,destaddr,txid2,vout2,0) <= 0 )
return(0);
}
return(1);
}
@ -1077,12 +1114,12 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
int32_t LP_inventory_prevent(int32_t iambob,char *symbol,bits256 txid,int32_t vout)
{
struct LP_address_utxo *up; struct LP_utxoinfo *utxo; struct LP_transaction *tx; struct iguana_info *coin;
struct LP_address_utxo *up; struct iguana_info *coin; //struct LP_utxoinfo *utxo; struct LP_transaction *tx;
if ( (coin= LP_coinfind(symbol)) == 0 )
return(1);
if ( LP_allocated(txid,vout) != 0 )
return(1);
if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 )
/*if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 )
{
if ( coin != 0 && (tx= LP_transactionfind(coin,txid)) != 0 )
{
@ -1095,7 +1132,7 @@ int32_t LP_inventory_prevent(int32_t iambob,char *symbol,bits256 txid,int32_t vo
//char str[65]; printf("prevent adding iambob.%d %s/v%d to inventory\n",iambob,bits256_str(str,txid),vout);
return(1);
}
}
}*/
if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) != 0 && up->spendheight > 0 )
return(1);
return(0);

905
iguana/exchanges/LP_utxos.c

@ -1,905 +0,0 @@
/******************************************************************************
* 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
//
int32_t LP_ismine(struct LP_utxoinfo *utxo)
{
if ( utxo != 0 && bits256_cmp(utxo->pubkey,G.LP_mypub25519) == 0 )
return(1);
else return(0);
}
int32_t LP_isunspent(struct LP_utxoinfo *utxo)
{
struct LP_address_utxo *up; struct _LP_utxoinfo u; struct iguana_info *coin;
if ( (coin= LP_coinfind(utxo->coin)) == 0 )
return(0);
if ( (up= LP_address_utxofind(coin,utxo->coinaddr,utxo->payment.txid,utxo->payment.vout)) != 0 && up->spendheight > 0 )
{
utxo->T.spentflag = up->spendheight;
return(0);
}
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
if ( (up= LP_address_utxofind(coin,utxo->coinaddr,u.txid,u.vout)) != 0 && up->spendheight > 0 )
{
utxo->T.spentflag = up->spendheight;
return(0);
}
if ( utxo != 0 && utxo->T.spentflag == 0 && LP_isavailable(utxo) > 0 )
return(1);
else return(0);
}
struct LP_utxoinfo *LP_utxopairfind(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2)
{
struct LP_utxoinfo *utxo=0; struct _LP_utxoinfo u;
if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 )
{
u = (iambob != 0) ? utxo->deposit : utxo->fee;
if (vout2 == u.vout && bits256_cmp(u.txid,txid2) == 0 )
return(utxo);
}
return(0);
}
struct LP_utxoinfo *LP_utxofinds(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2)
{
struct LP_utxoinfo *utxo;
if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxofind(iambob,txid2,vout2)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid2,vout2)) != 0 )
return(utxo);
else return(0);
}
int32_t LP_utxoaddptrs(struct LP_utxoinfo *ptrs[],int32_t n,struct LP_utxoinfo *utxo)
{
int32_t i;
for (i=0; i<n; i++)
if ( ptrs[i] == utxo )
return(n);
ptrs[n++] = utxo;
return(n);
}
/*uint32_t LP_allocated(bits256 txid,int32_t vout)
{
struct LP_utxoinfo *utxo;
if ( (utxo= _LP_utxofind(0,txid,vout)) != 0 && LP_isavailable(utxo) == 0 )
{
//char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout);
return(utxo);
}
if ( (utxo= _LP_utxo2find(0,txid,vout)) != 0 && LP_isavailable(utxo) == 0 )
{
//char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout);
return(utxo);
}
if ( (utxo= _LP_utxofind(1,txid,vout)) != 0 && LP_isavailable(utxo) == 0 )
{
//char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout);
return(utxo);
}
if ( (utxo= _LP_utxo2find(1,txid,vout)) != 0 && LP_isavailable(utxo) == 0 )
{
//char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout);
return(utxo);
}
return(0);
}
int32_t LP_isavailable(struct LP_utxoinfo *utxo)
{
if ( time(NULL) > utxo->T.swappending )
utxo->T.swappending = 0;
if ( utxo != 0 && utxo->T.swappending == 0 && utxo->S.swap == 0 )
return(1);
else return(0);
}
int32_t LP_utxocollisions(struct LP_utxoinfo *ptrs[],struct LP_utxoinfo *refutxo)
{
int32_t iambob,n = 0; struct LP_utxoinfo *utxo; struct _LP_utxoinfo u;
if ( refutxo == 0 )
return(0);
portable_mutex_lock(&LP_utxomutex);
for (iambob=0; iambob<=1; iambob++)
{
if ( (utxo= _LP_utxofind(iambob,refutxo->payment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo )
n = LP_utxoaddptrs(ptrs,n,utxo);
if ( (utxo= _LP_utxo2find(iambob,refutxo->payment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo )
n = LP_utxoaddptrs(ptrs,n,utxo);
u = (refutxo->iambob != 0) ? refutxo->deposit : refutxo->fee;
if ( (utxo= _LP_utxofind(iambob,u.txid,u.vout)) != 0 && utxo != refutxo )
n = LP_utxoaddptrs(ptrs,n,utxo);
if ( (utxo= _LP_utxo2find(iambob,u.txid,u.vout)) != 0 && utxo != refutxo )
n = LP_utxoaddptrs(ptrs,n,utxo);
}
portable_mutex_unlock(&LP_utxomutex);
if ( 0 && n > 0 )
printf("LP_utxocollisions n.%d\n",n);
return(n);
}
int32_t _LP_availableset(struct LP_utxoinfo *utxo)
{
int32_t flag = 0;
if ( utxo != 0 )
{
if ( bits256_nonz(utxo->S.otherpubkey) != 0 )
flag = 1, memset(&utxo->S.otherpubkey,0,sizeof(utxo->S.otherpubkey));
if ( utxo->S.swap != 0 )
flag = 1, utxo->S.swap = 0;
if ( utxo->T.swappending != 0 )
flag = 1, utxo->T.swappending = 0;
return(flag);
}
return(0);
}
void _LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey)
{
if ( utxo != 0 )
{
utxo->T.swappending = (uint32_t)(time(NULL) + LP_RESERVETIME);
utxo->S.otherpubkey = otherpubkey;
}
}
void LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey)
{
struct LP_utxoinfo *ptrs[8]; int32_t i,n; struct _LP_utxoinfo u;
memset(ptrs,0,sizeof(ptrs));
if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 )
{
for (i=0; i<n; i++)
_LP_unavailableset(ptrs[i],otherpubkey);
}
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
char str[65],str2[65]; printf("UTXO.[%d] RESERVED %s/v%d %s/v%d collisions.%d\n",utxo->iambob,bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,u.txid),u.vout,n);
_LP_unavailableset(utxo,otherpubkey);
}
void LP_availableset(struct LP_utxoinfo *utxo)
{
struct LP_utxoinfo *ptrs[8]; int32_t i,n,count = 0; struct _LP_utxoinfo u;
if ( utxo != 0 )
{
memset(ptrs,0,sizeof(ptrs));
if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 )
{
for (i=0; i<n; i++)
count += _LP_availableset(ptrs[i]);
}
count += _LP_availableset(utxo);
if ( count > 0 )
{
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
char str[65],str2[65]; printf("UTXO.[%d] AVAIL %s/v%d %s/v%d collisions.%d\n",utxo->iambob,bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,u.txid),u.vout,n);
}
}
}
*/
cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo)
{
struct _LP_utxoinfo u;
//jaddstr(item,"method","oldutxo");
if ( utxo == 0 )
return(item);
if ( utxo->gui[0] != 0 )
jaddstr(item,"gui",utxo->gui);
jaddstr(item,"coin",utxo->coin);
//jaddnum(item,"now",time(NULL));
jaddnum(item,"iambob",utxo->iambob);
jaddstr(item,"address",utxo->coinaddr);
jaddbits256(item,"txid",utxo->payment.txid);
jaddnum(item,"vout",utxo->payment.vout);
jadd64bits(item,"value",utxo->payment.value);
jadd64bits(item,"satoshis",utxo->S.satoshis);
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
if ( bits256_nonz(u.txid) != 0 )
{
jaddbits256(item,"txid2",u.txid);
jaddnum(item,"vout2",u.vout);
jadd64bits(item,"value2",u.value);
}
if ( utxo->T.swappending != 0 )
jaddnum(item,"pending",utxo->T.swappending);
if ( utxo->iambob != 0 )
{
jaddbits256(item,"srchash",utxo->pubkey);//LP_mypub25519);
if ( bits256_nonz(utxo->S.otherpubkey) != 0 )
jaddbits256(item,"desthash",utxo->S.otherpubkey);
}
else
{
jaddbits256(item,"desthash",utxo->pubkey);//LP_mypub25519);
if ( bits256_nonz(utxo->S.otherpubkey) != 0 )
jaddbits256(item,"srchash",utxo->S.otherpubkey);
}
//if ( utxo->S.swap != 0 )
// jaddstr(item,"swap","in progress");
if ( utxo->T.spentflag != 0 )
jaddnum(item,"spent",utxo->T.spentflag);
jaddnum(item,"session",utxo->T.sessionid);
return(item);
}
cJSON *LP_utxojson(struct LP_utxoinfo *utxo)
{
cJSON *item = cJSON_CreateObject();
item = LP_inventoryjson(item,utxo);
jaddbits256(item,"pubkey",utxo->pubkey);
//jaddnum(item,"profit",utxo->S.profitmargin);
jaddstr(item,"base",utxo->coin);
//jaddstr(item,"script",utxo->spendscript);
return(item);
}
struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis)
{
uint64_t srcvalue,srcvalue2; struct LP_utxoinfo *utxo,*tmp,*bestutxo = 0; int32_t bestsize,iambob = 0;
if ( symbol == 0 || destsatoshis == 0 )
{
printf("LP_utxo_bestfit error symbol.%p %.8f\n",symbol,dstr(destsatoshis));
return(0);
}
HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp)
{
if ( strcmp(symbol,utxo->coin) != 0 )
continue;
if ( LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 )
{
//printf("(%.8f %.8f %.8f)\n",dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis));
//char str[65]; printf("s%u %d [%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",utxo->T.spentflag,LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout),dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis);
bestsize = 0;
if ( bestutxo == 0 )
{
if ( utxo->S.satoshis > destsatoshis/LP_MINCLIENTVOL )
bestsize = 1;
}
else
{
if ( bestutxo->S.satoshis < destsatoshis )
{
if ( utxo->S.satoshis > destsatoshis )
bestsize = 1;
else if ( utxo->S.satoshis > bestutxo->S.satoshis )
bestsize = 1;
}
else
{
if ( utxo->S.satoshis > destsatoshis && utxo->S.satoshis < bestutxo->S.satoshis )
bestsize = 1;
}
}
if ( bestsize > 0 )
{
//printf("bestsize.%d %.8f %.8f -> %.8f\n",bestsize,dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis));
if ( LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout) == 0 )
{
//if ( utxo->T.spentflag == 0 )
// utxo->T.spentflag = (uint32_t)time(NULL);
continue;
}
bestutxo = utxo;
} //else printf("skip alice utxo %.8f vs dest %.8f, bestsize.%d %p\n",dstr(utxo->S.satoshis),dstr(destsatoshis),bestsize,bestutxo);
}
}
return(bestutxo);
}
void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector)
{
if ( utxo == 0 )
return;
utxo->T.spentflag = (uint32_t)time(NULL);
}
struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid,uint64_t satoshis)
{
uint64_t val,val2=0,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0;
if ( symbol == 0 || symbol[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 )//|| sessionid == 0 )
{
char str[65],str2[65]; printf("REJECT (%s) iambob.%d %s utxoadd.(%.8f %.8f) %s/v%d %s/v%d\n",coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2);
printf("session.%u addutxo %d %d %d %d %d %d %d %d\n",sessionid,symbol == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(txid2) == 0,vout < 0,vout2 < 0,value <= 0,value2 <= 0);
return(0);
}
if ( (coin= LP_coinfind(symbol)) == 0 || (IAMLP == 0 && coin->inactive != 0) )
{
//printf("LP_utxoadd reject inactive %s\n",symbol);
return(0);
}
txfee = LP_txfeecalc(coin,0,0);
/*if ( iambob != 0 && value2 < 9 * (satoshis >> 3) + 2*txfee ) // big txfee padding
{
if ( value2 > 2*txfee )
tmpsatoshis = (((value2 - 2*txfee) / 9) << 3);
else
{
printf("value2 %.8f <= 2 * %.8f\n",dstr(value2),dstr(txfee));
return(0);
}
} else tmpsatoshis = (satoshis - txfee);*/
char str[65],str2[65],dispflag = 0;//(iambob == 0);
if ( iambob == 0 && bits256_cmp(pubkey,G.LP_mypub25519) != 0 )
{
printf("trying to add Alice utxo when not mine? %s/v%d\n",bits256_str(str,txid),vout);
return(0);
}
if ( coin->inactive == 0 )
{
if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,satoshis,txid2,vout2) <= 0 )
{
static uint32_t counter;
if ( counter++ < 3 )
printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f:%.8f, value2 %.8f:%.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(val),dstr(value2),dstr(val2),dstr(satoshis));
return(0);
}
if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid,vout,0)) <= 0 )
{
printf("LP_utxoadd reject numconfirms.%d %s.%s\n",numconfirms,symbol,bits256_str(str,txid));
return(0);
}
if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid2,vout2,0)) <= 0 )
{
printf("LP_utxoadd reject2 numconfirms.%d %s %s/v%d\n",numconfirms,symbol,bits256_str(str,txid2),vout2);
return(0);
}
}
else
{
val = value;
val2 = value2;
}
dispflag = 0;
if ( dispflag != 0 )
printf("%.8f %.8f %s iambob.%d %s utxoadd.(%.8f %.8f) %s %s\n",dstr(val),dstr(val2),coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2));
dispflag = 1;
if ( (utxo= LP_utxofinds(iambob,txid,vout,txid2,vout2)) != 0 )
{
if ( 0 && LP_ismine(utxo) == 0 )
{
char str2[65],str3[65]; printf("iambob.%d %s %s utxoadd.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,pubkey),symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2));
printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(satoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis));
}
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || satoshis != utxo->S.satoshis || vout2 != u.vout || value2 != u.value || strcmp(symbol,utxo->coin) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || bits256_cmp(pubkey,utxo->pubkey) != 0 )
{
utxo->T.errors++;
char str[65],str2[65],str3[65],str4[65],str5[65],str6[65];
if ( utxo->T.spentflag != 0 || LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) < utxo->payment.value || LP_txvalue(0,utxo->coin,u.txid,u.vout) < u.value )
{
//if ( utxo->T.spentflag == 0 )
// utxo->T.spentflag = (uint32_t)time(NULL);
printf("original utxo pair not valid\n");
if ( dispflag != 0 )
printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,satoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey));
utxo = 0;
}
}
if ( utxo != 0 )
{
if ( utxo->T.sessionid == 0 )
utxo->T.sessionid = sessionid;
//else if ( profitmargin > SMALLVAL )
// utxo->S.profitmargin = profitmargin;
utxo->T.lasttime = (uint32_t)time(NULL);
//printf("return existing utxo[%d] %s %s\n",iambob,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid));
return(utxo);
}
}
utxo = calloc(1,sizeof(*utxo));
//utxo->S.profitmargin = profitmargin;
utxo->pubkey = pubkey;
safecopy(utxo->gui,gui,sizeof(utxo->gui));
safecopy(utxo->coin,symbol,sizeof(utxo->coin));
safecopy(utxo->coinaddr,coinaddr,sizeof(utxo->coinaddr));
//safecopy(utxo->spendscript,spendscript,sizeof(utxo->spendscript));
utxo->payment.txid = txid;
utxo->payment.vout = vout;
utxo->payment.value = value;
utxo->S.satoshis = satoshis;
if ( (utxo->iambob= iambob) != 0 )
{
utxo->deposit.txid = txid2;
utxo->deposit.vout = vout2;
utxo->deposit.value = value2;
}
else
{
utxo->fee.txid = txid2;
utxo->fee.vout = vout2;
utxo->fee.value = value2;
}
LP_utxosetkey(utxo->key,txid,vout);
LP_utxosetkey(utxo->key2,txid2,vout2);
if ( LP_ismine(utxo) > 0 )
utxo->T.sessionid = G.LP_sessionid;
else utxo->T.sessionid = sessionid;
if ( coin->inactive == 0 && (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,coinaddr,txid,vout,txid2,vout2)) >= 0 )
{
printf("utxoadd selector.%d spent in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini);
utxo->T.spentflag = (uint32_t)time(NULL);
}
//printf(" %s %.8f %.8f %p addutxo.%d (%s %s) session.%u iambob.%d <<<<<<<<<<<<<<< %.8f\n",symbol,dstr(value),dstr(value2),utxo,LP_ismine(utxo) > 0,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid),utxo->T.sessionid,iambob,dstr(satoshis));
portable_mutex_lock(&LP_utxomutex);
HASH_ADD_KEYPTR(hh,G.LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo);
if ( _LP_utxo2find(iambob,txid2,vout2) == 0 )
HASH_ADD_KEYPTR(hh2,G.LP_utxoinfos2[iambob],utxo->key2,sizeof(utxo->key2),utxo);
portable_mutex_unlock(&LP_utxomutex);
if ( iambob != 0 )
{
if ( LP_ismine(utxo) > 0 )
{
//LP_utxo_clientpublish(utxo);
if ( LP_mypeer != 0 )
utxo->T.lasttime = (uint32_t)time(NULL);
}
}
return(utxo);
}
int32_t _LP_utxos_remove(bits256 txid,int32_t vout)
{
struct LP_utxoinfo *utxo,*utxo2; int32_t retval = 0,iambob = 1;
utxo = utxo2 = 0;
if ( (utxo= _LP_utxofind(iambob,txid,vout)) != 0 )
{
if ( LP_isavailable(utxo) == 0 )
retval = -1;
else
{
if ( (utxo2= _LP_utxo2find(iambob,txid,vout)) != 0 )
{
if ( LP_isavailable(utxo) == 0 )
retval = -1;
else
{
_LP_utxo_delete(iambob,utxo);
_LP_utxo2_delete(iambob,utxo2);
}
}
}
}
else if ( (utxo2= _LP_utxo2find(iambob,txid,vout)) != 0 )
{
if ( LP_isavailable(utxo2) == 0 )
retval = -1;
else _LP_utxo2_delete(iambob,utxo2);
}
return(retval);
}
int32_t LP_utxos_remove(bits256 txid,int32_t vout)
{
int32_t retval;
portable_mutex_lock(&LP_utxomutex);
retval = _LP_utxos_remove(txid,vout);
portable_mutex_unlock(&LP_utxomutex);
return(retval);
}
cJSON *LP_inventory(char *symbol)
{
struct LP_utxoinfo *utxo,*tmp; struct _LP_utxoinfo u; char *myipaddr; cJSON *array; uint64_t val,val2; int32_t iambob = 0; struct iguana_info *coin;
array = cJSON_CreateArray();
if ( LP_mypeer != 0 )
myipaddr = LP_mypeer->ipaddr;
else myipaddr = "127.0.0.1";
if ( (coin= LP_coinfind(symbol)) != 0 )
LP_listunspent_both(symbol,coin->smartaddr,0);
HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp)
{
char str[65];
//printf("iambob.%d iterate %s\n",iambob,bits256_str(str,LP_mypub25519));
if ( LP_isunspent(utxo) != 0 && strcmp(symbol,utxo->coin) == 0 && utxo->iambob == iambob && LP_ismine(utxo) > 0 )
{
u = (iambob != 0) ? utxo->deposit : utxo->fee;
if ( LP_iseligible(&val,&val2,iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,u.txid,u.vout) == 0 )
{
//if ( utxo->T.spentflag == 0 )
// utxo->T.spentflag = (uint32_t)time(NULL);
//printf("%s %s ineligible %.8f %.8f\n",utxo->coin,bits256_str(str,u.txid),dstr(val),dstr(val2));
continue;
}
//if ( iambob != 0 )
// LP_utxo_clientpublish(utxo);
jaddi(array,LP_inventoryjson(cJSON_CreateObject(),utxo));
}
else if ( 0 && LP_ismine(utxo) > 0 && strcmp(symbol,utxo->coin) == 0 )
printf("skip %s %s %d %d %d %d\n",utxo->coin,bits256_str(str,utxo->payment.txid),LP_isunspent(utxo) != 0,strcmp(symbol,utxo->coin) == 0,utxo->iambob == iambob,LP_ismine(utxo) > 0);
}
return(array);
}
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(int32_t iambob,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 ( iambob != 0 && dist < 0 && -dist < values[i]/10 )
dist = -dist;
//printf("(%.8f %.8f %.8f).%d ",dstr(values[i]),dstr(dist),dstr(mindist),mini);
if ( dist >= 0 && dist < mindist )
{
mini = i;
mindist = dist;
}
}
return(mini);
}
int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub)
{
int32_t enable_utxos = 0;
char *script,destaddr[64]; struct LP_utxoinfo *utxo; cJSON *array,*item; bits256 txid,deposittxid; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,biggerval,value,total = 0; int64_t targetval;
if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) )
{
//printf("coin not active\n");
return(0);
}
if ( coin->privkeydepth > 0 )
return(0);
coin->privkeydepth++;
LP_address(coin,coin->smartaddr);
if ( coin->inactive == 0 )
LP_listunspent_issue(coin->symbol,coin->smartaddr,0);
array = LP_listunspent(coin->symbol,coin->smartaddr);
if ( array != 0 )
{
txfee = LP_txfeecalc(coin,0,0);
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
coin->numutxos = n;
//printf("LP_privkey_init %s %d\n",coin->symbol,n);
for (iambob=0; iambob<=1; iambob++)
{
if ( iambob == 0 )
values = calloc(n,sizeof(*values));
else memset(values,0,n * sizeof(*values));
used = 0;
for (i=0; i<n; i++)
{
item = jitem(array,i);
if ( coin->electrum == 0 )
{
txid = jbits256(item,"txid");
vout = juint(item,"vout");
value = LP_value_extract(item,0);
height = LP_txheight(coin,txid);//LP_getheight(coin) - jint(item,"confirmations") + 1;
}
else
{
txid = jbits256(item,"tx_hash");
vout = juint(item,"tx_pos");
value = j64bits(item,"value");
height = jint(item,"height");
}
satoshis = LP_txvalue(destaddr,coin->symbol,txid,vout);
if ( satoshis != 0 && satoshis != value )
printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest"));
if ( coin->electrum != 0 || LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 )//&& height > 0 )
{
values[i] = satoshis;
//flag += LP_address_utxoadd(coin,destaddr,txid,vout,satoshis,height,-1);
} else used++;
}
//printf("array.%d\n",n);
while ( used < n-1 )
{
//for (i=0; i<n; i++)
// printf("%.8f ",dstr(values[i]));
//printf("used.%d of n.%d\n",used,n);
if ( (i= LP_maxvalue(values,n)) >= 0 )
{
item = jitem(array,i);
if ( coin->electrum == 0 )
{
deposittxid = jbits256(item,"txid");
depositvout = juint(item,"vout");
script = jstr(item,"scriptPubKey");
}
else
{
deposittxid = jbits256(item,"tx_hash");
depositvout = juint(item,"tx_pos");
script = coin->smartaddr;
}
biggerval = values[i];
values[i] = 0, used++;
if ( iambob == 0 )
targetval = (biggerval / 776) + txfee;
else targetval = (biggerval / 9) * 8 + 2*txfee;
if ( targetval < txfee*2 )
targetval = txfee*2;
//printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(biggerval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval));
if ( biggerval < (1+LP_MINSIZE_TXFEEMULT)*txfee )
continue;
i = -1;
if ( iambob != 0 )
{
if ( (i= LP_nearestvalue(iambob,values,n,targetval)) < 0 )
targetval /= 4;
if ( targetval < txfee*(1+LP_MINSIZE_TXFEEMULT) )
continue;
}
if ( i >= 0 || (i= LP_nearestvalue(iambob,values,n,targetval)) >= 0 )
{
//printf("iambob.%d i.%d %.8f target %.8f\n",iambob,i,dstr(biggerval),dstr(targetval));
item = jitem(array,i);
cmpflag = 0;
if ( coin->electrum == 0 )
{
txid = jbits256(item,"txid");
vout = juint(item,"vout");
if ( jstr(item,"scriptPubKey") != 0 && strcmp(script,jstr(item,"scriptPubKey")) == 0 )
cmpflag = 1;
}
else
{
txid = jbits256(item,"tx_hash");
vout = juint(item,"tx_pos");
cmpflag = 1;
}
if ( cmpflag != 0 )
{
value = values[i];
values[i] = 0, used++;
portable_mutex_lock(&LP_UTXOmutex);
if ( iambob != 0 )
{
if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,biggerval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 )
{
}
}
else
{
//printf("call utxoadd\n");
if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,biggerval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,biggerval)) != 0 )
{
}
}
portable_mutex_unlock(&LP_UTXOmutex);
total += value;
} // else printf("scriptmismatch.(%s) vs %s\n",script,jprint(item,0));
} //else printf("nothing near i.%d\n",i);
} else break;
}
if ( enable_utxos == 0 )
break;
}
}
free_json(array);
if ( 0 && flag != 0 )
LP_postutxos(coin->symbol,coin->smartaddr);
}
if ( values != 0 )
free(values);
if ( coin->privkeydepth > 0 )
coin->privkeydepth--;
//printf("privkey.%s %.8f\n",symbol,dstr(total));
return(flag);
}
char *LP_secretaddresses(void *ctx,char *prefix,char *passphrase,int32_t n,uint8_t taddr,uint8_t pubtype)
{
int32_t i; uint8_t tmptype,pubkey33[33],rmd160[20]; char output[777*45],str[65],str2[65],buf[8192],wifstr[128],coinaddr[64]; bits256 checkprivkey,privkey,pubkey; cJSON *retjson;
retjson = cJSON_CreateObject();
if ( prefix == 0 || prefix[0] == 0 )
prefix = "secretaddress";
if ( passphrase == 0 || passphrase[0] == 0 )
passphrase = "password";
if ( n <= 0 )
n = 16;
else if ( n > 777 )
n = 777;
conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,taddr,pubtype);
printf("generator (%s) secrets.[%d] <%s> t.%u p.%u\n",coinaddr,n,passphrase,taddr,pubtype);
sprintf(output,"\"addresses\":[");
for (i=0; i<n; i++)
{
sprintf(buf,"%s %s %03d",prefix,passphrase,i);
conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)buf,(int32_t)strlen(buf));
bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,taddr,pubtype);
bitcoin_priv2wif(0,wifstr,privkey,188);
bitcoin_wif2priv(0,&tmptype,&checkprivkey,wifstr);
bitcoin_addr2rmd160(taddr,&tmptype,rmd160,coinaddr);
if ( bits256_cmp(checkprivkey,privkey) != 0 )
{
printf("WIF.(%s) error -> %s vs %s?\n",wifstr,bits256_str(str,privkey),bits256_str(str2,checkprivkey));
free_json(retjson);
return(clonestr("{\"error\":\"couldnt validate wifstr\"}"));
}
else if ( tmptype != pubtype )
{
printf("checktype.%d != pubtype.%d\n",tmptype,pubtype);
free_json(retjson);
return(clonestr("{\"error\":\"couldnt validate pubtype\"}"));
}
jaddstr(retjson,coinaddr,wifstr);
sprintf(output+strlen(output),"\\\"%s\\\"%c ",coinaddr,i<n-1?',':' ');
printf("./komodo-cli jumblr_secret %s\n",coinaddr);
}
printf("%s]\n",output);
return(jprint(retjson,1));
}
bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguana_info *coin,char *passphrase,char *wifstr)
{
//static uint32_t counter;
bits256 privkey,userpub,userpass,checkkey; char tmpstr[128]; cJSON *retjson; uint8_t tmptype;
if ( passphrase != 0 && passphrase[0] != 0 )
{
conv_NXTpassword(privkey.bytes,pubkeyp->bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
//vcalc_sha256(0,checkkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
//printf("SHA256.(%s) ",bits256_str(pstr,checkkey));
//printf("privkey.(%s)\n",bits256_str(pstr,privkey));
}
else
{
bitcoin_wif2priv(coin->wiftaddr,&tmptype,&privkey,wifstr);
if ( 0 )
{
char str[65],str2[65];
checkkey = iguana_wif2privkey(wifstr);
if ( bits256_cmp(checkkey,privkey) != 0 )
printf("WIF.(%s) -> %s or %s?\n",wifstr,bits256_str(str,privkey),bits256_str(str2,checkkey));
}
}
privkey.bytes[0] &= 248, privkey.bytes[31] &= 127, privkey.bytes[31] |= 64;
bitcoin_priv2pub(ctx,coin->pubkey33,coin->smartaddr,privkey,coin->taddr,coin->pubtype);
if ( coin->counter == 0 )
{
coin->counter++;
memcpy(G.LP_pubsecp,coin->pubkey33,33);
bitcoin_priv2wif(coin->wiftaddr,tmpstr,privkey,coin->wiftype);
bitcoin_addr2rmd160(coin->taddr,&tmptype,G.LP_myrmd160,coin->smartaddr);
LP_privkeyadd(privkey,G.LP_myrmd160);
G.LP_privkey = privkey;
if ( 0 && (coin->pubtype != 60 || strcmp(coin->symbol,"KMD") == 0) )
printf("%s (%s) %d wif.(%s) (%s)\n",coin->symbol,coin->smartaddr,coin->pubtype,tmpstr,passphrase);
if ( G.counter++ == 0 )
{
bitcoin_priv2wif(coin->wiftaddr,G.USERPASS_WIFSTR,privkey,188);
bitcoin_wif2priv(coin->wiftaddr,&tmptype,&checkkey,G.USERPASS_WIFSTR);
if ( bits256_cmp(checkkey,privkey) != 0 )
{
char str[65],str2[65];
printf("FATAL ERROR converting USERPASS_WIFSTR %s -> %s != %s\n",G.USERPASS_WIFSTR,bits256_str(str,checkkey),bits256_str(str2,privkey));
exit(-1);
}
conv_NXTpassword(userpass.bytes,pubkeyp->bytes,(uint8_t *)G.USERPASS_WIFSTR,(int32_t)strlen(G.USERPASS_WIFSTR));
userpub = curve25519(userpass,curve25519_basepoint9());
printf("userpass.(%s)\n",bits256_str(G.USERPASS,userpub));
}
}
if ( coin->importedprivkey == 0 && coin->electrum == 0 && coin->userpass[0] != 0 && LP_getheight(coin) > 0 )
{
LP_listunspent_issue(coin->symbol,coin->smartaddr,0);
if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 )
{
if ( jobj(retjson,"error") != 0 )
{
printf("cant importprivkey.%s -> (%s), abort session\n",coin->symbol,jprint(retjson,1));
exit(-1);
}
free_json(retjson);
}
coin->importedprivkey = (uint32_t)time(NULL);
}
vcalc_sha256(0,checkkey.bytes,privkey.bytes,sizeof(privkey));
checkkey.bytes[0] &= 248, checkkey.bytes[31] &= 127, checkkey.bytes[31] |= 64;
G.LP_mypub25519 = *pubkeyp = curve25519(checkkey,curve25519_basepoint9());
G.LP_mypriv25519 = checkkey;
LP_pubkeyadd(G.LP_mypub25519);
return(privkey);
}
void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase)
{
struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33]; int32_t initonly;
initonly = (passphrase != 0);
memset(privkey.bytes,0,sizeof(privkey));
memset(pubkey.bytes,0,sizeof(pubkey));
//printf("Total coins: %d\n", HASH_COUNT(LP_coins));
//int num_iter = 0;
HASH_ITER(hh,LP_coins,coin,tmp)
{
//printf("LP_privkey_updates [%02d / %02d]\n", num_iter++, HASH_COUNT(LP_coins));
if ( initonly != 0 )
{
coin->counter = 0;
memset(coin->smartaddr,0,sizeof(coin->smartaddr));
if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 )
privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,"");
}
//printf("i.%d of %d\n",i,LP_numcoins);
else if ( IAMLP == 0 || coin->inactive == 0 )
{
//printf("from updates %s\n",coin->symbol);
if ( LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (LP_rand() % 10) == 0 )
{
//LP_postutxos(coin->symbol,coin->smartaddr);
}
}
}
}
int32_t LP_passphrase_init(char *passphrase,char *gui)
{
static void *ctx; int32_t iambob,counter; struct LP_utxoinfo *utxo,*tmp;
if ( ctx == 0 )
ctx = bitcoin_ctx();
if ( G.LP_pendingswaps != 0 )
return(-1);
G.initializing = 1;
if ( gui == 0 )
gui = "cli";
counter = G.USERPASS_COUNTER;
while ( G.waiting == 0 )
{
printf("waiting for G.waiting\n");
sleep(5);
}
for (iambob=0; iambob<2; iambob++)
{
if ( G.LP_utxoinfos[iambob] != 0 )
{
HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp)
{
HASH_DELETE(hh,G.LP_utxoinfos[iambob],utxo);
//free(utxo);
}
}
if ( G.LP_utxoinfos2[iambob] != 0 )
{
G.LP_utxoinfos2[iambob] = 0;
/*HASH_ITER(hh,G.LP_utxoinfos2[iambob],utxo,tmp)
{
HASH_DELETE(hh,G.LP_utxoinfos2[iambob],utxo);
free(utxo);
}*/
}
}
memset(&G,0,sizeof(G));
LP_privkey_updates(ctx,LP_mypubsock,passphrase);
init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20);
G.LP_sessionid = (uint32_t)time(NULL);
safecopy(G.gui,gui,sizeof(G.gui));
G.USERPASS_COUNTER = counter;
G.initializing = 0;
return(0);
}

2
iguana/exchanges/auto_chipsbtc

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

2
iguana/exchanges/auto_chipskmd

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

3
iguana/exchanges/autofill

@ -1,3 +0,0 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autofill\",\"base\":\"KMD\",\"rel\":\"BTC\",\"price\":0.0005,\"relvolume\":0.1}"

3
iguana/exchanges/autotrade

@ -1,3 +0,0 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autotrade\",\"base\":\"REVS\",\"rel\":\"KMD\",\"relvolume\":1.01,\"price\":1.234}"

3
iguana/exchanges/balances

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

4
iguana/exchanges/bots

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
# this will only work for watchonly addresses that have been rescanned and with active coins
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RNdqHx26GWy9bk8MtmH1UiXjQcXE4RKK2P\",\"divisor\":1000000}"

3
iguana/exchanges/claim

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

5
iguana/exchanges/coins

File diff suppressed because one or more lines are too long

5
iguana/exchanges/coins.json

File diff suppressed because one or more lines are too long

3
iguana/exchanges/deposit1

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"instantdex_deposit\",\"weeks\":1,\"amount\":10.0,\"broadcast\":1}"

3
iguana/exchanges/deposit10

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"instantdex_deposit\",\"weeks\":10,\"amount\":10.0,\"broadcast\":1}"

4
iguana/exchanges/dex

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
# this will only work for watchonly addresses that have been rescanned and with active coins
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf\",\"divisor\":1000000}"

3
iguana/exchanges/dynamictrust

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

17
iguana/exchanges/enable

@ -1,5 +1,18 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"REVS\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"CHIPS\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"MNZ\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BTC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"SUPERNET\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"CRYPTO\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"DEX\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BOTS\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BET\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"HODL\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"MSHARK\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"MGW\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"PANGEA\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"JUMBLR\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"HUSH\",\"ipaddr\":\"173.212.225.176\",\"port\":50013}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"BTCH\",\"ipaddr\":\"electrum1.cipig.net\",\"port\":10020}"

4
iguana/exchanges/fundvalue

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
# this will only work for watchonly addresses that have been rescanned and with active coins
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":650000}"

15
iguana/exchanges/get_supernet

@ -0,0 +1,15 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"REVS\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"CHIPS\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"KMD\",\"rel\":\"BTC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"SUPERNET\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"CRYPTO\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"DEX\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"BOTS\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"BET\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"HODL\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"MSHARK\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"MGW\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"PANGEA\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"JUMBLR\",\"rel\":\"KMD\"}"

4
iguana/exchanges/hodl

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
# this will only work for watchonly addresses that have been rescanned and with active coins
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RNcUaMUEFLxVwtTo7rgruhwYanGk1jTkeU\",\"holdings\":[{\"coin\":\"siacoin\",\"balance\":185000000,\"comment\":\"using siafunds equal to million siacoin\"}],\"divisor\":10000000}"

2
iguana/exchanges/install

@ -1,5 +1,5 @@
#!/bin/bash
cp invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js trust trusted setconfirms balance listunspent electrum snapshot_balance snapshot_loop secretaddresses dividends snapshot goals goal portfolio autoprice deletemessages getmessages debug buy sell bestfit orderbook client run_osx client_osx run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices help inv setprice status ../dexscripts
cp install get_supernet trackbtc auto_chipskmd auto_chipsbtc pendingswaps fundvalue balances dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js trust trusted setconfirms balance listunspent electrum snapshot_balance snapshot_loop secretaddresses dividends snapshot goals goal portfolio autoprice deletemessages getmessages debug buy sell bestfit orderbook client run_osx client_osx run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices help inv setprice status ../dexscripts
cp coins.json ..
cd ../dexscripts
#cp ../exchanges/passphrase ../exchanges/userpass .

4
iguana/exchanges/jumblr

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
# this will only work for watchonly addresses that have been rescanned and with active coins
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RGhxXpXSSBTBm9EvNsXnTQczthMCxHX91t\",\"divisor\":1000000}"

3
iguana/exchanges/kickstart

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"KMD\",\"ipaddr\":\"\",\"port\":0}"

943
iguana/exchanges/mm 17740.c

@ -0,0 +1,943 @@
/******************************************************************************
* 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. *
* *
******************************************************************************/
//
// main.c
// marketmaker
//
// Copyright © 2017 SuperNET. All rights reserved.
//
void PNACL_message(char *arg,...)
{
}
#define FROM_MARKETMAKER
#include <stdio.h>
#include <stdint.h>
#ifndef NATIVE_WINDOWS
#include "OS_portable.h"
#else
#include "../../crypto777/OS_portable.h"
#endif // !_WIN_32
uint32_t DOCKERFLAG;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port);
#include "stats.c"
void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]);
//defined(__APPLE__) ||
#ifdef FROM_JS // defined(WIN32) || defined(USE_STATIC_NANOMSG)
#include "../../crypto777/nanosrc/nn.h"
#include "../../crypto777/nanosrc/bus.h"
#include "../../crypto777/nanosrc/pubsub.h"
#include "../../crypto777/nanosrc/pipeline.h"
#include "../../crypto777/nanosrc/reqrep.h"
#include "../../crypto777/nanosrc/tcp.h"
#include "../../crypto777/nanosrc/pair.h"
#else
#if defined(WIN32) || defined(USE_STATIC_NANOMSG)
#include "../../crypto777/nanosrc/nn.h"
#include "../../crypto777/nanosrc/bus.h"
#include "../../crypto777/nanosrc/pubsub.h"
#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"
#include "/usr/local/include/nanomsg/pubsub.h"
#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
#endif
char DEX_baseaddr[64],DEX_reladdr[64];
struct mmpending_order
{
double price,volume;
int32_t dir;
uint32_t pending,completed,canceled,cancelstarted,reported;
cJSON *errorjson;
char exchange[16],base[65],rel[65],orderid[64];
} *Pending_orders;
int32_t Num_Pending;
#define IGUANA_URL "http://127.0.0.1:7778"
/*char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies
"CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies
};*/
double PAXPRICES[sizeof(CURRENCIES)/sizeof(*CURRENCIES)];
uint32_t PAXACTIVE;
char *DEX_swapstatus()
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"getswaplist\"}");
return(bitcoind_RPC(0,"InstantDEX",url,0,"getswaplist",postdata,0));
}
char *DEX_amlp(char *blocktrail)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"amlp\",\"blocktrail\":\"%s\"}",blocktrail);
return(bitcoind_RPC(0,"tradebot",url,0,"amlp",postdata,0));
}
char *DEX_openorders(char *exchange)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"openorders\",\"exchange\":\"%s\"}",exchange);
return(bitcoind_RPC(0,"InstantDEX",url,0,"openorders",postdata,0));
}
char *DEX_tradehistory(char *exchange)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"tradehistory\",\"exchange\":\"%s\"}",exchange);
return(bitcoind_RPC(0,"InstantDEX",url,0,"tradehistory",postdata,0));
}
char *DEX_orderstatus(char *exchange,char *orderid)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"orderstatus\",\"exchange\":\"%s\",\"orderid\":\"%s\"}",exchange,orderid);
return(bitcoind_RPC(0,"InstantDEX",url,0,"orderstatus",postdata,0));
}
char *DEX_cancelorder(char *exchange,char *orderid)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"cancelorder\",\"exchange\":\"%s\",\"orderid\":\"%s\"}",exchange,orderid);
return(bitcoind_RPC(0,"InstantDEX",url,0,"cancelorder",postdata,0));
}
char *DEX_balance(char *exchange,char *base,char *coinaddr)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
if ( strcmp(exchange,"DEX") == 0 )
{
sprintf(postdata,"{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"%s\",\"symbol\":\"%s\"}",coinaddr,base);
return(bitcoind_RPC(0,"dex",url,0,"getbalance",postdata,0));
}
else
{
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"balance\",\"exchange\":\"%s\",\"base\":\"%s\"}",exchange,base);
return(bitcoind_RPC(0,"InstantDEX",url,0,"balance",postdata,0));
}
}
char *DEX_apikeypair(char *exchange,char *apikey,char *apisecret)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"apikeypair\",\"exchange\":\"%s\",\"apikey\":\"%s\",\"apisecret\":\"%s\"}",exchange,apikey,apisecret);
return(bitcoind_RPC(0,"InstantDEX",url,0,"apikeypair",postdata,0));
}
char *DEX_setuserid(char *exchange,char *userid,char *tradepassword)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"setuserid\",\"exchange\":\"%s\",\"userid\":\"%s\",\"tradepassword\":\"%s\"}",exchange,userid,tradepassword);
return(bitcoind_RPC(0,"InstantDEX",url,0,"setuserid",postdata,0));
}
char *DEX_trade(char *exchange,char *base,char *rel,int32_t dir,double price,double volume)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"%s\",\"exchange\":\"%s\",\"base\":\"%s\",\"rel\":\"%s\",\"price\":%.8f,\"volume\":%.8f,\"dotrade\":1}",dir>0?"buy":"sell",exchange,base,rel,price,volume);
//printf("DEX_trade.(%s)\n",postdata);
return(bitcoind_RPC(0,"InstantDEX",url,0,dir>0?"buy":"sell",postdata,0));
}
char *DEX_withdraw(char *exchange,char *base,char *destaddr,double amount)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"withdraw\",\"exchange\":\"%s\",\"destaddr\":\"%s\",\"amount\":%.8f}",exchange,destaddr,amount);
return(bitcoind_RPC(0,"InstantDEX",url,0,"withdraw",postdata,0));
}
char *iguana_walletpassphrase(char *passphrase,int32_t timeout)
{
char url[512],postdata[1024];
sprintf(url,"%s/coin=KMD&agent=bitcoinrpc&method=walletpassphrase?",IGUANA_URL);
sprintf(postdata,"[\"%s\", %d]",passphrase,timeout);
return(bitcoind_RPC(0,"",url,0,"walletpassphrase",postdata,0));
}
/*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,int32_t numpeers)
{
char url[512];
sprintf(url,"http://%s:%u/api/stats/intro?ipaddr=%s&port=%u&numpeers=%d",destip,destport,ipaddr,port,numpeers);
printf("(%s)\n",url);
return(issue_curl(url));
}*/
//
// http://127.0.0.1:7779/api/stats/getpeers
char *DEX_listunspent(char *coin,char *coinaddr)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"%s\",\"symbol\":\"%s\",\"timeout\":60000}",coinaddr,coin);
return(bitcoind_RPC(0,"dex",url,0,"listunspent",postdata,0));
}
bits256 iguana_wif2privkey(char *wifstr)
{
char url[512],postdata[1024],*retstr,*privstr; bits256 privkey; cJSON *retjson;
memset(privkey.bytes,0,sizeof(privkey));
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"SuperNET\",\"method\":\"wif2priv\",\"wif\":\"%s\"}",wifstr);
if ( (retstr= bitcoind_RPC(0,"SuperNET",url,0,"wif2priv",postdata,0)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (privstr= jstr(retjson,"privkey")) != 0 )
{
if ( strlen(privstr) == 64 )
decode_hex(privkey.bytes,32,privstr);
}
free_json(retjson);
}
free(retstr);
}
return(privkey);
}
double bittrex_balance(char *base,char *coinaddr)
{
char *retstr; cJSON *retjson; double balance = 0.;
if ( (retstr= DEX_balance("bittrex",base,coinaddr)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
balance = jdouble(retjson,"balance");
free_json(retjson);
}
free(retstr);
}
return(balance);
}
double dex_balance(char *base,char *coinaddr)
{
char *retstr; cJSON *retjson; double balance = 0.;
if ( (retstr= DEX_balance("DEX",base,coinaddr)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
balance = jdouble(retjson,"balance");
free_json(retjson);
}
free(retstr);
}
return(balance);
}
int32_t komodo_baseid(char *base)
{
int32_t i;
for (i=0; i<sizeof(CURRENCIES)/sizeof(*CURRENCIES); i++)
if ( strcmp(base,CURRENCIES[i]) == 0 )
return(i);
return(-1);
}
cJSON *yahoo_allcurrencies()
{
char *retstr; cJSON *retjson = 0;
if ( (retstr= issue_curl("http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json")) != 0 )
{
retjson = cJSON_Parse(retstr);
free(retstr);
}
return(retjson);
}
void _marketmaker_fiatupdate(int32_t baseid,double price)
{
PAXPRICES[baseid] = price * PAXPRICES[0];
printf("%.6f %s per USD, %.8f %s per KMD\n",price,CURRENCIES[baseid],PAXPRICES[baseid],CURRENCIES[baseid]);
}
uint32_t marketmaker_fiatupdate(cJSON *fiatjson)
{
int32_t i,n,baseid; cJSON *item,*array; double price; char *name; uint64_t mask = 0;
fiatjson = jobj(fiatjson,"list");
if ( fiatjson != 0 && (array= jarray(&n,fiatjson,"resources")) > 0 )
{
for (i=0; i<n; i++)
{
/*
"resource" : {
"classname" : "Quote",
"fields" : {
"name" : "USD/BRX",
"price" : "3.063200",
"symbol" : "BRX=X",
"ts" : "1487866204",
"type" : "currency",
"utctime" : "2017-02-23T16:10:04+0000",
"volume" : "0"
}
*/
item = jitem(array,i);
if ( (item= jobj(item,"resource")) != 0 )
item = jobj(item,"fields");
if ( item != 0 )
{
price = jdouble(item,"price");
if ( price > SMALLVAL && (name= jstr(item,"name")) != 0 && strncmp(name,"USD/",4) == 0 )
{
if ( (baseid= komodo_baseid(name+4)) >= 0 && baseid < 32 )
{
if ( ((1LL << baseid) & mask) == 0 )
{
_marketmaker_fiatupdate(baseid,price);
mask |= (1LL << baseid);
} else if ( fabs(price*PAXPRICES[0] - PAXPRICES[baseid]) > SMALLVAL )
printf("DUPLICATE PRICE? %s %.8f vs %.8f\n",name+4,price*PAXPRICES[0],PAXPRICES[baseid]);
}
}
}
}
}
printf("pax mask.%x\n",(uint32_t)mask);
return((uint32_t)mask);
}
void marketmaker_cancel(struct mmpending_order *ptr)
{
char *retstr; cJSON *retjson;
if ( ptr->pending != 0 && ptr->cancelstarted == 0 )
{
ptr->cancelstarted = (uint32_t)time(NULL);
if ( (retstr= DEX_cancelorder(ptr->exchange,ptr->orderid)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
printf("cancel %s (%s/%s) %.8f vol %.8f dir.%d -> (%s)\n",ptr->exchange,ptr->base,ptr->rel,ptr->price,ptr->volume,ptr->dir,jprint(retjson,0));
free_json(retjson);
ptr->pending = 0;
ptr->canceled = (uint32_t)time(NULL);
}
free(retstr);
}
}
}
void marketmaker_queue(char *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *retjson)
{
struct mmpending_order *ptr; char *orderid;
//DEX_trade.({"success":true,"message":"","result":{"uuid":"d5faa9e4-660d-436f-a257-2c6a40442d8c"},"tag":"11271578410079391025"}
if ( is_cJSON_True(jobj(retjson,"success")) != 0 && jobj(retjson,"result") != 0 )
retjson = jobj(retjson,"result");
printf("QUEUE.%s %s/%s dir.%d %.8f %.6f (%s)\n",exchange,base,rel,dir,price,volume,jprint(retjson,0));
Pending_orders = realloc(Pending_orders,(1 + Num_Pending) * sizeof(*Pending_orders));
ptr = &Pending_orders[Num_Pending++];
memset(ptr,0,sizeof(*ptr));
ptr->price = price;
ptr->volume = volume;
ptr->dir = dir;
ptr->pending = (uint32_t)time(NULL);
strcpy(ptr->exchange,exchange);
strcpy(ptr->base,base);
strcpy(ptr->rel,rel);
if ( (orderid= jstr(retjson,"OrderUuid")) != 0 || (orderid= jstr(retjson,"uuid")) != 0 )
strcpy(ptr->orderid,orderid);
else strcpy(ptr->orderid,"0");
}
void marketmaker_pendingupdate(char *exchange,char *base,char *rel)
{
char *retstr; cJSON *retjson,*obj; int32_t i; struct mmpending_order *ptr;
for (i=0; i<Num_Pending; i++)
{
ptr = &Pending_orders[i];
if ( strcmp(exchange,ptr->exchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 )
continue;
if ( ptr->completed == 0 && (retstr= DEX_orderstatus(exchange,ptr->orderid)) != 0 )
{
//printf("%s status.(%s)\n",ptr->orderid,retstr);
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
obj = jobj(retjson,"result");
if ( is_cJSON_Array(obj) != 0 )
obj = jitem(retjson,0);
if ( jdouble(obj,"QuantityRemaining") == 0. || is_cJSON_True(jobj(obj,"IsOpen")) == 0 )
{
//{"Uuid":null,"OrderUuid":"e7b0789c-0c4e-413b-a768-3d5734d9cbe5","Exchange":"BTC-KMD","OrderType":"LIMIT_SELL","Quantity":877.77700000,"QuantityRemaining":462.50512234,"Limit":0.00011770,"CommissionPaid":0.00012219,"Price":0.04887750,"PricePerUnit":0.00011769,"Opened":"2017-02-20T13:16:22.29","Closed":null,"CancelInitiated":false,"ImmediateOrCancel":false,"IsConditional":false,"Condition":"NONE","ConditionTarget":null} printf("uuid.(%s) finished.(%s)\n",ptr->orderid,jprint(retjson,0));
ptr->completed = (uint32_t)time(NULL);
ptr->pending = 0;
}
free_json(retjson);
}
free(retstr);
}
}
}
void marketmaker_pendinginit(char *exchange,char *base,char *rel)
{
char *retstr,*orderid,*pairstr,relbase[65]; cJSON *retjson,*array,*item; int32_t i,j,n,dir; struct mmpending_order *ptr;
sprintf(relbase,"%s-%s",rel,base);
if ( (retstr= DEX_openorders(exchange)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
//printf("%s\n",jprint(retjson,0));
if ( is_cJSON_True(jobj(retjson,"success")) != 0 && (array= jarray(&n,retjson,"result")) != 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
if ( (pairstr= jstr(item,"Exchange")) == 0 )
continue;
if ( strcmp(pairstr,relbase) != 0 )
{
printf("skip %s when %s\n",pairstr,relbase);
continue;
}
//printf("(%s)\n",jprint(item,0));
//{"success":true,"message":"","result":[{"Uuid":null,"OrderUuid":"81ad3e37-65d4-4fee-9c29-03b050f5192b","Exchange":"BTC-KMD","OrderType":"LIMIT_BUY","Quantity":885.19934578,"QuantityRemaining":885.19934578,"Limit":0.00011184,"CommissionPaid":0,"Price":0,"PricePerUnit":null,"Opened":"2017-02-19T19:14:02.94","Closed":null,"CancelInitiated":false,"ImmediateOrCancel":false,"IsConditional":false,"Condition":"NONE","ConditionTarget":null}],"tag":"10056789044100011414"}
if ( (orderid= jstr(item,"OrderUuid")) != 0 && is_cJSON_Null(jobj(item,"Closed")) != 0 && is_cJSON_False(jobj(item,"CancelInitiated")) != 0 )
{
for (j=0; j<Num_Pending; j++)
{
ptr = &Pending_orders[j];
if ( strcmp(exchange,ptr->exchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 )
continue;
if ( strcmp(ptr->orderid,orderid) == 0 )
{
ptr->pending = (uint32_t)time(NULL);
ptr->completed = 0;
printf("%s pending\n",orderid);
break;
}
}
if ( j == Num_Pending )
{
if ( jstr(item,"OrderType") != 0 )
{
if ( strcmp(jstr(item,"OrderType"),"LIMIT_BUY") == 0 )
dir = 1;
else if ( strcmp(jstr(item,"OrderType"),"LIMIT_SELL") == 0 )
dir = -1;
else dir = 0;
if ( dir != 0 )
marketmaker_queue(exchange,base,rel,dir,jdouble(item,"Limit"),jdouble(item,"QuantityRemaining"),item);
else printf("no dir (%s) (%s)\n",jprint(item,0),jstr(item,"OrderType"));
}
}
}
}
}
free_json(retjson);
}
free(retstr);
}
}
double marketmaker_filled(char *exchange,char *base,char *rel,double *buyvolp,double *sellvolp,double *pendingbidsp,double *pendingasksp)
{
double pricesum = 0.,volsum = 0.; struct mmpending_order *ptr; int32_t i;
*pendingbidsp = *pendingasksp = 0.;
for (i=0; i<Num_Pending; i++)
{
ptr = &Pending_orders[i];
if ( strcmp(exchange,ptr->exchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 )
continue;
if ( ptr->completed != 0 )
{
if ( ptr->reported == 0 )
{
if ( ptr->dir > 0 )
(*buyvolp) += ptr->volume;
else if ( ptr->dir < 0 )
(*sellvolp) += ptr->volume;
pricesum += ptr->volume * ptr->price;
volsum += ptr->volume;
ptr->reported = (uint32_t)time(NULL);
printf("REPORT dir.%d vol %.8f\n",ptr->dir,ptr->volume);
}
}
else if ( ptr->pending != 0 ) // alternative is error or cancelled
{
if ( ptr->dir > 0 )
(*pendingbidsp) += ptr->volume;
else if ( ptr->dir < 0 )
(*pendingasksp) += ptr->volume;
}
}
if ( volsum != 0. )
pricesum /= volsum;
return(pricesum);
}
int32_t marketmaker_prune(char *exchange,char *base,char *rel,int32_t polarity,double bid,double ask,double separation)
{
int32_t i,n = 0; struct mmpending_order *ptr;
for (i=0; i<Num_Pending; i++)
{
ptr = &Pending_orders[i];
if ( strcmp(exchange,ptr->exchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 )
continue;
if ( ptr->pending != 0 && ptr->cancelstarted == 0 )
{
if ( polarity != 0 )
{
if ( ((ptr->dir*polarity > 0 && ptr->price < bid-separation) || (ptr->dir*polarity < 0 && ptr->price > ask+separation)) )
{
printf("polarity.%d dir.%d price.%f bid.%f ask.%f\n",polarity,ptr->dir,ptr->price,bid,ask);
marketmaker_cancel(ptr), n++;
}
}
/*else
{,*prunebid=0,*pruneask=0; double lowbid=0.,highask=0.
if ( ptr->dir > 0 && (lowbid == 0. || ptr->price < lowbid) )
{
lowbid = ptr->price;
prunebid = ptr;
}
else if ( ptr->dir < 0 && (highask == 0. || ptr->price > highask) )
{
highask = ptr->price;
pruneask = ptr;
}
}*/
}
}
/*if ( polarity == 0 )
{
if ( prunebid != 0 && fabs(prunebid->price - bid) > separation )
marketmaker_cancel(prunebid), n++;
if ( pruneask != 0 && fabs(pruneask->price - ask) > separation )
marketmaker_cancel(pruneask), n++;
}*/
return(n);
}
void marketmaker_volumeset(double *bidincrp,double *askincrp,double incr,double buyvol,double pendingbids,double sellvol,double pendingasks,double maxexposure)
{
*bidincrp = *askincrp = incr;
//if ( pendingbids >= pendingasks+maxexposure )
// *bidincrp = 0.;
//else if ( pendingasks >= pendingbids+maxexposure )
// *askincrp = 0.;
if ( *bidincrp > 0. && pendingbids + *bidincrp > maxexposure )
*bidincrp = (maxexposure - *bidincrp);
if ( *askincrp > 0. && pendingasks + *askincrp > maxexposure )
*askincrp = (maxexposure - *askincrp);
if ( *bidincrp < 0. )
*bidincrp = 0.;
if ( *askincrp < 0. )
*askincrp = 0.;
}
int32_t marketmaker_spread(char *exchange,char *base,char *rel,double bid,double bidvol,double ask,double askvol,double separation)
{
int32_t nearflags[2],i,n = 0; struct mmpending_order *ptr; cJSON *retjson,*vals; char *retstr,postdata[1024],url[128]; double vol,spread_ratio;
memset(nearflags,0,sizeof(nearflags));
if ( strcmp("DEX",exchange) != 0 )
{
for (i=0; i<Num_Pending; i++)
{
ptr = &Pending_orders[i];
if ( strcmp(exchange,ptr->exchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 )
continue;
if ( ptr->pending != 0 && ptr->cancelstarted == 0 )
{
if ( bid > SMALLVAL && bidvol > SMALLVAL && ptr->dir > 0 && fabs(bid - ptr->price) < separation )
{
//printf("bid %.8f near %.8f\n",bid,ptr->price);
nearflags[0]++;
}
if ( ask > SMALLVAL && askvol > SMALLVAL && ptr->dir < 0 && fabs(ask - ptr->price) < separation )
{
//printf("%.8f near %.8f\n",ask,ptr->price);
nearflags[1]++;
}
}
}
}
//printf("spread.%s (%.8f %.6f) (%.8f %.6f)\n",exchange,bid,bidvol,ask,askvol);
if ( bid > SMALLVAL && bidvol > SMALLVAL && nearflags[0] == 0 )
{
if ( strcmp("DEX",exchange) == 0 && strcmp(base,"KMD") == 0 && strcmp(rel,"BTC") == 0 )
{
if ( ask > SMALLVAL && askvol > SMALLVAL )
{
/*li.profit = jdouble(vals,"profit");
li.refprice = jdouble(vals,"refprice");
li.bid = jdouble(vals,"bid");
li.ask = jdouble(vals,"ask");
if ( (li.minvol= jdouble(vals,"minvol")) <= 0. )
li.minvol = (strcmp("BTC",base) == 0) ? 0.0001 : 0.001;
if ( (li.maxvol= jdouble(vals,"maxvol")) < li.minvol )
li.maxvol = li.minvol;*/
//curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"MVP\",\"vals\":{\"rel\":\"USD\",\"bid\":0.09,\"ask\":0.11,\"maxvol\":100}}"
vals = cJSON_CreateObject();
jaddstr(vals,"rel","BTC");
jaddnum(vals,"bid",bid);
jaddnum(vals,"ask",ask);
vol = bidvol > askvol ? askvol : bidvol;
jaddnum(vals,"maxvol",vol);
jaddnum(vals,"minvol",vol*0.1 > 100 ? 100 : vol * 0.1);
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"%s\",\"vals\":%s}",base,jprint(vals,1));
//printf("(%s)\n",postdata);
if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata,0)) != 0 )
{
//printf("(%s) -> (%s)\n",postdata,retstr);
free(retstr);
}
spread_ratio = .5 * ((ask - bid) / (bid + ask));
for (i=0; i<sizeof(CURRENCIES)/sizeof(*CURRENCIES); i++)
{
if ( (PAXACTIVE & (1<<i)) == 0 )
continue;
if ( PAXPRICES[i] > SMALLVAL )
{
vals = cJSON_CreateObject();
jaddstr(vals,"rel",CURRENCIES[i]);
jaddnum(vals,"bid",PAXPRICES[i] * (1. - spread_ratio));
jaddnum(vals,"ask",PAXPRICES[i] * (1. + spread_ratio));
jaddnum(vals,"maxvol",vol * PAXPRICES[i]);
jaddnum(vals,"minvol",MAX(1,(int32_t)(vol * 0.01 * PAXPRICES[i])));
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"%s\",\"vals\":%s}","KMD",jprint(vals,1));
if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata,0)) != 0 )
{
//printf("(%s) -> (%s)\n",postdata,retstr);
free(retstr);
}
}
//break;
}
} else printf("unsupported ask only for DEX %s/%s\n",base,rel);
}
else if ( (retstr= DEX_trade(exchange,base,rel,1,bid,bidvol)) != 0 )
{
//printf("DEX_trade.(%s)\n",retstr);
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
marketmaker_queue(exchange,base,rel,1,bid,bidvol,retjson);
free_json(retjson);
}
free(retstr);
} //else printf("skip bid %s %.8f vol %f\n",exchange,bid,bidvol);
}
if ( ask > SMALLVAL && askvol > SMALLVAL && nearflags[1] == 0 && strcmp("DEX",exchange) != 0 )
{
if ( (retstr= DEX_trade(exchange,base,rel,-1,ask,askvol)) != 0 )
{
//printf("DEX_trade.(%s)\n",retstr);
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
marketmaker_queue(exchange,base,rel,-1,ask,askvol,retjson);
free_json(retjson);
}
free(retstr);
}
} //else printf("skip ask %s %.8f vol %f\n",exchange,bid,bidvol);
return(n);
}
double marketmaker_updateprice(char *name,char *base,char *rel,double theoretical,double *incrp)
{
static uint32_t counter;
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);
start_DEXrel = dex_balance(rel,reladdr);
while ( 1 )
{
if ( time(NULL) > lasttime+60 )
{
if ( (theoretical= marketmaker_updateprice(name,base,rel,theoretical,&incr)) != 0. )
{
if ( lasttime == 0 )
maxexposure /= theoretical;
}
if ( strcmp(exchange,"bittrex") == 0 )
{
balance_base = bittrex_balance(base,"");
balance_rel = bittrex_balance(rel,"");
DEX_base = dex_balance(base,baseaddr);
DEX_rel = dex_balance(rel,reladdr);
} else printf("add support for %s balance\n",exchange);
lasttime = (uint32_t)time(NULL);
}
marketmaker_pendingupdate(exchange,base,rel);
if ( theoretical > SMALLVAL && avebid > SMALLVAL && aveask > SMALLVAL )
{
aveprice = (avebid + aveask) * 0.5;
// if order is filled, theoretical <- filled (theoretical + price)/2
if ( (filledprice= marketmaker_filled(exchange,base,rel,&buyvol,&sellvol,&pendingbids,&pendingasks)) != 0. )
theoretical = (theoretical + filledprice) * 0.5;
buyvol = sellvol = 0;
if ( (balance_base + DEX_base) < (start_BASE + start_DEXbase) )
sellvol += ((start_BASE + start_DEXbase) - (balance_base + DEX_base));
else buyvol += ((balance_base + DEX_base) - (start_BASE + start_DEXbase));
if ( (balance_rel + DEX_rel) < (start_REL + start_DEXrel) )
buyvol += ((start_REL + start_DEXrel) - (balance_rel + DEX_rel)) / theoretical;
else sellvol += ((balance_rel + DEX_rel) - (start_REL + start_DEXrel)) / theoretical;
mmbid = theoretical - theoretical*profitmargin;
mmask = theoretical + theoretical*profitmargin;
// if any existing order exceeds double margin distance, cancel
marketmaker_prune(exchange,base,rel,1,mmbid - theoretical*profitmargin,mmask + theoretical*profitmargin,0.);
// if new prices crosses existing order, cancel old order first
marketmaker_prune(exchange,base,rel,-1,mmbid,mmask,0.);
//printf("(%.8f %.8f) ",mmbid,mmask);
if ( (1) )
{
if ( mmbid >= lowask || (maxbid > SMALLVAL && mmbid > maxbid) ) //mmbid < highbid ||
{
printf("clear mmbid %.8f lowask %.8f maxbid %.8f\n",mmbid,lowask,maxbid);
mmbid = 0.;
}
if ( mmask <= highbid || (minask > SMALLVAL && mmask < minask) ) // mmask > lowask ||
mmask = 0.;
}
marketmaker_volumeset(&bidincr,&askincr,incr,buyvol,pendingbids,sellvol,pendingasks,maxexposure);
printf("AVE.(%.8f %.8f) hbla %.8f %.8f bid %.8f ask %.8f theory %.8f buys.(%.6f %.6f) sells.(%.6f %.6f) incr.(%.6f %.6f) balances.(%.8f + %.8f, %.8f + %.8f) test %f\n",avebid,aveask,highbid,lowask,mmbid,mmask,theoretical,buyvol,pendingbids,sellvol,pendingasks,bidincr,askincr,balance_base,DEX_base,balance_rel,DEX_rel,(aveask - avebid)/aveprice);
if ( (retstr= DEX_swapstatus()) != 0 )
printf("%s\n",retstr), free(retstr);
printf("%s %s %s, %s %s %s\n",base,DEX_baseaddr,DEX_balance("DEX",base,DEX_baseaddr),rel,DEX_reladdr,DEX_balance("DEX",rel,DEX_reladdr));
if ( (aveask - avebid)/aveprice > profitmargin )
bid = highbid * (1 - profitmargin), ask = lowask * (1 + profitmargin);
else bid = avebid - profitmargin*aveprice, ask = avebid + profitmargin*aveprice;
marketmaker_spread("DEX",base,rel,bid,incr,ask,incr,profitmargin*aveprice*0.5);
if ( (pendingbids + buyvol) > (pendingasks + sellvol) && (pendingbids + buyvol) > bidincr )
{
bidincr *= ((double)(pendingasks + sellvol) / ((pendingbids + buyvol) + (pendingasks + sellvol)));
printf("bidincr %f buy.(%f + %f) sell.(%f + %f)\n",bidincr,pendingbids,buyvol,pendingasks,sellvol);
if ( bidincr < 0.1*incr )
bidincr = 0.1*incr;
if ( bidincr > 1. )
bidincr = (int32_t)bidincr + 0.777;
}
if ( (pendingbids + buyvol) < (pendingasks + sellvol) && (pendingasks + sellvol) > askincr )
{
askincr *= (double)(pendingbids + buyvol) / ((pendingbids + buyvol) + (pendingasks + sellvol));
if ( askincr < 0.1*incr )
askincr = 0.1*incr;
if ( askincr > 1. )
askincr = (int32_t)askincr + 0.777;
}
//printf("mmbid %.8f %.6f, mmask %.8f %.6f\n",mmbid,bidincr,mmask,askincr);
marketmaker_spread(exchange,base,rel,mmbid,bidincr,mmask,askincr,profitmargin*aveprice*0.5);
sleep(60);
}
}
}
#include "LP_nativeDEX.c"
void LP_main(void *ptr)
{
char *passphrase; double profitmargin; uint16_t port; cJSON *argjson = ptr;
if ( (passphrase= jstr(argjson,"passphrase")) != 0 )
{
profitmargin = jdouble(argjson,"profitmargin");
LP_profitratio += profitmargin;
if ( (port= juint(argjson,"rpcport")) < 1000 )
port = LP_RPCPORT;
LPinit(port,LP_RPCPORT+10,LP_RPCPORT+20,LP_RPCPORT+30,passphrase,jint(argjson,"client"),jstr(argjson,"userhome"),argjson);
}
}
int main(int argc, const char * argv[])
{
char dirname[512],*base,*rel,*name,*exchange,*apikey,*apisecret,*blocktrail,*retstr,*baseaddr,*reladdr,*passphrase;
double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid,incr;
cJSON *retjson,*loginjson; int32_t i;
OS_init();
if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 )
{
uint8_t addrtype,rmd160[20],rmd160b[20]; char coinaddr[64],coinaddr2[64];
bitcoin_addr2rmd160(0,&addrtype,rmd160,(char *)argv[1]);
if ( addrtype == 0 )
{
bitcoin_address(coinaddr,0,60,rmd160,20);
bitcoin_addr2rmd160(0,&addrtype,rmd160b,coinaddr);
bitcoin_address(coinaddr2,0,0,rmd160b,20);
}
else if ( addrtype == 60 )
{
bitcoin_address(coinaddr,0,0,rmd160,20);
bitcoin_addr2rmd160(0,&addrtype,rmd160b,coinaddr);
bitcoin_address(coinaddr2,0,60,rmd160b,20);
}
printf("(%s) -> %s -> %s\n",(char *)argv[1],coinaddr,coinaddr2);
if ( strcmp((char *)argv[1],coinaddr2) != 0 )
printf("ERROR\n");
exit(0);
}
sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname);
sprintf(dirname,"%s/SWAPS",GLOBAL_DBDIR), OS_ensure_directory(dirname);
sprintf(dirname,"%s/PRICES",GLOBAL_DBDIR), OS_ensure_directory(dirname);
sprintf(dirname,"%s/UNSPENTS",GLOBAL_DBDIR), OS_ensure_directory(dirname);
#ifdef FROM_JS
argc = 2;
retjson = cJSON_Parse("{\"client\":1,\"passphrase\":\"test\"}");
printf("calling LP_main(%s)\n",jprint(retjson,0));
LP_main(retjson);
emscripten_set_main_loop(LP_fromjs_iter,1,0);
#else
if ( argc == 1 )
{
LP_NXT_redeems();
sleep(3);
return(0);
}
if ( argc > 1 && (retjson= cJSON_Parse(argv[1])) != 0 )
{
if ( jint(retjson,"docker") == 1 )
DOCKERFLAG = 1;
else if ( jstr(retjson,"docker") != 0 )
DOCKERFLAG = (uint32_t)calc_ipbits(jstr(retjson,"docker"));
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 (%s)\n",jprint(retjson,0));
exit(-1);
} //else printf("(%s) launched.(%s)\n",argv[1],passphrase);
incr = 100.;
while ( (1) )
sleep(100000);
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");
apikey = jstr(retjson,"apikey");
apisecret = jstr(retjson,"apisecret");
base = jstr(retjson,"base");
name = jstr(retjson,"name");
rel = jstr(retjson,"rel");
blocktrail = jstr(retjson,"blocktrail");
exchange = jstr(retjson,"exchange");
PAXACTIVE = juint(retjson,"paxactive");
if ( profitmargin < 0. || maxexposure <= 0. || incrratio <= 0. || apikey == 0 || apisecret == 0 || base == 0 || name == 0 || rel == 0 || exchange == 0 || blocktrail == 0 )
{
printf("illegal parameter (%s)\n",jprint(retjson,0));
exit(-1);
}
if ( (retstr= iguana_walletpassphrase(passphrase,999999)) != 0 )
{
printf("(%s/%s) login.(%s)\n",base,rel,retstr);
if ( (loginjson= cJSON_Parse(retstr)) != 0 )
{
if ( PAXACTIVE != 0 )
{
for (i=0; i<32; i++)
{
if ( ((1<<i) & PAXACTIVE) != 0 )
{
if ( jstr(loginjson,CURRENCIES[i]) == 0 )
PAXACTIVE &= ~(1 << i);
}
}
}
if ( (baseaddr= jstr(loginjson,base)) == 0 || (reladdr= jstr(loginjson,rel)) == 0 )
{
printf("Need to activate both %s and %s before marketmaker\n",base,rel);
exit(1);
}
printf("%s\n",DEX_apikeypair(exchange,apikey,apisecret));
marketmaker_pendinginit(exchange,base,rel);
if ( baseaddr != 0 && reladdr != 0 )
{
printf("PAXACTIVE.%08x %s\n",PAXACTIVE,DEX_amlp(blocktrail));
strncpy(DEX_baseaddr,baseaddr,sizeof(DEX_baseaddr)-1);
strncpy(DEX_reladdr,reladdr,sizeof(DEX_reladdr)-1);
printf("%s.%s %s\n",base,baseaddr,DEX_balance("DEX",base,baseaddr));
printf("%s.%s %s\n",rel,reladdr,DEX_balance("DEX",rel,reladdr));
// initialize state using DEX_pendingorders, etc.
marketmaker(minask,maxbid,baseaddr,reladdr,start_base,start_rel,profitmargin,maxexposure,incrratio,exchange,name,base,rel);
}
free_json(loginjson);
} else printf("ERROR parsing.(%s)\n",retstr);
free(retstr);
}
free_json(retjson);
}
#endif
return 0;
}

935
iguana/exchanges/mm.c

@ -20,7 +20,6 @@
//
void PNACL_message(char *arg,...)
{
@ -35,6 +34,7 @@ void PNACL_message(char *arg,...)
#include "../../crypto777/OS_portable.h"
#endif // !_WIN_32
uint32_t DOCKERFLAG;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port);
#include "stats.c"
@ -69,799 +69,8 @@ void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveas
#endif
#endif
char DEX_baseaddr[64],DEX_reladdr[64];
struct mmpending_order
{
double price,volume;
int32_t dir;
uint32_t pending,completed,canceled,cancelstarted,reported;
cJSON *errorjson;
char exchange[16],base[65],rel[65],orderid[64];
} *Pending_orders;
int32_t Num_Pending;
#define IGUANA_URL "http://127.0.0.1:7778"
/*char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies
"CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies
};*/
double PAXPRICES[sizeof(CURRENCIES)/sizeof(*CURRENCIES)];
uint32_t PAXACTIVE;
char *DEX_swapstatus()
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"getswaplist\"}");
return(bitcoind_RPC(0,"InstantDEX",url,0,"getswaplist",postdata,0));
}
char *DEX_amlp(char *blocktrail)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"amlp\",\"blocktrail\":\"%s\"}",blocktrail);
return(bitcoind_RPC(0,"tradebot",url,0,"amlp",postdata,0));
}
char *DEX_openorders(char *exchange)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"openorders\",\"exchange\":\"%s\"}",exchange);
return(bitcoind_RPC(0,"InstantDEX",url,0,"openorders",postdata,0));
}
char *DEX_tradehistory(char *exchange)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"tradehistory\",\"exchange\":\"%s\"}",exchange);
return(bitcoind_RPC(0,"InstantDEX",url,0,"tradehistory",postdata,0));
}
char *DEX_orderstatus(char *exchange,char *orderid)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"orderstatus\",\"exchange\":\"%s\",\"orderid\":\"%s\"}",exchange,orderid);
return(bitcoind_RPC(0,"InstantDEX",url,0,"orderstatus",postdata,0));
}
char *DEX_cancelorder(char *exchange,char *orderid)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"cancelorder\",\"exchange\":\"%s\",\"orderid\":\"%s\"}",exchange,orderid);
return(bitcoind_RPC(0,"InstantDEX",url,0,"cancelorder",postdata,0));
}
char *DEX_balance(char *exchange,char *base,char *coinaddr)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
if ( strcmp(exchange,"DEX") == 0 )
{
sprintf(postdata,"{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"%s\",\"symbol\":\"%s\"}",coinaddr,base);
return(bitcoind_RPC(0,"dex",url,0,"getbalance",postdata,0));
}
else
{
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"balance\",\"exchange\":\"%s\",\"base\":\"%s\"}",exchange,base);
return(bitcoind_RPC(0,"InstantDEX",url,0,"balance",postdata,0));
}
}
char *DEX_apikeypair(char *exchange,char *apikey,char *apisecret)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"apikeypair\",\"exchange\":\"%s\",\"apikey\":\"%s\",\"apisecret\":\"%s\"}",exchange,apikey,apisecret);
return(bitcoind_RPC(0,"InstantDEX",url,0,"apikeypair",postdata,0));
}
char *DEX_setuserid(char *exchange,char *userid,char *tradepassword)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"setuserid\",\"exchange\":\"%s\",\"userid\":\"%s\",\"tradepassword\":\"%s\"}",exchange,userid,tradepassword);
return(bitcoind_RPC(0,"InstantDEX",url,0,"setuserid",postdata,0));
}
char *DEX_trade(char *exchange,char *base,char *rel,int32_t dir,double price,double volume)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"%s\",\"exchange\":\"%s\",\"base\":\"%s\",\"rel\":\"%s\",\"price\":%.8f,\"volume\":%.8f,\"dotrade\":1}",dir>0?"buy":"sell",exchange,base,rel,price,volume);
//printf("DEX_trade.(%s)\n",postdata);
return(bitcoind_RPC(0,"InstantDEX",url,0,dir>0?"buy":"sell",postdata,0));
}
char *DEX_withdraw(char *exchange,char *base,char *destaddr,double amount)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"withdraw\",\"exchange\":\"%s\",\"destaddr\":\"%s\",\"amount\":%.8f}",exchange,destaddr,amount);
return(bitcoind_RPC(0,"InstantDEX",url,0,"withdraw",postdata,0));
}
char *iguana_walletpassphrase(char *passphrase,int32_t timeout)
{
char url[512],postdata[1024];
sprintf(url,"%s/coin=KMD&agent=bitcoinrpc&method=walletpassphrase?",IGUANA_URL);
sprintf(postdata,"[\"%s\", %d]",passphrase,timeout);
return(bitcoind_RPC(0,"",url,0,"walletpassphrase",postdata,0));
}
/*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,int32_t numpeers)
{
char url[512];
sprintf(url,"http://%s:%u/api/stats/intro?ipaddr=%s&port=%u&numpeers=%d",destip,destport,ipaddr,port,numpeers);
printf("(%s)\n",url);
return(issue_curl(url));
}*/
//
// http://127.0.0.1:7779/api/stats/getpeers
char *DEX_listunspent(char *coin,char *coinaddr)
{
char url[512],postdata[1024];
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"%s\",\"symbol\":\"%s\",\"timeout\":60000}",coinaddr,coin);
return(bitcoind_RPC(0,"dex",url,0,"listunspent",postdata,0));
}
bits256 iguana_wif2privkey(char *wifstr)
{
char url[512],postdata[1024],*retstr,*privstr; bits256 privkey; cJSON *retjson;
memset(privkey.bytes,0,sizeof(privkey));
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"SuperNET\",\"method\":\"wif2priv\",\"wif\":\"%s\"}",wifstr);
if ( (retstr= bitcoind_RPC(0,"SuperNET",url,0,"wif2priv",postdata,0)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (privstr= jstr(retjson,"privkey")) != 0 )
{
if ( strlen(privstr) == 64 )
decode_hex(privkey.bytes,32,privstr);
}
free_json(retjson);
}
free(retstr);
}
return(privkey);
}
double bittrex_balance(char *base,char *coinaddr)
{
char *retstr; cJSON *retjson; double balance = 0.;
if ( (retstr= DEX_balance("bittrex",base,coinaddr)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
balance = jdouble(retjson,"balance");
free_json(retjson);
}
free(retstr);
}
return(balance);
}
double dex_balance(char *base,char *coinaddr)
{
char *retstr; cJSON *retjson; double balance = 0.;
if ( (retstr= DEX_balance("DEX",base,coinaddr)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
balance = jdouble(retjson,"balance");
free_json(retjson);
}
free(retstr);
}
return(balance);
}
int32_t komodo_baseid(char *base)
{
int32_t i;
for (i=0; i<sizeof(CURRENCIES)/sizeof(*CURRENCIES); i++)
if ( strcmp(base,CURRENCIES[i]) == 0 )
return(i);
return(-1);
}
cJSON *yahoo_allcurrencies()
{
char *retstr; cJSON *retjson = 0;
if ( (retstr= issue_curl("http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json")) != 0 )
{
retjson = cJSON_Parse(retstr);
free(retstr);
}
return(retjson);
}
void _marketmaker_fiatupdate(int32_t baseid,double price)
{
PAXPRICES[baseid] = price * PAXPRICES[0];
printf("%.6f %s per USD, %.8f %s per KMD\n",price,CURRENCIES[baseid],PAXPRICES[baseid],CURRENCIES[baseid]);
}
uint32_t marketmaker_fiatupdate(cJSON *fiatjson)
{
int32_t i,n,baseid; cJSON *item,*array; double price; char *name; uint64_t mask = 0;
fiatjson = jobj(fiatjson,"list");
if ( fiatjson != 0 && (array= jarray(&n,fiatjson,"resources")) > 0 )
{
for (i=0; i<n; i++)
{
/*
"resource" : {
"classname" : "Quote",
"fields" : {
"name" : "USD/BRX",
"price" : "3.063200",
"symbol" : "BRX=X",
"ts" : "1487866204",
"type" : "currency",
"utctime" : "2017-02-23T16:10:04+0000",
"volume" : "0"
}
*/
item = jitem(array,i);
if ( (item= jobj(item,"resource")) != 0 )
item = jobj(item,"fields");
if ( item != 0 )
{
price = jdouble(item,"price");
if ( price > SMALLVAL && (name= jstr(item,"name")) != 0 && strncmp(name,"USD/",4) == 0 )
{
if ( (baseid= komodo_baseid(name+4)) >= 0 && baseid < 32 )
{
if ( ((1LL << baseid) & mask) == 0 )
{
_marketmaker_fiatupdate(baseid,price);
mask |= (1LL << baseid);
} else if ( fabs(price*PAXPRICES[0] - PAXPRICES[baseid]) > SMALLVAL )
printf("DUPLICATE PRICE? %s %.8f vs %.8f\n",name+4,price*PAXPRICES[0],PAXPRICES[baseid]);
}
}
}
}
}
printf("pax mask.%x\n",(uint32_t)mask);
return((uint32_t)mask);
}
void marketmaker_cancel(struct mmpending_order *ptr)
{
char *retstr; cJSON *retjson;
if ( ptr->pending != 0 && ptr->cancelstarted == 0 )
{
ptr->cancelstarted = (uint32_t)time(NULL);
if ( (retstr= DEX_cancelorder(ptr->exchange,ptr->orderid)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
printf("cancel %s (%s/%s) %.8f vol %.8f dir.%d -> (%s)\n",ptr->exchange,ptr->base,ptr->rel,ptr->price,ptr->volume,ptr->dir,jprint(retjson,0));
free_json(retjson);
ptr->pending = 0;
ptr->canceled = (uint32_t)time(NULL);
}
free(retstr);
}
}
}
void marketmaker_queue(char *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *retjson)
{
struct mmpending_order *ptr; char *orderid;
//DEX_trade.({"success":true,"message":"","result":{"uuid":"d5faa9e4-660d-436f-a257-2c6a40442d8c"},"tag":"11271578410079391025"}
if ( is_cJSON_True(jobj(retjson,"success")) != 0 && jobj(retjson,"result") != 0 )
retjson = jobj(retjson,"result");
printf("QUEUE.%s %s/%s dir.%d %.8f %.6f (%s)\n",exchange,base,rel,dir,price,volume,jprint(retjson,0));
Pending_orders = realloc(Pending_orders,(1 + Num_Pending) * sizeof(*Pending_orders));
ptr = &Pending_orders[Num_Pending++];
memset(ptr,0,sizeof(*ptr));
ptr->price = price;
ptr->volume = volume;
ptr->dir = dir;
ptr->pending = (uint32_t)time(NULL);
strcpy(ptr->exchange,exchange);
strcpy(ptr->base,base);
strcpy(ptr->rel,rel);
if ( (orderid= jstr(retjson,"OrderUuid")) != 0 || (orderid= jstr(retjson,"uuid")) != 0 )
strcpy(ptr->orderid,orderid);
else strcpy(ptr->orderid,"0");
}
void marketmaker_pendingupdate(char *exchange,char *base,char *rel)
{
char *retstr; cJSON *retjson,*obj; int32_t i; struct mmpending_order *ptr;
for (i=0; i<Num_Pending; i++)
{
ptr = &Pending_orders[i];
if ( strcmp(exchange,ptr->exchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 )
continue;
if ( ptr->completed == 0 && (retstr= DEX_orderstatus(exchange,ptr->orderid)) != 0 )
{
//printf("%s status.(%s)\n",ptr->orderid,retstr);
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
obj = jobj(retjson,"result");
if ( is_cJSON_Array(obj) != 0 )
obj = jitem(retjson,0);
if ( jdouble(obj,"QuantityRemaining") == 0. || is_cJSON_True(jobj(obj,"IsOpen")) == 0 )
{
//{"Uuid":null,"OrderUuid":"e7b0789c-0c4e-413b-a768-3d5734d9cbe5","Exchange":"BTC-KMD","OrderType":"LIMIT_SELL","Quantity":877.77700000,"QuantityRemaining":462.50512234,"Limit":0.00011770,"CommissionPaid":0.00012219,"Price":0.04887750,"PricePerUnit":0.00011769,"Opened":"2017-02-20T13:16:22.29","Closed":null,"CancelInitiated":false,"ImmediateOrCancel":false,"IsConditional":false,"Condition":"NONE","ConditionTarget":null} printf("uuid.(%s) finished.(%s)\n",ptr->orderid,jprint(retjson,0));
ptr->completed = (uint32_t)time(NULL);
ptr->pending = 0;
}
free_json(retjson);
}
free(retstr);
}
}
}
void marketmaker_pendinginit(char *exchange,char *base,char *rel)
{
char *retstr,*orderid,*pairstr,relbase[65]; cJSON *retjson,*array,*item; int32_t i,j,n,dir; struct mmpending_order *ptr;
sprintf(relbase,"%s-%s",rel,base);
if ( (retstr= DEX_openorders(exchange)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
//printf("%s\n",jprint(retjson,0));
if ( is_cJSON_True(jobj(retjson,"success")) != 0 && (array= jarray(&n,retjson,"result")) != 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
if ( (pairstr= jstr(item,"Exchange")) == 0 )
continue;
if ( strcmp(pairstr,relbase) != 0 )
{
printf("skip %s when %s\n",pairstr,relbase);
continue;
}
//printf("(%s)\n",jprint(item,0));
//{"success":true,"message":"","result":[{"Uuid":null,"OrderUuid":"81ad3e37-65d4-4fee-9c29-03b050f5192b","Exchange":"BTC-KMD","OrderType":"LIMIT_BUY","Quantity":885.19934578,"QuantityRemaining":885.19934578,"Limit":0.00011184,"CommissionPaid":0,"Price":0,"PricePerUnit":null,"Opened":"2017-02-19T19:14:02.94","Closed":null,"CancelInitiated":false,"ImmediateOrCancel":false,"IsConditional":false,"Condition":"NONE","ConditionTarget":null}],"tag":"10056789044100011414"}
if ( (orderid= jstr(item,"OrderUuid")) != 0 && is_cJSON_Null(jobj(item,"Closed")) != 0 && is_cJSON_False(jobj(item,"CancelInitiated")) != 0 )
{
for (j=0; j<Num_Pending; j++)
{
ptr = &Pending_orders[j];
if ( strcmp(exchange,ptr->exchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 )
continue;
if ( strcmp(ptr->orderid,orderid) == 0 )
{
ptr->pending = (uint32_t)time(NULL);
ptr->completed = 0;
printf("%s pending\n",orderid);
break;
}
}
if ( j == Num_Pending )
{
if ( jstr(item,"OrderType") != 0 )
{
if ( strcmp(jstr(item,"OrderType"),"LIMIT_BUY") == 0 )
dir = 1;
else if ( strcmp(jstr(item,"OrderType"),"LIMIT_SELL") == 0 )
dir = -1;
else dir = 0;
if ( dir != 0 )
marketmaker_queue(exchange,base,rel,dir,jdouble(item,"Limit"),jdouble(item,"QuantityRemaining"),item);
else printf("no dir (%s) (%s)\n",jprint(item,0),jstr(item,"OrderType"));
}
}
}
}
}
free_json(retjson);
}
free(retstr);
}
}
double marketmaker_filled(char *exchange,char *base,char *rel,double *buyvolp,double *sellvolp,double *pendingbidsp,double *pendingasksp)
{
double pricesum = 0.,volsum = 0.; struct mmpending_order *ptr; int32_t i;
*pendingbidsp = *pendingasksp = 0.;
for (i=0; i<Num_Pending; i++)
{
ptr = &Pending_orders[i];
if ( strcmp(exchange,ptr->exchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 )
continue;
if ( ptr->completed != 0 )
{
if ( ptr->reported == 0 )
{
if ( ptr->dir > 0 )
(*buyvolp) += ptr->volume;
else if ( ptr->dir < 0 )
(*sellvolp) += ptr->volume;
pricesum += ptr->volume * ptr->price;
volsum += ptr->volume;
ptr->reported = (uint32_t)time(NULL);
printf("REPORT dir.%d vol %.8f\n",ptr->dir,ptr->volume);
}
}
else if ( ptr->pending != 0 ) // alternative is error or cancelled
{
if ( ptr->dir > 0 )
(*pendingbidsp) += ptr->volume;
else if ( ptr->dir < 0 )
(*pendingasksp) += ptr->volume;
}
}
if ( volsum != 0. )
pricesum /= volsum;
return(pricesum);
}
int32_t marketmaker_prune(char *exchange,char *base,char *rel,int32_t polarity,double bid,double ask,double separation)
{
int32_t i,n = 0; struct mmpending_order *ptr;
for (i=0; i<Num_Pending; i++)
{
ptr = &Pending_orders[i];
if ( strcmp(exchange,ptr->exchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 )
continue;
if ( ptr->pending != 0 && ptr->cancelstarted == 0 )
{
if ( polarity != 0 )
{
if ( ((ptr->dir*polarity > 0 && ptr->price < bid-separation) || (ptr->dir*polarity < 0 && ptr->price > ask+separation)) )
{
printf("polarity.%d dir.%d price.%f bid.%f ask.%f\n",polarity,ptr->dir,ptr->price,bid,ask);
marketmaker_cancel(ptr), n++;
}
}
/*else
{,*prunebid=0,*pruneask=0; double lowbid=0.,highask=0.
if ( ptr->dir > 0 && (lowbid == 0. || ptr->price < lowbid) )
{
lowbid = ptr->price;
prunebid = ptr;
}
else if ( ptr->dir < 0 && (highask == 0. || ptr->price > highask) )
{
highask = ptr->price;
pruneask = ptr;
}
}*/
}
}
/*if ( polarity == 0 )
{
if ( prunebid != 0 && fabs(prunebid->price - bid) > separation )
marketmaker_cancel(prunebid), n++;
if ( pruneask != 0 && fabs(pruneask->price - ask) > separation )
marketmaker_cancel(pruneask), n++;
}*/
return(n);
}
void marketmaker_volumeset(double *bidincrp,double *askincrp,double incr,double buyvol,double pendingbids,double sellvol,double pendingasks,double maxexposure)
{
*bidincrp = *askincrp = incr;
//if ( pendingbids >= pendingasks+maxexposure )
// *bidincrp = 0.;
//else if ( pendingasks >= pendingbids+maxexposure )
// *askincrp = 0.;
if ( *bidincrp > 0. && pendingbids + *bidincrp > maxexposure )
*bidincrp = (maxexposure - *bidincrp);
if ( *askincrp > 0. && pendingasks + *askincrp > maxexposure )
*askincrp = (maxexposure - *askincrp);
if ( *bidincrp < 0. )
*bidincrp = 0.;
if ( *askincrp < 0. )
*askincrp = 0.;
}
int32_t marketmaker_spread(char *exchange,char *base,char *rel,double bid,double bidvol,double ask,double askvol,double separation)
{
int32_t nearflags[2],i,n = 0; struct mmpending_order *ptr; cJSON *retjson,*vals; char *retstr,postdata[1024],url[128]; double vol,spread_ratio;
memset(nearflags,0,sizeof(nearflags));
if ( strcmp("DEX",exchange) != 0 )
{
for (i=0; i<Num_Pending; i++)
{
ptr = &Pending_orders[i];
if ( strcmp(exchange,ptr->exchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 )
continue;
if ( ptr->pending != 0 && ptr->cancelstarted == 0 )
{
if ( bid > SMALLVAL && bidvol > SMALLVAL && ptr->dir > 0 && fabs(bid - ptr->price) < separation )
{
//printf("bid %.8f near %.8f\n",bid,ptr->price);
nearflags[0]++;
}
if ( ask > SMALLVAL && askvol > SMALLVAL && ptr->dir < 0 && fabs(ask - ptr->price) < separation )
{
//printf("%.8f near %.8f\n",ask,ptr->price);
nearflags[1]++;
}
}
}
}
//printf("spread.%s (%.8f %.6f) (%.8f %.6f)\n",exchange,bid,bidvol,ask,askvol);
if ( bid > SMALLVAL && bidvol > SMALLVAL && nearflags[0] == 0 )
{
if ( strcmp("DEX",exchange) == 0 && strcmp(base,"KMD") == 0 && strcmp(rel,"BTC") == 0 )
{
if ( ask > SMALLVAL && askvol > SMALLVAL )
{
/*li.profit = jdouble(vals,"profit");
li.refprice = jdouble(vals,"refprice");
li.bid = jdouble(vals,"bid");
li.ask = jdouble(vals,"ask");
if ( (li.minvol= jdouble(vals,"minvol")) <= 0. )
li.minvol = (strcmp("BTC",base) == 0) ? 0.0001 : 0.001;
if ( (li.maxvol= jdouble(vals,"maxvol")) < li.minvol )
li.maxvol = li.minvol;*/
//curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"MVP\",\"vals\":{\"rel\":\"USD\",\"bid\":0.09,\"ask\":0.11,\"maxvol\":100}}"
vals = cJSON_CreateObject();
jaddstr(vals,"rel","BTC");
jaddnum(vals,"bid",bid);
jaddnum(vals,"ask",ask);
vol = bidvol > askvol ? askvol : bidvol;
jaddnum(vals,"maxvol",vol);
jaddnum(vals,"minvol",vol*0.1 > 100 ? 100 : vol * 0.1);
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"%s\",\"vals\":%s}",base,jprint(vals,1));
//printf("(%s)\n",postdata);
if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata,0)) != 0 )
{
//printf("(%s) -> (%s)\n",postdata,retstr);
free(retstr);
}
spread_ratio = .5 * ((ask - bid) / (bid + ask));
for (i=0; i<sizeof(CURRENCIES)/sizeof(*CURRENCIES); i++)
{
if ( (PAXACTIVE & (1<<i)) == 0 )
continue;
if ( PAXPRICES[i] > SMALLVAL )
{
vals = cJSON_CreateObject();
jaddstr(vals,"rel",CURRENCIES[i]);
jaddnum(vals,"bid",PAXPRICES[i] * (1. - spread_ratio));
jaddnum(vals,"ask",PAXPRICES[i] * (1. + spread_ratio));
jaddnum(vals,"maxvol",vol * PAXPRICES[i]);
jaddnum(vals,"minvol",MAX(1,(int32_t)(vol * 0.01 * PAXPRICES[i])));
sprintf(url,"%s/?",IGUANA_URL);
sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"%s\",\"vals\":%s}","KMD",jprint(vals,1));
if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata,0)) != 0 )
{
//printf("(%s) -> (%s)\n",postdata,retstr);
free(retstr);
}
}
//break;
}
} else printf("unsupported ask only for DEX %s/%s\n",base,rel);
}
else if ( (retstr= DEX_trade(exchange,base,rel,1,bid,bidvol)) != 0 )
{
//printf("DEX_trade.(%s)\n",retstr);
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
marketmaker_queue(exchange,base,rel,1,bid,bidvol,retjson);
free_json(retjson);
}
free(retstr);
} //else printf("skip bid %s %.8f vol %f\n",exchange,bid,bidvol);
}
if ( ask > SMALLVAL && askvol > SMALLVAL && nearflags[1] == 0 && strcmp("DEX",exchange) != 0 )
{
if ( (retstr= DEX_trade(exchange,base,rel,-1,ask,askvol)) != 0 )
{
//printf("DEX_trade.(%s)\n",retstr);
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
marketmaker_queue(exchange,base,rel,-1,ask,askvol,retjson);
free_json(retjson);
}
free(retstr);
}
} //else printf("skip ask %s %.8f vol %f\n",exchange,bid,bidvol);
return(n);
}
double marketmaker_updateprice(char *name,char *base,char *rel,double theoretical,double *incrp)
{
static uint32_t counter;
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);
start_DEXrel = dex_balance(rel,reladdr);
while ( 1 )
{
if ( time(NULL) > lasttime+60 )
{
if ( (theoretical= marketmaker_updateprice(name,base,rel,theoretical,&incr)) != 0. )
{
if ( lasttime == 0 )
maxexposure /= theoretical;
}
if ( strcmp(exchange,"bittrex") == 0 )
{
balance_base = bittrex_balance(base,"");
balance_rel = bittrex_balance(rel,"");
DEX_base = dex_balance(base,baseaddr);
DEX_rel = dex_balance(rel,reladdr);
} else printf("add support for %s balance\n",exchange);
lasttime = (uint32_t)time(NULL);
}
marketmaker_pendingupdate(exchange,base,rel);
if ( theoretical > SMALLVAL && avebid > SMALLVAL && aveask > SMALLVAL )
{
aveprice = (avebid + aveask) * 0.5;
// if order is filled, theoretical <- filled (theoretical + price)/2
if ( (filledprice= marketmaker_filled(exchange,base,rel,&buyvol,&sellvol,&pendingbids,&pendingasks)) != 0. )
theoretical = (theoretical + filledprice) * 0.5;
buyvol = sellvol = 0;
if ( (balance_base + DEX_base) < (start_BASE + start_DEXbase) )
sellvol += ((start_BASE + start_DEXbase) - (balance_base + DEX_base));
else buyvol += ((balance_base + DEX_base) - (start_BASE + start_DEXbase));
if ( (balance_rel + DEX_rel) < (start_REL + start_DEXrel) )
buyvol += ((start_REL + start_DEXrel) - (balance_rel + DEX_rel)) / theoretical;
else sellvol += ((balance_rel + DEX_rel) - (start_REL + start_DEXrel)) / theoretical;
mmbid = theoretical - theoretical*profitmargin;
mmask = theoretical + theoretical*profitmargin;
// if any existing order exceeds double margin distance, cancel
marketmaker_prune(exchange,base,rel,1,mmbid - theoretical*profitmargin,mmask + theoretical*profitmargin,0.);
// if new prices crosses existing order, cancel old order first
marketmaker_prune(exchange,base,rel,-1,mmbid,mmask,0.);
//printf("(%.8f %.8f) ",mmbid,mmask);
if ( (1) )
{
if ( mmbid >= lowask || (maxbid > SMALLVAL && mmbid > maxbid) ) //mmbid < highbid ||
{
printf("clear mmbid %.8f lowask %.8f maxbid %.8f\n",mmbid,lowask,maxbid);
mmbid = 0.;
}
if ( mmask <= highbid || (minask > SMALLVAL && mmask < minask) ) // mmask > lowask ||
mmask = 0.;
}
marketmaker_volumeset(&bidincr,&askincr,incr,buyvol,pendingbids,sellvol,pendingasks,maxexposure);
printf("AVE.(%.8f %.8f) hbla %.8f %.8f bid %.8f ask %.8f theory %.8f buys.(%.6f %.6f) sells.(%.6f %.6f) incr.(%.6f %.6f) balances.(%.8f + %.8f, %.8f + %.8f) test %f\n",avebid,aveask,highbid,lowask,mmbid,mmask,theoretical,buyvol,pendingbids,sellvol,pendingasks,bidincr,askincr,balance_base,DEX_base,balance_rel,DEX_rel,(aveask - avebid)/aveprice);
if ( (retstr= DEX_swapstatus()) != 0 )
printf("%s\n",retstr), free(retstr);
printf("%s %s %s, %s %s %s\n",base,DEX_baseaddr,DEX_balance("DEX",base,DEX_baseaddr),rel,DEX_reladdr,DEX_balance("DEX",rel,DEX_reladdr));
if ( (aveask - avebid)/aveprice > profitmargin )
bid = highbid * (1 - profitmargin), ask = lowask * (1 + profitmargin);
else bid = avebid - profitmargin*aveprice, ask = avebid + profitmargin*aveprice;
marketmaker_spread("DEX",base,rel,bid,incr,ask,incr,profitmargin*aveprice*0.5);
if ( (pendingbids + buyvol) > (pendingasks + sellvol) && (pendingbids + buyvol) > bidincr )
{
bidincr *= ((double)(pendingasks + sellvol) / ((pendingbids + buyvol) + (pendingasks + sellvol)));
printf("bidincr %f buy.(%f + %f) sell.(%f + %f)\n",bidincr,pendingbids,buyvol,pendingasks,sellvol);
if ( bidincr < 0.1*incr )
bidincr = 0.1*incr;
if ( bidincr > 1. )
bidincr = (int32_t)bidincr + 0.777;
}
if ( (pendingbids + buyvol) < (pendingasks + sellvol) && (pendingasks + sellvol) > askincr )
{
askincr *= (double)(pendingbids + buyvol) / ((pendingbids + buyvol) + (pendingasks + sellvol));
if ( askincr < 0.1*incr )
askincr = 0.1*incr;
if ( askincr > 1. )
askincr = (int32_t)askincr + 0.777;
}
//printf("mmbid %.8f %.6f, mmask %.8f %.6f\n",mmbid,bidincr,mmask,askincr);
marketmaker_spread(exchange,base,rel,mmbid,bidincr,mmask,askincr,profitmargin*aveprice*0.5);
sleep(60);
}
}
}
#include "LP_nativeDEX.c"
/*MERK d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a ht.518777 -> {"pos":1,"merkle":["526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8", "f68b03a7b6e418c9b306d8d8b21917ae5a584696f9b0b8cb0741733d7097fdfd"],"block_height":518777} root.(0000000000000000000000000000000000000000000000000000000000000000)
MERK c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543 ht.518777 -> {"pos":2,"merkle":["fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501", "8c116e974c842ad3ad8b3ddbd71da3debb150e3fe692f5bd628381bc167311a7"],"block_height":518777} root.(0000000000000000000000000000000000000000000000000000000000000000)*/
/*526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8
d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a
c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543
fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501*/
/*0: 526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8
1: d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a
2: c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543
3: fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501
4: 8c116e974c842ad3ad8b3ddbd71da3debb150e3fe692f5bd628381bc167311a7
5: f68b03a7b6e418c9b306d8d8b21917ae5a584696f9b0b8cb0741733d7097fdfd
6: a87ee259560f20b20182760c0e7cc7896d44381f0ad58a2e755a2b6b895b01ec*/
/*
0 1 2 3
4 5
6
1 -> [0, 5]
2 -> [3, 4]
if odd -> right, else left
then /= 2
*/
/*void testmerk()
{
bits256 tree[256],roothash,txid; int32_t i; char str[65];
memset(tree,0,sizeof(tree));
decode_hex(tree[0].bytes,32,"526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8");
decode_hex(tree[1].bytes,32,"d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a");
decode_hex(tree[2].bytes,32,"c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543");
decode_hex(tree[3].bytes,32,"fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501");
roothash = iguana_merkle(tree,4);
for (i=0; i<256; i++)
{
if ( bits256_nonz(tree[i]) == 0 )
break;
printf("%d: %s\n",i,bits256_str(str,tree[i]));
}
memset(tree,0,sizeof(tree));
decode_hex(tree[0].bytes,32,"526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8");
decode_hex(tree[1].bytes,32,"f68b03a7b6e418c9b306d8d8b21917ae5a584696f9b0b8cb0741733d7097fdfd");
decode_hex(txid.bytes,32,"d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a");
roothash = validate_merkle(1,txid,tree,2);
printf("validate 1: %s\n",bits256_str(str,roothash));
memset(tree,0,sizeof(tree));
decode_hex(tree[0].bytes,32,"fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501");
decode_hex(tree[1].bytes,32,"8c116e974c842ad3ad8b3ddbd71da3debb150e3fe692f5bd628381bc167311a7");
decode_hex(txid.bytes,32,"c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543");
roothash = validate_merkle(2,txid,tree,2);
printf("validate 2: %s\n",bits256_str(str,roothash));
}*/
void LP_main(void *ptr)
{
char *passphrase; double profitmargin; uint16_t port; cJSON *argjson = ptr;
@ -877,10 +86,83 @@ void LP_main(void *ptr)
int main(int argc, const char * argv[])
{
char dirname[512],*base,*rel,*name,*exchange,*apikey,*apisecret,*blocktrail,*retstr,*baseaddr,*reladdr,*passphrase;
double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid,incr;
cJSON *retjson,*loginjson; int32_t i;
char dirname[512],*passphrase; double incr; cJSON *retjson;
OS_init();
if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 )
{
uint8_t addrtype,rmd160[20],rmd160b[20]; char coinaddr[64],coinaddr2[64];
bitcoin_addr2rmd160(0,&addrtype,rmd160,(char *)argv[1]);
if ( addrtype == 0 )
{
bitcoin_address(coinaddr,0,60,rmd160,20);
bitcoin_addr2rmd160(0,&addrtype,rmd160b,coinaddr);
bitcoin_address(coinaddr2,0,0,rmd160b,20);
}
else if ( addrtype == 60 )
{
bitcoin_address(coinaddr,0,0,rmd160,20);
bitcoin_addr2rmd160(0,&addrtype,rmd160b,coinaddr);
bitcoin_address(coinaddr2,0,60,rmd160b,20);
}
printf("(%s) -> %s -> %s\n",(char *)argv[1],coinaddr,coinaddr2);
if ( strcmp((char *)argv[1],coinaddr2) != 0 )
printf("ERROR\n");
exit(0);
}
else if ( argv[1] != 0 && strcmp(argv[1],"hush") == 0 )
{
uint32_t timestamp; char str[65],wifstr[128]; bits256 privkey; int32_t i;
timestamp = (uint32_t)time(NULL);
//printf("start hush vanitygen t.%u\n",timestamp);
for (i=0; i<1000000000; i++)
{
OS_randombytes(privkey.bytes,sizeof(privkey));
privkey.bytes[0] = 0x0e;
privkey.bytes[1] = 0x5b;
privkey.bytes[2] = 0xf9;
privkey.bytes[3] = 0xc6;
privkey.bytes[4] = 0x06;
privkey.bytes[5] = 0xdd;
privkey.bytes[6] = 0xbb;
bitcoin_priv2wiflong(0xab,wifstr,privkey,0x36);
if ( wifstr[2] == 'x' && wifstr[4] == 'H' && wifstr[5] == 'u' && wifstr[6] == 's' )//&& wifstr[3] == 'x' )
{
if ( wifstr[7] == 'h' && wifstr[8] == 'L' && wifstr[9] == 'i' )
{
//printf("i.%d %s -> wif.%s\n",i,bits256_str(str,privkey),wifstr);
if ( wifstr[10] == 's' && wifstr[11] == 't' )
{
printf("{\"iters\":%d,\"privkey\":\"%s\",\"wif\":\"%s\"}\n",i,bits256_str(str,privkey),wifstr);
break;
}
}
} //else printf("failed %s\n",wifstr);
}
//printf("done hush vanitygen done %u elapsed %d\n",(uint32_t)time(NULL),(uint32_t)time(NULL) - timestamp);
exit(0);
}
else if ( argv[1] != 0 && strcmp(argv[1],"vanity") == 0 && argv[2] != 0 )
{
uint32_t timestamp; uint8_t pubkey33[33]; char str[65],coinaddr[64],wifstr[128]; bits256 privkey; int32_t i,len; void *ctx;
ctx = bitcoin_ctx();
len = (int32_t)strlen(argv[2]);
timestamp = (uint32_t)time(NULL);
printf("start vanitygen (%s).%d t.%u\n",argv[2],len,timestamp);
for (i=0; i<1000000000; i++)
{
OS_randombytes(privkey.bytes,sizeof(privkey));
bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,0,60);
if ( strncmp(coinaddr+1,argv[2],len-1) == 0 )
{
bitcoin_priv2wif(0,wifstr,privkey,188);
printf("i.%d %s -> %s wif.%s\n",i,bits256_str(str,privkey),coinaddr,wifstr);
if ( coinaddr[1+len-1] == argv[2][len-1] )
break;
} //else printf("failed %s\n",wifstr);
}
printf("done vanitygen.(%s) done %u elapsed %d\n",argv[2],(uint32_t)time(NULL),(uint32_t)time(NULL) - timestamp);
exit(0);
}
sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname);
sprintf(dirname,"%s/SWAPS",GLOBAL_DBDIR), OS_ensure_directory(dirname);
sprintf(dirname,"%s/PRICES",GLOBAL_DBDIR), OS_ensure_directory(dirname);
@ -894,12 +176,17 @@ int main(int argc, const char * argv[])
#else
if ( argc == 1 )
{
//LP_privkey_tests();
LP_NXT_redeems();
sleep(3);
return(0);
}
if ( argc > 1 && (retjson= cJSON_Parse(argv[1])) != 0 )
{
if ( jint(retjson,"docker") == 1 )
DOCKERFLAG = 1;
else if ( jstr(retjson,"docker") != 0 )
DOCKERFLAG = (uint32_t)calc_ipbits(jstr(retjson,"docker"));
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 )
@ -910,64 +197,6 @@ int main(int argc, const char * argv[])
incr = 100.;
while ( (1) )
sleep(100000);
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");
apikey = jstr(retjson,"apikey");
apisecret = jstr(retjson,"apisecret");
base = jstr(retjson,"base");
name = jstr(retjson,"name");
rel = jstr(retjson,"rel");
blocktrail = jstr(retjson,"blocktrail");
exchange = jstr(retjson,"exchange");
PAXACTIVE = juint(retjson,"paxactive");
if ( profitmargin < 0. || maxexposure <= 0. || incrratio <= 0. || apikey == 0 || apisecret == 0 || base == 0 || name == 0 || rel == 0 || exchange == 0 || blocktrail == 0 )
{
printf("illegal parameter (%s)\n",jprint(retjson,0));
exit(-1);
}
if ( (retstr= iguana_walletpassphrase(passphrase,999999)) != 0 )
{
printf("(%s/%s) login.(%s)\n",base,rel,retstr);
if ( (loginjson= cJSON_Parse(retstr)) != 0 )
{
if ( PAXACTIVE != 0 )
{
for (i=0; i<32; i++)
{
if ( ((1<<i) & PAXACTIVE) != 0 )
{
if ( jstr(loginjson,CURRENCIES[i]) == 0 )
PAXACTIVE &= ~(1 << i);
}
}
}
if ( (baseaddr= jstr(loginjson,base)) == 0 || (reladdr= jstr(loginjson,rel)) == 0 )
{
printf("Need to activate both %s and %s before marketmaker\n",base,rel);
exit(1);
}
printf("%s\n",DEX_apikeypair(exchange,apikey,apisecret));
marketmaker_pendinginit(exchange,base,rel);
if ( baseaddr != 0 && reladdr != 0 )
{
printf("PAXACTIVE.%08x %s\n",PAXACTIVE,DEX_amlp(blocktrail));
strncpy(DEX_baseaddr,baseaddr,sizeof(DEX_baseaddr)-1);
strncpy(DEX_reladdr,reladdr,sizeof(DEX_reladdr)-1);
printf("%s.%s %s\n",base,baseaddr,DEX_balance("DEX",base,baseaddr));
printf("%s.%s %s\n",rel,reladdr,DEX_balance("DEX",rel,reladdr));
// initialize state using DEX_pendingorders, etc.
marketmaker(minask,maxbid,baseaddr,reladdr,start_base,start_rel,profitmargin,maxexposure,incrratio,exchange,name,base,rel);
}
free_json(loginjson);
} else printf("ERROR parsing.(%s)\n",retstr);
free(retstr);
}
free_json(retjson);
}
#endif
return 0;

4
iguana/exchanges/mshark

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

3
iguana/exchanges/pendingswaps

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

49
iguana/exchanges/prices/autoprice

@ -0,0 +1,49 @@
#!/bin/bash
margin=0.05
source userpass
./auto_chipskmd
./auto_chipsbtc
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTC\",\"margin\":$margin,\"refbase\":\"komodo\",\"refrel\":\"coinmarketcap\"}"
#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BTC\",\"rel\":\"KMD\",\"fixed\":0.00025,\"margin\":$margin}"
#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTC\",\"fixed\":4000,\"margin\":$margin}"
#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"MNZ\",\"offset\":0.0,\"refbase\":\"KMD\",\"refrel\":\"BTC\",\"factor\":15000,\"margin\":-0.2}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"HUSH\",\"rel\":\"KMD\",\"margin\":$margin,\"refbase\":\"hush\",\"refrel\":\"coinmarketcap\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTCH\",\"offset\":0.0,\"refbase\":\"KMD\",\"refrel\":\"HUSH\",\"factor\":1.44,\"buymargin\":0.01,\"sellmargin\":0.01}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BTCH\",\"rel\":\"KMD\",\"offset\":0.0,\"refbase\":\"HUSH\",\"refrel\":\"KMD\",\"factor\":0.7,\"buymargin\":0.01,\"sellmargin\":0.01}"
source crypto
source trackbtc
source dex
source trackbtc
source jumblr
source trackbtc
source pangea
source trackbtc
source bots
source trackbtc
source bet
source trackbtc
source revs
source trackbtc
source mgw
source trackbtc
source revs
source trackbtc
sharkholdings="{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"bitcoin-cash\",\"balance\":1200}, {\"coin\":\"bitcoin\",\"balance\":145}"
curl --url "http://127.0.0.1:7783" --data "{\"base\":\"MSHARK\",\"rel\":\"KMD\",\"fundvalue_bid\":\"NAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC\",\"holdings\":[$sharkholdings],\"divisor\":1400000}"
curl --url "http://127.0.0.1:7783" --data "{\"base\":\"SUPERNET\",\"rel\":\"KMD\",\"fundvalue_bid\":\"NAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}"
curl --url "http://127.0.0.1:7783" --data "{\"margin\":$margin,\"base\":\"HODL\",\"rel\":\"KMD\",\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RNcUaMUEFLxVwtTo7rgruhwYanGk1jTkeU\",\"holdings\":[{\"coin\":\"siacoin\",\"balance\":185000000,\"comment\":\"using siafunds equal to million siacoin\"}],\"divisor\":10000000}"

3
iguana/exchanges/prices/bet

@ -0,0 +1,3 @@
coin=BET
price=0.0005
invprice=2000

3
iguana/exchanges/prices/bots

@ -0,0 +1,3 @@
coin=BOTS
price=0.001
invprice=1000

3
iguana/exchanges/prices/crypto

@ -0,0 +1,3 @@
coin=CRYPTO
price=0.002666666
invprice=375

3
iguana/exchanges/prices/dex

@ -0,0 +1,3 @@
coin=DEX
price=0.0030
invprice=333

18
iguana/exchanges/prices/gets

@ -0,0 +1,18 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"REVS\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"CHIPS\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"KMD\",\"rel\":\"BTC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"SUPERNET\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"CRYPTO\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"DEX\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"BOTS\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"BET\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"HODL\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"MSHARK\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"MGW\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"PANGEA\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"JUMBLR\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"HUSH\",\"rel\":\"KMD\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"BTCH\",\"rel\":\"KMD\"}"

3
iguana/exchanges/prices/jumblr

@ -0,0 +1,3 @@
coin=JUMBLR
price=0.002
invprice=500

3
iguana/exchanges/prices/mgw

@ -0,0 +1,3 @@
coin=MGW
price=0.00015
invprice=6666

3
iguana/exchanges/prices/pangea

@ -0,0 +1,3 @@
coin=PANGEA
price=0.001
invprice=1000

3
iguana/exchanges/prices/revs

@ -0,0 +1,3 @@
coin=REVS
price=0.0005
invprice=2000

2
iguana/exchanges/sell

@ -1,3 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"KMD\",\"rel\":\"BTC\",\"basevolume\":10.0\",\"price\":0.0005}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"KMD\",\"rel\":\"BTC\",\"basevolume\":10.0,\"price\":0.0005}"

160
iguana/exchanges/stats.c

@ -32,13 +32,15 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char
char *stats_validmethods[] =
{
"psock", "getprices", "notify", "getpeers", // from issue_ "uitem", "listunspent",
"orderbook", "help", "getcoins", "pricearray", "balance", "tradestatus"
"psock", "ticker", "balances", "getprice", "notify", "getpeers", // from issue_ "uitem", "listunspent",
"orderbook", "statsdisp", "fundvalue", "help", "getcoins", "pricearray", "balance", "tradesarray"
};
int32_t LP_valid_remotemethod(cJSON *argjson)
{
char *method; int32_t i;
if ( DOCKERFLAG != 0 )
return(1);
if ( (method= jstr(argjson,"method")) != 0 )
{
for (i=0; i<sizeof(stats_validmethods)/sizeof(*stats_validmethods); i++)
@ -310,7 +312,7 @@ cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr)
jaddstr(json,key,value);
else jaddistr(array,key);
len += (n + 1);
if ( strcmp(key,"Content-Length") == 0 && (datalen= atoi(value)) > 0 )
if ( (strcmp(key,"Content-Length") == 0 || strcmp(key,"content-length") == 0) && (datalen= atoi(value)) > 0 )
{
data = &urlstr[totallen - datalen];
data[-1] = 0;
@ -329,8 +331,7 @@ extern void *bitcoin_ctx();
char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr,char *filetype,uint16_t port)
{
static void *ctx;
cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; char *myipaddr="127.0.0.1",symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr,*filestr,*token = 0; int32_t i,j,n,num=0;
//printf("rpcparse.(%s)\n",urlstr);
cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; char *myipaddr="127.0.0.1",symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr=0,*filestr,*token = 0; int32_t i,j,n,num=0;
if ( ctx == 0 )
ctx = bitcoin_ctx();
for (i=0; i<sizeof(urlmethod)-1&&urlstr[i]!=0&&urlstr[i]!=' '; i++)
@ -339,6 +340,7 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po
n = i;
//printf("URLMETHOD.(%s)\n",urlmethod);
*postflagp = (strcmp(urlmethod,"POST") == 0);
//printf("POST.%d rpcparse.(%s)\n",*postflagp,urlstr);
for (i=0; i<sizeof(url)-1&&urlstr[n+i]!=0&&urlstr[n+i]!=' '; i++)
url[i] = urlstr[n+i];
url[i++] = 0;
@ -412,7 +414,13 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po
{
jadd(json,"tokens",tokens);
jaddstr(json,"urlmethod",urlmethod);
if ( (data= jstr(json,"POST")) == 0 || (argjson= cJSON_Parse(data)) == 0 )
if ( (data= jstr(json,"POST")) != 0 )
{
free_json(argjson);
argjson = cJSON_Parse(data);
//printf("data.(%s)\n",data);
}
if ( argjson != 0 )
{
userpass = jstr(argjson,"userpass");
//printf("userpass.(%s)\n",userpass);
@ -499,62 +507,62 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po
}
}
}
}
if ( is_cJSON_Array(argjson) != 0 && (n= cJSON_GetArraySize(argjson)) > 0 )
{
cJSON *retitem,*retarray = cJSON_CreateArray();
origargjson = argjson;
symbol[0] = 0;
for (i=0; i<n; i++)
if ( is_cJSON_Array(argjson) != 0 && (n= cJSON_GetArraySize(argjson)) > 0 )
{
argjson = jitem(origargjson,i);
if ( userpass != 0 && jstr(argjson,"userpass") == 0 )
jaddstr(argjson,"userpass",userpass);
//printf("after urlconv.(%s) argjson.(%s)\n",jprint(json,0),jprint(argjson,0));
#ifdef FROM_MARKETMAKER
if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(argjson) > 0 )
cJSON *retitem,*retarray = cJSON_CreateArray();
origargjson = argjson;
symbol[0] = 0;
for (i=0; i<n; i++)
{
argjson = jitem(origargjson,i);
if ( userpass != 0 && jstr(argjson,"userpass") == 0 )
jaddstr(argjson,"userpass",userpass);
//printf("after urlconv.(%s) argjson.(%s)\n",jprint(json,0),jprint(argjson,0));
#ifdef FROM_MARKETMAKER
if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(argjson) > 0 )
{
if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 )
{
if ( (retitem= cJSON_Parse(retstr)) != 0 )
jaddi(retarray,retitem);
free(retstr);
}
} else retstr = clonestr("{\"error\":\"invalid remote method\"}");
#else
if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 )
{
if ( (retitem= cJSON_Parse(retstr)) != 0 )
jaddi(retarray,retitem);
free(retstr);
}
} else retstr = clonestr("{\"error\":\"invalid remote method\"}");
#else
if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 )
{
if ( (retitem= cJSON_Parse(retstr)) != 0 )
jaddi(retarray,retitem);
free(retstr);
}
#endif
//printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),jprint(json,0),*postflagp,retstr);
//printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),jprint(json,0),*postflagp,retstr);
}
free_json(origargjson);
retstr = jprint(retarray,1);
}
free_json(origargjson);
retstr = jprint(retarray,1);
}
else
{
cJSON *arg;
if ( jstr(argjson,"agent") != 0 && strcmp(jstr(argjson,"agent"),"bitcoinrpc") != 0 && jobj(argjson,"params") != 0 )
else
{
arg = jobj(argjson,"params");
if ( is_cJSON_Array(arg) != 0 && cJSON_GetArraySize(arg) == 1 )
arg = jitem(arg,0);
} else arg = argjson;
//printf("ARGJSON.(%s)\n",jprint(arg,0));
if ( userpass != 0 && jstr(arg,"userpass") == 0 )
jaddstr(arg,"userpass",userpass);
cJSON *arg;
if ( jstr(argjson,"agent") != 0 && strcmp(jstr(argjson,"agent"),"bitcoinrpc") != 0 && jobj(argjson,"params") != 0 )
{
arg = jobj(argjson,"params");
if ( is_cJSON_Array(arg) != 0 && cJSON_GetArraySize(arg) == 1 )
arg = jitem(arg,0);
} else arg = argjson;
//printf("ARGJSON.(%s)\n",jprint(arg,0));
if ( userpass != 0 && jstr(arg,"userpass") == 0 )
jaddstr(arg,"userpass",userpass);
#ifdef FROM_MARKETMAKER
if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(arg) > 0 )
retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port);
else retstr = clonestr("{\"error\":\"invalid remote method\"}");
if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(arg) > 0 )
retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port);
else retstr = clonestr("{\"error\":\"invalid remote method\"}");
#else
retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port);
retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port);
#endif
}
free_json(argjson);
}
free_json(argjson);
free_json(json);
if ( tmpjson != 0 )
free(tmpjson);
@ -562,15 +570,17 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po
}
free_json(argjson);
if ( tmpjson != 0 )
free(tmpjson);
free_json(tmpjson);
if ( tokens != 0 )
free_json(tokens);
*jsonflagp = 1;
return(clonestr("{\"error\":\"couldnt process packet\"}"));
}
int32_t iguana_getcontentlen(char *buf,int32_t recvlen)
{
char *str,*clenstr = "Content-Length: "; int32_t len = -1;
if ( (str= strstr(buf,clenstr)) != 0 )
char *str,*clenstr = "Content-Length: ",*clenstr2 = "content-length: "; int32_t len = -1;
if ( (str= strstr(buf,clenstr)) != 0 || (str= strstr(buf,clenstr2)) != 0 )
{
//printf("strstr.(%s)\n",str);
str += strlen(clenstr);
@ -597,15 +607,16 @@ void LP_rpc_processreq(void *_ptr)
static uint32_t spawned,maxspawned;
char filetype[128],content_type[128];
int32_t recvlen,flag,postflag=0,contentlen,remains,sock,numsent,jsonflag=0,hdrsize,len;
char helpname[512],remoteaddr[64],*buf,*retstr,*space,*jsonbuf; struct rpcrequest_info *req = _ptr;
char helpname[512],remoteaddr[64],*buf,*retstr,space[8192],space2[32786],*jsonbuf; struct rpcrequest_info *req = _ptr;
uint32_t ipbits,i,size = IGUANA_MAXPACKETSIZE + 512;
ipbits = req->ipbits;;
expand_ipbits(remoteaddr,ipbits);
sock = req->sock;
recvlen = flag = 0;
retstr = 0;
space = calloc(1,size);
//space = calloc(1,size);
jsonbuf = calloc(1,size);
//printf("alloc jsonbuf.%p\n",jsonbuf);
remains = size-1;
buf = jsonbuf;
spawned++;
@ -624,10 +635,12 @@ void LP_rpc_processreq(void *_ptr)
printf("EAGAIN for len %d, remains.%d\n",len,remains);
usleep(10000);
}
//printf("errno.%d len.%d remains.%d\n",errno,len,remains);
break;
}
else
{
//printf("received len.%d\n%s\n",len,buf);
if ( len > 0 )
{
buf[len] = 0;
@ -694,16 +707,23 @@ void LP_rpc_processreq(void *_ptr)
//printf("RETURN.(%s) jsonflag.%d postflag.%d\n",retstr,jsonflag,postflag);
if ( jsonflag != 0 || postflag != 0 )
{
if ( retstr == 0 )
retstr = clonestr("{}");
response = malloc(strlen(retstr)+1024+1+1);
sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr));
if ( strlen(retstr)+1024+1+1 < sizeof(space2) )
response = space2;
else
{
response = malloc(strlen(retstr)+1024+1+1);
//printf("alloc response.%p\n",response);
}
sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr)+1);
response[0] = '\0';
strcat(response,hdrs);
strcat(response,retstr);
strcat(response,"\n");
if ( retstr != space )
{
//printf("free retstr0.%p\n",retstr);
free(retstr);
}
retstr = response;
//printf("RET.(%s)\n",retstr);
}
@ -727,16 +747,28 @@ void LP_rpc_processreq(void *_ptr)
printf("iguana sent.%d remains.%d of recvlen.%d (%s)\n",numsent,remains,recvlen,jsonbuf);
}
}
if ( retstr != space)
if ( retstr != space && retstr != space2 )
{
//printf("free retstr.%p\n",retstr);
free(retstr);
}
}
free(space);
//free(space);
//printf("free jsonbuf.%p\n",jsonbuf);
free(jsonbuf);
closesocket(sock);
portable_mutex_lock(&LP_gcmutex);
DL_APPEND(LP_garbage_collector,req);
if ( 1 )
{
portable_mutex_lock(&LP_gcmutex);
DL_APPEND(LP_garbage_collector,req);
portable_mutex_unlock(&LP_gcmutex);
}
else
{
//printf("free req.%p\n",req);
free(req);
}
spawned--;
portable_mutex_unlock(&LP_gcmutex);
}
extern int32_t IAMLP;
@ -761,7 +793,7 @@ void stats_rpcloop(void *args)
//fcntl(bindsock, F_SETFL, fcntl(bindsock, F_GETFL, 0) | O_NONBLOCK);
#endif
//if ( counter++ < 1 )
printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled <<<<<<<<<\n",port,bindsock);
printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled at unixtime.%u <<<<<<<<<\n",port,bindsock,(uint32_t)time(NULL));
}
//printf("after sock.%d\n",sock);
clilen = sizeof(cli_addr);
@ -785,12 +817,16 @@ void stats_rpcloop(void *args)
}
#endif*/
memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits));
if ( DOCKERFLAG != 0 && (DOCKERFLAG == 1 || ipbits == DOCKERFLAG) )
ipbits = localhostbits;
if ( port == RPC_port && ipbits != localhostbits )
{
//printf("port.%u RPC_port.%u ipbits %x != %x\n",port,RPC_port,ipbits,localhostbits);
closesocket(sock);
continue;
}
req = calloc(1,sizeof(*req));
//printf("alloc req.%p\n",req);
req->sock = sock;
req->ipbits = ipbits;
req->port = port;

20
iguana/exchanges/supernet

@ -0,0 +1,20 @@
#!/bin/bash
source userpass
# this will only work for watchonly addresses that have been rescanned and with active coins
echo mshark
./mshark
echo hodl
./hodl
echo dex
./dex
echo jumblr
./jumblr
echo bots
./bots
echo supernet
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}"
echo supernet
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}"
#curl --url "http://5.9.253.196:7782" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}"

3
iguana/exchanges/ticker

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"ticker\",\"base\":\"REVS\",\"rel\":\"KMD\"}"

2
iguana/exchanges/trackbtc

@ -0,0 +1,2 @@
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"$coin\",\"offset\":0.0,\"refbase\":\"KMD\",\"refrel\":\"BTC\",\"factor\":$invprice,\"margin\":$margin}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"$coin\",\"rel\":\"KMD\",\"offset\":0.0,\"refbase\":\"BTC\",\"refrel\":\"KMD\",\"factor\":$price,\"margin\":$margin}"

3
iguana/exchanges/tradesarray

@ -0,0 +1,3 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"tradesarray\",\"base\":\"REVS\",\"rel\":\"KMD\",\"timescale\":3600}"

13
iguana/iguana777.h

@ -18,6 +18,19 @@
copy that into basilisk as coin, changing RELAY -> 0
*/
/*
To add a new dPoW'ed assetchain with DEX* API support:
1. add to komodo/src: assetchains, assetchains.old, dpowassets, fiat-cli
2. add to end of NOTARY_CURRENCIES[] array in fundnotaries (iguana_notary.c)
3. create fiat/<ac_name>
4. add to m_notary coins/<ac_name> get gen_acname from where komodod was launched, change RELAY:-1 and port to 7776 and make <ac_name>_7776 variant
5. make coins/basilisk/<ac_name>
6. launch from a single node with -gen, launch a second node using -addnode=<ipaddr of 1st node> but without -gen
7. from a single node, fundnotaries <ac_name> to get notaries able to dPoW
8. m_splitfunds
*/
#ifndef iguana777_net_h
#define iguana777_net_h

11
iguana/iguana_init.c

@ -15,17 +15,6 @@
#include "iguana777.h"
/*
To add a new dPoW'ed assetchain with DEX* API support:
1. add to komodo/src: assetchains, dpowassets, fiat-cli
2. add to end of NOTARY_CURRENCIES[] array in fundnotaries (iguana_notary.c)
3. create fiat/<ac_name>
4. add to m_notary coins/<ac_name> get gen_acname from where komodod was launched, change RELAY:-1 and port to 7776 and make <ac_name>_7776 variant
5. make coins/basilisk/<ac_name>
6. launch from a single node with -gen, launch a second node using -addnode=<ipaddr of 1st node> but without -gen
7. from a single node, fundnotaries <ac_name> to get notaries able to dPoW
*/
void iguana_initQ(queue_t *Q,char *name)
{
struct stritem *tst,*item;

73
iguana/iguana_notary.c

@ -558,7 +558,78 @@ STRING_ARG(iguana,addnotary,ipaddr)
char NOTARY_CURRENCIES[][16] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD",
"CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK",
"REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "SHARK", "BOTS", "MGW", "COQUI", "WLC", "KV", "CEAL", "MESH", "MNZ", "CHIPS" }; // "LTC",
"REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "BOTS", "MGW", "COQUI", "WLC", "KV", "CEAL", "MESH", "MNZ", "CHIPS", "MSHARK", "AXO", "ETOMIC", "BTCH" }; // "LTC",
void _iguana_notarystats(char *fname,int32_t totals[64],int32_t dispflag)
{
FILE *fp; uint64_t signedmask; long fpos,startfpos; int32_t i,height,iter,prevheight;
if ( (fp= fopen(fname,"rb")) != 0 )
{
printf("opened %s\n",fname);
startfpos = 0;
prevheight = -1;
for (iter=0; iter<2; iter++)
{
while ( 1 )
{
fpos = ftell(fp);
if (fread(&height,1,sizeof(height),fp) == sizeof(height) && fread(&signedmask,1,sizeof(signedmask),fp) == sizeof(signedmask) )
{
//printf("%6d %016llx\n",height,(long long)signedmask);
if ( height < prevheight )
{
startfpos = fpos;
if ( iter == 0 )
printf("found reversed height %d vs %d\n",height,prevheight);
else printf("fpos.%ld fatal unexpected height reversal %d vs %d\n",fpos,height,prevheight);
}
if ( iter == 1 && (height >= 180000 || strcmp(fname,"signedmasks") != 0) )
{
for (i=0; i<64; i++)
{
if ( ((1LL << i) & signedmask) != 0 )
{
totals[i]++;
if ( dispflag > 1 )
printf("%2d ",i);
}
}
if ( dispflag > 1 )
printf("height.%d %016llx %s\n",height,(long long)signedmask,fname);
}
prevheight = height;
} else break;
}
if ( iter == 0 )
{
prevheight = -1;
fseek(fp,startfpos,SEEK_SET);
printf("set startfpos %ld\n",startfpos);
}
}
fclose(fp);
if ( dispflag != 0 )
{
printf("after %s\n",fname);
for (i=0; i<64; i++)
{
if ( totals[i] != 0 )
printf("%s, %d\n",Notaries_elected[i][0],totals[i]);
}
}
} else printf("couldnt open.(%s)\n",fname);
}
void iguana_notarystats(int32_t totals[64],int32_t dispflag)
{
int32_t i; char fname[512];
_iguana_notarystats("signedmasks",totals,dispflag);
for (i=0; i<sizeof(NOTARY_CURRENCIES)/sizeof(*NOTARY_CURRENCIES); i++)
{
sprintf(fname,"%s/signedmasks",NOTARY_CURRENCIES[i]);
_iguana_notarystats(fname,totals,dispflag);
}
}
ZERO_ARGS(dpow,notarychains)
{

48
iguana/m_notary

@ -2,50 +2,4 @@
pkill -15 iguana
rm -f ../agents/iguana *.o
git pull
cd secp256k1; ./m_unix; cd ..
cd ../crypto777; ./m_LP; cd ../iguana
#gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c
clang -g -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c
#gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c
clang -g -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c
clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm
../agents/iguana notary & #> iguana.log 2> error.log &
myip=`curl -s4 checkip.amazonaws.com`
source pubkey.txt
sleep 4
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"$myip\"}"
sleep 3
tests/addnotarys_7776
coins/btc_7776
coins/ltc_7776
coins/kmd_7776
coins/chips_7776
./wp_7776
coins/revs_7776
coins/supernet_7776
coins/dex_7776
coins/bet_7776
coins/bots_7776
coins/hodl_7776
coins/shark_7776
coins/jumblr_7776
coins/crypto_7776
coins/pangea_7776
coins/mgw_7776
#coins/mvp_7776
coins/coqui_7776
coins/wlc_7776
coins/kv_7776
coins/ceal_7776
coins/mesh_7776
coins/mnz_7776
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"passthru\",\"method\":\"paxfiats\",\"timeout\":900000}"
#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"$myip\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KMD\",\"pubkey\":\"$pubkey\"}"
sleep 17
./m_notary_run

50
iguana/m_notary_run

@ -0,0 +1,50 @@
#!/bin/bash
cd secp256k1; ./m_unix; cd ..
cd ../crypto777; ./m_LP; cd ../iguana
#gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c
clang -g -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c
#gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c
clang -g -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c
clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm
../agents/iguana notary & #> iguana.log 2> error.log &
myip=`curl -s4 checkip.amazonaws.com`
source pubkey.txt
sleep 4
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"$myip\"}"
sleep 3
tests/addnotarys_7776
coins/btc_7776
coins/ltc_7776
coins/kmd_7776
coins/chips_7776
./wp_7776
coins/revs_7776
coins/supernet_7776
coins/dex_7776
coins/bet_7776
coins/bots_7776
coins/hodl_7776
coins/shark_7776
coins/mshark_7776
coins/jumblr_7776
coins/crypto_7776
coins/pangea_7776
coins/mgw_7776
coins/coqui_7776
coins/wlc_7776
coins/kv_7776
coins/ceal_7776
coins/mesh_7776
coins/mnz_7776
coins/axo_7776
coins/etomic_7776
coins/btch_7776
#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"passthru\",\"method\":\"paxfiats\",\"timeout\":900000}"
#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"$myip\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KMD\",\"pubkey\":\"$pubkey\"}"

69
iguana/m_splitfund

@ -13,7 +13,7 @@ curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JUMBLR\",\"agent\":\"igua
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BET\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CRYPTO\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HODL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SHARK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MSHARK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BOTS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MGW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MVP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
@ -23,37 +23,40 @@ curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KV\",\"agent\":\"iguana\"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CEAL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MESH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MNZ\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"AXO\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BTCH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ETOMIC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"USD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"EUR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"USD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"EUR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JPY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"GBP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"AUD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CAD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CHF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NZD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CNY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RUB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MXN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BRL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"INR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HKD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"TRY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ZAR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PLN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NOK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SEK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DKK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CZK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HUF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ILS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KRW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MYR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PHP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RON\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SGD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"THB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BGN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"IDR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HRK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JPY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"GBP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"AUD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CAD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CHF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NZD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CNY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RUB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MXN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BRL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"INR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HKD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"TRY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ZAR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PLN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NOK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SEK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DKK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CZK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HUF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ILS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KRW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MYR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PHP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RON\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SGD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"THB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BGN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"IDR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HRK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"

28
iguana/main.c

@ -793,7 +793,7 @@ void iguana_launchdaemons(struct supernet_info *myinfo)
if ( COMMANDLINE_ARGFILE == 0 )
iguana_launch(0,"rpcloop",iguana_rpcloop,myinfo,IGUANA_PERMTHREAD); // limit to oneprocess
printf("launch mainloop\n");
OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)DEX_explorerloop,(void *)myinfo);
// disable basilisk: OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)DEX_explorerloop,(void *)myinfo);
OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)jumblr_loop,(void *)myinfo);
OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_psockloop,(void *)myinfo);
mainloop(myinfo);
@ -2198,11 +2198,19 @@ void iguana_main(void *arg)
{
if ( strcmp((char *)arg,"OStests") == 0 )
do_OStests = 1;
else if ( strcmp((char *)arg,"stats") == 0 )
{
void iguana_notarystats(int32_t totals[64],int32_t dispflag);
int32_t totals[64];
memset(totals,0,sizeof(totals));
iguana_notarystats(totals,1);
exit(0);
}
else if ( strcmp((char *)arg,"notary") == 0 )
{
myinfo->rpcport = IGUANA_NOTARYPORT;
myinfo->IAMNOTARY = 1;
myinfo->DEXEXPLORER = 1;
myinfo->DEXEXPLORER = 0;//1; disable as SPV is used now
}
else if ( strncmp((char *)arg,"-port=",6) == 0 )
{
@ -2262,22 +2270,6 @@ void iguana_main(void *arg)
{
basilisks_init(myinfo);
}
if ( (0) )
{
char *jsonstr = "[\"03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828\", \"02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344\", \"03750cf30d739cd7632f77c1c02812dd7a7181628b0558058d4755838117e05339\", \"0394f3529d2e8cc69ffa7a2b55f3761e7be978fa1896ef4c55dc9c275e77e5bf5e\", \"0243c1eeb3777af47187d542e5f8c84f0ac4b05cf5a7ad77faa8cb6d2d56db7823\", \"02bb298844175640a34e908ffdfa2839f77aba3d5edadefee16beb107826e00063\", \"02fa88e549b4b871498f892e527a5d57287916809f8cc3163f641d71c535e8df5a\", \"032f799e370f06476793a122fcd623db7804898fe5aef5572095cfee6353df34bf\", \"02c06fe5401faff4442ef87b7d1b56c2e5a214166615f9a2f2030c71b0cb067ae8\", \"038ac67ca49a8169bcc5de83fe020071095a2c3b2bc4d1c17386977329758956d5\"]";
int32_t i,n; char coinaddr[64]; uint8_t pubkey33[33]; double val = 0.1; cJSON *array;
if ( (array= cJSON_Parse(jsonstr)) != 0 )
{
n = cJSON_GetArraySize(array);
for (i=0; i<n; i++)
{
decode_hex(pubkey33,33,jstri(array,i));
bitcoin_address(coinaddr,60,pubkey33,33);
printf("./komodo-cli -ac_name=REVS sendtoaddress %s %f\n",coinaddr,val);
}
} else printf("couldnt parse.(%s)\n",jsonstr);
}
iguana_launchdaemons(myinfo);
}

252
iguana/mini-gmp.c

@ -2836,89 +2836,90 @@ static int gmp_detect_endian (void)
void *mpz_export (void *r, size_t *countp, int order, size_t size, int endian,size_t nails, const mpz_t u)
{
size_t count;
mp_size_t un;
if (nails != 0)
gmp_die ("mpz_import: Nails not supported.");
assert (order == 1 || order == -1);
assert (endian >= -1 && endian <= 1);
assert (size > 0 || u->_mp_size == 0);
un = u->_mp_size;
count = 0;
if (un != 0)
{
size_t k;
uint8_t *p;
ptrdiff_t word_step;
/* The current (partial) limb. */
mp_limb_t limb;
/* The number of bytes left to to in this limb. */
size_t bytes;
/* The index where the limb was read. */
mp_size_t i;
un = GMP_ABS (un);
/* Count bytes in top limb. */
limb = u->_mp_d[un-1];
assert (limb != 0);
k = 0;
do {
k++; limb >>= CHAR_BIT;
} while (limb != 0);
count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size;
if (!r)
r = malloc (count * size);
if (endian == 0)
endian = gmp_detect_endian ();
p = (uint8_t *) r;
word_step = (order != endian) ? 2 * size : 0;
/* Process bytes from the least significant end, so point p at the
least significant word. */
if (order == 1)
{
p += size * (count - 1);
word_step = - word_step;
}
/* And at least significant byte of that word. */
if (endian == 1)
p += (size - 1);
for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step)
{
size_t j;
for (j = 0; j < size; j++, p -= (ptrdiff_t) endian)
{
if (bytes == 0)
{
if (i < un)
limb = u->_mp_d[i++];
bytes = sizeof (mp_limb_t);
}
*p = limb;
limb >>= CHAR_BIT;
bytes--;
}
}
assert (i == un);
assert (k == count);
size_t count;
mp_size_t un;
if (nails != 0)
gmp_die ("mpz_import: Nails not supported.");
assert (order == 1 || order == -1);
assert (endian >= -1 && endian <= 1);
assert (size > 0 || u->_mp_size == 0);
un = u->_mp_size;
count = 0;
if (un != 0)
{
size_t k;
uint8_t *p;
ptrdiff_t word_step;
/* The current (partial) limb. */
mp_limb_t limb;
/* The number of bytes left to to in this limb. */
size_t bytes;
/* The index where the limb was read. */
mp_size_t i;
un = GMP_ABS (un);
/* Count bytes in top limb. */
limb = u->_mp_d[un-1];
assert (limb != 0);
k = 0;
do {
k++; limb >>= CHAR_BIT;
} while (limb != 0);
count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size;
if (!r)
r = malloc (count * size);
if (endian == 0)
endian = gmp_detect_endian ();
p = (uint8_t *) r;
word_step = (order != endian) ? 2 * size : 0;
/* Process bytes from the least significant end, so point p at the
least significant word. */
if (order == 1)
{
p += size * (count - 1);
word_step = - word_step;
}
/* And at least significant byte of that word. */
if (endian == 1)
p += (size - 1);
for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step)
{
size_t j;
for (j = 0; j < size; j++, p -= (ptrdiff_t) endian)
{
if (bytes == 0)
{
if (i < un)
limb = u->_mp_d[i++];
bytes = sizeof (mp_limb_t);
}
*p = limb;
//printf("{%02x} ",*p);
limb >>= CHAR_BIT;
bytes--;
}
}
assert (i == un);
assert (k == count);
}
if (countp)
*countp = count;
return r;
if (countp)
*countp = count;
//printf("mpz_export.%d\n",(int32_t)count);
return r;
}
/////////////////////////////////
@ -4360,44 +4361,6 @@ char *bitcoin_base58encode(char *coinaddr,uint8_t *data,int32_t datalen)
return(coinaddr);
}
int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr)
{
uint32_t zeroes,be_sz=0; size_t count; const char *p,*p1; mpz_t bn58,bn;
mpz_init_set_ui(bn58,58);
mpz_init_set_ui(bn,0);
while ( isspace((uint32_t)(*coinaddr & 0xff)) )
coinaddr++;
for (p=coinaddr; *p; p++)
{
p1 = strchr(base58_chars,*p);
if ( p1 == 0 )
{
while (isspace((uint32_t)*p))
p++;
if ( *p != '\0' )
{
mpz_clear(bn), mpz_clear(bn58);
return(-1);
}
break;
}
mpz_mul(bn,bn,bn58);
mpz_add_ui(bn,bn,(int32_t)(p1 - base58_chars));
}
zeroes = 0;
for (p=coinaddr; *p==base58_chars[0]; p++)
data[zeroes++] = 0;
mpz_export(data+zeroes,&count,1,sizeof(data[0]),-1,0,bn);
if ( count >= 2 && data[count - 1] == 0 && data[count - 2] >= 0x80 )
count--;
be_sz = (uint32_t)count + (uint32_t)zeroes;
//memset(data,0,be_sz);
//for (i=0; i<count; i++)
// data[i+zeroes] = revdata[count - 1 - i];
//printf(" count.%d len.%d be_sz.%d zeroes.%d data[0] %02x %02x\n",(int32_t)count,be_sz+zeroes,be_sz,zeroes,data[0],data[1]);
mpz_clear(bn), mpz_clear(bn58);
return(be_sz);
}
#include "../includes/curve25519.h"
@ -4423,6 +4386,55 @@ bits256 mpz_to_bits256(mpz_t bn)
return(x);
}
int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr)
{
uint32_t zeroes,be_sz=0; size_t count; const char *p,*p1; mpz_t bn58,bn; int32_t nonz=0;
mpz_init_set_ui(bn58,58);
mpz_init_set_ui(bn,0);
while ( isspace((uint32_t)(*coinaddr & 0xff)) )
coinaddr++;
for (p=coinaddr; *p; p++)
{
p1 = strchr(base58_chars,*p);
if ( p1 == 0 )
{
while (isspace((uint32_t)*p))
p++;
if ( *p != '\0' )
{
printf("bitcoin_base58decode error: p %02x != 0x00\n",*p);
mpz_clear(bn), mpz_clear(bn58);
return(-1);
}
break;
}
mpz_mul(bn,bn,bn58);
mpz_add_ui(bn,bn,(int32_t)(p1 - base58_chars));
//printf("%d ",(int32_t)(p1 - base58_chars));
nonz++;
}
//printf("nonz.%d\n",nonz);
zeroes = 0;
for (p=coinaddr; *p==base58_chars[0]; p++)
data[zeroes++] = 0;
mpz_export(data+zeroes,&count,1,sizeof(data[0]),-1,0,bn);
/*if ( 0 )
{
bits256 privkey; char *bits256_str(char *str,bits256 privkey);
privkey = mpz_to_bits256(bn);
char str[65]; printf("bn -> %s\n",bits256_str(str,privkey));
}*/
if ( count >= 2 && data[count - 1] == 0 && data[count - 2] >= 0x80 )
count--;
be_sz = (uint32_t)count + (uint32_t)zeroes;
//memset(data,0,be_sz);
//for (i=0; i<count; i++)
// data[i+zeroes] = revdata[count - 1 - i];
//printf(" count.%d len.%d be_sz.%d zeroes.%d data[0] %02x %02x\n",(int32_t)count,be_sz+zeroes,be_sz,zeroes,data[0],data[1]);
mpz_clear(bn), mpz_clear(bn58);
return(be_sz);
}
bits256 mpz_muldivcmp(bits256 oldval,int32_t mulval,int32_t divval,bits256 targetval)
{
mpz_t bn,target; bits256 newval;

Loading…
Cancel
Save