Browse Source

Merge pull request #486 from jl777/dev

barterDEX support, no changes for notaries
beta
jl777 7 years ago
committed by GitHub
parent
commit
6f71f71667
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      .gitignore
  2. 1
      crypto777/OS_portable.h
  3. 75
      crypto777/bitcoind_RPC.c
  4. 132
      crypto777/cJSON.c
  5. 2
      crypto777/iguana_utils.c
  6. 7
      iguana/dexscripts.win32/bot_buy.cmd
  7. 7
      iguana/dexscripts.win32/bot_list.cmd
  8. 7
      iguana/dexscripts.win32/bot_statuslist.cmd
  9. 7
      iguana/dexscripts.win32/bot_stop.cmd
  10. 9
      iguana/dexscripts.win32/electrum.cmd
  11. 2
      iguana/dexscripts.win32/help.cmd
  12. 62
      iguana/dexscripts.win32/how_to_use.md
  13. BIN
      iguana/dexscripts.win32/images/conemu_jq.png
  14. 5
      iguana/dexscripts.win32/sendrawtransaction.cmd
  15. 8
      iguana/dexscripts.win32/withdraw.cmd
  16. 14
      iguana/dexscripts.win32/withdraw_10_send.cmd
  17. 14
      iguana/dexscripts.win32/withdraw_send.cmd
  18. 4
      iguana/exchanges/DEXstats.h
  19. 4
      iguana/exchanges/LP_RTmetrics.c
  20. 101
      iguana/exchanges/LP_bitcoin.c
  21. 20
      iguana/exchanges/LP_cache.c
  22. 2
      iguana/exchanges/LP_coins.c
  23. 17
      iguana/exchanges/LP_commands.c
  24. 63
      iguana/exchanges/LP_include.h
  25. 188
      iguana/exchanges/LP_nativeDEX.c
  26. 46
      iguana/exchanges/LP_network.c
  27. 537
      iguana/exchanges/LP_ordermatch.c
  28. 2
      iguana/exchanges/LP_peers.c
  29. 8
      iguana/exchanges/LP_portfolio.c
  30. 121
      iguana/exchanges/LP_prices.c
  31. 96
      iguana/exchanges/LP_remember.c
  32. 82
      iguana/exchanges/LP_rpc.c
  33. 4
      iguana/exchanges/LP_scan.c
  34. 45
      iguana/exchanges/LP_signatures.c
  35. 52
      iguana/exchanges/LP_socket.c
  36. 185
      iguana/exchanges/LP_statemachine.c
  37. 13
      iguana/exchanges/LP_stats.c
  38. 202
      iguana/exchanges/LP_swap.c
  39. 17
      iguana/exchanges/LP_tradebots.c
  40. 689
      iguana/exchanges/LP_transaction.c
  41. 286
      iguana/exchanges/LP_utxo.c
  42. 97
      iguana/exchanges/LP_utxos.c
  43. 2
      iguana/exchanges/install
  44. 4
      iguana/exchanges/invreset
  45. 8
      iguana/exchanges/mm.c
  46. 8
      iguana/exchanges/stats.c
  47. 2
      iguana/m_mm
  48. 3
      includes/cJSON.h
  49. 8
      marketmaker.vcxproj
  50. 82
      marketmaker_build_32_64.cmd

4
.gitignore

@ -489,3 +489,7 @@ iguana/DB/PRICES/.tmpmarker
iguana/DB/KMD/0/.tmpmarker
*.swp
iguana/myipaddr
iguana/DB/UNSPENTS/.tmpmarker

1
crypto777/OS_portable.h

@ -276,6 +276,7 @@ void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize,int32_
void *queue_free(queue_t *queue);
void *queue_clone(queue_t *clone,queue_t *queue,int32_t size);
int32_t queue_size(queue_t *queue);
char *mbstr(char *str,double n);
void iguana_memreset(struct OS_memspace *mem);
void iguana_mempurge(struct OS_memspace *mem);

75
crypto777/bitcoind_RPC.c

@ -13,10 +13,24 @@
* *
******************************************************************************/
#ifndef FROM_JS
#include "OS_portable.h"
#define LIQUIDITY_PROVIDER 1
/*#define malloc(n) LP_alloc(n)
#define realloc(ptr,n) LP_realloc(ptr,n)
#define calloc(a,b) LP_alloc((uint64_t)(a) * (b))
#define free(ptr) LP_free(ptr)
#define clonestr(str) LP_clonestr(str)
void *LP_realloc(void *ptr,uint64_t len);
void *LP_alloc(uint64_t len);
void LP_free(void *ptr);
char *LP_clonestr(char *str);*/
#if LIQUIDITY_PROVIDER
#include <curl/curl.h>
#include <curl/easy.h>
@ -31,8 +45,11 @@ struct return_string {
size_t len;
};
struct MemoryStruct { char *memory; size_t size,allocsize; };
size_t accumulate(void *ptr, size_t size, size_t nmemb, struct return_string *s);
void init_string(struct return_string *s);
static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data);
/************************************************************************
@ -56,7 +73,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
char *retstr = 0;
cJSON *json,*result,*error;
#ifdef FROM_MARKETMAKER
usleep(5000);
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 )
@ -78,7 +95,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 = cJSON_Print(result);
retstr = jprint(result,0);
len = strlen(retstr);
if ( retstr[0] == '"' && retstr[len-1] == '"' )
{
@ -122,8 +139,9 @@ char *Jay_NXTrequest(char *command,char *params)
char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout)
{
static int didinit,count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY;
struct MemoryStruct chunk;
struct curl_slist *headers = NULL; struct return_string s; CURLcode res; CURL *curl_handle;
char *bracket0,*bracket1,*databuf = 0; long len; int32_t specialcase,numretries; double starttime;
char *bracket0,*bracket1,*retstr,*databuf = 0; long len; int32_t specialcase,numretries; double starttime;
if ( didinit == 0 )
{
didinit = 1;
@ -147,14 +165,24 @@ try_again:
*retstrp = 0;
starttime = OS_milliseconds();
curl_handle = curl_easy_init();
init_string(&s);
headers = curl_slist_append(0,"Expect:");
curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )");
curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl_handle,CURLOPT_URL, url);
curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulate); // send all data to this function
curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback
if ( (0) )
{
init_string(&s);
curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulate); // send all data to this function
curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback
}
else
{
memset(&chunk,0,sizeof(chunk));
curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION,WriteMemoryCallback);
curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA,(void *)&chunk);
}
curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash
curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS, 1L); // no progress callback
if ( timeout > 0 )
@ -209,23 +237,24 @@ try_again:
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(s.ptr);
free(chunk.memory); //free(s.ptr);
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(s.ptr);
free(chunk.memory);//free(s.ptr);
return(0);
}
free(s.ptr);
free(chunk.memory);//free(s.ptr);
sleep((1<<numretries));
goto try_again;
}
else
{
retstr = chunk.memory; // retstr = s.ptr;
if ( command != 0 && specialcase == 0 )
{
count++;
@ -234,20 +263,20 @@ try_again:
printf("%d: ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,elapsedsum/count,(OS_milliseconds() - starttime),command,url);
if ( retstrp != 0 )
{
*retstrp = s.ptr;
return(s.ptr);
*retstrp = retstr;
return(retstr);
}
return(post_process_bitcoind_RPC(debugstr,command,s.ptr,params));
return(post_process_bitcoind_RPC(debugstr,command,retstr,params));
}
else
{
if ( (0) && specialcase != 0 )
fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: BTCD.(%s) -> (%s)\n",params,s.ptr);
fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: BTCD.(%s) -> (%s)\n",params,retstr);
count2++;
elapsedsum2 += (OS_milliseconds() - starttime);
if ( (count2 % 10000) == 0)
printf("%d: ave %9.6f | elapsed %.3f millis | NXT calls.(%s) cmd.(%s)\n",count2,elapsedsum2/count2,(double)(OS_milliseconds() - starttime),url,command);
return(s.ptr);
return(retstr);
}
}
//printf("bitcoind_RPC: impossible case\n");
@ -294,13 +323,23 @@ size_t accumulate(void *ptr,size_t size,size_t nmemb,struct return_string *s)
return(size * nmemb);
}
struct MemoryStruct { char *memory; size_t size; };
static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data)
{
size_t realsize = (size * nmemb);
size_t needed,realsize = (size * nmemb);
struct MemoryStruct *mem = (struct MemoryStruct *)data;
mem->memory = (ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1);
needed = mem->size + realsize + 1;
if ( ptr == 0 && needed < 256 )
{
mem->allocsize = 256;
mem->memory = malloc(mem->allocsize);
}
if ( mem->allocsize < needed )
{
//printf("curl needs %d more\n",(int32_t)realsize);
mem->memory = (ptr != 0) ? realloc(mem->memory,needed) : malloc(needed);
mem->allocsize = needed;
}
//mem->memory = (ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1);
if ( mem->memory != 0 )
{
if ( ptr != 0 )

132
crypto777/cJSON.c

@ -54,8 +54,43 @@ static int32_t cJSON_strcasecmp(const char *s1,const char *s2)
return tolower((int32_t)(*(const unsigned char *)s1)) - tolower((int32_t)(*(const unsigned char *)s2));
}
static void *(*cJSON_malloc)(size_t sz) = malloc;
static void (*cJSON_free)(void *ptr) = free;
void *LP_alloc(uint64_t len);
void LP_free(void *ptr);
static void *(*cJSON_malloc)(size_t sz) = (void *)malloc;//LP_alloc;
static void (*cJSON_free)(void *ptr) = free;//LP_free;
static void *cJSON_mallocstr(int32_t len)
{
return(cJSON_malloc(len));
}
static char **cJSON_mallocptrs(int32_t num,char **space,int32_t max)
{
if ( num < max )
return(space);
else return(cJSON_malloc(num * sizeof(char *)));
}
static void *cJSON_mallocnode()
{
return(cJSON_malloc(sizeof(cJSON)));
}
static void cJSON_freeptrs(char **ptrs,int32_t num,char **space)
{
if ( ptrs != space )
cJSON_free(ptrs);
}
static void cJSON_freestr(char *str)
{
cJSON_free(str);
}
static void cJSON_freenode(cJSON *item)
{
cJSON_free(item);
}
static char* cJSON_strdup(const char* str)
{
@ -63,7 +98,7 @@ static char* cJSON_strdup(const char* str)
char* copy;
len = strlen(str) + 1;
if (!(copy = (char*)cJSON_malloc(len+1))) return 0;
if (!(copy = (char*)cJSON_mallocstr((int32_t)len+1))) return 0;
memcpy(copy,str,len);
return copy;
}
@ -76,14 +111,14 @@ void cJSON_InitHooks(cJSON_Hooks* hooks)
return;
}
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
}
/* Internal constructor. */
static cJSON *cJSON_New_Item(void)
{
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
cJSON* node = (cJSON*)cJSON_mallocnode();
if (node) memset(node,0,sizeof(cJSON));
return node;
}
@ -96,9 +131,9 @@ void cJSON_Delete(cJSON *c)
{
next=c->next;
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
if (c->string) cJSON_free(c->string);
cJSON_free(c);
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_freestr(c->valuestring);
if (c->string) cJSON_freestr(c->string);
cJSON_freenode(c);
c=next;
}
}
@ -132,13 +167,13 @@ static char *print_number(cJSON *item)
double d = item->valuedouble;
if ( fabs(((double)item->valueint) - d) <= DBL_EPSILON && d >= (1. - DBL_EPSILON) && d < (1LL << 62) )//d <= INT_MAX && d >= INT_MIN )
{
str = (char *)cJSON_malloc(24); /* 2^64+1 can be represented in 21 chars + sign. */
str = (char *)cJSON_mallocstr(24); /* 2^64+1 can be represented in 21 chars + sign. */
if ( str != 0 )
sprintf(str,"%lld",(long long)item->valueint);
}
else
{
str = (char *)cJSON_malloc(66); /* This is a nice tradeoff. */
str = (char *)cJSON_mallocstr(66); /* This is a nice tradeoff. */
if ( str != 0 )
{
if ( fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60 )
@ -173,7 +208,7 @@ static const char *parse_string(cJSON *item,const char *str)
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; // Skip escaped quotes
out=(char*)cJSON_malloc(len+2); /* This is how long we need for the string, roughly. */
out=(char*)cJSON_mallocstr(len+2); /* This is how long we need for the string, roughly. */
if (!out) return 0;
ptr=str+1;ptr2=out;
@ -238,7 +273,7 @@ static char *print_string_ptr(const char *str)
if (!str) return cJSON_strdup("");
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
out=(char*)cJSON_malloc(len+3+1);
out=(char*)cJSON_mallocstr(len+3+1);
if (!out) return 0;
ptr2=out;ptr=str;
@ -372,7 +407,7 @@ static const char *parse_array(cJSON *item,const char *value)
/* Render an array to text */
static char *print_array(cJSON *item,int32_t depth,int32_t fmt)
{
char **entries;
char **entries,*space_entries[512];
char *out=0,*ptr,*ret;int32_t len=5;
cJSON *child=item->child;
int32_t numentries=0,i=0,fail=0;
@ -382,12 +417,12 @@ static char *print_array(cJSON *item,int32_t depth,int32_t fmt)
/* Explicitly handle numentries==0 */
if (!numentries)
{
out=(char*)cJSON_malloc(3+1);
out=(char*)cJSON_mallocstr(3+1);
if (out) strcpy(out,"[]");
return out;
}
/* Allocate an array to hold the values for each */
entries=(char**)cJSON_malloc((1+numentries)*sizeof(char*));
entries=cJSON_mallocptrs(1+numentries,space_entries,sizeof(space_entries)/sizeof(*space_entries));
if (!entries) return 0;
memset(entries,0,numentries*sizeof(char*));
/* Retrieve all the results: */
@ -401,15 +436,15 @@ static char *print_array(cJSON *item,int32_t depth,int32_t fmt)
}
/* If we didn't fail, try to malloc the output string */
if (!fail) out=(char*)cJSON_malloc(len+1);
if (!fail) out=(char*)cJSON_mallocstr(len+1);
/* If that fails, we fail. */
if (!out) fail=1;
/* Handle failure. */
if (fail)
{
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
cJSON_free(entries);
for (i=0;i<numentries;i++) if (entries[i]) cJSON_freestr(entries[i]);
cJSON_freeptrs(entries,numentries,space_entries);
return 0;
}
@ -420,9 +455,9 @@ static char *print_array(cJSON *item,int32_t depth,int32_t fmt)
{
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
cJSON_free(entries[i]);
cJSON_freestr(entries[i]);
}
cJSON_free(entries);
cJSON_freeptrs(entries,numentries,space_entries);
*ptr++=']';*ptr++=0;
return out;
}
@ -466,7 +501,7 @@ static const char *parse_object(cJSON *item,const char *value)
/* Render an object to text. */
static char *print_object(cJSON *item,int32_t depth,int32_t fmt)
{
char **entries=0,**names=0;
char **entries=0,**names=0,*space_entries[512],*space_names[512];
char *out=0,*ptr,*ret,*str;int32_t len=7,i=0,j;
cJSON *child=item->child,*firstchild;
int32_t numentries=0,fail=0;
@ -485,7 +520,7 @@ static char *print_object(cJSON *item,int32_t depth,int32_t fmt)
/* Explicitly handle empty object case */
if (!numentries)
{
out=(char*)cJSON_malloc(fmt?depth+4+1:3+1);
out=(char*)cJSON_mallocstr(fmt?depth+4+1:3+1);
if (!out) return 0;
ptr=out;*ptr++='{';
if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
@ -493,10 +528,10 @@ static char *print_object(cJSON *item,int32_t depth,int32_t fmt)
return out;
}
/* Allocate space for the names and the objects */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
entries=(char**)cJSON_mallocptrs(numentries,space_entries,sizeof(space_entries)/sizeof(*space_entries));
if (!entries) return 0;
names=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!names) {cJSON_free(entries);return 0;}
names=(char**)cJSON_mallocptrs(numentries,space_names,sizeof(space_names)/sizeof(*space_names));
if (!names) {cJSON_freeptrs(entries,numentries,space_entries);return 0;}
memset(entries,0,sizeof(char*)*numentries);
memset(names,0,sizeof(char*)*numentries);
@ -513,14 +548,15 @@ static char *print_object(cJSON *item,int32_t depth,int32_t fmt)
}
/* Try to allocate the output string */
if (!fail) out=(char*)cJSON_malloc(len+1);
if (!fail) out=(char*)cJSON_mallocstr(len+1);
if (!out) fail=1;
/* Handle failure */
if (fail)
{
for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
cJSON_free(names);cJSON_free(entries);
for (i=0;i<numentries;i++) {if (names[i]) cJSON_freestr(names[i]);if (entries[i]) cJSON_freestr(entries[i]);}
cJSON_freeptrs(names,numentries,space_names);
cJSON_freeptrs(entries,numentries,space_entries);
return 0;
}
@ -534,10 +570,11 @@ static char *print_object(cJSON *item,int32_t depth,int32_t fmt)
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-1) *ptr++=',';
if (fmt) *ptr++='\n';*ptr=0;
cJSON_free(names[i]);cJSON_free(entries[i]);
cJSON_freestr(names[i]);cJSON_freestr(entries[i]);
}
cJSON_free(names);cJSON_free(entries);
cJSON_freeptrs(names,numentries,space_names);
cJSON_freeptrs(entries,numentries,space_entries);
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
*ptr++='}';*ptr++=0;
return out;
@ -578,8 +615,6 @@ cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->t
cJSON *cJSON_CreateBool(int32_t b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int64_t)num;}return item;}
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
/* Create Arrays: */
cJSON *cJSON_CreateIntArray(int64_t *numbers,int32_t count) {int32_t i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber((double)numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
@ -1129,4 +1164,33 @@ cJSON *addrs_jsonarray(uint64_t *addrs,int32_t num)
return(array);
}
void free_json(cJSON *json) { if ( json != 0 ) cJSON_Delete(json); }
cJSON *cJSON_CreateArray(void)
{
cJSON *item = cJSON_New_Item();
if ( item )
item->type = cJSON_Array;
//#ifdef CJSON_GARBAGECOLLECTION
// cJSON_register(item);
//#endif
return(item);
}
cJSON *cJSON_CreateObject(void)
{
cJSON *item = cJSON_New_Item();
if ( item )
item->type = cJSON_Object;
//#ifdef CJSON_GARBAGECOLLECTION
// cJSON_register(item);
//#endif
return item;
}
void free_json(cJSON *item)
{
//#ifdef CJSON_GARBAGECOLLECTION
// cJSON_unregister(item);
//#endif
if ( item != 0 )
cJSON_Delete(item);
}

2
crypto777/iguana_utils.c

@ -446,7 +446,6 @@ char *clonestr(char *str)
return(clone);
}
int32_t safecopy(char *dest,char *src,long len)
{
int32_t i = -1;
@ -459,6 +458,7 @@ int32_t safecopy(char *dest,char *src,long len)
if ( i == len )
{
printf("safecopy: %s too long %ld\n",src,len);
//printf("divide by zero! %d\n",1/zeroval());
#ifdef __APPLE__
//getchar();
#endif

7
iguana/dexscripts.win32/bot_buy.cmd

@ -0,0 +1,7 @@
@echo off
set /p TMPUSERPASS=<userpass
set USERPASS=%TMPUSERPASS: =%
set /p PASSPHRASE=<passphrase
echo passphrase: "%PASSPHRASE%"
echo userpass: "%USERPASS%"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"bot_buy\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"maxprice\":0.20,\"relvolume\":10.0}"

7
iguana/dexscripts.win32/bot_list.cmd

@ -0,0 +1,7 @@
@echo off
set /p TMPUSERPASS=<userpass
set USERPASS=%TMPUSERPASS: =%
set /p PASSPHRASE=<passphrase
rem echo passphrase: "%PASSPHRASE%"
rem echo userpass: "%USERPASS%"
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"bot_list\"}"

7
iguana/dexscripts.win32/bot_statuslist.cmd

@ -0,0 +1,7 @@
@echo off
set /p TMPUSERPASS=<userpass
set USERPASS=%TMPUSERPASS: =%
set /p PASSPHRASE=<passphrase
rem echo passphrase: "%PASSPHRASE%"
rem echo userpass: "%USERPASS%"
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"bot_statuslist\"}"

7
iguana/dexscripts.win32/bot_stop.cmd

@ -0,0 +1,7 @@
@echo off
set /p TMPUSERPASS=<userpass
set USERPASS=%TMPUSERPASS: =%
set /p PASSPHRASE=<passphrase
rem echo passphrase: "%PASSPHRASE%"
rem echo userpass: "%USERPASS%"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"bot_stop\",\"botid\":1376557535}"

9
iguana/dexscripts.win32/electrum.cmd

@ -0,0 +1,9 @@
@echo off
rem http://pad.supernet.org/electrum-servers
set /p TMPUSERPASS=<userpass
set USERPASS=%TMPUSERPASS: =%
set /p PASSPHRASE=<passphrase
echo passphrase: "%PASSPHRASE%"
echo userpass: "%USERPASS%"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"electrum\",\"coin\":\"KMD\",\"ipaddr\":\"electrum.cipig.net\",\"port\":10001}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"electrum\",\"coin\":\"MNZ\",\"ipaddr\":\"electrum.cipig.net\",\"port\":10002}"

2
iguana/dexscripts.win32/help.cmd

@ -0,0 +1,2 @@
@echo off
curl --url "http://127.0.0.1:7783" --data "{\"method\":\"help\"}"

62
iguana/dexscripts.win32/how_to_use.md

@ -1,15 +1,15 @@
## DexScripts for Windows. How to use? ##
**1. ** Before start you should put scripts and following binaries into one folder:
**1.** Before start you should put scripts and following binaries into one folder:
- curl.exe (required for all scripts)
- marketmaker.exe
- libcurl.dll (required to run marketmaker)
- nanomsg.dll (required to run marketmaker)
**2. ** Don't forget to put `coins.json` file into a same folder. This file is available it this repo.
**2.** Don't forget to put `coins.json` file into a same folder. This file is available it this repo.
**3. ** Type your passphrase into passphrase file in this folder (you should create file with name `passphrase` and without extension) and run `1-client.cmd`. This will run marketmaker. Next step is to obtain userpass needed for other scripts, you can simply copy and paste it from marketmaker output on startup into userpass file.
**3.** Type your passphrase into passphrase file in this folder (you should create file with name `passphrase` and without extension) and run `1-client.cmd`. This will run marketmaker. Next step is to obtain userpass needed for other scripts, you can simply copy and paste it from marketmaker output on startup into userpass file.
![](./images/userpass.png)
@ -23,9 +23,41 @@ You should see your userpass on screen, and after it will automatically copied i
**4.** For using other scripts please refer to barterDEX API. Or **barterDEX API Summary by Category** document by *shossain*.
## Scripts List ##
**NB!** Before you use any script that do some actions with your coins (for example, withdraw and others) **edit it** and make sure that it have correct addresses, coin name and volumes inside. Don't run any scripts without looking on it's source and clearly understanding what it does.
* **1-client.cmd** - used to start Marketmaker. Make sure you already have filled a strong passphrase into `passphrase` file as described above.
* **2-getuserpass.cmd** - fills userpass in `userpass` file. this step needed to use any other scripts.
* **balance.cmd** - displays current balance of selected coin.
* **enable.cmd** - enables a selected coin for trading.
* **getcoin.cmd** - prints information about a selecting coin:
{"result":"success","enabled":2,"disabled":70,"coin":{"coin":"KMD","installed":true,"height":580716,"balance":72.68774305,"KMDvalue":72.68774305,"status":"active","electrum":"electrum.cipig.net:10001","smartaddress":"RTCVGuoSNehKG8YYxcoskC7LK1yZhgvQRV","rpc":"127.0.0.1:7771","pubtype":60,"p2shtype":85,"wiftype":188,"txfee":10000}}
* **getutxos.cmd** - seems alredy deprecated.
* **inventory.cmd** - prints your inventory.
* **listunspent.cmd** - prints your utxos.
* **orderbook.cmd** - prints base/rel orderbook.
* **portfolio.cmd** - prints porfolio information.
* **snapshot.cmd** - ...
* **electrum.cmd** - allows you to run coins in electum mode (!), example includes two coins - KMD and MNZ. if you need to run more coins in electrum mode, add needed electrum servers from here - [http://pad.supernet.org/electrum-servers](http://pad.supernet.org/electrum-servers).
* **help.cmd** - displays help about all available API commands.
* **bot_buy.cmd** - launches bot for buying. you'll need to set base and rel coin in script, and also maxprice and relvolume.
* **bot_list.cmd** - lists id of all running bots.
* **bot_statuslist.cmd** - list statuses of all running bots.
* **bot_stop.cmd** - stopt the bot with given bot_id.
* **withdraw.cmd** - example of withdraw method. you can send coins from your smartaddress to any other address using widthraw. as a result method generates signed raw tx in hex, which you can use with sendrawtransaction.cmd . remember, that withdraw only *prepares* transaction, but it doesn't broadcast (send) it to network. after tx is prepared we need to send it using sendrawtransaction method.
* **sendrawtransaction.cmd** - sends raw transaction. you'll need a signedtx in hex.
* **withdraw_send.cmd** - combines withdraw and send raw tx scripts. you can call it `send`, just specify coin, volume and addresses to which you wan send coins and it will prepare and broadcast transaction automatically.
* **withdraw_10_send.cmd** - example of inventory split: this split 10 KMD from your balance to Alice inventory in 10 utxos pairs (1.002, 0.00386871). Strongly recommended to read [http://pad.supernet.org/barterdex-readme](http://pad.supernet.org/barterdex-readme) -> UTXO PAIRS to understand the basics. This script is just for example how you can split your coins in (X, X/777) to start trading them.
## F.A.Q. ##
**Q.** Is any simple way how i can display JSON results returned by all scripts, like orderbook and others, in human readable form?
**A.** Yes, you can use this service [JSON Editor Online](http://jsoneditoronline.org/), just copy and paste output of script in left column and see structured output in right.
**Q.** I see an output like this when i'm start `1-client.cmd` :
@ -42,3 +74,27 @@ And nothing works.
**A.** Before run `1-client.cmd` make sure in Task Manager that you haven't already running `marketmaker.exe`. If have - kill this process via Task Manager or via command line command `taskkill /f /im taskkill.exe` .
**Q.** How can i pretty print JSON answers of marketmaker?
**A.** You can get best results with 2 tools - [conemu](https://conemu.github.io/) and [jq](https://stedolan.github.io/jq/), conemu supports ANSI X3.64 and Xterm 256 colors and jq allow you to pretty-print json output with colors, like this:
![](./images/conemu_jq.png)
Also i'm always recommend to install [Far Manager](https://www.farmanager.com/index.php?l=en) - this is powerful console file manager for Windows, like Midnight Commander in *nix.
**Q.** What additional dependencies required by marketmaker?
**A.** Currently marketmaker (Windows) used the following DLLs:
*32 bit:*
- libcrypto-1_1.dll
- libcurl.dll
- libssl-1_1.dll
- nanomsg.dll
- pthreadvc2.dll
*64-bit:*
- libcurl.dll
- nanomsg.dll
It already included in repo and in archive with release.

BIN
iguana/dexscripts.win32/images/conemu_jq.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

5
iguana/dexscripts.win32/sendrawtransaction.cmd

@ -0,0 +1,5 @@
@echo off
set /p TMPUSERPASS=<userpass
set USERPASS=%TMPUSERPASS: =%
set HEX=your_signed_raw_tx
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"sendrawtransaction\",\"coin\":\"KMD\",\"signedtx\":%HEX%"\"}"

8
iguana/dexscripts.win32/withdraw.cmd

@ -0,0 +1,8 @@
@echo off
set /p TMPUSERPASS=<userpass
set USERPASS=%TMPUSERPASS: =%
rem *** Change coin and outputs before use (!) ***
set COIN=KMD
set OUTPUTS=[{\"RDecker69MM5dhDBosUXPNTzfoGqxPQqHu\":0.00007777}]
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"withdraw\",\"coin\":\"%COIN%\",\"outputs\":%OUTPUTS%}" > withdraw.txt
type withdraw.txt

14
iguana/dexscripts.win32/withdraw_10_send.cmd

@ -0,0 +1,14 @@
@echo off
set /p TMPUSERPASS=<userpass
set USERPASS=%TMPUSERPASS: =%
rem *** Change coin and outputs before use (!) ***
set COIN=KMD
set SMARTADDRESS=RDecker69MM5dhDBosUXPNTzfoGqxPQqHu
set OUTPUTS=[{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871},{\"%SMARTADDRESS%\":1.002},{\"%SMARTADDRESS%\":0.00386871}]
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"withdraw\",\"coin\":\"%COIN%\",\"outputs\":%OUTPUTS%}" > withdraw.txt
type withdraw.txt
timeout /t 5 /nobreak
for /f "tokens=4 delims=:," %%a in (' find "hex" "withdraw.txt" ') do (
rem echo [%%~a]
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"sendrawtransaction\",\"coin\":\"%COIN%\",\"signedtx\":\"%%~a\"}"
)

14
iguana/dexscripts.win32/withdraw_send.cmd

@ -0,0 +1,14 @@
@echo off
set /p TMPUSERPASS=<userpass
set USERPASS=%TMPUSERPASS: =%
rem *** Change coin and outputs before use (!) ***
set COIN=KMD
set OUTPUTS=[{\"RDecker69MM5dhDBosUXPNTzfoGqxPQqHu\":0.00007777}]
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"withdraw\",\"coin\":\"%COIN%\",\"outputs\":%OUTPUTS%}" > withdraw.txt
type withdraw.txt
timeout /t 5 /nobreak
for /f "tokens=4 delims=:," %%a in (' find "hex" "withdraw.txt" ') do (
rem echo [%%~a]
curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"sendrawtransaction\",\"coin\":\"%COIN%\",\"signedtx\":\"%%~a\"}"
)

4
iguana/exchanges/DEXstats.h

@ -51,7 +51,7 @@ struct DEXstats_pricepoint
struct DEXstats_pairinfo
{
char dest[16];
char dest[128];
int32_t numprices;
struct DEXstats_pricepoint *prices;
};
@ -64,7 +64,7 @@ struct DEXstats_datenuminfo
struct DEXstats_priceinfo
{
char symbol[16];
char symbol[128];
int32_t firstdatenum,numdates;
struct DEXstats_datenuminfo *dates;
} Prices[1024];

4
iguana/exchanges/LP_RTmetrics.c

@ -29,7 +29,7 @@ struct LP_metricinfo
struct LP_RTmetrics_pendings
{
char refbase[16],refrel[16];
char refbase[65],refrel[65];
int32_t numswaps,numavoidtxids,numwhitelist,numblacklist,numpendings,pending_swaps[1024];
bits256 avoidtxids[8192],whitelist[1024],blacklist[1024],pending_pubkeys[1024];
} LP_RTmetrics;
@ -161,7 +161,7 @@ void LP_RTmetrics_update(char *base,char *rel)
{
if ( (swaps= jarray(&numswaps,statsjson,"swaps")) != 0 )
{
printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0));
//printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0));
if ( numswaps > 0 )
LP_RTmetrics_swapsinfo(base,rel,swaps,numswaps);
}

101
iguana/exchanges/LP_bitcoin.c

@ -2340,7 +2340,7 @@ 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,int32_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(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 j,n,siglen,plen; uint8_t *p2shscript;
j = n = 0;
@ -2583,6 +2583,39 @@ 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;
@ -3198,6 +3231,7 @@ cJSON *iguana_voutjson(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,struct igu
jadd(json,"scriptPubKey",skey);
}
}
free(vp);
return(json);
}
@ -3247,7 +3281,7 @@ int32_t iguana_vinarray_check(cJSON *vinarray,bits256 txid,int32_t vout)
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);
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,int32_t hashtype,char *vpnstr,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)
{
int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest;
dest = *msgtx;
@ -3330,7 +3364,7 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj
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 i,n,len = 0,extraused=0; uint8_t 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]; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version);
if ( json != 0 )
@ -3350,6 +3384,22 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is
if ( json != 0 )
jaddnum(json,"timestamp",msg->timestamp);
}
if ( rwflag == 0 && zcash == 0 )
{
/*
normal: nVersion|txins|txouts|nLockTime.
segwit
nVersion|marker|flag|txins|txouts|witness|nLockTime
Format of nVersion, txins, txouts, and nLockTime are same as the original format
The marker MUST be 0x00
The flag MUST be 0x01
*/
if ( serialized[len] == 0x00 && (segwitflag= serialized[len+1]) == 0x01 )
{
len += 2;
//printf("SEGWIT transaction\n");
}
}
len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in);
if ( rwflag == 0 )
{
@ -3417,6 +3467,40 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is
if ( voutarray != 0 )
jaddi(voutarray,iguana_voutjson(taddr,pubtype,p2shtype,&msg->vouts[i],i,*txidp));
}
if ( segwitflag != 0 )
{
segtxlen = len - 2 + sizeof(msg->lock_time);
segtx = malloc(segtxlen);
memcpy(segtx,serialized,sizeof(int32_t));
memcpy(&segtx[sizeof(int32_t)],&serialized[sizeof(int32_t)+2],len-2-sizeof(int32_t));
//printf("tx_out %d, tx_in %d %02x %02x %02x\n",msg->tx_out,msg->tx_in,serialized[len],serialized[len+1],serialized[len+2]);
if ( rwflag != 0 )
printf("unsupported rwflag.%d when segwitflag\n",rwflag);
else
{
for (i=0; i<msg->tx_in; i++)
{
len += iguana_rwvarint32(rwflag,&serialized[len],&segitems);
//printf("vini.%d (%d:",i,segitems);
for (j=0; j<segitems; j++)
{
len += iguana_rwvarint32(rwflag,&serialized[len],&tmp);
//printf(" %d",tmp);
if ( len+tmp >= maxsize )
{
printf("vini.%d of %d, j.%d of segitems.%d overflowed %d+%d >= max.%d\n",i,msg->tx_in,j,segitems,len,tmp,maxsize);
break;
} else len += tmp;
}
//printf("), ");
}
memcpy(&segtx[segtxlen-sizeof(int32_t)],&serialized[len],sizeof(int32_t));
*txidp = bits256_doublesha256(0,segtx,segtxlen);
free(segtx);
//char str[65]; printf("witness sum %d vs max.%d txid %s\n",len,maxsize,bits256_str(str,txid));
}
}
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time);
//printf("lock_time.%08x len.%d\n",msg->lock_time,len);
if ( zcash == LP_IS_ZCASHPROTOCOL && msg->version > 1 )
@ -3449,8 +3533,12 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is
memset(sigtxid.bytes,0,sizeof(sigtxid));
if ( vins != 0 && jitem(vins,i) != 0 )
{
uint32_t sighash;
iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript));
sigtxid = bitcoin_sigtxid(taddr,pubtype,p2shtype,isPoS,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,SIGHASH_ALL,vpnstr,suppress_pubkeys,zcash);
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);
//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));
@ -3469,7 +3557,8 @@ int32_t iguana_rwmsgtx(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t is
jadd(json,"vout",voutarray);
jaddnum(json,"numvouts",msg->tx_out);
}
*txidp = bits256_doublesha256(txidstr,txstart,len);
if ( segwitflag == 0 )
*txidp = bits256_doublesha256(txidstr,txstart,len);
if ( json != 0 )
{
jaddnum(json,"locktime",msg->lock_time);
@ -3603,7 +3692,7 @@ cJSON *bitcoin_data2json(uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t
if ( n != len )
{
int32_t i;
for (i=0; i<len; i++)
for (i=0; i<len&&i<n; i++)
printf("%02x",serialized[i]);
printf(" data2json n.%d vs len.%d\n",n,len);
}

20
iguana/exchanges/LP_cache.c

@ -45,10 +45,10 @@ 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 = serialized;
//free(serialized);
tx->serialized = 0;//serialized;
free(serialized);
tx->fpos = fpos;
tx->len = tx->len;
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++)
@ -58,7 +58,7 @@ struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 tx
tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest");
LP_destaddr(tx->outpoints[i].coinaddr,vout);
//printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value));
LP_address_utxoadd("LP_create_transaction",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1);
LP_address_utxoadd((uint32_t)time(NULL),"LP_create_transaction",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1);
}
for (i=0; i<numvins; i++)
{
@ -76,7 +76,7 @@ struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 tx
tx->outpoints[spentvout].spendtxid = txid;
tx->outpoints[spentvout].spendvini = i;
tx->outpoints[spentvout].spendheight = height > 0 ? height : 1;
LP_address_utxoadd("LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1);
LP_address_utxoadd((uint32_t)time(NULL),"LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1);
if ( 0 && strcmp(coin->symbol,"REVS") == 0 )
printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height);
}
@ -235,7 +235,7 @@ int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_i
return(0);
if ( (tx= LP_transactionfind(coin,txid)) == 0 && strcmp(coinaddr,coin->smartaddr) == 0 )
{
if ( (retjson= electrum_transaction(coin->symbol,ep,&retjson,txid)) != 0 )
if ( (retjson= electrum_transaction(coin->symbol,ep,&retjson,txid,0)) != 0 )
free_json(retjson);
}
if ( tx != 0 )
@ -247,7 +247,7 @@ int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_i
if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 )
{
char str[65],str2[65],str3[65];
SPV = -1;
SPV = 0;
memset(roothash.bytes,0,sizeof(roothash));
if ( (merkles= jarray(&m,merkobj,"merkle")) != 0 )
{
@ -271,7 +271,11 @@ int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_i
}
//printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash));
}
else printf("ERROR MERK %s ht.%d -> %s root.(%s) vs %s\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash),bits256_str(str3,merkleroot));
else
{
SPV = -1;
printf("ERROR MERK %s ht.%d -> %s root.(%s) vs %s\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash),bits256_str(str3,merkleroot));
}
} else SPV = 0;
}
if ( SPV < 0 )

2
iguana/exchanges/LP_coins.c

@ -229,7 +229,7 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif)
jaddnum(item,"pubtype",coin->pubtype);
jaddnum(item,"p2shtype",coin->p2shtype);
jaddnum(item,"wiftype",coin->wiftype);
jaddnum(item,"txfee",coin->txfee);
jaddnum(item,"txfee",strcmp(coin->symbol,"BTC") != 0 ? coin->txfee : LP_txfeecalc(coin,0,0));
return(item);
}

17
iguana/exchanges/LP_commands.c

@ -35,8 +35,10 @@ 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;
//printf("stats_JSON(%s)\n",jprint(argjson,0));
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);
/*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 )
@ -103,7 +105,7 @@ notarizations(coin)\n\
parselog()\n\
statsdisp(starttime=0, endtime=0, gui="", pubkey="")\n\
getrawtransaction(coin, txid)\n\
inventory(coin)\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\
@ -431,7 +433,7 @@ bot_resume(botid)\n\
}
else if ( strcmp(method,"getrawtransaction") == 0 )
{
return(jprint(LP_gettx(coin,jbits256(argjson,"txid")),0));
return(jprint(LP_gettx(coin,jbits256(argjson,"txid")),1));
}
else if ( strcmp(method,"withdraw") == 0 )
{
@ -484,10 +486,13 @@ bot_resume(botid)\n\
struct iguana_info *ptr;
if ( (ptr= LP_coinfind(coin)) != 0 )
{
//privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,ptr,"",USERPASS_WIFSTR);
//LP_utxopurge(0);
LP_address(ptr,ptr->smartaddr);
LP_listunspent_issue(coin,ptr->smartaddr,2);
if ( jint(argjson,"reset") != 0 )
{
ptr->privkeydepth = 0;
LP_address_utxo_reset(ptr);
LP_passphrase_init(jstr(argjson,"passphrase"),G.gui);
}
if ( bits256_nonz(G.LP_privkey) != 0 )
LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519);
else printf("no LP_privkey\n");

63
iguana/exchanges/LP_include.h

@ -23,7 +23,9 @@
#define LP_MAJOR_VERSION "0"
#define LP_MINOR_VERSION "1"
#define LP_BUILD_NUMBER "14336"
#define LP_BUILD_NUMBER "15256"
#define LP_BARTERDEX_VERSION 1
#define LP_MAGICBITS 8
#ifdef FROM_JS
#include <emscripten.h>
@ -38,12 +40,11 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#endif
//#define LP_STRICTPEERS
#define LP_BARTERDEX_VERSION 1
#define LP_MAGICBITS 8
#define LP_MAXVINS 64
#define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL)
#define LP_AUTOTRADE_TIMEOUT 40
#define LP_AUTOTRADE_TIMEOUT 30
#define LP_RESERVETIME (LP_AUTOTRADE_TIMEOUT * 2)
#define ELECTRUM_TIMEOUT 7
#define LP_ELECTRUM_KEEPALIVE 60
#define LP_ELECTRUM_MAXERRORS 777
@ -52,8 +53,8 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#define LP_MIN_PEERS 8
#define LP_MAX_PEERS 32
#define LP_MAXDESIRED_UTXOS 128
#define LP_MINDESIRED_UTXOS 32
#define LP_MAXDESIRED_UTXOS (IAMLP != 0 ? 128 : 64)
#define LP_MINDESIRED_UTXOS (IAMLP != 0 ? 32 : 16)
#define LP_DUSTCOMBINE_THRESHOLD 1000000
// RTmetrics
@ -81,7 +82,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 1000
#define LP_MINCLIENTVOL 100
#define LP_MINSIZE_TXFEEMULT 10
#define LP_REQUIRED_TXFEE 0.8
@ -96,14 +97,13 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#define JUMBLR_RMD160 "5177f8b427e5f47342a4b8ab5dac770815d4389e"
#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146"
#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu"
#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf"
#define INSTANTDEX_KMD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf"
//#define BASILISK_DISABLEWAITTX
//#define BASILISK_DISABLESENDTX
#define LP_RPCPORT 7783
#define LP_PROPAGATION_SLACK 100 // txid ordering is not enforced, so getting extra recent txid
#define LP_RESERVETIME 60
#define LP_AVETXSIZE 256
#define LP_CACHEDURATION 60
#define BASILISK_DEFAULT_NUMCONFIRMS 1
@ -150,8 +150,8 @@ struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],r
struct vin_info
{
struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid;
int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,hashtype,userdatalen,suppress_pubkeys,ignore_cltverr;
uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65];
int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,userdatalen,suppress_pubkeys,ignore_cltverr;
uint32_t sequence,unspentind,hashtype; struct vin_signer signers[16]; char coinaddr[65];
uint8_t rmd160[20],spendscript[10000],p2shscript[10000],userdata[10000];
};
@ -166,7 +166,7 @@ struct basilisk_swap;
struct basilisk_rawtxinfo
{
char destaddr[64],coinstr[16];
char destaddr[64];
bits256 txid,signedtxid,actualtxid;
int64_t amount,change,inputsum;
int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys;
@ -180,17 +180,16 @@ struct basilisk_request
int64_t srcamount,unused; // 16 to 31
bits256 srchash; // 32 to 63
bits256 desthash;
char src[8],dest[8];
char src[68],dest[68];
uint64_t destamount;
int32_t optionhours,DEXselector;
};
struct basilisk_rawtx
{
char name[32];
char name[32],symbol[65];
struct iguana_msgtx msgtx;
struct basilisk_rawtxinfo I;
struct iguana_info *coin;
char vinstr[8192],p2shaddr[64];
cJSON *vins;
bits256 utxotxid; int32_t utxovout;
@ -200,7 +199,7 @@ struct basilisk_rawtx
struct basilisk_swapinfo
{
struct basilisk_request req;
char bobstr[64],alicestr[64];
char bobstr[128],alicestr[128];
bits256 myhash,otherhash,orderhash;
uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration;
int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad,aliceistrusted,bobistrusted,otheristrusted,otherstrust,alicemaxconfirms,bobmaxconfirms;
@ -241,7 +240,7 @@ struct LP_swap_remember
uint32_t finishtime,tradeid,requestid,quoteid,plocktime,dlocktime,expiration,state,otherstate;
int32_t iambob,finishedflag,origfinishedflag,Predeemlen,Dredeemlen,sentflags[sizeof(txnames)/sizeof(*txnames)];
uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],Predeemscript[1024],Dredeemscript[1024],pubkey33[33],other33[33];
char src[64],dest[64],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[64],bobcoin[64],*txbytes[sizeof(txnames)/sizeof(*txnames)];
char Agui[65],Bgui[65],gui[65],src[65],dest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)];
};
struct LP_outpoint
@ -270,13 +269,13 @@ struct iguana_info
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;
uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag,userconfirms,isassetchain,maxconfirms;
char symbol[16],smartaddr[64],userpass[1024],serverport[128];
char symbol[128],smartaddr[64],userpass[1024],serverport[128];
// 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;
bits256 lastprivkey; uint32_t lastprivkeytime; int32_t privkeydepth;
int32_t privkeydepth;
bits256 cachedtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen;
bits256 cachedmerkle; int32_t cachedmerkleheight;
};
@ -289,7 +288,7 @@ struct LP_utxobob { struct _LP_utxoinfo utxo,deposit; };
struct LP_utxoalice { struct _LP_utxoinfo utxo,fee; };
struct LP_utxoswap { bits256 otherpubkey; void *swap; uint64_t satoshis; };
struct LP_utxoswap { bits256 otherpubkey; uint64_t satoshis; };
struct LP_utxoinfo
{
@ -301,7 +300,7 @@ struct LP_utxoinfo
int32_t iambob,iamlp;
uint8_t key[sizeof(bits256) + sizeof(int32_t)];
uint8_t key2[sizeof(bits256) + sizeof(int32_t)];
char coin[16],coinaddr[64],gui[16];//spendscript[256];
char coin[65],coinaddr[64],gui[16];//spendscript[256];
};
struct LP_address_utxo
@ -309,6 +308,7 @@ struct LP_address_utxo
struct LP_address_utxo *next,*prev;
struct _LP_utxoinfo U;
int32_t SPV,spendheight;
//uint32_t timestamp;
};
struct LP_address
@ -340,14 +340,14 @@ struct LP_quoteinfo
uint64_t satoshis,txfee,destsatoshis,desttxfee,aliceid;
uint32_t timestamp,quotetime,tradeid;
int32_t vout,vout2,destvout,feevout,pair;
char srccoin[16],coinaddr[64],destcoin[16],destaddr[64],gui[64];
char srccoin[65],coinaddr[64],destcoin[65],destaddr[64],gui[64];
};
struct LP_endpoint { int32_t pair; char ipaddr[64]; uint16_t port; };
struct basilisk_swap
{
void *ctx; struct iguana_info bobcoin,alicecoin; struct LP_utxoinfo *utxo;
void *ctx; //struct LP_utxoinfo *utxo;
struct LP_endpoint N;
void (*balancingtrade)(struct basilisk_swap *swap,int32_t iambob);
int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf;
@ -364,12 +364,21 @@ struct basilisk_swap
};
struct LP_pubkey_quote
{
struct LP_pubkey_quote *next,*prev;
float price;
uint32_t maxutxo,aveutxo;
uint8_t baseind,relind,numutxos,scale;
};
#define LP_MAXPRICEINFOS 256
struct LP_pubkeyinfo
{
UT_hash_handle hh;
bits256 pubkey;
float matrix[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS];
struct LP_pubkey_quote *quotes;
//float matrix[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS];
//uint32_t timestamps[LP_MAXPRICEINFOS][LP_MAXPRICEINFOS];
uint32_t timestamp,numerrors,lasttime;
int32_t istrusted;
@ -384,7 +393,7 @@ struct electrum_info
int32_t bufsize,sock,*heightp,numerrors;
struct iguana_info *coin;
uint32_t stratumid,lasttime,keepalive,pending,*heighttimep;
char ipaddr[64],symbol[16];
char ipaddr[64],symbol[66];
uint16_t port;
uint8_t buf[];
};
@ -411,7 +420,7 @@ 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_komodo_interest(bits256 txid,int64_t value);
void LP_availableset(struct LP_utxoinfo *utxo);
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);
void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag);
@ -453,7 +462,7 @@ 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);
int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight);
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);
cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret);

188
iguana/exchanges/LP_nativeDEX.c

@ -13,22 +13,23 @@
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_nativeDEX.c
// marketmaker
//
// BCH signing: FORKID_BCC = 0, FORKID_BTG = 79, // Atomic number AU
// alice waiting for bestprice
// regen inventory
// 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
// there is still a pending one with `-1 wait for bobpayment bYoNxkfvwQ42Yufry8J5y8BYi6mQxokvW9 numconfs.1 MNZ c0ea4aa808a653222a15122d96692fecf734dbbacfb9a54cb4711306ea0c3cef`, but that tx is already spent including 6 confirmation
// bot safe to exit?
//
// BCH signing
// dPoW security -> 4: KMD notarized, 5: BTC notarized, after next notary elections
// bigendian architectures need to use little endian for sighash calcs
#include <stdio.h>
long LP_cjson_allocated,LP_cjson_total,LP_cjson_count;
struct LP_millistats
{
double lastmilli,millisum,threshold;
@ -80,7 +81,7 @@ 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;
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;
int32_t LP_canbind;
char *Broadcaststr,*Reserved_msgs[2][1000];
int32_t num_Reserved_msgs[2],max_Reserved_msgs[2];
@ -89,11 +90,12 @@ struct LP_forwardinfo *LP_forwardinfos;
struct iguana_info *LP_coins;
struct LP_pubkeyinfo *LP_pubkeyinfos;
struct rpcrequest_info *LP_garbage_collector;
struct LP_address_utxo *LP_garbage_collector2;
//uint32_t LP_deadman_switch;
uint16_t LP_fixed_pairport,LP_publicport;
uint32_t LP_lastnonce,LP_counter;
uint32_t LP_lastnonce,LP_counter,LP_swap_endcritical,LP_swap_critical;
int32_t LP_mybussock = -1;
int32_t LP_mypubsock = -1;
int32_t LP_mypullsock = -1;
@ -114,6 +116,16 @@ struct LP_globals
struct LP_privkey LP_privkeys[100];
} G;
uint32_t LP_rand()
{
uint32_t retval;
retval = rand();
retval = (retval << 7) ^ (retval >> 17) ^ rand();
retval = (retval << 13) ^ (retval >> 13) ^ rand();
retval = (retval << 17) ^ (retval >> 7) ^ rand();
return(retval);
}
#include "LP_network.c"
char *activecoins[] = { "BTC", "KMD" };
@ -121,12 +133,11 @@ char GLOBAL_DBDIR[] = { "DB" };
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",
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" }; //
// stubs
void tradebot_swap_balancingtrade(struct basilisk_swap *swap,int32_t iambob)
@ -178,7 +189,6 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson
char *retstr=0;
if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 )
return(0);
//double millis = OS_milliseconds();
if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 )
{
if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,"127.0.0.1",0)) != 0 )
@ -188,8 +198,6 @@ char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson
//LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0);
}
} //else printf("finished tradecommand (%s)\n",jprint(argjson,0));
//if ( OS_milliseconds()-millis > 100 )
// printf("%.3f %s\n",OS_milliseconds()-millis,jprint(argjson,0));
return(retstr);
}
@ -229,7 +237,7 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,
dup++;
else uniq++;
portable_mutex_lock(&LP_commandmutex);
if ( (rand() % 10000) == 0 )
if ( (LP_rand() % 10000) == 0 )
printf("%s dup.%d (%u / %u) %.1f%% encrypted.%d recv.%u [%02x %02x] vs %02x %02x\n",typestr,duplicate,dup,dup+uniq,(double)100*dup/(dup+uniq),encrypted,crc32,ptr[0],ptr[1],crc32&0xff,(crc32>>8)&0xff);
if ( duplicate == 0 )
{
@ -312,10 +320,10 @@ char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,
if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 )
{
}
//printf("%.3f %s LP_command_process\n",OS_milliseconds()-millis,jstr(argjson,"method"));
}
free_json(argjson);
}
if ( argjson != 0 )
free_json(argjson);
}
} //else printf("DUPLICATE.(%s)\n",(char *)ptr);
portable_mutex_unlock(&LP_commandmutex);
@ -337,8 +345,12 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int
pfd.events = NN_POLLIN;
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 )
@ -386,8 +398,11 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int
free(str);
}
}
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
}
if ( ptr != 0 )
{
nn_freemsg(ptr), ptr = 0;
//free(buf);
}
}
}
@ -404,7 +419,7 @@ int32_t LP_nanomsg_recvs(void *ctx)
{
if ( peer->errors >= LP_MAXPEER_ERRORS )
{
if ( (rand() % 10000) == 0 )
if ( (LP_rand() % 10000) == 0 )
peer->errors--;
else
{
@ -506,6 +521,8 @@ void LP_coinsloop(void *_coins)
continue;
}
}
if ( coin->smartaddr[0] == 0 )
printf("%s has no smartaddress??\n",coin->symbol);
memset(&zero,0,sizeof(zero));
if ( coin->inactive != 0 )
continue;
@ -515,8 +532,6 @@ void LP_coinsloop(void *_coins)
{
if ( (backupep= ep->prev) == 0 )
backupep = ep;
// skip cLP_address MNZ bXcSsYBiVKtTzYErqxvma4UsojZTEf5L6H
//printf("electrum %s\n",coin->symbol);
if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 )
{
if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 )
@ -528,7 +543,7 @@ void LP_coinsloop(void *_coins)
if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1)) != 0 )
free_json(retjson);
}
HASH_ITER(hh,coin->addresses,ap,atmp)
if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 )
{
DL_FOREACH_SAFE(ap->utxos,up,tmp)
{
@ -605,7 +620,9 @@ void LP_coinsloop(void *_coins)
{
if ( LP_blockinit(coin,coin->lastscanht) < 0 )
{
printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht);
static uint32_t counter;
if ( counter++ < 3 )
printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht);
break;
}
coin->lastscanht++;
@ -662,11 +679,15 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins)
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 )
coin->inactive = (uint32_t)time(NULL);
else LP_unspents_load(coin->symbol,coin->smartaddr);
if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 )
coin->txfee = LP_MIN_TXFEE;
}
}
if ( (n= cJSON_GetArraySize(coins)) > 0 )
@ -684,6 +705,8 @@ void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins)
if ( LP_getheight(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 )
coin->txfee = LP_MIN_TXFEE;
}
}
}
@ -754,7 +777,7 @@ void LP_pubkeysloop(void *ctx)
}
if ( time(NULL) > lasttime+LP_ORDERBOOK_DURATION*0.5 )
{
//printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL));
//printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL));
LP_notify_pubkeys(ctx,LP_mypubsock);
lasttime = (uint32_t)time(NULL);
}
@ -771,7 +794,7 @@ void LP_privkeysloop(void *ctx)
{
LP_millistats_update(&LP_privkeysloop_stats);
LP_counter += 1000;
//printf("LP_privkeysloop %u\n",LP_counter);
//printf("LP_privkeysloop %u\n",LP_counter);
LP_privkey_updates(ctx,LP_mypubsock,0);
sleep(LP_ORDERBOOK_DURATION * .777);
}
@ -787,10 +810,9 @@ void LP_swapsloop(void *ignore)
{
LP_millistats_update(&LP_swapsloop_stats);
LP_counter += 10000;
//printf("LP_swapsloop %u\n",LP_counter);
//printf("LP_swapsloop %u\n",LP_counter);
if ( (retstr= basilisk_swapentry(0,0)) != 0 )
free(retstr);
//LP_millistats_update(0);
sleep(600);
}
}
@ -823,14 +845,14 @@ void LP_reserved_msgs(void *ignore)
if ( num_Reserved_msgs[1] > 0 )
{
num_Reserved_msgs[1]--;
//printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]);
//printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]);
LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[1][num_Reserved_msgs[1]]);
Reserved_msgs[1][num_Reserved_msgs[1]] = 0;
}
else if ( num_Reserved_msgs[0] > 0 )
{
num_Reserved_msgs[0]--;
//printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]);
//printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]);
LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[0][num_Reserved_msgs[0]]);
Reserved_msgs[0][num_Reserved_msgs[0]] = 0;
}
@ -840,8 +862,8 @@ void LP_reserved_msgs(void *ignore)
if ( ignore == 0 )
break;
if ( nonz != 0 )
usleep(3000);
else usleep(25000);
usleep(1000);
else usleep(5000);
}
}
@ -866,8 +888,14 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha
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; 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();
printf("Marketmaker %s.%s %s\n",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER);
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));
printf("%s %u\n",version,calc_crc32(0,version,(int32_t)strlen(version)));
if ( LP_MAXPRICEINFOS > 256 )
{
printf("LP_MAXPRICEINFOS %d wont fit in a uint8_t, need to increase the width of the baseind and relind for struct LP_pubkey_quote\n",LP_MAXPRICEINFOS);
exit(-1);
}
LP_showwif = juint(argjson,"wif");
if ( passphrase == 0 || passphrase[0] == 0 )
{
@ -883,6 +911,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
}
#endif
OS_randombytes((void *)&n,sizeof(n));
srand((uint32_t)n);
if ( jobj(argjson,"gui") != 0 )
safecopy(LP_gui,jstr(argjson,"gui"),sizeof(LP_gui));
if ( jobj(argjson,"canbind") == 0 )
@ -919,6 +948,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
portable_mutex_init(&LP_networkmutex);
portable_mutex_init(&LP_gcmutex);
portable_mutex_init(&LP_forwardmutex);
portable_mutex_init(&LP_inusemutex);
portable_mutex_init(&LP_psockmutex);
portable_mutex_init(&LP_coinmutex);
portable_mutex_init(&LP_pubkeymutex);
@ -929,6 +959,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
portable_mutex_init(&LP_reservedmutex);
portable_mutex_init(&LP_nanorecvsmutex);
portable_mutex_init(&LP_tradebotsmutex);
portable_mutex_init(&LP_cJSONmutex);
myipaddr = clonestr("127.0.0.1");
#ifndef _WIN32
#ifndef FROM_JS
@ -1004,6 +1035,7 @@ 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"));
#ifndef FROM_JS
@ -1175,4 +1207,94 @@ void LP_fromjs_iter()
#endif
#undef calloc
#undef free
#undef realloc
#undef clonestr
struct LP_memory_list
{
struct LP_memory_list *next,*prev;
uint32_t timestamp,len;
void *ptr;
} *LP_memory_list;
int32_t zeroval() { return(0); }
void *LP_alloc(uint64_t len)
{
//return(calloc(1,len));
LP_cjson_allocated += len;
LP_cjson_total += len;
LP_cjson_count++;
struct LP_memory_list *mp;
mp = calloc(1,sizeof(*mp) + len);
mp->ptr = calloc(1,len);
//printf(">>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu %llu\n",mp,mp->ptr,(long long)len,(long long)LP_cjson_allocated);
mp->timestamp = (uint32_t)time(NULL);
mp->len = (uint32_t)len;
portable_mutex_lock(&LP_cJSONmutex);
DL_APPEND(LP_memory_list,mp);
portable_mutex_unlock(&LP_cJSONmutex);
return(mp->ptr);
}
void LP_free(void *ptr)
{
static uint32_t lasttime,unknown; static int64_t lasttotal;
//free(ptr); return;
uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp;
if ( (now= (uint32_t)time(NULL)) > lasttime+1 )
{
n = lagging = 0;
DL_FOREACH_SAFE(LP_memory_list,mp,tmp)
{
total += mp->len;
n++;
if ( 0 && now > mp->timestamp+120 )
{
lagging++;
if ( now > mp->timestamp+240 )
{
portable_mutex_lock(&LP_cJSONmutex);
DL_DELETE(LP_memory_list,mp);
portable_mutex_unlock(&LP_cJSONmutex);
free(mp->ptr);
free(mp);
}
}
}
printf("[%lld] total %d allocated total %llu/%llu [%llu %llu] %.1f ave %s unknown.%u lagging.%d\n",(long long)(total-lasttotal),n,(long long)total,(long long)LP_cjson_allocated,(long long)LP_cjson_total,(long long)LP_cjson_count,(double)LP_cjson_total/LP_cjson_count,mbstr(str,total),unknown,lagging);
lasttime = (uint32_t)time(NULL);
lasttotal = total;
}
DL_FOREACH_SAFE(LP_memory_list,mp,tmp)
{
if ( mp->ptr == ptr )
break;
mp = 0;
}
if ( mp != 0 )
{
LP_cjson_allocated -= mp->len;
portable_mutex_lock(&LP_cJSONmutex);
DL_DELETE(LP_memory_list,mp);
portable_mutex_unlock(&LP_cJSONmutex);
//printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u %llu\n",ptr,mp,mp->len,(long long)LP_cjson_allocated);
free(mp->ptr);
free(mp);
} else unknown++; // free from source file with #define redirect for alloc that wasnt
}
/*char *LP_clonestr(char *str)
{
char *retstr = LP_alloc(strlen(str)+1);
strcpy(retstr,str);
return(retstr);
}
void *LP_realloc(void *ptr,uint64_t len)
{
return(realloc(ptr,len));
}*/

46
iguana/exchanges/LP_network.c

@ -183,7 +183,7 @@ bits256 LP_calc_magic(uint8_t *msg,int32_t len)
sum += (OS_milliseconds() - millis);
nsum += n;
counter++;
if ( n > maxn || (rand() % 10000) == 0 )
if ( n > maxn || (LP_rand() % 10000) == 0 )
{
if ( n > maxn )
{
@ -237,7 +237,7 @@ int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32)
break;
}
if ( i >= sizeof(crcs)/sizeof(*crcs) )
i = (rand() % (sizeof(crcs)/sizeof(*crcs)));
i = (LP_rand() % (sizeof(crcs)/sizeof(*crcs)));
return(i);
}
else
@ -267,9 +267,9 @@ int32_t LP_peerindsock(int32_t *peerindp)
void gc_loop(void *arg)
{
struct rpcrequest_info *req,*rtmp; int32_t flag = 0;
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 = 1100.;
LP_gcloop_stats.threshold = 11000.;
while ( 1 )
{
flag = 0;
@ -282,10 +282,21 @@ void gc_loop(void *arg)
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(1);
sleep(10);
}
}
@ -305,7 +316,7 @@ void queue_loop(void *arg)
flag = 0;
if ( ptr->sock >= 0 )
{
if ( ptr->notready == 0 || (rand() % ptr->notready) == 0 )
if ( ptr->notready == 0 || (LP_rand() % ptr->notready) == 0 )
{
if ( LP_sockcheck(ptr->sock) > 0 )
{
@ -376,11 +387,11 @@ void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32
if ( sock0 < 0 && sock1 < 0 )
{
if ( (maxind= LP_numpeers()) > 0 )
peerind = (rand() % maxind) + 1;
peerind = (LP_rand() % maxind) + 1;
else peerind = 1;
sock0 = LP_peerindsock(&peerind);
if ( (maxind= LP_numpeers()) > 0 )
peerind = (rand() % maxind) + 1;
peerind = (LP_rand() % maxind) + 1;
else peerind = 1;
sock1 = LP_peerindsock(&peerind);
}
@ -563,12 +574,19 @@ 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);
buf = 0;
if ( (size= nn_recv(ptr->publicsock,&buf,NN_MSG,0)) > 0 )
{
ptr->lasttime = now;
sendsock = ptr->sendsock;
break;
}
else if ( buf != 0 )
{
nn_freemsg(buf);
buf = 0;
size = 0;
}
}
}
n++;
@ -595,12 +613,12 @@ void LP_psockloop(void *_ptr) // printouts seem to be needed for forwarding to w
sendsock = ptr->publicsock;
break;
}
else
{
nn_freemsg(buf);
buf = 0;
size = 0;
}
}
if ( buf != 0 )
{
nn_freemsg(buf);
buf = 0;
size = 0;
}
}
}

537
iguana/exchanges/LP_ordermatch.c

@ -18,33 +18,47 @@
// LP_ordermatch.c
// marketmaker
//
struct LP_quoteinfo LP_Alicequery;
struct LP_quoteinfo LP_Alicequery,LP_Alicereserved;
double LP_Alicemaxprice;
bits256 LP_Alicedestpubkey;
uint32_t Alice_expiration;
struct { uint64_t aliceid; double bestprice; } Bob_competition[512];
struct { uint64_t aliceid; double bestprice; uint32_t starttime,counter; } Bob_competition[512];
double LP_bob_competition(uint64_t aliceid,double price)
double LP_bob_competition(int32_t *counterp,uint64_t aliceid,double price,int32_t counter)
{
int32_t i,firsti = -1;
int32_t i,firsti = -1; uint32_t now = (uint32_t)time(NULL);
*counterp = 0;
for (i=0; i<sizeof(Bob_competition)/sizeof(*Bob_competition); i++)
{
if ( Bob_competition[i].aliceid == aliceid )
{
if ( now > Bob_competition[i].starttime+LP_AUTOTRADE_TIMEOUT )
{
//printf("aliceid.%llu expired\n",(long long)aliceid);
Bob_competition[i].bestprice = 0.;
Bob_competition[i].starttime = now;
Bob_competition[i].counter = 0;
}
if ( price != 0. && (Bob_competition[i].bestprice == 0. || price < Bob_competition[i].bestprice) )
{
Bob_competition[i].bestprice = price;
//printf("Bob competition aliceid.%llx <- bestprice %.8f\n",(long long)aliceid,price);
//printf("Bob competition aliceid.%llu <- bestprice %.8f\n",(long long)aliceid,price);
}
Bob_competition[i].counter += counter;
*counterp = Bob_competition[i].counter;
return(Bob_competition[i].bestprice);
}
else if ( Bob_competition[i].aliceid == 0 )
firsti = i;
}
if ( firsti < 0 )
firsti = (rand() % (sizeof(Bob_competition)/sizeof(*Bob_competition)));
firsti = (LP_rand() % (sizeof(Bob_competition)/sizeof(*Bob_competition)));
Bob_competition[firsti].starttime = (uint32_t)time(NULL);
Bob_competition[firsti].counter = counter;
Bob_competition[firsti].aliceid = aliceid;
Bob_competition[firsti].bestprice = price;
//printf("Bob competition aliceid.%llx %.8f\n",(long long)aliceid,price);
*counterp = counter;
//printf("Bob competition aliceid.%llu %.8f\n",(long long)aliceid,price);
return(price);
}
@ -112,7 +126,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str
{
if ( LP_iseligible(&srcvalue,&srcvalue2,1,qp->srccoin,qp->txid,qp->vout,qp->satoshis,qp->txid2,qp->vout2) == 0 )
{
printf("bob not eligible %s (%.8f %.8f)\n",jprint(LP_quotejson(qp),1),dstr(srcvalue),dstr(srcvalue2));
//printf("bob not eligible %s (%.8f %.8f)\n",jprint(LP_quotejson(qp),1),dstr(srcvalue),dstr(srcvalue2));
return(-2);
}
if ( (txout= LP_gettxout(qp->srccoin,qp->coinaddr,qp->txid,qp->vout)) != 0 )
@ -144,7 +158,8 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str
{
if ( LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 )
{
char str[65],str2[65]; printf("alice not eligible %.8f -> dest %.8f %.8f (%.8f %.8f) %s/v%d %s/v%d\n",dstr(qp->satoshis),dstr(qp->destsatoshis),(double)qp->destsatoshis/qp->satoshis,dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout);
//alice not eligible 0.36893923 -> dest 0.55020000 1.49130251 (0.61732249 0.00104324) 14b8b74808d2d34a70e5eddd1cad47d855858f8b23cac802576d4d37b5f8af8f/v1 abec6e76169bcb738235ca67fab02cc55390f39e422aa71f1badf8747c290cc4/v1
//char str[65],str2[65]; printf("alice not eligible %.8f -> dest %.8f %.8f (%.8f %.8f) %s/v%d %s/v%d\n",dstr(qp->satoshis),dstr(qp->destsatoshis),(double)qp->destsatoshis/qp->satoshis,dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout);
return(-3);
}
if ( (txout= LP_gettxout(qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout)) != 0 )
@ -237,7 +252,7 @@ int32_t LP_nanobind(void *ctx,char *pairstr)
{
for (i=0; i<10; i++)
{
r = (10000 + (rand() % 50000)) & 0xffff;
r = (10000 + (LP_rand() % 50000)) & 0xffff;
if ( LP_fixed_pairport != 0 )
r = LP_fixed_pairport;
nanomsg_transportname(0,pairstr,LP_myipaddr,r);
@ -260,7 +275,7 @@ int32_t LP_nanobind(void *ctx,char *pairstr)
int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_address_utxo **utxos,int32_t n,uint64_t targetval)
{
int32_t i,mini = -1; struct LP_address_utxo *up; struct electrum_info *backupep=0,*ep; int64_t dist; uint64_t mindist = (1LL << 60);
int32_t i,replacei,bestheight,mini = -1; struct LP_address_utxo *up,*bestup; struct electrum_info *backupep=0,*ep; int64_t dist,bestdist; uint64_t mindist = (1LL << 60);
if ( (ep= coin->electrum) != 0 )
{
if ( (backupep= ep->prev) == 0 )
@ -275,7 +290,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a
//printf("nearest i.%d target %.8f val %.8f dist %.8f mindist %.8f mini.%d spent.%d\n",i,dstr(targetval),dstr(up->U.value),dstr(dist),dstr(mindist),mini,up->spendheight);
if ( up->spendheight <= 0 )
{
if ( dist >= 0 && dist < mindist ) //(coin->electrum == 0 || up->SPV > 0) &&
if ( dist >= 0 && dist < mindist )
{
//printf("(%.8f %.8f %.8f).%d ",dstr(up->U.value),dstr(dist),dstr(mindist),mini);
mini = i;
@ -284,70 +299,49 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a
}
}
}
//printf("return mini.%d\n",mini);
return(mini);
}
uint64_t LP_basesatoshis(double relvolume,double price,uint64_t txfee,uint64_t desttxfee)
{
//printf("basesatoshis %.8f (rel %.8f / price %.8f)\n",dstr(SATOSHIDEN * ((relvolume) / price) + 2*txfee),relvolume,price);
if ( relvolume > dstr(desttxfee) && price > SMALLVAL )
return(SATOSHIDEN * (relvolume / price) + 2*txfee);
else return(0);
}
struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct iguana_info *coin,char *coinaddr,uint64_t txfee,double relvolume,double price,uint64_t desttxfee)
{
struct LP_address *ap; uint64_t targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; struct LP_utxoinfo *utxo = 0;//,*utmp;
targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee);
targetval2 = (targetval / 8) * 9 + 2*txfee;
if ( coin != 0 && (ap= LP_addressfind(coin,coinaddr)) != 0 )
if ( mini >= 0 && (bestup= utxos[mini]) != 0 )
{
if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 )
bestdist = (bestup->U.value - targetval);
replacei = -1;
bestheight = bestup->U.height;
for (i=0; i<n; i++)
{
if ( 0 )
if ( i != mini && (up= utxos[i]) != 0 )
{
int32_t i;
for (i=0; i<m; i++)
printf("%.8f ",dstr(utxos[i]->U.value));
printf("targetval %.8f vol %.8f price %.8f txfee %.8f %s\n",dstr(targetval),relvolume,price,dstr(txfee),coinaddr);
}
mini = -1;
if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval)) >= 0 )
{
up = utxos[mini];
utxos[mini] = 0;
//printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n",mini,dstr(up->U.value),dstr(targetval),dstr(targetval2),(double)up->U.value/targetval);
if ( (double)up->U.value/targetval < LP_MINVOL-1 )
dist = (up->U.value - targetval);
if ( dist > 0 && up->U.height < bestheight )
{
if ( (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,(targetval2+2*txfee) * 1.01)) >= 0 )
if ( (double)dist/bestdist < sqrt(bestheight - up->U.height) )
{
if ( up != 0 && (up2= utxos[mini]) != 0 )
{
if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0,targetval)) != 0 )
{
utxo->S.satoshis = targetval;
char str[65],str2[65]; printf("butxo.%p targetval %.8f, found val %.8f %s | targetval2 %.8f val2 %.8f %s\n",utxo,dstr(targetval),dstr(up->U.value),bits256_str(str,utxo->payment.txid),dstr(targetval2),dstr(up2->U.value),bits256_str(str2,utxo->deposit.txid));
return(utxo);
}
}
} //else printf("cant find targetval2 %.8f\n",dstr(targetval2));
} //else printf("failed ratio test %.8f\n",(double)up->U.value/targetval);
} else if ( targetval != 0 && mini >= 0 )
printf("targetval %.8f mini.%d\n",dstr(targetval),mini);
} //else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr);
} else printf("couldnt find %s %s\n",coin->symbol,coinaddr);
/*HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,utmp)
{
if ( LP_isavailable(utxo) != 0 && utxo->payment.value >= targetval && targetval >= utxo->payment.value/2 && utxo->deposit.value >= targetval2 )
replacei = i;
bestheight = up->U.height;
} //else printf("almost ratio %.3f dist %.8f vs best %.8f, ht %d vs best ht %d\n",(double)dist/bestdist,dstr(dist),dstr(bestdist),up->U.height,bestheight);
}
}
}
if ( replacei >= 0 )
{
utxo->S.satoshis = targetval;
printf("backup method found utxo!\n");
return(utxo);
//printf("REPLACE bestdist %.8f height %d with dist %.8f height %d\n",dstr(bestdist),bestup->U.height,dstr(utxos[replacei]->U.value - targetval),utxos[replacei]->U.height);
return(replacei);
}
}*/
return(0);
}
//printf("return mini.%d\n",mini);
return(mini);
}
void LP_butxo_set(struct LP_utxoinfo *butxo,struct iguana_info *coin,struct LP_address_utxo *up,struct LP_address_utxo *up2,int64_t satoshis)
{
butxo->pubkey = G.LP_mypub25519;
safecopy(butxo->coin,coin->symbol,sizeof(butxo->coin));
safecopy(butxo->coinaddr,coin->smartaddr,sizeof(butxo->coinaddr));
butxo->payment.txid = up->U.txid;
butxo->payment.vout = up->U.vout;
butxo->payment.value = up->U.value;
butxo->iambob = 1;
butxo->deposit.txid = up2->U.txid;
butxo->deposit.vout = up2->U.vout;
butxo->deposit.value = up2->U.value;
butxo->S.satoshis = satoshis;
}
void LP_abutxo_set(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP_quoteinfo *qp)
@ -384,20 +378,82 @@ void LP_abutxo_set(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP
}
}
int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJSON *argjson,char *base,char *rel,double price,struct LP_quoteinfo *qp)
uint64_t LP_basesatoshis(double relvolume,double price,uint64_t txfee,uint64_t desttxfee)
{
//printf("basesatoshis %.8f (rel %.8f / price %.8f)\n",dstr(SATOSHIDEN * ((relvolume) / price) + 2*txfee),relvolume,price);
if ( relvolume > dstr(desttxfee) && price > SMALLVAL )
return(SATOSHIDEN * (relvolume / price) + 2*txfee);
else return(0);
}
struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct iguana_info *coin,char *coinaddr,uint64_t txfee,double relvolume,double price,uint64_t desttxfee)
{
struct LP_address *ap; uint64_t targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2;
memset(butxo,0,sizeof(*butxo));
targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee);
targetval2 = (targetval / 8) * 9 + 2*txfee;
if ( coin != 0 && (ap= LP_address(coin,coinaddr)) != 0 )
{
if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 )
{
if ( 0 )
{
int32_t i;
for (i=0; i<m; i++)
if ( utxos[i]->U.value >= targetval )
printf("%.8f ",dstr(utxos[i]->U.value));
printf("targetval %.8f vol %.8f price %.8f txfee %.8f %s %s\n",dstr(targetval),relvolume,price,dstr(txfee),coin->symbol,coinaddr);
}
mini = -1;
if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval+txfee)) >= 0 )
{
up = utxos[mini];
utxos[mini] = 0;
//printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n",mini,dstr(up->U.value),dstr(targetval),dstr(targetval2),(double)up->U.value/targetval);
if ( (double)up->U.value/targetval < LP_MINVOL-1 )
{
if ( (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,(targetval2+2*txfee) * 1.01)) >= 0 )
{
if ( up != 0 && (up2= utxos[mini]) != 0 )
{
/*if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0,targetval)) != 0 )
{
utxo->S.satoshis = targetval;
char str[65],str2[65]; printf("butxo.%p targetval %.8f, found val %.8f %s | targetval2 %.8f val2 %.8f %s\n",utxo,dstr(targetval),dstr(up->U.value),bits256_str(str,utxo->payment.txid),dstr(targetval2),dstr(up2->U.value),bits256_str(str2,utxo->deposit.txid));
return(butxo);
}*/
LP_butxo_set(butxo,coin,up,up2,targetval);
return(butxo);
}
} else printf("cant find targetval2 %.8f\n",dstr(targetval2));
} else printf("failed ratio test %.8f\n",(double)up->U.value/targetval);
} else if ( targetval != 0 && mini >= 0 )
printf("targetval %.8f mini.%d\n",dstr(targetval),mini);
} else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr);
} else printf("address_myutxopair couldnt find %s %s\n",coin->symbol,coinaddr);
return(0);
}
int32_t LP_connectstartbob(void *ctx,int32_t pubsock,cJSON *argjson,char *base,char *rel,double price,struct LP_quoteinfo *qp)
{
char pairstr[512]; cJSON *retjson; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; struct basilisk_swap *swap; struct iguana_info *coin;
printf("LP_connectstartbob.(%s) with.(%s) %s\n",LP_myipaddr,jprint(argjson,0),LP_myipaddr);
qp->quotetime = (uint32_t)time(NULL);
if ( (coin= LP_coinfind(utxo->coin)) == 0 )
if ( (coin= LP_coinfind(qp->srccoin)) == 0 )
{
printf("cant find coin.%s\n",utxo->coin);
printf("cant find coin.%s\n",qp->srccoin);
return(-1);
}
privkey = LP_privkey(utxo->coinaddr,coin->taddr);
if ( bits256_nonz(privkey) != 0 && bits256_cmp(G.LP_mypub25519,qp->srchash) == 0 ) //qp->quotetime >= qp->timestamp-3 && qp->quotetime <= utxo->T.swappending &&
privkey = LP_privkey(coin->smartaddr,coin->taddr);
if ( bits256_nonz(privkey) != 0 && bits256_cmp(G.LP_mypub25519,qp->srchash) == 0 )
{
LP_requestinit(&qp->R,qp->srchash,qp->desthash,base,qp->satoshis-qp->txfee,rel,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector);
if ( LP_pendingswap(qp->R.requestid,qp->R.quoteid) > 0 )
{
printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid);
return(-1);
}
if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp)) == 0 )
{
printf("cant initialize swap\n");
@ -406,45 +462,37 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ
if ( (pair= LP_nanobind(ctx,pairstr)) >= 0 )
{
swap->N.pair = pair;
utxo->S.swap = swap;
swap->utxo = utxo;
//utxo->S.swap = swap;
//swap->utxo = utxo;
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_bobloop,(void *)swap) == 0 )
{
retjson = LP_quotejson(qp);
jaddstr(retjson,"method","connected");
jaddstr(retjson,"pair",pairstr);
//jaddnum(retjson,"requestid",qp->R.requestid);
//jaddnum(retjson,"quoteid",qp->R.quoteid);
// LP_addsig
char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,utxo->S.otherpubkey));
LP_reserved_msg(1,base,rel,utxo->S.otherpubkey,jprint(retjson,0));
char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash));
LP_reserved_msg(1,base,rel,qp->desthash,jprint(retjson,0));
sleep(1);
bits256 zero;
memset(zero.bytes,0,sizeof(zero));
LP_reserved_msg(1,base,rel,zero,jprint(retjson,0));
//LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->desthash,jprint(retjson,0));
free_json(retjson);
retval = 0;
} else printf("error launching swaploop\n");
} else printf("couldnt bind to any port %s\n",pairstr);
}
else
{
printf("dest %.8f vs required %.8f (%d %d %d %d %d)\n",dstr(qp->destsatoshis),dstr(price*(utxo->S.satoshis-qp->txfee)),bits256_nonz(privkey) != 0 ,qp->timestamp == utxo->T.swappending-LP_RESERVETIME,qp->quotetime >= qp->timestamp-3,qp->quotetime < utxo->T.swappending,bits256_cmp(G.LP_mypub25519,qp->srchash) == 0);
}
if ( retval < 0 )
{
if ( pair >= 0 )
nn_close(pair);
LP_availableset(utxo);
} else LP_unavailableset(utxo,utxo->S.otherpubkey);
//LP_butxo_swapfields(utxo);
LP_availableset(qp->txid,qp->vout);
LP_availableset(qp->txid2,qp->vout2);
}
return(retval);
}
char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid)
char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid,bits256 destpubkey)
{
struct LP_utxoinfo *aliceutxo; double price; //cJSON *bestitem=0; int32_t DEXselector=0; uint32_t expiration; double price; struct LP_pubkeyinfo *pubp; struct basilisk_swap *swap;
struct LP_utxoinfo *aliceutxo; double price;
if ( (aliceutxo= LP_utxopairfind(0,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) == 0 )
{
char str[65],str2[65]; printf("dest.(%s)/v%d fee.(%s)/v%d\n",bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout);
@ -454,28 +502,47 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q
memset(qp->txid.bytes,0,sizeof(qp->txid));
qp->txid2 = qp->txid;
qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout);
qp->tradeid = tradeid;
if ( (qp->tradeid= tradeid) == 0 )
qp->tradeid = LP_rand();
LP_query(ctx,myipaddr,mypubsock,"request",qp);
LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout;
printf("LP_trade %s/%s %.8f vol %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis));
LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = destpubkey;
char str[65]; printf("LP_trade %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),maxprice);
return(LP_recent_swaps(0));
}
int32_t LP_quotecmp(struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2)
int32_t LP_quotecmp(int32_t strictflag,struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2)
{
if ( bits256_cmp(qp->desthash,qp2->desthash) == 0 && strcmp(qp->srccoin,qp2->srccoin) == 0 && strcmp(qp->destcoin,qp2->destcoin) == 0 && bits256_cmp(qp->desttxid,qp2->desttxid) == 0 && qp->destvout == qp2->destvout && bits256_cmp(qp->feetxid,qp2->feetxid) == 0 && qp->feevout == qp2->feevout && qp->destsatoshis == qp2->destsatoshis && qp->txfee >= qp2->txfee && qp->desttxfee == qp2->desttxfee ) //bits256_cmp(qp->srchash,qp2->srchash) == 0 &&
return(0);
else return(-1);
if ( bits256_nonz(LP_Alicedestpubkey) != 0 )
{
if (bits256_cmp(LP_Alicedestpubkey,qp->srchash) != 0 )
{
printf("reject quote from non-matching pubkey\n");
return(-1);
} else printf("dont reject quote from destpubkey\n");
}
if ( bits256_cmp(qp->desthash,qp2->desthash) == 0 && strcmp(qp->srccoin,qp2->srccoin) == 0 && strcmp(qp->destcoin,qp2->destcoin) == 0 && bits256_cmp(qp->desttxid,qp2->desttxid) == 0 && qp->destvout == qp2->destvout && bits256_cmp(qp->feetxid,qp2->feetxid) == 0 && qp->feevout == qp2->feevout && qp->destsatoshis == qp2->destsatoshis && qp->txfee >= qp2->txfee && qp->desttxfee == qp2->desttxfee )
{
if ( strictflag == 0 || (qp->aliceid == qp2->aliceid && qp->R.requestid == qp2->R.requestid && qp->R.quoteid == qp2->R.quoteid && qp->vout == qp2->vout && qp->vout2 == qp2->vout2 && qp->satoshis == qp2->satoshis && bits256_cmp(qp->txid,qp2->txid) == 0 && bits256_cmp(qp->txid2,qp2->txid2) == 0 && bits256_cmp(qp->srchash,qp2->srchash) == 0) )
return(0);
else printf("strict compare failure\n");
}
return(-1);
}
int32_t LP_alice_eligible()
void LP_alicequery_clear()
{
if ( Alice_expiration != 0 && time(NULL) > Alice_expiration )
memset(&LP_Alicequery,0,sizeof(LP_Alicequery));
memset(&LP_Alicedestpubkey,0,sizeof(LP_Alicedestpubkey));
LP_Alicemaxprice = 0.;
Alice_expiration = 0;
}
int32_t LP_alice_eligible(uint32_t quotetime)
{
if ( Alice_expiration != 0 && quotetime > Alice_expiration )
{
printf("time expired for Alice_request\n");
memset(&LP_Alicequery,0,sizeof(LP_Alicequery));
LP_Alicemaxprice = 0.;
Alice_expiration = 0;
LP_alicequery_clear();
}
return(Alice_expiration == 0 || time(NULL) < Alice_expiration);
}
@ -483,24 +550,23 @@ int32_t LP_alice_eligible()
void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp)
{
double price=0.,maxprice = LP_Alicemaxprice;
if ( LP_alice_eligible() > 0 && LP_quotecmp(qp,&LP_Alicequery) == 0 )
if ( LP_quotecmp(0,qp,&LP_Alicequery) == 0 )
{
price = LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout);
if ( LP_pricevalid(price) > 0 && maxprice > SMALLVAL && price <= maxprice*1.005 )
if ( LP_pricevalid(price) > 0 && maxprice > SMALLVAL && price <= maxprice )
{
qp->tradeid = LP_Alicequery.tradeid;
memset(&LP_Alicequery,0,sizeof(LP_Alicequery));
LP_Alicemaxprice = 0.;
Alice_expiration = 0;
LP_Alicereserved = *qp;
LP_alicequery_clear();
printf("send CONNECT\n");
LP_query(ctx,myipaddr,mypubsock,"connect",qp);
} else printf("LP_reserved price %.8f vs maxprice %.8f\n",price,maxprice*1.005);
} else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(),price,maxprice);
} else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(qp->quotetime),price,maxprice);
}
char *LP_connectedalice(cJSON *argjson) // alice
{
cJSON *retjson; double bid,ask,price,qprice; int32_t pairsock = -1; char *pairstr; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,B,*butxo; struct LP_quoteinfo Q; struct basilisk_swap *swap; struct iguana_info *coin; //uint64_t value,value2;
cJSON *retjson; double bid,ask,price,qprice; int32_t pairsock = -1; char *pairstr; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct LP_quoteinfo Q; struct basilisk_swap *swap; struct iguana_info *coin;
if ( LP_quoteparse(&Q,argjson) < 0 )
{
LP_aliceid(Q.tradeid,Q.aliceid,"error0",0,0);
@ -511,26 +577,31 @@ char *LP_connectedalice(cJSON *argjson) // alice
LP_aliceid(Q.tradeid,Q.aliceid,"error1",0,0);
return(clonestr("{\"result\",\"update stats\"}"));
}
printf("CONNECTED.(%s) numpending.%d tradeid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.tradeid);
if ( (autxo= LP_utxopairfind(0,Q.desttxid,Q.destvout,Q.feetxid,Q.feevout)) == 0 )
printf("CONNECTED.(%s) numpending.%d tradeid.%u requestid.%u quoteid.%u\n",jprint(argjson,0),G.LP_pendingswaps,Q.tradeid,Q.R.requestid,Q.R.quoteid);
LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector);
printf("calculated requestid.%u quoteid.%u\n",Q.R.requestid,Q.R.quoteid);
if ( LP_pendingswap(Q.R.requestid,Q.R.quoteid) > 0 )
{
printf("cant find autxo\n");
LP_aliceid(Q.tradeid,Q.aliceid,"error2",0,0);
return(clonestr("{\"error\":\"cant find autxo\"}"));
printf("requestid.%u quoteid.%u is already in progres\n",Q.R.requestid,Q.R.quoteid);
retjson = cJSON_CreateObject();
jaddstr(retjson,"error","swap already in progress");
return(jprint(retjson,1));
}
if ( autxo->S.swap != 0 )
if ( LP_quotecmp(1,&Q,&LP_Alicereserved) == 0 )
{
printf("ignore duplicate swap\n");
LP_aliceid(Q.tradeid,Q.aliceid,"error3",0,0);
return(clonestr("{\"error\":\"ignore duplicate swap\"}"));
printf("mismatched between reserved and connected\n");
}
memset(&LP_Alicereserved,0,sizeof(LP_Alicereserved));
LP_aliceid(Q.tradeid,Q.aliceid,"connected",Q.R.requestid,Q.R.quoteid);
autxo = &A;
butxo = &B;
memset(autxo,0,sizeof(*autxo));
memset(butxo,0,sizeof(*butxo));
LP_abutxo_set(0,butxo,&Q);
LP_abutxo_set(autxo,butxo,&Q);
if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL )
{
LP_availableset(autxo);
LP_availableset(Q.desttxid,Q.vout);
LP_availableset(Q.feetxid,Q.feevout);
LP_aliceid(Q.tradeid,Q.aliceid,"error4",0,0);
printf("quote validate error %.0f\n",qprice);
return(clonestr("{\"error\":\"quote validation error\"}"));
@ -538,7 +609,8 @@ char *LP_connectedalice(cJSON *argjson) // alice
if ( LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin) <= SMALLVAL || bid <= SMALLVAL )
{
printf("this node has no price for %s/%s (%.8f %.8f)\n",Q.destcoin,Q.srccoin,bid,ask);
LP_availableset(autxo);
LP_availableset(Q.desttxid,Q.vout);
LP_availableset(Q.feetxid,Q.feevout);
LP_aliceid(Q.tradeid,Q.aliceid,"error5",0,0);
return(clonestr("{\"error\":\"no price set\"}"));
}
@ -553,11 +625,11 @@ char *LP_connectedalice(cJSON *argjson) // alice
if ( bits256_nonz(Q.privkey) != 0 )//&& Q.quotetime >= Q.timestamp-3 )
{
retjson = cJSON_CreateObject();
LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector);
if ( (swap= LP_swapinit(0,0,Q.privkey,&Q.R,&Q)) == 0 )
{
jaddstr(retjson,"error","couldnt swapinit");
LP_availableset(autxo);
LP_availableset(Q.desttxid,Q.vout);
LP_availableset(Q.feetxid,Q.feevout);
LP_aliceid(Q.tradeid,Q.aliceid,"error7",Q.R.requestid,Q.R.quoteid);
return(jprint(retjson,1));
}
@ -573,8 +645,8 @@ char *LP_connectedalice(cJSON *argjson) // alice
//nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
swap->tradeid = Q.tradeid;
swap->N.pair = pairsock;
autxo->S.swap = swap;
swap->utxo = autxo;
//autxo->S.swap = swap;
//swap->utxo = autxo;
LP_aliceid(Q.tradeid,Q.aliceid,"started",Q.R.requestid,Q.R.quoteid);
printf("alice pairstr.(%s) pairsock.%d\n",pairstr,pairsock);
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_aliceloop,(void *)swap) == 0 )
@ -597,12 +669,16 @@ char *LP_connectedalice(cJSON *argjson) // alice
}
printf("connected result.(%s)\n",jprint(retjson,0));
if ( jobj(retjson,"error") != 0 )
LP_availableset(autxo);
{
LP_availableset(Q.desttxid,Q.vout);
LP_availableset(Q.feetxid,Q.feevout);
}
return(jprint(retjson,1));
}
else
{
LP_availableset(autxo);
LP_availableset(Q.desttxid,Q.vout);
LP_availableset(Q.feetxid,Q.feevout);
LP_aliceid(Q.tradeid,Q.aliceid,"error11",0,0);
printf("no privkey found coin.%s %s taddr.%u\n",Q.destcoin,Q.destaddr,coin->taddr);
return(clonestr("{\"error\",\"no privkey\"}"));
@ -611,7 +687,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag)
{
int32_t i,v,numconfs,height,n=0; uint64_t value; bits256 txid; char buf[512]; cJSON *array,*item; struct iguana_info *coin = LP_coinfind(symbol);
int32_t i,v,numconfs,height,n=0; uint64_t value; bits256 txid; char buf[512]; cJSON *array,*item; uint32_t now; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin != 0 )//&& (IAMLP != 0 || coin->inactive == 0) )
{
if ( coin->electrum != 0 || LP_address_ismine(symbol,coinaddr) <= 0 )
@ -632,6 +708,7 @@ int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag)
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
now = (uint32_t)time(NULL);
for (i=0; i<n; i++)
{
item = jitem(array,i);
@ -640,9 +717,10 @@ int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag)
value = LP_value_extract(item,0);
height = LP_txheight(coin,txid);
//char str[65]; printf("LP_listunspent_both: %s/v%d ht.%d %.8f\n",bits256_str(str,txid),v,height,dstr(value));
LP_address_utxoadd("LP_listunspent_both",coin,coinaddr,txid,v,value,height,-1);
LP_address_utxoadd(now,"LP_listunspent_both",coin,coinaddr,txid,v,value,height,-1);
}
}
free_json(array);
}
}
} //else printf("%s coin.%p inactive.%d\n",symbol,coin,coin!=0?coin->inactive:-1);
@ -668,10 +746,23 @@ int32_t LP_aliceonly(char *symbol)
int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
{
struct electrum_info *ep,*backupep; struct LP_address_utxo *up; struct iguana_info *coin;
struct electrum_info *ep,*backupep; cJSON *txobj; struct LP_address_utxo *up; struct iguana_info *coin; struct LP_transaction *tx;
coin = LP_coinfind(symbol);
if ( coin != 0 && (ep= coin->electrum) != 0 )
{
if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) == 0 )
{
if ( (txobj= electrum_transaction(symbol,ep,&txobj,txid,coinaddr)) != 0 )
free_json(txobj);
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
{
if ( vout < tx->numvouts && tx->height > 0 )
{
printf("added missing utxo for SPV checking\n");
LP_address_utxoadd((uint32_t)time(NULL),"LP_validSPV",coin,coinaddr,txid,vout,tx->outpoints[vout].value,tx->height,-1);
}
}
}
if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 )
{
if ( up->SPV < 0 )
@ -688,14 +779,14 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen)
{
char *method,*msg,*retstr,str[65]; int32_t DEXselector = 0; uint64_t aliceid,value,value2; cJSON *retjson; double qprice,range,bestprice,price,bid,ask; struct LP_utxoinfo A,B,*autxo,*butxo; struct iguana_info *coin; struct LP_address_utxo *utxos[1000]; struct LP_quoteinfo Q; int32_t r,retval = -1,recalc,max=(int32_t)(sizeof(utxos)/sizeof(*utxos));
char *method,*msg,*retstr,str[65]; int32_t DEXselector = 0; uint64_t aliceid; cJSON *retjson; double qprice,range,bestprice,price,bid,ask; struct LP_utxoinfo A,B,*autxo,*butxo; struct iguana_info *coin; struct LP_address_utxo *utxos[1000]; struct LP_quoteinfo Q; int32_t r,counter,retval = -1,max=(int32_t)(sizeof(utxos)/sizeof(*utxos));
if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"reserved") == 0 ||strcmp(method,"connected") == 0 || strcmp(method,"request") == 0 || strcmp(method,"connect") == 0) )
{
// LP_checksig
LP_quoteparse(&Q,argjson);
LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector);
LP_tradecommand_log(argjson);
//printf("LP_tradecommand: check received method %12s aliceid.%16llx %5s/%-5s %12.8f -> %12.8f price %12.8f\n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis);
printf("(%-10u %10u) %12s aliceid.%22llu %5s/%-5s %12.8f -> %12.8f price %12.8f\n",Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis);
retval = 1;
autxo = &A;
butxo = &B;
@ -706,12 +797,21 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
qprice = jdouble(argjson,"price");
if ( strcmp(method,"reserved") == 0 )
{
bestprice = LP_bob_competition(aliceid,qprice);
//printf("aliceid.%llx price %.8f -> bestprice %.8f\n",(long long)aliceid,qprice,bestprice);
bestprice = LP_bob_competition(&counter,aliceid,qprice,1);
//printf("%s lag %ld: aliceid.%llu price %.8f -> bestprice %.8f Alice max %.8f\n",jprint(argjson,0),Q.quotetime - (time(NULL)-20),(long long)aliceid,qprice,bestprice,LP_Alicemaxprice);
if ( LP_Alicemaxprice == 0. )
return(retval);
if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 )
if ( bits256_nonz(LP_Alicedestpubkey) != 0 )
{
if (bits256_cmp(LP_Alicedestpubkey,Q.srchash) != 0 )
{
printf("got reserved response from different node %s\n",bits256_str(str,Q.srchash));
return(retval);
} else printf("got reserved response from destpubkey %s\n",bits256_str(str,Q.srchash));
}
if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && Q.quotetime > time(NULL)-20 && LP_alice_eligible(Q.quotetime) > 0 )
{
printf("alice %s received RESERVED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0));
if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL )
{
printf("reserved quote validate error %.0f\n",qprice);
@ -728,7 +828,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
return(retval);
}
LP_aliceid(Q.tradeid,Q.aliceid,"reserved",0,0);
printf("alice %s received RESERVED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0));
if ( (retstr= LP_quotereceived(argjson)) != 0 )
free(retstr);
LP_reserved(ctx,myipaddr,pubsock,&Q);
@ -737,6 +836,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
}
else if ( strcmp(method,"connected") == 0 )
{
bestprice = LP_bob_competition(&counter,aliceid,qprice,1000);
if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 )
{
if ( (qprice= LP_quote_validate(autxo,butxo,&Q,0)) <= SMALLVAL )
@ -767,7 +867,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
return(retval);
}
price = ask;
//printf("MYPRICE %s/%s %.8f\n",Q.srccoin,Q.destcoin,price);
//printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",Q.srccoin,Q.destcoin,price,qprice);
if ( LP_validSPV(Q.destcoin,Q.destaddr,Q.desttxid,Q.destvout) < 0 )
{
printf("%s dest %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.desttxid));
@ -785,9 +885,8 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
}
if ( strcmp(method,"request") == 0 )
{
char str[65];//,str2[65];
recalc = 0;
if ( bits256_cmp(Q.srchash,G.LP_mypub25519) != 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 )
char str[65];
if ( bits256_nonz(Q.srchash) == 0 || bits256_cmp(Q.srchash,G.LP_mypub25519) == 0 )
{
qprice = (double)Q.destsatoshis / Q.satoshis;
strcpy(Q.gui,G.gui);
@ -797,76 +896,47 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
memset(&Q.txid,0,sizeof(Q.txid));
memset(&Q.txid2,0,sizeof(Q.txid2));
Q.vout = Q.vout2 = -1;
recalc = 1;
}
else if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL )
recalc = 1;
else if ( price < qprice )
{
char tmp[64];
if ( bits256_nonz(Q.txid) != 0 )
LP_utxos_remove(Q.txid,Q.vout);
else recalc = 1;
if ( bits256_nonz(Q.txid2) != 0 )
LP_utxos_remove(Q.txid2,Q.vout2);
else recalc = 1;
printf("price %.8f qprice %.8f\n",price,qprice);
if ( recalc == 0 )
{
value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout);
value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2);
//printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2));
if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0,Q.satoshis)) == 0 )
recalc = 1;
else if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout )
recalc = 1;
}
} else return(retval);
if ( qprice > price )
{
r = (rand() % 100);
r = (LP_rand() % 100);
range = (qprice - price);
printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f\n",price,qprice,r,range,price + (r*range)/100.,LP_bob_competition(aliceid,price));
price += (r * range) / 100.;
bestprice = LP_bob_competition(aliceid,price);
if ( price < bestprice+SMALLVAL )
bestprice = LP_bob_competition(&counter,aliceid,price,0);
printf(">>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",ask,qprice,r,range,price,bestprice,counter);
if ( counter > 3 || price > bestprice ) // skip if late or bad price
return(retval);
} else return(retval);
//printf("recalc.%d address.(%s/%s) price %.8f request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,price,jprint(argjson,0));
if ( recalc != 0 )
LP_RTmetrics_update(Q.srccoin,Q.destcoin);
if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 )
{
LP_RTmetrics_update(Q.srccoin,Q.destcoin);
if ( LP_RTmetrics_blacklisted(Q.desthash) >= 0 )
{
printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash));
return(retval);
}
LP_listunspent_both(Q.srccoin,Q.coinaddr,0);
if ( (butxo= LP_address_utxopair(1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 )
{
strcpy(Q.gui,G.gui);
strcpy(Q.coinaddr,coin->smartaddr);
Q.srchash = G.LP_mypub25519;
Q.txid = butxo->payment.txid;
Q.vout = butxo->payment.vout;
Q.txid2 = butxo->deposit.txid;
Q.vout2 = butxo->deposit.vout;
Q.satoshis = butxo->S.satoshis;
//printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis));
}
else
{
//printf("cant find utxopair\n");
return(retval);
}
printf("request from blacklisted %s, ignore\n",bits256_str(str,Q.desthash));
return(retval);
}
LP_address_utxo_reset(coin);
if ( (butxo= LP_address_myutxopair(butxo,1,utxos,max,LP_coinfind(Q.srccoin),Q.coinaddr,Q.txfee,dstr(Q.destsatoshis),price,Q.desttxfee)) != 0 )
{
strcpy(Q.gui,G.gui);
strcpy(Q.coinaddr,coin->smartaddr);
Q.srchash = G.LP_mypub25519;
Q.txid = butxo->payment.txid;
Q.vout = butxo->payment.vout;
Q.txid2 = butxo->deposit.txid;
Q.vout2 = butxo->deposit.vout;
Q.satoshis = butxo->S.satoshis;
Q.quotetime = (uint32_t)time(NULL);
printf("found %.8f -> %.8f newprice %.8f vs ask %.8f += %.8f qprice %.8f\n",dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,ask,price,qprice);
}
else
{
printf("cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f\n",(long long)aliceid,Q.srccoin,Q.destcoin,dstr(LP_basesatoshis(dstr(Q.destsatoshis),price,Q.txfee,Q.desttxfee)),dstr(Q.destsatoshis));
return(retval);
}
}
else // "connect"
else if ( strcmp(method,"connect") == 0 )
{
if ( bits256_cmp(G.LP_mypub25519,Q.srchash) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0 )
{
butxo = LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2); // better work!
} else return(retval);
if ( bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 || bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 )
return(retval);
}
if ( strcmp(Q.coinaddr,coin->smartaddr) != 0 )
{
@ -888,54 +958,48 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
printf("(%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s %.8f < %.8f\n",bid,ask,qprice,price,Q.srccoin,Q.destcoin,qprice,(ask - 0.00000001) * 0.998);
return(retval);
}
char str[65],str2[65]; printf("butxo.%p (%s %s) TRADECOMMAND.(%s)\n",butxo,butxo!=0?bits256_str(str,butxo->payment.txid):"",butxo!=0?bits256_str(str2,butxo->deposit.txid):"",jprint(argjson,0));
if ( butxo->S.swap == 0 && time(NULL) > butxo->T.swappending )
butxo->T.swappending = 0;
char *astr = jprint(argjson,0);
char str[65],str2[65]; printf("(%s/v%d %s/v%d) TRADECOMMAND.(%s)\n",bits256_str(str,Q.txid),Q.vout,bits256_str(str2,Q.txid2),Q.vout2,astr);
free(astr);
if ( strcmp(method,"request") == 0 ) // bob needs apayment + fee tx's
{
if ( LP_isavailable(butxo) > 0 )
if ( LP_allocated(Q.txid,Q.vout) == 0 && LP_allocated(Q.txid2,Q.vout2) == 0 )
{
autxo->T.swappending = butxo->T.swappending = Q.timestamp + LP_RESERVETIME;
retjson = LP_quotejson(&Q);
butxo->S.otherpubkey = jbits256(argjson,"desthash");
LP_unavailableset(butxo,butxo->S.otherpubkey);
jaddnum(retjson,"quotetime",juint(argjson,"quotetime"));
jaddnum(retjson,"pending",butxo->T.swappending);
jaddbits256(retjson,"desthash",butxo->S.otherpubkey);
jaddbits256(retjson,"pubkey",butxo->S.otherpubkey);
LP_unavailableset(Q.txid,Q.vout,Q.timestamp + LP_RESERVETIME,Q.desthash);
LP_unavailableset(Q.txid2,Q.vout2,Q.timestamp + LP_RESERVETIME,Q.desthash);
if ( Q.quotetime == 0 )
Q.quotetime = (uint32_t)time(NULL);
jaddnum(retjson,"quotetime",Q.quotetime);
jaddnum(retjson,"pending",Q.timestamp + LP_RESERVETIME);
//jaddbits256(retjson,"desthash",Q.desthash);
jaddstr(retjson,"method","reserved");
msg = jprint(retjson,0);
butxo->T.lasttime = (uint32_t)time(NULL);
printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",butxo->T.swappending,qprice,ask,msg);
// LP_addsig
//msg2 = clonestr(msg);
LP_reserved_msg(1,Q.srccoin,Q.destcoin,butxo->S.otherpubkey,clonestr(msg));
printf("return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f\n(%s)\n",Q.timestamp + LP_RESERVETIME,qprice,ask,msg);
LP_reserved_msg(1,Q.srccoin,Q.destcoin,Q.desthash,clonestr(msg));
sleep(1);
bits256 zero;
memset(zero.bytes,0,sizeof(zero));
LP_reserved_msg(1,Q.srccoin,Q.destcoin,zero,msg);
//LP_broadcast_message(LP_mypubsock,Q.srccoin,Q.destcoin,Q.desthash,jprint(retjson,0));
free_json(retjson);
butxo->T.lasttime = (uint32_t)time(NULL);
return(retval);
} else printf("warning swappending.%u swap.%p\n",butxo->T.swappending,butxo->S.swap);
} else printf("request processing selected ineligible utxos?\n");
}
else if ( strcmp(method,"connect") == 0 ) // bob
{
retval = 4;
if ( butxo->S.swap == 0 && butxo->T.swappending != 0 )
if ( LP_reservation_check(Q.txid,Q.vout,Q.desthash) == 0 && LP_reservation_check(Q.txid2,Q.vout2,Q.desthash) == 0 )
{
// validate SPV alice
LP_connectstartbob(ctx,pubsock,butxo,argjson,Q.srccoin,Q.destcoin,qprice,&Q);
//LP_butxo_swapfields_set(butxo);
LP_connectstartbob(ctx,pubsock,argjson,Q.srccoin,Q.destcoin,qprice,&Q);
return(retval);
}
else printf("pend.%u swap %p when connect came in (%s)\n",butxo->T.swappending,butxo->S.swap,jprint(argjson,0));
} else printf("connect message from non-reserved (%s)\n",jprint(argjson,0));
}
//LP_butxo_swapfields_set(butxo);
}
return(retval);
}
#ifdef oldway
struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t max,double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct iguana_info *basecoin,char *coinaddr,uint64_t asatoshis,double price,uint64_t txfee,uint64_t desttxfee,bits256 pubkey,char *gui)
{
uint64_t basesatoshis; struct LP_utxoinfo *bestutxo;
@ -1005,7 +1069,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
{
bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160));
asatoshis = autxo->S.satoshis;
LP_listunspent_query(base,coinaddr);
//LP_listunspent_query(base,coinaddr);
for (j=0; j<maxiters; j++)
{
if ( (bestutxo= LP_ordermatch_iter(utxos,max,ordermatchpricep,bestsatoshisp,bestdestsatoshisp,basecoin,coinaddr,asatoshis,maxprice*.999,txfee,desttxfee,pubp->pubkey,gui)) != 0 )
@ -1040,10 +1104,11 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
LP_mypriceset(&changed,autxo->coin,base,1. / *ordermatchpricep);
return(bestutxo);
}
#endif
char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration,char *gui,uint32_t nonce,bits256 destpubkey,uint32_t tradeid)
{
uint64_t desttxfee,txfee; uint32_t lastnonce; int32_t i,maxiters,numpubs = 0; int64_t bestsatoshis=0,destsatoshis,bestdestsatoshis=0; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,B,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; bits256 pubkeys[100];
uint64_t desttxfee,txfee; uint32_t lastnonce; int64_t bestsatoshis=0,destsatoshis; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,B; struct LP_quoteinfo Q; bits256 pubkeys[100];
basecoin = LP_coinfind(base);
relcoin = LP_coinfind(rel);
if ( gui == 0 )
@ -1075,12 +1140,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
}
if ( time(NULL) < Alice_expiration )
return(clonestr("{\"error\":\"only one pending request at a time\"}"));
else
{
Alice_expiration = 0;
memset(&LP_Alicequery,0,sizeof(LP_Alicequery));
LP_Alicemaxprice = 0.;
}
else LP_alicequery_clear();
if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 )
return(clonestr("{\"error\":\"invalid parameter\"}"));
if ( strcmp("BTC",rel) == 0 )
@ -1089,8 +1149,10 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
memset(pubkeys,0,sizeof(pubkeys));
LP_txfees(&txfee,&desttxfee,base,rel);
destsatoshis = SATOSHIDEN * relvolume;
LP_address_utxo_reset(relcoin);
if ( (autxo= LP_utxo_bestfit(rel,destsatoshis + 2*desttxfee)) == 0 )
return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}"));
//printf("bestfit selected alice (%.8f %.8f) for %.8f sats %.8f\n",dstr(autxo->payment.value),dstr(autxo->fee.value),dstr(destsatoshis),dstr(autxo->S.satoshis));
if ( destsatoshis - desttxfee < autxo->S.satoshis )
{
destsatoshis -= desttxfee;
@ -1108,7 +1170,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value));
return(clonestr("{\"error\":\"cant find alice utxo that is small enough\"}"));
}
bestsatoshis = LP_basesatoshis(dstr(destsatoshis),maxprice,txfee,desttxfee);
bestsatoshis = 1.001 * LP_basesatoshis(dstr(destsatoshis),maxprice,txfee,desttxfee);
memset(&B,0,sizeof(B));
strcpy(B.coin,base);
if ( LP_quoteinfoinit(&Q,&B,rel,maxprice,bestsatoshis,destsatoshis) < 0 )
@ -1117,8 +1179,8 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
return(clonestr("{\"error\":\"cant set ordermatch quote info\"}"));
int32_t changed;
LP_mypriceset(&changed,autxo->coin,base,1. / maxprice);
return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid));
return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey));
#ifdef oldway
LP_RTmetrics_update(base,rel);
while ( 1 )
{
@ -1157,9 +1219,10 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
else return(clonestr("{\"error\":\"cant ordermatch to destpubkey\"}"));
}
printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f\n",i,maxiters,dstr(qprice),dstr(maxprice));
return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid));
return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey));
}
return(clonestr("{\"error\":\"cant get here\"}"));
#endif
}

2
iguana/exchanges/LP_peers.c

@ -235,7 +235,7 @@ uint16_t LP_randpeer(char *destip)
numpeers = LP_numpeers();
if ( numpeers > 0 )
{
r = rand() % numpeers;
r = LP_rand() % numpeers;
n = 0;
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{

8
iguana/exchanges/LP_portfolio.c

@ -18,7 +18,7 @@
// marketmaker
//
char LP_portfolio_base[16],LP_portfolio_rel[16];
char LP_portfolio_base[128],LP_portfolio_rel[128];
double LP_portfolio_relvolume;
cJSON *LP_portfolio_entry(struct iguana_info *coin)
@ -203,7 +203,7 @@ int32_t LP_autoprices,num_LP_autorefs;
struct LP_autoprice_ref
{
char refbase[16],refrel[16],base[16],rel[16];
char refbase[65],refrel[65],base[65],rel[65];
} LP_autorefs[100];
/*int32_t LP_autofill(char *base,char *rel,double maxprice,double totalrelvolume)
@ -325,7 +325,7 @@ double LP_pricesparse(void *ctx,int32_t trexflag,char *retstr,struct LP_priceinf
{
//{"success":true,"message":"","result":[{"MarketName":"BTC-KMD","High":0.00040840,"Low":0.00034900,"Volume":328042.46061669,"Last":0.00037236,"BaseVolume":123.36439511,"TimeStamp":"2017-07-15T13:50:21.87","Bid":0.00035721,"Ask":0.00037069,"OpenBuyOrders":343,"OpenSellOrders":1690,"PrevDay":0.00040875,"Created":"2017-02-11T23:04:01.853"},
//{"TradePairId":4762,"Label":"WAVES/BTC","AskPrice":0.00099989,"BidPrice":0.00097350,"Low":0.00095000,"High":0.00108838,"Volume":6501.24403100,"LastPrice":0.00098028,"BuyVolume":1058994.86554882,"SellVolume":2067.87377158,"Change":-7.46,"Open":0.00105926,"Close":0.00098028,"BaseVolume":6.52057452,"BuyBaseVolume":2.33098660,"SellBaseVolume":1167.77655709},
int32_t i,j,n,iter; double price,kmdbtc,bid,ask,nxtkmd=0.; struct LP_priceinfo *coinpp,*refpp; char symbol[16],*name,*refcoin; cJSON *retjson,*array,*item;
int32_t i,j,n,iter; double price,kmdbtc,bid,ask,nxtkmd=0.; struct LP_priceinfo *coinpp,*refpp; char symbol[65],*name,*refcoin; cJSON *retjson,*array,*item;
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
//printf("got.(%s)\n",retstr);
@ -553,7 +553,7 @@ int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,str
else return(-1);
}
struct LP_portfoliotrade { double metric; char buycoin[16],sellcoin[16]; };
struct LP_portfoliotrade { double metric; char buycoin[65],sellcoin[65]; };
int32_t LP_portfolio_order(struct LP_portfoliotrade *trades,int32_t max,cJSON *array)
{

121
iguana/exchanges/LP_prices.c

@ -18,11 +18,11 @@
// marketmaker
//
struct LP_orderbookentry { bits256 pubkey; double price; uint64_t minsatoshis,maxsatoshis,depth; uint32_t timestamp; int32_t numutxos; char coinaddr[64]; };
struct LP_orderbookentry { bits256 pubkey; double price; uint64_t avesatoshis,maxsatoshis,depth; uint32_t timestamp; int32_t numutxos; char coinaddr[64]; };
struct LP_priceinfo
{
char symbol[16];
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
@ -48,6 +48,79 @@ struct LP_cacheinfo
uint32_t timestamp;
} *LP_cacheinfos;
float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkeyinfo *pubp,uint32_t baseind,uint32_t relind)
{
struct LP_pubkey_quote *pq,*tmp; int32_t scale; int64_t scale64;
*numutxosp = 0;
*avesatoshisp = *maxsatoshisp = 0;
DL_FOREACH_SAFE(pubp->quotes,pq,tmp)
{
if ( baseind == pq->baseind && relind == pq->relind )
{
if ( (scale= pq->scale) == 0 )
pq->scale = scale = 6;
scale64 = 1;
while ( scale > 0 )
{
scale64 *= 10;
scale--;
}
*numutxosp = pq->numutxos;
*avesatoshisp = pq->aveutxo * scale64;
*maxsatoshisp = pq->maxutxo * scale64;
return(pq->price);
}
}
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)
{
struct LP_pubkey_quote *pq,*tmp; int64_t aveutxo,scale64,ave64,max64; int32_t scale;
DL_FOREACH_SAFE(pubp->quotes,pq,tmp)
{
if ( baseind == pq->baseind && relind == pq->relind )
break;
pq = 0;
}
if ( pq == 0 )
{
pq = calloc(1,sizeof(*pq));
pq->baseind = baseind;
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()
}
pq->price = price;
if ( utxocoin != 0 && utxocoin[0] != 0 )
{
if ( (scale= pq->scale) == 0 )
pq->scale = scale = 6;
scale64 = 1;
while ( scale > 0 )
{
scale64 *= 10;
scale--;
}
if ( numutxos >= 256 )
pq->numutxos = 255;
else pq->numutxos = numutxos;
aveutxo = (balance + (scale64>>1)) / numutxos;
if ( (ave64= (aveutxo / scale64)) >= (1LL << 32) )
ave64 = (1LL << 32) - 1;
max64 = ((maxutxo + (scale64>>1)) / scale64);
if ( max64 >= (1LL << 32) )
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));
}
}
struct LP_priceinfo *LP_priceinfo(int32_t ind)
{
if ( ind < 0 || ind >= LP_MAXPRICEINFOS )
@ -265,13 +338,14 @@ uint64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr)
}
}
metric = _LP_unspents_metric(total,n);
free_json(array);
}
return(metric);
}
cJSON *LP_pubkeyjson(struct LP_pubkeyinfo *pubp)
{
int32_t baseid,relid; char *base,hexstr[67],hexstr2[67],sigstr[256]; double price; cJSON *item,*array,*obj;
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();
array = cJSON_CreateArray();
for (baseid=0; baseid<LP_numpriceinfos; baseid++)
@ -279,7 +353,7 @@ cJSON *LP_pubkeyjson(struct LP_pubkeyinfo *pubp)
base = LP_priceinfos[baseid].symbol;
for (relid=0; relid<LP_numpriceinfos; relid++)
{
price = pubp->matrix[baseid][relid];
price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseid,relid);//pubp->matrix[baseid][relid];
if ( LP_pricevalid(price) > 0 )
{
item = cJSON_CreateArray();
@ -494,7 +568,8 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price)
if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 )
{
pubp->timestamp = (uint32_t)time(NULL);
pubp->matrix[basepp->ind][relpp->ind] = price;
LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,0,0,0,0,0);
//pubp->matrix[basepp->ind][relpp->ind] = price;
//pubp->timestamps[basepp->ind][relpp->ind] = pubp->timestamp;
//pubp->matrix[relpp->ind][basepp->ind] = (1. / price);
}
@ -670,7 +745,7 @@ cJSON *LP_orderbookjson(char *symbol,struct LP_orderbookentry *op)
jaddstr(item,"address",op->coinaddr);
jaddnum(item,"price",op->price);
jaddnum(item,"numutxos",op->numutxos);
jaddnum(item,"minvolume",dstr(op->minsatoshis)*0.8);
jaddnum(item,"avevolume",dstr(op->avesatoshis)*0.8);
jaddnum(item,"maxvolume",dstr(op->maxsatoshis)*0.8);
jaddnum(item,"depth",dstr(op->depth)*0.8);
jaddbits256(item,"pubkey",op->pubkey);
@ -679,7 +754,7 @@ cJSON *LP_orderbookjson(char *symbol,struct LP_orderbookentry *op)
return(item);
}
struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,double price,int32_t numutxos,uint64_t minsatoshis,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,uint64_t avesatoshis,uint64_t maxsatoshis,bits256 pubkey,uint32_t timestamp,uint64_t balance)
{
struct LP_orderbookentry *op;
if ( (op= calloc(1,sizeof(*op))) != 0 )
@ -687,7 +762,7 @@ struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,d
safecopy(op->coinaddr,address,sizeof(op->coinaddr));
op->price = price;
op->numutxos = numutxos;
op->minsatoshis = minsatoshis;
op->avesatoshis = avesatoshis;
op->maxsatoshis = maxsatoshis;
op->pubkey = pubkey;
op->timestamp = timestamp;
@ -717,7 +792,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; uint64_t minsatoshis,maxsatoshis,balance;
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;
if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 )
baseid = basepp->ind;
else return(num);
@ -736,23 +811,23 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *
if ( pubp->timestamp < oldest )
continue;
bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160));
minsatoshis = maxsatoshis = n = 0;
avesatoshis = maxsatoshis = n = 0;
ap = 0;
if ( (price= pubp->matrix[baseid][relid]) > SMALLVAL )//&& pubp->timestamps[baseid][relid] >= oldest )
if ( (price= LP_pubkey_price(&n,&avesatoshis,&maxsatoshis,pubp,baseid,relid)) > SMALLVAL ) //pubp->matrix[baseid][relid]) > SMALLVAL )//&& pubp->timestamps[baseid][relid] >= oldest )
{
balance = 0;
if ( (ap= LP_addressfind(basecoin,coinaddr)) != 0 )
balance = avesatoshis * n;
//if ( (ap= LP_addressfind(basecoin,coinaddr)) != 0 )
{
n = LP_address_minmax(&balance,&minsatoshis,&maxsatoshis,ap);
//n = LP_address_minmax(&balance,&minsatoshis,&maxsatoshis,ap);
if ( polarity > 0 )
{
balance *= price;
minsatoshis *= price;
avesatoshis *= price;
maxsatoshis *= price;
}
//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,minsatoshis,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)) != 0 )
{
*arrayp = realloc(*arrayp,sizeof(*(*arrayp)) * (num+1));
(*arrayp)[num++] = op;
@ -817,7 +892,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration)
{
//printf("bid ping %s %s\n",rel,bids[i]->coinaddr);
LP_address(relcoin,bids[i]->coinaddr);
if ( 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 )
@ -841,7 +916,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration)
{
//printf("ask ping %s %s\n",base,asks[i]->coinaddr);
LP_address(basecoin,asks[i]->coinaddr);
if ( 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 )
@ -1035,7 +1110,7 @@ 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)
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)
{
struct LP_priceinfo *basepp,*relpp; uint32_t now; uint64_t price64; struct LP_pubkeyinfo *pubp; char str[65],fname[512]; FILE *fp;
//printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey));
@ -1069,12 +1144,14 @@ void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price)
}
if ( (pubp= LP_pubkeyadd(pubkey)) != 0 )
{
if ( (rand() % 1000) == 0 )
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);
pubp->timestamp = (uint32_t)time(NULL);
if ( fabs(pubp->matrix[basepp->ind][relpp->ind] - price) > SMALLVAL )
LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,balance,utxocoin,numrelutxos,minutxo,maxutxo);
//pubp->depthinfo[basepp->ind][relpp->ind] = LP_depthinfo_compact();
//if ( fabs(pubp->matrix[basepp->ind][relpp->ind] - price) > SMALLVAL )
{
pubp->matrix[basepp->ind][relpp->ind] = price;
//pubp->matrix[basepp->ind][relpp->ind] = price;
//pubp->timestamps[basepp->ind][relpp->ind] = pubp->timestamp;
dxblend(&basepp->relvals[relpp->ind],price,0.9);
dxblend(&relpp->relvals[basepp->ind],1. / price,0.9);

96
iguana/exchanges/LP_remember.c

@ -32,13 +32,15 @@ void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,in
void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,int32_t locktime,bits256 triggertxid)
{
char zeroes[32],fname[512],str[65],coinaddr[64],secretAmstr[41],secretAm256str[65],secretBnstr[41],secretBn256str[65]; FILE *fp; int32_t i,len; uint8_t redeemscript[256],script[256];
char zeroes[32],fname[512],str[65],coinaddr[64],secretAmstr[41],secretAm256str[65],secretBnstr[41],secretBn256str[65]; FILE *fp; int32_t i,len; uint8_t redeemscript[256],script[256]; struct iguana_info *bobcoin,*alicecoin;
sprintf(fname,"%s/SWAPS/%u-%u.%s",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid,rawtx->name), OS_compatible_path(fname);
bobcoin = LP_coinfind(swap->I.bobstr);
alicecoin = LP_coinfind(swap->I.alicestr);
coinaddr[0] = secretAmstr[0] = secretAm256str[0] = secretBnstr[0] = secretBn256str[0] = 0;
memset(zeroes,0,sizeof(zeroes));
if ( rawtx != 0 && (fp= fopen(fname,"wb")) != 0 )
if ( alicecoin != 0 && bobcoin != 0 && rawtx != 0 && (fp= fopen(fname,"wb")) != 0 )
{
fprintf(fp,"{\"name\":\"%s\",\"coin\":\"%s\"",rawtx->name,rawtx->coin->symbol);
fprintf(fp,"{\"name\":\"%s\",\"coin\":\"%s\"",rawtx->name,rawtx->symbol);
if ( rawtx->I.datalen > 0 )
{
fprintf(fp,",\"tx\":\"");
@ -47,10 +49,10 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx
fprintf(fp,"\",\"txid\":\"%s\"",bits256_str(str,bits256_doublesha256(0,rawtx->txbytes,rawtx->I.datalen)));
if ( rawtx == &swap->bobdeposit || rawtx == &swap->bobpayment )
{
LP_swap_coinaddr(&swap->bobcoin,coinaddr,0,rawtx->txbytes,rawtx->I.datalen,0);
LP_swap_coinaddr(bobcoin,coinaddr,0,rawtx->txbytes,rawtx->I.datalen,0);
if ( coinaddr[0] != 0 )
{
LP_importaddress(swap->bobcoin.symbol,coinaddr);
LP_importaddress(swap->I.bobstr,coinaddr);
if ( rawtx == &swap->bobdeposit )
safecopy(swap->Bdeposit,coinaddr,sizeof(swap->Bdeposit));
else safecopy(swap->Bpayment,coinaddr,sizeof(swap->Bpayment));
@ -63,16 +65,16 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx
fprintf(fp,",\"%s\":\"%s\"","Bpayment",swap->Bpayment);
fprintf(fp,",\"expiration\":%u",swap->I.expiration);
fprintf(fp,",\"iambob\":%d",swap->I.iambob);
fprintf(fp,",\"bobcoin\":\"%s\"",swap->bobcoin.symbol);
fprintf(fp,",\"alicecoin\":\"%s\"",swap->alicecoin.symbol);
fprintf(fp,",\"bobcoin\":\"%s\"",swap->I.bobstr);
fprintf(fp,",\"alicecoin\":\"%s\"",swap->I.alicestr);
fprintf(fp,",\"lock\":%u",locktime);
fprintf(fp,",\"amount\":%.8f",dstr(rawtx->I.amount));
if ( bits256_nonz(triggertxid) != 0 )
fprintf(fp,",\"trigger\":\"%s\"",bits256_str(str,triggertxid));
if ( bits256_nonz(swap->I.pubAm) != 0 && bits256_nonz(swap->I.pubBn) != 0 )
{
basilisk_alicescript(redeemscript,&len,script,0,coinaddr,swap->alicecoin.taddr,swap->alicecoin.p2shtype,swap->I.pubAm,swap->I.pubBn);
LP_importaddress(swap->alicecoin.symbol,coinaddr);
basilisk_alicescript(redeemscript,&len,script,0,coinaddr,alicecoin->taddr,alicecoin->p2shtype,swap->I.pubAm,swap->I.pubBn);
LP_importaddress(swap->I.alicestr,coinaddr);
fprintf(fp,",\"Apayment\":\"%s\"",coinaddr);
}
if ( rawtx->I.redeemlen > 0 )
@ -94,6 +96,10 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx
if ( (fp= fopen(fname,"wb")) != 0 )
{
fprintf(fp,"{\"tradeid\":%u,\"aliceid\":\"%llu\",\"src\":\"%s\",\"srcamount\":%.8f,\"dest\":\"%s\",\"destamount\":%.8f,\"requestid\":%u,\"quoteid\":%u,\"iambob\":%d,\"state\":%u,\"otherstate\":%u,\"expiration\":%u,\"dlocktime\":%u,\"plocktime\":%u,\"Atxfee\":%llu,\"Btxfee\":%llu",swap->tradeid,(long long)swap->aliceid,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.requestid,swap->I.req.quoteid,swap->I.iambob,swap->I.statebits,swap->I.otherstatebits,swap->I.expiration,swap->bobdeposit.I.locktime,swap->bobpayment.I.locktime,(long long)swap->I.Atxfee,(long long)swap->I.Btxfee);
if ( swap->I.iambob == 0 )
fprintf(fp,",\"Agui\":\"%s\"",G.gui);
else fprintf(fp,",\"Bgui\":\"%s\"",G.gui);
fprintf(fp,",\"gui\":\"%s\"",G.gui);
if ( memcmp(zeroes,swap->I.secretAm,20) != 0 )
{
init_hexbytes_noT(secretAmstr,swap->I.secretAm,20);
@ -450,11 +456,20 @@ cJSON *LP_swap_json(struct LP_swap_remember *rswap)
{
cJSON *item,*array; int32_t i;
item = cJSON_CreateObject();
if ( LP_swap_endcritical < LP_swap_critical )
{
jaddstr(item,"warning","swaps in critical section");
jaddnum(item,"critical",LP_swap_critical);
jaddnum(item,"endcritical",LP_swap_endcritical);
}
jaddnum(item,"expiration",rswap->expiration);// - INSTANTDEX_LOCKTIME*2);
jaddnum(item,"tradeid",rswap->tradeid);
jaddnum(item,"requestid",rswap->requestid);
jaddnum(item,"quoteid",rswap->quoteid);
jaddnum(item,"iambob",rswap->iambob);
jaddstr(item,"Bgui",rswap->Bgui);
jaddstr(item,"Agui",rswap->Agui);
jaddstr(item,"gui",rswap->gui);
jaddstr(item,"bob",rswap->src);
jaddnum(item,"srcamount",dstr(rswap->srcamount));
jaddnum(item,"bobtxfee",dstr(rswap->Btxfee));
@ -503,6 +518,9 @@ int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t
if ( (item= cJSON_Parse(fstr)) != 0 )
{
rswap->iambob = jint(item,"iambob");
safecopy(rswap->Bgui,jstr(item,"Bgui"),sizeof(rswap->Bgui));
safecopy(rswap->Agui,jstr(item,"Agui"),sizeof(rswap->Agui));
safecopy(rswap->gui,jstr(item,"gui"),sizeof(rswap->gui));
rswap->tradeid = juint(item,"tradeid");
rswap->aliceid = j64bits(item,"aliceid");
if ( (secretstr= jstr(item,"secretAm")) != 0 && strlen(secretstr) == 40 )
@ -1235,29 +1253,6 @@ char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid)
if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid)) != 0 )
return(jprint(item,1));
else return(clonestr("{\"error\":\"cant find requestid-quoteid\"}"));
/*if ( (liststr= basilisk_swaplist(requestid,quoteid)) != 0 )
{
//printf("swapentry.(%s)\n",liststr);
if ( (retjson= cJSON_Parse(liststr)) != 0 )
{
if ( (array= jarray(&n,retjson,"swaps")) != 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
//printf("(%s) check r%u/q%u\n",jprint(item,0),juint(item,"requestid"),juint(item,"quoteid"));
if ( juint(item,"requestid") == requestid && juint(item,"quoteid") == quoteid )
{
retstr = jprint(item,0);
break;
}
}
}
free_json(retjson);
}
free(liststr);
}
return(retstr);*/
}
extern struct LP_quoteinfo LP_Alicequery;
@ -1429,3 +1424,40 @@ char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit)
return(jprint(retarray,1));
}
int32_t LP_pendingswap(uint32_t requestid,uint32_t quoteid)
{
cJSON *retjson,*array,*pending,*item; uint32_t r,q; char *retstr; int32_t i,n,retval = 0;
if ( (retstr= LP_recent_swaps(1000)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (array= jarray(&n,retjson,"swaps")) != 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
r = juint(jitem(item,0),0);
q = juint(jitem(item,1),0);
if ( r == requestid && q == quoteid )
{
retval = 1;
break;
}
}
}
if ( retval == 0 )
{
if ( (pending= jobj(retjson,"pending")) != 0 )
{
r = juint(pending,"requestid");
q = juint(pending,"quoteid");
if ( r == requestid && q == quoteid )
retval = 1;
}
}
free_json(retjson);
}
free(retstr);
}
return(retval);
}

82
iguana/exchanges/LP_rpc.c

@ -115,7 +115,7 @@ cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params)
void LP_unspents_mark(char *symbol,cJSON *vins)
{
printf("LOCK (%s)\n",jprint(vins,0));
//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" };
@ -208,7 +208,7 @@ cJSON *LP_NXT_decrypt(uint64_t txnum,char *account,char *data,char *nonce,char *
cJSON *LP_NXT_redeems()
{
char url[1024],*retstr,*recv,*method,*msgstr,assetname[16]; 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;
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 = "";
@ -314,13 +314,13 @@ char *account = "NXT-MRBN-8DFH-PFMK-A4DBM";
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[rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid);
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[rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid);
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);
@ -429,7 +429,7 @@ cJSON *LP_gettx(char *symbol,bits256 txid)
}
else
{
if ( (retjson= electrum_transaction(symbol,coin->electrum,&retjson,txid)) != 0 )
if ( (retjson= electrum_transaction(symbol,coin->electrum,&retjson,txid,0)) != 0 )
return(retjson);
else printf("failed blockchain.transaction.get %s %s\n",coin->symbol,bits256_str(str,txid));
return(cJSON_Parse("{\"error\":\"no transaction bytes\"}"));
@ -507,7 +507,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 )
if ( (txobj= electrum_transaction(symbol,coin->electrum,&txobj,txid,0)) != 0 )
{
if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n > 0 )
LP_destaddr(coinaddr,jitem(vouts,vout));
@ -544,7 +544,7 @@ cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
return(retjson);
}
}
printf("couldnt find %s (%s) %s/v%d\n",symbol,coinaddr,bits256_str(str,txid),vout);
//printf("couldnt find %s (%s) %s/v%d\n",symbol,coinaddr,bits256_str(str,txid),vout);
return(cJSON_Parse("{\"error\":\"couldnt get tx\"}"));
}
}
@ -682,15 +682,6 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
{
//printf("LP_listunspent_query.(%s %s)\n",symbol,coinaddr);
LP_listunspent_query(coin->symbol,coin->smartaddr);
/*if ( fullflag != 0 )
{
if ( (destport= LP_randpeer(destip)) > 0 )
{
retstr = issue_LP_listunspent(destip,destport,symbol,coinaddr);
//printf("issue %s %s %s -> (%s)\n",coin->symbol,coinaddr,destip,retstr);
retjson = cJSON_Parse(retstr);
} else printf("LP_listunspent_issue couldnt get a random peer?\n");
}*/
}
if ( retjson != 0 )
{
@ -875,6 +866,7 @@ char *LP_sendrawtransaction(char *symbol,char *signedtx)
errobj = cJSON_CreateObject();
jaddstr(errobj,"error","rejected");
jaddnum(errobj,"code",-27);
free(retstr);
retstr = jprint(errobj,1);
}
else
@ -931,36 +923,38 @@ char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON *
return(jprint(retjson,1));
}
return(signedtx);
array = cJSON_CreateArray();
jaddistr(array,rawtx);
jaddi(array,jduplicate(vins));
jaddi(array,jduplicate(privkeys));
paramstr = jprint(array,1);
//printf("signrawtransaction\n");
if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"signrawtransaction",paramstr)) != 0 )
if ( (0) )
{
if ( (json= cJSON_Parse(retstr)) != 0 )
array = cJSON_CreateArray();
jaddistr(array,rawtx);
jaddi(array,jduplicate(vins));
jaddi(array,jduplicate(privkeys));
paramstr = jprint(array,1);
//printf("signrawtransaction\n");
if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"signrawtransaction",paramstr)) != 0 )
{
if ( (hexstr= jstr(json,"hex")) != 0 )
if ( (json= cJSON_Parse(retstr)) != 0 )
{
len = (int32_t)strlen(hexstr);
signedtx = calloc(1,len+1);
strcpy(signedtx,hexstr);
*completedp = is_cJSON_True(jobj(json,"complete"));
len >>= 1;
data = malloc(len);
decode_hex(data,len,hexstr);
*signedtxidp = bits256_doublesha256(0,data,len);
if ( (hexstr= jstr(json,"hex")) != 0 )
{
len = (int32_t)strlen(hexstr);
signedtx = calloc(1,len+1);
strcpy(signedtx,hexstr);
*completedp = is_cJSON_True(jobj(json,"complete"));
len >>= 1;
data = malloc(len);
decode_hex(data,len,hexstr);
*signedtxidp = bits256_doublesha256(0,data,len);
}
//else
printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr);
free_json(json);
}
//else
printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr);
free_json(json);
free(retstr);
}
free(retstr);
free(paramstr);
return(signedtx);
}
free(paramstr);
return(signedtx);
}
cJSON *LP_getblock(char *symbol,bits256 txid)
@ -1041,7 +1035,7 @@ uint32_t LP_heighttime(char *symbol,int32_t height)
{
if ( (retjson= cJSON_Parse(blockhashstr)) != 0 )
{
printf("height.(%s)\n",jprint(retjson,0));
//printf("height.(%s)\n",jprint(retjson,0));
timestamp = juint(retjson,"time");
free_json(retjson);
}
@ -1052,7 +1046,7 @@ uint32_t LP_heighttime(char *symbol,int32_t height)
{
if ( (retjson= electrum_getheader(coin->symbol,ep,&retjson,height)) != 0 )
{
printf("%s\n",jprint(retjson,0));
//printf("%s\n",jprint(retjson,0));
timestamp = juint(retjson,"timestamp");
free_json(retjson);
}
@ -1083,7 +1077,7 @@ cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t hei
*heightp = juint(json,"height");
if ( height >= 0 && *heightp != height )
{
printf("unexpected height %d vs %d for %s (%s)\n",*heightp,height,blockhashstr,jprint(json,0));
//printf("unexpected height %d vs %d for %s (%s)\n",*heightp,height,blockhashstr,jprint(json,0));
*heightp = -1;
free_json(json);
json = 0;
@ -1264,7 +1258,7 @@ int32_t LP_notarization_latest(int32_t *bestheightp,struct iguana_info *coin)
blockhash = jbits256(blockjson,"previousblockhash");
if ( bits256_nonz(blockhash) == 0 )
{
printf("null prev.(%s)\n",jprint(blockjson,0));
//printf("null prev.(%s)\n",jprint(blockjson,0));
free_json(blockjson);
break;
}

4
iguana/exchanges/LP_scan.c

@ -127,7 +127,7 @@ int sort_balance(void *a,void *b)
cJSON *LP_snapshot(struct iguana_info *coin,int32_t height)
{
static bits256 bannedarray[64]; static int32_t numbanned,indallvouts,maxsnapht; static char lastcoin[16];
static bits256 bannedarray[64]; static int32_t numbanned,indallvouts,maxsnapht; static char lastcoin[65];
struct LP_transaction *tx,*tmp; struct LP_address *ap,*atmp; int32_t isKMD,i,j,n,skipflag=0,startht,endht,ht; uint64_t banned_balance=0,balance=0,noaddr_balance=0; cJSON *retjson,*array,*item;
if ( bannedarray[0].txid == 0 )
numbanned = komodo_bannedset(&indallvouts,bannedarray,(int32_t)(sizeof(bannedarray)/sizeof(*bannedarray)));
@ -466,7 +466,7 @@ int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int
{
if ( (array= electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr)) != 0 )
{
char str[65]; printf("check %s mempool.(%s)\n",bits256_str(str,txid),jprint(array,0));
//char str[65]; printf("check %s mempool.(%s)\n",bits256_str(str,txid),jprint(array,0));
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)

45
iguana/exchanges/LP_signatures.c

@ -104,6 +104,7 @@ cJSON *LP_quotejson(struct LP_quoteinfo *qp)
int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson)
{
uint32_t rid,qid;
memset(qp,0,sizeof(*qp));
safecopy(qp->gui,LP_gui,sizeof(qp->gui));
safecopy(qp->srccoin,jstr(argjson,"base"),sizeof(qp->srccoin));
safecopy(qp->coinaddr,jstr(argjson,"address"),sizeof(qp->coinaddr));
@ -131,14 +132,16 @@ int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson)
qp->R.quoteid = juint(argjson,"quoteid");
if ( qp->R.requestid == 0 )
{
rid= basilisk_requestid(&qp->R);
//printf("requestid.%u -> %u\n",qp->R.requestid,rid);
rid = basilisk_requestid(&qp->R);
if ( qp->R.requestid != 0 && qp->R.requestid != rid )
printf("requestid.%u -> %u\n",qp->R.requestid,rid);
qp->R.requestid = rid;
}
if ( qp->R.quoteid == 0 )
{
qid= basilisk_quoteid(&qp->R);
//printf("quoteid.%u -> %u\n",qp->R.quoteid,qid);
qid = basilisk_quoteid(&qp->R);
if ( qp->R.quoteid != 0 && qp->R.quoteid != qid )
printf("quoteid.%u -> %u\n",qp->R.quoteid,qid);
qp->R.quoteid = qid;
}
return(0);
@ -327,6 +330,7 @@ int32_t LP_utxos_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,uint8_t *pub
void LP_postutxos(char *symbol,char *coinaddr)
{
bits256 zero; uint32_t timestamp; bits256 utxoshash; char pubsecpstr[67]; struct iguana_info *coin; cJSON *array,*reqjson = cJSON_CreateObject();
return;
if ( (coin= LP_coinfind(symbol)) != 0 && (array= LP_address_utxos(coin,coinaddr,1)) != 0 )
{
//printf("LP_postutxos pubsock.%d %s %s\n",pubsock,symbol,coin->smartaddr);
@ -359,6 +363,7 @@ 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 )
@ -446,7 +451,8 @@ 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; char pubsecpstr[67]; uint32_t timestamp; uint64_t price64; bits256 zero; cJSON *reqjson = cJSON_CreateObject();
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;
reqjson = cJSON_CreateObject();
// LP_addsig
if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 && basecoin->electrum == 0 )//&& relcoin->electrum == 0 )
{
@ -462,6 +468,18 @@ 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 ( (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));
}
}
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));
return(clonestr("{\"result\":\"success\"}"));
@ -479,7 +497,7 @@ 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);
LP_pricefeedupdate(pubkey,base,rel,price,jstr(argjson,"utxocoin"),jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN);
return(clonestr("{\"result\":\"success\"}"));
} else return(clonestr("{\"error\":\"sig failure\"}"));
}
@ -613,6 +631,7 @@ char *LP_notify_recv(cJSON *argjson)
void LP_smartutxos_push(struct iguana_info *coin)
{
uint64_t value; bits256 zero,txid; int32_t i,vout,height,n; cJSON *array,*item,*req;
return;
if ( coin->smartaddr[0] == 0 )
return;
//LP_notify_pubkeys(coin->ctx,LP_mypubsock);
@ -648,6 +667,7 @@ void LP_smartutxos_push(struct iguana_info *coin)
char *LP_uitem_recv(cJSON *argjson)
{
bits256 txid; int32_t vout,height; uint64_t value; struct iguana_info *coin; char *coinaddr,*symbol;
printf("LP_uitem_recv deprecated\n");
txid = jbits256(argjson,"txid");
vout = jint(argjson,"vout");
height = jint(argjson,"ht");
@ -657,7 +677,7 @@ char *LP_uitem_recv(cJSON *argjson)
{
//char str[65]; printf("uitem %s %s %s/v%d %.8f ht.%d\n",symbol,coinaddr,bits256_str(str,txid),vout,dstr(value),height);
if ( strcmp(coin->smartaddr,coinaddr) != 0 )
LP_address_utxoadd("LP_uitem_recv",coin,coinaddr,txid,vout,value,height,-1);
LP_address_utxoadd((uint32_t)time(NULL),"LP_uitem_recv",coin,coinaddr,txid,vout,value,height,-1);
//else printf("ignore external uitem %s %s\n",symbol,coin->smartaddr);
}
return(clonestr("{\"result\":\"success\"}"));
@ -675,11 +695,14 @@ 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; struct LP_utxoinfo *utxo;
cJSON *reqjson; bits256 zero; char *msg,*msg2; int32_t flag = 0;
if ( strcmp(method,"request") == 0 )
{
if ( (utxo= LP_utxofind(0,qp->desttxid,qp->destvout)) != 0 && LP_ismine(utxo) > 0 && LP_isavailable(utxo) > 0 )
LP_unavailableset(utxo,qp->srchash);
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);
}
else
{
printf("couldnt find my txid to make request\n");
@ -694,7 +717,7 @@ void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_
jaddnum(reqjson,"timestamp",time(NULL));
msg = jprint(reqjson,1);
msg2 = clonestr(msg);
//printf("QUERY.(%s)\n",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 )

52
iguana/exchanges/LP_socket.c

@ -98,7 +98,7 @@ int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port)
#endif
expand_ipbits(checkipaddr,saddr.sin_addr.s_addr);
if ( strcmp(ipaddr,checkipaddr) != 0 )
printf("bindflag.%d iguana_socket mismatch (%s) -> (%s)?\n",bindflag,checkipaddr,ipaddr);
printf("bindflag.%d iguana_socket mismatch (%s) -> (%s)\n",bindflag,checkipaddr,ipaddr);
//#endif
if ( (sock= socket(AF_INET,SOCK_STREAM,0)) < 0 )
{
@ -272,7 +272,7 @@ struct electrum_info *electrum_server(char *symbol,struct electrum_info *ep)
ep = recent_ep;
if ( n > 0 )
{
i = (rand() % n);
i = (LP_rand() % n);
ep = rbuf[i];
}
}
@ -303,7 +303,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep
else
{
//printf("external unspent has no gettxout\n");
flag += LP_address_utxoadd("electrum process",coin,coinaddr,txid,v,value,0,1);
flag += LP_address_utxoadd((uint32_t)time(NULL),"electrum process",coin,coinaddr,txid,v,value,0,1);
}
}
else
@ -345,7 +345,7 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep
if ( tx->height > 0 )
{
//printf("from electrum_process_array\n");
flag += LP_address_utxoadd("electrum process2",coin,coinaddr,txid,v,value,tx->height,-1);
flag += LP_address_utxoadd((uint32_t)time(NULL),"electrum process2",coin,coinaddr,txid,v,value,tx->height,-1);
}
//printf("v.%d numvouts.%d %.8f (%s)\n",v,tx->numvouts,dstr(tx->outpoints[jint(item,"tx_pos")].value),jprint(item,0));
} //else printf("cant find tx\n");
@ -513,7 +513,7 @@ cJSON *electrum_address_subscribe(char *symbol,struct electrum_info *ep,cJSON **
cJSON *retjson;
if ( (retjson= electrum_strarg(symbol,ep,retjsonp,"blockchain.address.subscribe",addr,ELECTRUM_TIMEOUT)) != 0 )
{
printf("subscribe.(%s)\n",jprint(retjson,0));
//printf("subscribe.(%s)\n",jprint(retjson,0));
}
return(retjson);
}
@ -544,7 +544,7 @@ cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON *
if ( tx->height > 0 && tx->height != height )
printf("update %s height.%d <- %d\n",bits256_str(str,txid),tx->height,height);
tx->height = height;
LP_address_utxoadd("electrum history",coin,addr,txid,0,0,height,-1);
LP_address_utxoadd((uint32_t)time(NULL),"electrum history",coin,addr,txid,0,0,height,-1);
}
}
}
@ -578,6 +578,8 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON
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 )
return(0);
if ( strcmp(addr,INSTANTDEX_KMD) == 0 )
return(cJSON_Parse("[]"));
if ( ep == 0 || ep->heightp == 0 )
height = coin->longestchain;
else height = *(ep->heightp);
@ -600,7 +602,10 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON
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 )
LP_postutxos(coin->symbol,addr), updatedflag = 1;
{
//LP_postutxos(coin->symbol,addr);
updatedflag = 1;
}
if ( strcmp(addr,coin->smartaddr) == 0 )
{
retstr = jprint(retjson,0);
@ -701,11 +706,11 @@ cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjs
}
hexjson = electrum_hasharg(symbol,ep,&hexjson,"blockchain.transaction.get",txid,ELECTRUM_TIMEOUT);
hexstr = jprint(hexjson,0);
if ( strlen(hexstr) > 60000 )
if ( strlen(hexstr) > 100000 )
{
static uint32_t counter;
if ( counter++ < 3 )
printf("rawtransaction too big %d\n",(int32_t)strlen(hexstr));
printf("rawtransaction %s %s too big %d\n",coin->symbol,bits256_str(str,txid),(int32_t)strlen(hexstr));
free(hexstr);
free_json(hexjson);
*retjsonp = cJSON_Parse("{\"error\":\"transaction too big\"}");
@ -737,12 +742,27 @@ 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)
cJSON *electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,char *SPVcheck)
{
cJSON *retjson;
cJSON *retjson,*array; struct LP_transaction *tx; struct iguana_info *coin;
coin = LP_coinfind(symbol);
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->height <= 0 )
{
if ( (array= electrum_address_listunspent(symbol,ep,&array,SPVcheck,2)) != 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);
char str[65]; printf("%s %s %s SPV height %d SPV %d\n",coin->symbol,SPVcheck,bits256_str(str,txid),tx->height,tx->SPV);
}
if ( ep != 0 )
portable_mutex_unlock(&ep->txmutex);
return(retjson);
@ -784,7 +804,7 @@ 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 )
if ( (retjson= electrum_transaction(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 )
@ -920,9 +940,11 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len)
if ( item->type == idnum )
{
DL_DELETE(ep->pendingQ.list,item);
*((cJSON **)stritem->retptrp) = (resultjson != 0 ? jduplicate(resultjson) : jduplicate(strjson));
if ( resultjson != 0 )
*((cJSON **)stritem->retptrp) = jduplicate(resultjson);
else *((cJSON **)stritem->retptrp) = strjson, strjson = 0;
//printf("matched idnum.%d result.(%s)\n",idnum,jprint(*((cJSON **)stritem->retptrp),0));
resultjson = strjson = 0;
//resultjson = strjson = 0;
free(item);
break;
}
@ -1030,7 +1052,7 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port)
retjson = cJSON_CreateObject();
jaddstr(retjson,"ipaddr",ipaddr);
jaddnum(retjson,"port",port);
if ( (ep= LP_electrum_info(&already,coin->symbol,ipaddr,port,IGUANA_MAXPACKETSIZE * 10)) == 0 )
if ( (ep= LP_electrum_info(&already,coin->symbol,ipaddr,port,IGUANA_MAXPACKETSIZE)) == 0 )
{
jaddstr(retjson,"error","couldnt connect to electrum server");
return(retjson);

185
iguana/exchanges/LP_statemachine.c

@ -132,6 +132,18 @@ FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basil
}*/
return(fp);
}
//printf("VOUT.(%s)\n",jprint(vout,0));
/*if ( (skey= jobj(vout,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 )
{
item = jitem(addresses,0);
//printf("item.(%s)\n",jprint(item,0));
if ( (addr= jstr(item,0)) != 0 )
{
safecopy(coinaddr,addr,64);
//printf("extracted.(%s)\n",coinaddr);
}
}*/
/*if ( IAMLP != 0 && time(NULL) > lasthello+600 )
{
char *hellostr,*retstr; cJSON *retjson; int32_t allgood,sock = LP_bindsock;
@ -174,7 +186,7 @@ FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basil
{
if ( peer->errors >= LP_MAXPEER_ERRORS )
{
if ( (rand() % 10000) == 0 )
if ( (LP_rand() % 10000) == 0 )
{
peer->errors--;
if ( peer->errors < LP_MAXPEER_ERRORS )
@ -183,7 +195,7 @@ FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basil
if ( IAMLP == 0 )
continue;
}
if ( now > peer->lastpeers+LP_ORDERBOOK_DURATION*.777 || (rand() % 100000) == 0 )
if ( now > peer->lastpeers+LP_ORDERBOOK_DURATION*.777 || (LP_rand() % 100000) == 0 )
{
if ( strcmp(peer->ipaddr,myipaddr) != 0 )
{
@ -229,7 +241,7 @@ int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipa
if ( (peer= LP_peerfind(argipbits,argport)) == 0 )
{
numpeers = LP_numpeers();
if ( IAMLP != 0 || numpeers < LP_MIN_PEERS || (IAMLP == 0 && (rand() % LP_MAX_PEERS) > numpeers) )
if ( IAMLP != 0 || numpeers < LP_MIN_PEERS || (IAMLP == 0 && (LP_rand() % LP_MAX_PEERS) > numpeers) )
peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session"));
}
if ( peer != 0 )
@ -347,6 +359,94 @@ void issue_LP_uitem(char *destip,uint16_t destport,char *symbol,char *coinaddr,b
return(retstr);*/
}
/*if ( (liststr= basilisk_swaplist(requestid,quoteid)) != 0 )
{
//printf("swapentry.(%s)\n",liststr);
if ( (retjson= cJSON_Parse(liststr)) != 0 )
{
if ( (array= jarray(&n,retjson,"swaps")) != 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
//printf("(%s) check r%u/q%u\n",jprint(item,0),juint(item,"requestid"),juint(item,"quoteid"));
if ( juint(item,"requestid") == requestid && juint(item,"quoteid") == quoteid )
{
retstr = jprint(item,0);
break;
}
}
}
free_json(retjson);
}
free(liststr);
}
return(retstr);*/
/*struct cJSON_list
{
struct cJSON_list *next,*prev;
cJSON *item;
uint32_t timestamp,cjsonid;
} *LP_cJSONlist;
void cJSON_register(cJSON *item)
{
struct cJSON_list *ptr;
ptr = calloc(1,sizeof(*ptr));
ptr->timestamp = (uint32_t)time(NULL);
ptr->item = item;
item->cjsonid = LP_rand();
ptr->cjsonid = item->cjsonid;
portable_mutex_lock(&LP_cJSONmutex);
DL_APPEND(LP_cJSONlist,ptr);
portable_mutex_unlock(&LP_cJSONmutex);
}
void cJSON_unregister(cJSON *item)
{
static uint32_t lasttime;
int32_t n; char *tmpstr; uint64_t total = 0; struct cJSON_list *ptr,*tmp; uint32_t now;
if ( (now= (uint32_t)time(NULL)) > lasttime+6 )
{
n = 0;
DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp)
{
if ( ptr->item != 0 && ptr->item->child != 0 && ptr->cjsonid != 0 )
{
if ( (tmpstr= jprint(ptr->item,0)) != 0 )
{
total += strlen(tmpstr);
free(tmpstr);
}
}
n++;
}
printf("total %d cJSON pending\n",n);
lasttime = (uint32_t)time(NULL);
}
DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp)
{
if ( ptr->cjsonid == item->cjsonid )
break;
else if ( now > ptr->timestamp+60 && item->cjsonid != 0 )
{
portable_mutex_lock(&LP_cJSONmutex);
DL_DELETE(LP_cJSONlist,ptr);
portable_mutex_unlock(&LP_cJSONmutex);
printf("free expired\n");
cJSON_Delete(ptr->item);
free(ptr);
}
ptr = 0;
}
if ( ptr != 0 )
{
portable_mutex_lock(&LP_cJSONmutex);
DL_DELETE(LP_cJSONlist,ptr);
free(ptr);
portable_mutex_unlock(&LP_cJSONmutex);
} //else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid);
}*/
char *issue_LP_getprices(char *destip,uint16_t destport)
{
char url[512];
@ -355,6 +455,16 @@ char *issue_LP_getprices(char *destip,uint16_t destport)
return(LP_issue_curl("getprices",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));
}
/*if ( fullflag != 0 )
{
if ( (destport= LP_randpeer(destip)) > 0 )
{
retstr = issue_LP_listunspent(destip,destport,symbol,coinaddr);
//printf("issue %s %s %s -> (%s)\n",coin->symbol,coinaddr,destip,retstr);
retjson = cJSON_Parse(retstr);
} else printf("LP_listunspent_issue couldnt get a random peer?\n");
}*/
void issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coinaddr)
{
cJSON *reqjson = cJSON_CreateObject();
@ -595,24 +705,6 @@ void basilisk_swap_saveupdate(struct basilisk_swap *swap)
}
}
/*int32_t basilisk_swap_loadtx(struct basilisk_rawtx *rawtx,FILE *fp,char *bobcoinstr,char *alicecoinstr)
{
if ( fread(rawtx,1,sizeof(*rawtx),fp) == sizeof(*rawtx) )
{
rawtx->coin = 0;
rawtx->vins = 0;
if ( strcmp(rawtx->I.coinstr,bobcoinstr) == 0 || strcmp(rawtx->I.coinstr,alicecoinstr) == 0 )
{
rawtx->coin = LP_coinfind(rawtx->I.coinstr);
if ( rawtx->vinstr[0] != 0 )
rawtx->vins = cJSON_Parse(rawtx->vinstr);
printf("loaded.%s len.%d\n",rawtx->name,rawtx->I.datalen);
return(0);
}
}
return(-1);
}*/
void basilisk_swap_sendabort(struct basilisk_swap *swap)
{
uint32_t msgbits = 0; uint8_t buf[sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2]; int32_t sentbytes,offset=0;
@ -863,7 +955,7 @@ int32_t _basilisk_rawtx_gen(char *str,uint32_t swapstarted,uint8_t *pubkey33,int
{
char scriptstr[1024],wifstr[256],coinaddr[64],*signedtx,*rawtxbytes; uint32_t basilisktag; int32_t retval = -1; cJSON *vins,*privkeys,*addresses,*valsobj; struct vin_info *V;
init_hexbytes_noT(scriptstr,script,scriptlen);
basilisktag = (uint32_t)rand();
basilisktag = (uint32_t)LP_rand();
valsobj = cJSON_CreateObject();
jaddstr(valsobj,"coin",rawtx->coin->symbol);
jaddstr(valsobj,"spendscript",scriptstr);
@ -1103,7 +1195,7 @@ int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t
basilisk_swap_saveupdate(swap);
if ( swap->connected == 0 )
basilisk_psockinit(swap,swap->I.iambob != 0);
//if ( (rand() % 30) == 0 )
//if ( (LP_rand() % 30) == 0 )
printf("E r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL)));
if ( swap->I.iambob != 0 )
{
@ -1277,7 +1369,7 @@ int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t
}
}
}
if ( (rand() % 30) == 0 )
if ( (LP_rand() % 30) == 0 )
printf("finished swapstate.%x other.%x\n",swap->I.statebits,swap->I.otherstatebits);
if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits )
sleep(DEX_SLEEP + (swap->I.iambob == 0)*1);
@ -1673,7 +1765,7 @@ void basilisk_swaploop(void *_utxo)
else tradebot_pendingadd(swapjson(swap),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.src,dstr(swap->I.req.srcamount));
}
printf("%s swap finished statebits %x\n",swap->I.iambob!=0?"BOB":"ALICE",swap->I.statebits);
//basilisk_swap_purge(swap);
basilisk_swap_purge(swap);
free(data);
}
#endif
@ -1722,6 +1814,41 @@ int32_t bitcoin_coinptrs(bits256 pubkey,struct iguana_info **bobcoinp,struct igu
}
portable_mutex_unlock(&myinfo->DEX_swapmutex);
}*/
/*if ( bits256_nonz(Q.srchash) == 0 || bits256_cmp(Q.srchash,G.LP_mypub25519) == 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 )
{
qprice = (double)Q.destsatoshis / Q.satoshis;
strcpy(Q.gui,G.gui);
strcpy(Q.coinaddr,coin->smartaddr);
strcpy(butxo->coinaddr,coin->smartaddr);
Q.srchash = G.LP_mypub25519;
memset(&Q.txid,0,sizeof(Q.txid));
memset(&Q.txid2,0,sizeof(Q.txid2));
Q.vout = Q.vout2 = -1;
recalc = 1;
}
else if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL )
recalc = 1;
else if ( price < qprice )
{
char tmp[64];
if ( bits256_nonz(Q.txid) != 0 )
LP_utxos_remove(Q.txid,Q.vout);
else recalc = 1;
if ( bits256_nonz(Q.txid2) != 0 )
LP_utxos_remove(Q.txid2,Q.vout2);
else recalc = 1;
//printf("price %.8f qprice %.8f\n",price,qprice);
if ( recalc == 0 )
{
value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout);
value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2);
//printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2));
if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0,Q.satoshis)) == 0 )
recalc = 1;
else if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout )
recalc = 1;
}
} else return(retval);*/
/*int32_t LP_priceping(int32_t pubsock,struct LP_utxoinfo *utxo,char *rel,double origprice)
{
@ -2665,7 +2792,7 @@ void LP_price_broadcastloop(void *ctx)
minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum);
printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s price %.8f relvol %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p,relvol);
}
if ( (rand() % 2) == 0 )
if ( (LP_rand() % 2) == 0 )
{
bot->relsum += relvol;
bot->basesum += v;
@ -2682,7 +2809,7 @@ void LP_price_broadcastloop(void *ctx)
#ifdef FROM_JS
int32_t sentbytes,sock,peerind,maxind;
if ( (maxind= LP_numpeers()) > 0 )
peerind = (rand() % maxind) + 1;
peerind = (LP_rand() % maxind) + 1;
else peerind = 1;
sock = LP_peerindsock(&peerind);
if ( sock >= 0 )
@ -2724,11 +2851,11 @@ void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32
else
{
if ( (maxind= LP_numpeers()) > 0 )
peerind = (rand() % maxind) + 1;
peerind = (LP_rand() % maxind) + 1;
else peerind = 1;
sock0 = LP_peerindsock(&peerind);
if ( (maxind= LP_numpeers()) > 0 )
peerind = (rand() % maxind) + 1;
peerind = (LP_rand() % maxind) + 1;
else peerind = 1;
sock1 = LP_peerindsock(&peerind);
}

13
iguana/exchanges/LP_stats.c

@ -34,6 +34,13 @@ int32_t LP_statslog_parsequote(char *method,cJSON *lineobj);
char *LP_stats_methods[] = { "unknown", "request", "reserved", "connect", "connected", "tradestatus" };
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);
}
static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatuses,LP_parse_errors,LP_unknowns,LP_duplicates,LP_aliceids;
void LP_tradecommand_log(cJSON *argjson)
@ -195,14 +202,14 @@ int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSO
if ( (sp->finished= juint(lineobj,"timestamp")) == 0 )
sp->finished = (uint32_t)time(NULL);
}
if ( sp->finished == 0 && time(NULL) > sp->Q.timestamp+INSTANTDEX_LOCKTIME*2 )
if ( sp->finished == 0 && time(NULL) > sp->Q.timestamp+LP_atomic_locktime(base,rel)*2 )
sp->expired = (uint32_t)time(NULL);
return(0);
}
else
{
if ( requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid )
printf("mismatched tradestatus aliceid.%016llx 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));
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);
}
@ -337,7 +344,7 @@ char *LP_statslog_disp(int32_t n,uint32_t starttime,uint32_t endtime,char *refgu
array = cJSON_CreateArray();
HASH_ITER(hh,LP_swapstats,sp,tmp)
{
if ( sp->finished == 0 && time(NULL) > sp->Q.timestamp+INSTANTDEX_LOCKTIME*2 )
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 )

202
iguana/exchanges/LP_swap.c

@ -112,7 +112,7 @@
void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx)
{
if ( rawtx->vins != 0 )
free_json(rawtx->vins);
free_json(rawtx->vins), rawtx->vins = 0;
//if ( rawtx->txbytes != 0 )
// free(rawtx->txbytes), rawtx->txbytes = 0;
}
@ -120,11 +120,21 @@ 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 )
/*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
{
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
@ -177,6 +187,8 @@ uint32_t basilisk_requestid(struct basilisk_request *rp)
int32_t LP_pubkeys_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)
{
int32_t i,datalen = 0;
datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->I.req.requestid),&swap->I.req.requestid);
datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid);
data[datalen++] = swap->I.aliceconfirms;
data[datalen++] = swap->I.bobconfirms;
data[datalen++] = swap->I.alicemaxconfirms;
@ -186,14 +198,22 @@ int32_t LP_pubkeys_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)
data[datalen++] = swap->persistent_pubkey33[i];
for (i=0; i<sizeof(swap->deck)/sizeof(swap->deck[0][0]); i++)
datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->deck[i>>1][i&1]),&swap->deck[i>>1][i&1]);
printf("send >>>>>>>>> r.%u q.%u datalen.%d\n",swap->I.req.requestid,swap->I.req.quoteid,datalen);
return(datalen);
}
int32_t LP_pubkeys_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datalen)
{
int32_t i,nonz=0,alicemaxconfirms,bobmaxconfirms,aliceconfirms,bobconfirms,len = 0; uint8_t other33[33];
if ( datalen == sizeof(swap->otherdeck)+38 )
uint32_t requestid,quoteid; int32_t i,nonz=0,alicemaxconfirms,bobmaxconfirms,aliceconfirms,bobconfirms,len = 0; uint8_t other33[33];
if ( datalen == sizeof(swap->otherdeck)+38+sizeof(uint32_t)*2 )
{
len += iguana_rwnum(0,&data[len],sizeof(requestid),&requestid);
len += iguana_rwnum(0,&data[len],sizeof(quoteid),&quoteid);
if ( requestid != swap->I.req.requestid || quoteid != swap->I.req.quoteid )
{
printf("SWAP requestid.%u quoteid.%u mismatch received r.%u q.%u\n",swap->I.req.requestid,swap->I.req.quoteid,requestid,quoteid);
return(-1);
}
aliceconfirms = data[len++];
bobconfirms = data[len++];
alicemaxconfirms = data[len++];
@ -233,7 +253,7 @@ int32_t LP_pubkeys_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datal
len += iguana_rwnum(0,&data[len],sizeof(swap->otherdeck[i>>1][i&1]),&swap->otherdeck[i>>1][i&1]);
return(0);
}
printf("pubkeys verify size mismatch %d != %d\n",datalen,(int32_t)sizeof(swap->otherdeck)+36);
printf("pubkeys verify size mismatch %d != %d\n",datalen,(int32_t)(sizeof(swap->otherdeck)+38+sizeof(uint32_t)*2));
return(-1);
}
@ -556,7 +576,12 @@ struct basilisk_rawtx *LP_swapdata_rawtx(struct basilisk_swap *swap,uint8_t *dat
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)
{
bits256 otherhash,myhash,txid; int64_t txfee,val; int32_t i,offset=0,datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr,redeemaddr[64],checkaddr[64]; uint32_t quoteid,msgbits;
bits256 otherhash,myhash,txid; int64_t txfee,val; int32_t i,offset=0,datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr,redeemaddr[64],checkaddr[64]; uint32_t quoteid,msgbits; struct iguana_info *coin;
if ( (coin= LP_coinfind(rawtx->symbol)) == 0 )
{
printf("LP_rawtx_spendscript couldnt find coin.(%s)\n",rawtx->symbol);
return(-1);
}
for (i=0; i<32; i++)
otherhash.bytes[i] = recvbuf[offset++];
for (i=0; i<32; i++)
@ -577,9 +602,9 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba
memcpy(rawtx->redeemscript,&data[datalen],rawtx->I.redeemlen);
//for (i=0; i<rawtx->I.redeemlen; i++)
// printf("%02x",rawtx->redeemscript[i]);
bitcoin_address(redeemaddr,rawtx->coin->taddr,rawtx->coin->p2shtype,rawtx->redeemscript,rawtx->I.redeemlen);
//printf(" received redeemscript.(%s) %s taddr.%d\n",redeemaddr,rawtx->coin->symbol,rawtx->coin->taddr);
LP_swap_coinaddr(rawtx->coin,checkaddr,0,data,datalen,0);
bitcoin_address(redeemaddr,coin->taddr,coin->p2shtype,rawtx->redeemscript,rawtx->I.redeemlen);
//printf(" received redeemscript.(%s) %s taddr.%d\n",redeemaddr,coin->symbol,coin->taddr);
LP_swap_coinaddr(coin,checkaddr,0,data,datalen,0);
if ( strcmp(redeemaddr,checkaddr) != 0 )
{
printf("REDEEMADDR MISMATCH??? %s != %s\n",redeemaddr,checkaddr);
@ -609,20 +634,20 @@ 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(rawtx->coin->taddr,rawtx->coin->pubtype,rawtx->coin->p2shtype,rawtx->coin->isPoS,height,&rawtx->I.signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),data,datalen,0,suppress_pubkeys,rawtx->coin->zcash)) != 0 )
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 )
{
rawtx->I.actualtxid = rawtx->I.signedtxid;
rawtx->I.locktime = rawtx->msgtx.lock_time;
if ( (vouts= jarray(&n,txobj,"vout")) != 0 && v < n )
{
vout = jitem(vouts,v);
if ( strcmp("BTC",rawtx->coin->symbol) == 0 && rawtx == &swap->otherfee )
if ( strcmp("BTC",coin->symbol) == 0 && rawtx == &swap->otherfee )
txfee = LP_MIN_TXFEE;
else
{
if ( strcmp(rawtx->coin->symbol,swap->bobcoin.symbol) == 0 )
if ( strcmp(coin->symbol,swap->I.bobstr) == 0 )
txfee = swap->I.Btxfee;
else if ( strcmp(rawtx->coin->symbol,swap->alicecoin.symbol) == 0 )
else if ( strcmp(coin->symbol,swap->I.alicestr) == 0 )
txfee = swap->I.Atxfee;
else txfee = LP_MIN_TXFEE;
}
@ -641,9 +666,9 @@ int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct ba
if ( rawtx == &swap->otherfee )
{
char str[65];
LP_swap_coinaddr(rawtx->coin,rawtx->p2shaddr,0,data,datalen,0);
LP_swap_coinaddr(coin,rawtx->p2shaddr,0,data,datalen,0);
printf("got %s txid.%s (%s) -> %s\n",rawtx->name,bits256_str(str,rawtx->I.signedtxid),jprint(txobj,0),rawtx->p2shaddr);
} else bitcoin_address(rawtx->p2shaddr,rawtx->coin->taddr,rawtx->coin->p2shtype,rawtx->spendscript,hexlen);
} else bitcoin_address(rawtx->p2shaddr,coin->taddr,coin->p2shtype,rawtx->spendscript,hexlen);
}
} else printf("%s satoshis %.8f ERROR.(%s) txfees.[%.8f %.8f: %.8f] amount.%.8f -> %.8f\n",rawtx->name,dstr(j64bits(vout,"satoshis")),jprint(txobj,0),dstr(swap->I.Atxfee),dstr(swap->I.Btxfee),dstr(txfee),dstr(rawtx->I.amount),dstr(rawtx->I.amount)-dstr(txfee));
}
@ -659,7 +684,7 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3
{
if ( bits256_nonz(rawtx->I.signedtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 )
{
rawtx->I.actualtxid = LP_broadcast_tx(rawtx->name,rawtx->coin->symbol,rawtx->txbytes,rawtx->I.datalen);
rawtx->I.actualtxid = LP_broadcast_tx(rawtx->name,rawtx->symbol,rawtx->txbytes,rawtx->I.datalen);
if ( bits256_cmp(rawtx->I.actualtxid,rawtx->I.signedtxid) != 0 )
{
char str[65],str2[65];
@ -687,7 +712,7 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3
if ( suppress_swapsend == 0 )
{
retval = LP_swapsend(pairsock,swap,msgbits,sendbuf,sendlen,nextbits,rawtx->I.crcs);
if ( LP_waitmempool(rawtx->coin->symbol,rawtx->I.destaddr,rawtx->I.signedtxid,0,LP_SWAPSTEP_TIMEOUT*10) < 0 )
if ( LP_waitmempool(rawtx->symbol,rawtx->I.destaddr,rawtx->I.signedtxid,0,LP_SWAPSTEP_TIMEOUT*10) < 0 )
{
char str[65]; printf("failed to find %s %s %s in the mempool?\n",rawtx->name,rawtx->I.destaddr,bits256_str(str,rawtx->I.actualtxid));
retval = -1;
@ -771,6 +796,7 @@ void LP_bobloop(void *_swap)
basilisk_bobdeposit_refund(swap,swap->I.putduration);
//printf("depositlen.%d\n",swap->bobdeposit.I.datalen);
LP_swapsfp_update(&swap->I.req);
LP_swap_critical = (uint32_t)time(NULL);
if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*10,LP_verify_otherfee) < 0 )
printf("error waiting for alicefee\n");
else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0) == 0 )
@ -779,18 +805,21 @@ void LP_bobloop(void *_swap)
printf("error waiting for alicepayment\n");
else
{
LP_swap_critical = (uint32_t)time(NULL);
if ( basilisk_bobscripts_set(swap,0,1) < 0 )
printf("error bobscripts payment\n");
else
{
if ( strcmp(swap->alicecoin.symbol,"BTC") == 0 )
if ( strcmp(swap->I.alicestr,"BTC") == 0 )
m = 0;
else m = swap->I.aliceconfirms;
while ( (n= LP_numconfirms(swap->alicecoin.symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) // sync with alice
while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) // sync with alice
{
char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.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);
}
LP_swap_critical = (uint32_t)time(NULL);
if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 )
printf("error sending bobpayment\n");
//if ( LP_waitfor(swap->N.pair,swap,10,LP_verify_alicespend) < 0 )
@ -801,12 +830,13 @@ void LP_bobloop(void *_swap)
basilisk_bobpayment_reclaim(swap,swap->I.callduration);
if ( swap->N.pair >= 0 )
nn_close(swap->N.pair), swap->N.pair = -1;
LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,INSTANTDEX_LOCKTIME*2,30);
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);
}
}
}
basilisk_swap_finished(swap);
//free(swap);
free(swap);
} else printf("swap timed out\n");
G.LP_pendingswaps--;
}
@ -832,6 +862,7 @@ void LP_aliceloop(void *_swap)
else
{
LP_swapsfp_update(&swap->I.req);
LP_swap_critical = (uint32_t)time(NULL);
if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x80,data,maxlen,&swap->myfee,0x40,0) == 0 )
printf("error sending alicefee\n");
else if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobdeposit) < 0 )
@ -840,34 +871,37 @@ void LP_aliceloop(void *_swap)
printf("error sending alicepayment\n");
else
{
if ( strcmp(swap->alicecoin.symbol,"BTC") == 0 )
if ( strcmp(swap->I.alicestr,"BTC") == 0 )
m = 0;
else m = swap->I.aliceconfirms;
while ( (n= LP_numconfirms(swap->alicecoin.symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m )
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 alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->alicecoin.symbol,bits256_str(str,swap->alicepayment.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);
}
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
{
while ( (n= LP_numconfirms(swap->bobcoin.symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms )
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->bobcoin.symbol,bits256_str(str,swap->bobpayment.I.signedtxid));
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->alicecoin.symbol,swap->alicespend.I.destaddr,swap->alicespend.I.signedtxid,0,1)) < swap->I.aliceconfirms )
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->bobcoin.symbol,bits256_str(str,swap->alicespend.I.signedtxid));
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,INSTANTDEX_LOCKTIME*2,30);
LP_swapwait(swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,30);
}
}
}
@ -880,7 +914,7 @@ void LP_aliceloop(void *_swap)
}
basilisk_swap_finished(swap);
printf("finish swap.%p\n",swap);
//free(swap);
free(swap);
G.LP_pendingswaps--;
}
@ -968,8 +1002,8 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx *
numconfirms = 0;
#endif
strcpy(rawtx->name,name);
rawtx->coin = coin;
strcpy(rawtx->I.coinstr,coin->symbol);
printf("set coin.%s %s -> %s\n",coin->symbol,coin->smartaddr,name);
strcpy(rawtx->symbol,coin->symbol);
rawtx->I.numconfirms = numconfirms;
if ( (rawtx->I.amount= satoshis) < LP_MIN_TXFEE )
rawtx->I.amount = LP_MIN_TXFEE;
@ -980,13 +1014,13 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx *
if ( strcmp(coin->symbol,"BTC") == 0 && (quoteid % 10) == 0 )
decode_hex(rawtx->I.rmd160,20,TIERNOLAN_RMD160);
else decode_hex(rawtx->I.rmd160,20,INSTANTDEX_RMD160);
bitcoin_address(rawtx->I.destaddr,rawtx->coin->taddr,rawtx->coin->pubtype,rawtx->I.rmd160,20);
bitcoin_address(rawtx->I.destaddr,coin->taddr,coin->pubtype,rawtx->I.rmd160,20);
}
if ( pubkey33 != 0 )
{
memcpy(rawtx->I.pubkey33,pubkey33,33);
bitcoin_address(rawtx->I.destaddr,rawtx->coin->taddr,rawtx->coin->pubtype,rawtx->I.pubkey33,33);
bitcoin_addr2rmd160(rawtx->coin->taddr,&rawtx->I.addrtype,rawtx->I.rmd160,rawtx->I.destaddr);
bitcoin_address(rawtx->I.destaddr,coin->taddr,coin->pubtype,rawtx->I.pubkey33,33);
bitcoin_addr2rmd160(coin->taddr,&rawtx->I.addrtype,rawtx->I.rmd160,rawtx->I.destaddr);
}
if ( rawtx->I.vouttype <= 1 && rawtx->I.destaddr[0] != 0 )
{
@ -998,7 +1032,21 @@ void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx *
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)
{
//FILE *fp; char fname[512];
uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag=-2,x = -1; struct iguana_info *coin;
uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag=-2,x = -1; struct iguana_info *bobcoin,*alicecoin;
strcpy(swap->I.bobstr,swap->I.req.src);
strcpy(swap->I.alicestr,swap->I.req.dest);
if ( (alicecoin= LP_coinfind(swap->I.alicestr)) == 0 )
{
printf("missing alicecoin src.%p dest.%p\n",LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest));
free(swap);
return(0);
}
if ( (bobcoin= LP_coinfind(swap->I.bobstr)) == 0 )
{
printf("missing bobcoin src.%p dest.%p\n",LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest));
free(swap);
return(0);
}
if ( (swap->I.Atxfee= qp->desttxfee) < 0 )
{
printf("bitcoin_swapinit %s Atxfee %.8f rejected\n",swap->I.req.dest,dstr(swap->I.Atxfee));
@ -1009,7 +1057,7 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
printf("bitcoin_swapinit %s Btxfee %.8f rejected\n",swap->I.req.src,dstr(swap->I.Btxfee));
return(0);
}
swap->I.putduration = swap->I.callduration = INSTANTDEX_LOCKTIME;
swap->I.putduration = swap->I.callduration = LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr);
if ( optionduration < 0 )
swap->I.putduration -= optionduration;
else if ( optionduration > 0 )
@ -1028,8 +1076,6 @@ 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;
strcpy(swap->I.bobstr,swap->I.req.src);
strcpy(swap->I.alicestr,swap->I.req.dest);
swap->I.started = (uint32_t)time(NULL);
swap->I.expiration = swap->I.req.timestamp + swap->I.putduration + swap->I.callduration;
OS_randombytes((uint8_t *)&swap->I.choosei,sizeof(swap->I.choosei));
@ -1057,28 +1103,12 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
char str[65]; printf("couldnt generate privkeys %d %s\n",x,bits256_str(str,privkey));
return(0);
}
if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 )
swap->alicecoin = *coin;
else
{
printf("missing bobcoin.%p or missing alicecoin.%p src.%p dest.%p\n",&swap->bobcoin,&swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest));
free(swap);
return(0);
}
if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 )
swap->bobcoin = *coin;
else
{
printf("missing bobcoin.%p or missing alicecoin.%p src.%p dest.%p\n",&swap->bobcoin,&swap->alicecoin,LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest));
free(swap);
return(0);
}
if ( strcmp("BTC",swap->bobcoin.symbol) == 0 )
if ( strcmp("BTC",swap->I.bobstr) == 0 )
{
swap->I.bobconfirms = (1 + sqrt(dstr(swap->I.bobsatoshis) * .1));
swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS;
}
else if ( strcmp("BTC",swap->alicecoin.symbol) == 0 )
else if ( strcmp("BTC",swap->I.alicestr) == 0 )
{
swap->I.aliceconfirms = (1 + sqrt(dstr(swap->I.alicesatoshis) * .1));
swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS;
@ -1088,17 +1118,17 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS;
swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS;
}
if ( swap->bobcoin.isassetchain != 0 )
if ( bobcoin->isassetchain != 0 )
swap->I.bobconfirms = 1;
if ( swap->alicecoin.isassetchain != 0 )
if ( alicecoin->isassetchain != 0 )
swap->I.aliceconfirms = 1;
if ( swap->bobcoin.userconfirms > 0 )
swap->I.bobconfirms = swap->bobcoin.userconfirms;
if ( swap->alicecoin.userconfirms > 0 )
swap->I.aliceconfirms = swap->alicecoin.userconfirms;
if ( (swap->I.bobmaxconfirms= swap->bobcoin.maxconfirms) == 0 )
if ( bobcoin->userconfirms > 0 )
swap->I.bobconfirms = bobcoin->userconfirms;
if ( alicecoin->userconfirms > 0 )
swap->I.aliceconfirms = alicecoin->userconfirms;
if ( (swap->I.bobmaxconfirms= bobcoin->maxconfirms) == 0 )
swap->I.bobmaxconfirms = BASILISK_DEFAULT_MAXCONFIRMS;
if ( (swap->I.alicemaxconfirms= swap->alicecoin.maxconfirms) == 0 )
if ( (swap->I.alicemaxconfirms= alicecoin->maxconfirms) == 0 )
swap->I.alicemaxconfirms = BASILISK_DEFAULT_MAXCONFIRMS;
if ( swap->I.bobconfirms > swap->I.bobmaxconfirms )
swap->I.bobconfirms = swap->I.bobmaxconfirms;
@ -1106,53 +1136,53 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
swap->I.aliceconfirms = swap->I.alicemaxconfirms;
swap->I.bobconfirms *= !swap->I.bobistrusted;
swap->I.aliceconfirms *= !swap->I.aliceistrusted;
printf(">>>>>>>>>> jumblrflag.%d <<<<<<<<< use smart address, %.8f bobconfs.%d, %.8f aliceconfs.%d taddr.%d %d\n",jumblrflag,dstr(swap->I.bobsatoshis),swap->I.bobconfirms,dstr(swap->I.alicesatoshis),swap->I.aliceconfirms,swap->bobcoin.taddr,swap->alicecoin.taddr);
printf(">>>>>>>>>> jumblrflag.%d <<<<<<<<< r.%u q.%u, %.8f bobconfs.%d, %.8f aliceconfs.%d taddr.%d %d\n",jumblrflag,swap->I.req.requestid,swap->I.req.quoteid,dstr(swap->I.bobsatoshis),swap->I.bobconfirms,dstr(swap->I.alicesatoshis),swap->I.aliceconfirms,bobcoin->taddr,alicecoin->taddr);
if ( swap->I.iambob != 0 )
{
basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,&swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*swap->bobcoin.txfee,0,0,jumblrflag);
basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,&swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*swap->alicecoin.txfee,0,0,jumblrflag);
basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*bobcoin->txfee,0,0,jumblrflag);
basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*alicecoin->txfee,0,0,jumblrflag);
bobpub33 = pubkey33;
}
else
{
basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,&swap->bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*swap->bobcoin.txfee,0,0,jumblrflag);
basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,&swap->alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*swap->alicecoin.txfee,0,0,jumblrflag);
basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*bobcoin->txfee,0,0,jumblrflag);
basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*alicecoin->txfee,0,0,jumblrflag);
alicepub33 = pubkey33;
}
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,&swap->bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + 0*swap->bobcoin.txfee,4,0,jumblrflag);
basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,&swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,bobpub33,jumblrflag);
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("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,&swap->bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,alicepub33,jumblrflag);
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,&swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + 0*swap->bobcoin.txfee,3,0,jumblrflag);
basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,&swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag);
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("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,&swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag);
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,&swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + 0*swap->alicecoin.txfee,2,0,jumblrflag);
basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,&swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag);
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("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,&swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag);
basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag);
swap->alicereclaim.I.suppress_pubkeys = 1;
swap->bobpayment.utxotxid = qp->txid, swap->bobpayment.utxovout = qp->vout;
swap->bobdeposit.utxotxid = qp->txid2, swap->bobdeposit.utxovout = qp->vout2;
swap->alicepayment.utxotxid = qp->desttxid, swap->alicepayment.utxovout = qp->destvout;
LP_mark_spent(swap->bobcoin.symbol,qp->txid,qp->vout);
LP_mark_spent(swap->bobcoin.symbol,qp->txid2,qp->vout2);
LP_mark_spent(swap->alicecoin.symbol,qp->desttxid,qp->destvout);
LP_mark_spent(swap->I.bobstr,qp->txid,qp->vout);
LP_mark_spent(swap->I.bobstr,qp->txid2,qp->vout2);
LP_mark_spent(swap->I.alicestr,qp->desttxid,qp->destvout);
if ( swap->I.iambob != 0 )
swap->otherfee.utxotxid = qp->feetxid, swap->otherfee.utxovout = qp->feevout;
else
{
swap->myfee.utxotxid = qp->feetxid, swap->myfee.utxovout = qp->feevout;
LP_mark_spent(swap->alicecoin.symbol,qp->feetxid,qp->feevout);
LP_mark_spent(swap->I.alicestr,qp->feetxid,qp->feevout);
}
char str[65],str2[65],str3[65]; printf("IAMBOB.%d %s %s %s\n",swap->I.iambob,bits256_str(str,qp->txid),bits256_str(str2,qp->txid2),bits256_str(str3,qp->feetxid));
char str[65],str2[65],str3[65]; printf("IAMBOB.%d %s %s %s [%s %s]\n",swap->I.iambob,bits256_str(str,qp->txid),bits256_str(str2,qp->txid2),bits256_str(str3,qp->feetxid),swap->I.bobstr,swap->I.alicestr);
return(swap);
}
@ -1168,7 +1198,7 @@ struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256
G.LP_skipstatus[G.LP_numskips] = ((uint64_t)rp->requestid << 32) | rp->quoteid;
if ( G.LP_numskips < sizeof(G.LP_skipstatus)/sizeof(*G.LP_skipstatus) )
G.LP_numskips++;
printf("basilisk_thread_start request.%u iambob.%d (%s/%s) quoteid.%u\n",rp->requestid,iambob,rp->src,rp->dest,rp->quoteid);
printf("LP_swapinit request.%u iambob.%d (%s/%s) quoteid.%u\n",rp->requestid,iambob,rp->src,rp->dest,rp->quoteid);
bitcoin_pubkey33(swap->ctx,pubkey33,privkey);
pubkey25519 = curve25519(privkey,curve25519_basepoint9());
swap->persistent_pubkey = pubkey25519;

17
iguana/exchanges/LP_tradebots.c

@ -27,13 +27,13 @@ struct LP_tradebot_trade
uint64_t aliceid;
int32_t dispdir;
uint32_t started,finished,requestid,quoteid,tradeid,expired;
char base[32],rel[32],event[32];
char base[65],rel[65],event[32];
};
struct LP_tradebot
{
struct LP_tradebot *next,*prev;
char name[128],base[32],rel[32];
char name[128],base[65],rel[65];
int32_t numtrades,numpending,completed,dispdir;
double maxprice,totalrelvolume,totalbasevolume,basesum,relsum,pendbasesum,pendrelsum;
uint32_t lasttime,dead,pause,userpause,started,id;
@ -74,7 +74,7 @@ void LP_tradebot_calcstats(struct LP_tradebot *bot)
{
if ( (tp= bot->trades[i]) == 0 )
continue;
if ( tp->finished == 0 && time(NULL) > tp->started+INSTANTDEX_LOCKTIME*2 )
if ( tp->finished == 0 && time(NULL) > tp->started+LP_atomic_locktime(bot->base,bot->rel)*2 )
{
tp->expired = tp->finished = (uint32_t)time(NULL);
printf("tradeid.%u expired\n",tp->tradeid);
@ -324,7 +324,7 @@ void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot)
printf("try autobuy %s/%s remaining %.8f maxprice %.8f maxrel %.8f\n",bot->base,bot->rel,remaining,bot->maxprice,maxrel);
if ( maxrel < remaining )
remaining = maxrel;
tradeid = rand();
tradeid = LP_rand();
for (i=1; i<=maxiters; i++)
{
if ( remaining < 0.001 )
@ -386,7 +386,7 @@ void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid
if ( matched != 0 )
break;
}
if ( matched == 0 )
if ( 0 && matched == 0 )
printf("NO MATCH: bot event tradeid.%u aliceid.%llu (%s) r.%u q.%u\n",tradeid,(long long)aliceid,event,requestid,quoteid);
}
@ -479,9 +479,10 @@ char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,doubl
if ( relcoin->electrum != 0 )
balance = LP_unspents_load(relcoin->symbol,relcoin->smartaddr);
else balance = LP_RTsmartbalance(relcoin);
sum = (relvolume+2*dstr(txfees)) + 3 * ((relvolume+2*dstr(txfees))/777);
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 ( dstr(abalance) < relvolume + dstr(txfees) && balance > sum+txfee )
if ( (abalance < SATOSHIDEN*relvolume + txfees) || ((balance-abalance) < (uint64_t)(SATOSHIDEN*relvolume)/777 + txfees) )
//if ( dstr(abalance) < relvolume && balance > sum+2*txfee )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"error","not enough funds");
@ -492,7 +493,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+txfee )
if ( balance > sum+2*txfee )
{
char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item;
outputjson = cJSON_CreateObject();

689
iguana/exchanges/LP_transaction.c

@ -78,7 +78,8 @@ int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid)
bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxid)
{
char *retstr; bits256 txid; uint8_t *ptr; cJSON *retjson,*errorobj; int32_t i,len,sentflag = 0;
char *retstr,*errstr; bits256 txid; uint8_t *ptr; cJSON *retjson,*errorobj; struct iguana_info *coin; int32_t i,totalretries=0,len,sentflag = 0;
coin = LP_coinfind(symbol);
memset(&txid,0,sizeof(txid));
if ( txbytes == 0 || txbytes[0] == 0 )
return(txid);
@ -115,6 +116,15 @@ bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxi
txid = expectedtxid;
sentflag = 1;
}
else if ( (errstr= jstr(retjson,"error")) != 0 && strcmp(errstr,"timeout") == 0 && coin != 0 && coin->electrum != 0 )
{
if ( totalretries < 4 )
{
printf("time error with electrum, retry.%d\n",totalretries);
totalretries++;
i--;
}
}
else printf("broadcast error.(%s)\n",retstr);
}
free_json(retjson);
@ -525,7 +535,7 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_
{
if ( msgtx->vins[i].p2shlen != 0 )
{
char coinaddr[64]; uint32_t userdatalen,sigsize,pubkeysize; uint8_t *userdata; int32_t j,k,hashtype,type,flag; struct vin_info mvin,mainvin; bits256 zero;
char coinaddr[64]; uint32_t userdatalen,hashtype,sigsize,pubkeysize; uint8_t *userdata; int32_t j,k,type,flag; struct vin_info mvin,mainvin; bits256 zero;
memset(zero.bytes,0,sizeof(zero));
coinaddr[0] = 0;
sigsize = 0;
@ -609,6 +619,100 @@ int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_
return(complete);
}
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;
char *symbol; uint8_t wiftaddr,taddr,pubtype,p2shtype,isPoS;
height = coin->longestchain;
symbol = coin->symbol;
wiftaddr = coin->wiftaddr;
taddr = coin->taddr;
pubtype = coin->pubtype;
p2shtype = coin->p2shtype;
isPoS = coin->isPoS;
retjson = cJSON_CreateObject();
inputsum = outputsum = numinputs = numoutputs = 0;
if ( rawtx != 0 && rawtx[0] != 0 )
{
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 )
{
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++)
{
if ( iguana_parsevoutobj(serialized,maxsize,&vout,jitem(vouts,i)) > 0 )
outputsum += vout.value;
}
}
if ( (vins= jarray(&numinputs,txobj,"vin")) > 0 )
{
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;
msgtx->vins[i].spendscript = V[i].spendscript;
if ( (msgtx->vins[i].spendlen= V[i].spendlen) == 35 )
{
if ( (plen= bitcoin_pubkeylen(msgtx->vins[i].spendscript+1)) > 0 )
{
memcpy(V[i].signers[0].pubkey,msgtx->vins[i].spendscript+1,plen);
V[i].suppress_pubkeys = 1;
}
}
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;
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);
msgtx->txid = signedtxid;
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);
if ( signedtx != 0 )
free(signedtx);
free(V);
}
}
//char str[65]; printf("got txid.(%s)\n",bits256_str(str,txid));
}
msgtx->inputsum = inputsum;
msgtx->numinputs = numinputs;
msgtx->outputsum = outputsum;
msgtx->numoutputs = numoutputs;
msgtx->txfee = (inputsum - outputsum);
return(jprint(retjson,1));
}
void test_validate(char *signedtx)
{
char *retstr; uint8_t extraspace[8192]; int32_t mempool=0; struct iguana_msgtx msgtx; struct iguana_info *coin = LP_coinfind("BTC");
retstr = iguana_validaterawtx(bitcoin_ctx(),coin,&msgtx,extraspace,sizeof(extraspace),signedtx,mempool,0,coin->zcash);
printf("validate test.(%s)\n",retstr);
}
char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t utxovout,char *destaddr,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp,uint64_t satoshis,char *changeaddr,char *vinaddr,int32_t suppress_pubkeys,int32_t zcash)
{
char *rawtxbytes=0,*signedtx=0,str[65],tmpaddr[64],hexstr[999],wifstr[128],_destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *txobj,*vins,*obj,*vouts,*item,*privkeys; int32_t completed,spendlen,n,ignore_cltverr=1; struct vin_info V[8]; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; bits256 txid; uint64_t value=0,change = 0; struct iguana_msgtx msgtx; struct iguana_info *coin;
@ -907,12 +1011,12 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
if ( bits256_nonz(utxotxid) != 0 && numpre == 0 )
{
up = LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout);
printf("have utxotxid but wasnt found up.%p\n",up);
//printf("have utxotxid but wasnt found up.%p\n",up);
if ( up == 0 )
{
value = LP_txvalue(coin->smartaddr,coin->symbol,utxotxid,utxovout);
LP_address_utxoadd("withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1);
printf("added after not finding\n");
value = LP_txvalue(0,coin->symbol,utxotxid,utxovout);
LP_address_utxoadd((uint32_t)time(NULL),"withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1);
//printf("added after not finding\n");
}
if ( (up= LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout)) != 0 )
preselected[numpre++] = up;
@ -923,11 +1027,24 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
}
}
if ( dustcombine >= 1 && min0 != 0 && min0->U.value < LP_DUSTCOMBINE_THRESHOLD && (coin->electrum == 0 || min0->SPV > 0) )
preselected[numpre++] = min0;
{
for (j=0; j<numpre; j++)
if ( min0 == preselected[j] )
break;
if ( j == numpre )
preselected[numpre++] = min0;
}
else min0 = 0;
if ( dustcombine >= 2 && min1 != 0 && min1->U.value < LP_DUSTCOMBINE_THRESHOLD && (coin->electrum == 0 || min1->SPV > 0) )
preselected[numpre++] = min1;
{
for (j=0; j<numpre; j++)
if ( min1 == preselected[j] )
break;
if ( j == numpre )
preselected[numpre++] = min1;
}
else min1 = 0;
printf("dustcombine.%d numpre.%d min0.%p min1.%p numutxos.%d amount %.8f\n",dustcombine,numpre,min0,min1,numunspents,dstr(amount));
maxiters = numunspents+numpre;
for (i=0; i<maxiters; i++)
@ -978,7 +1095,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
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\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),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);
vp = &V[n++];
vp->N = vp->M = 1;
vp->signers[0].privkey = privkey;
@ -987,9 +1104,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);
if ( remains <= 0 && i >= numpre-1 )
break;
if ( numunspents == 0 )
if ( numunspents < 0 )
{
printf("total %.8f not enough for amount %.8f\n",dstr(total),dstr(amount));
return(0);
@ -1019,7 +1137,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
}
if ( coin->numutxos < LP_MINDESIRED_UTXOS )
dustcombine = 0;
else if ( coin->numutxos >= LP_MINDESIRED_UTXOS )
else if ( coin->numutxos >= LP_MAXDESIRED_UTXOS )
dustcombine = 2;
else dustcombine = 1;
amount = txfee;
@ -1047,18 +1165,26 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
return(0);
}
}
LP_listunspent_issue(coin->symbol,coin->smartaddr,1);
if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 )
//if ( bits256_nonz(utxotxid) == 0 )
{
printf("LP_createrawtransaction: cant find address data\n");
return(0);
if ( (ap= LP_address_utxo_reset(coin)) == 0 )
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 )
{
printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos);
//return(0);
if ( bits256_nonz(utxotxid) == 0 )
{
printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos);
return(0);
}
}
//char str[65];
//for (i=0; i<numutxos; i++)
// printf("utxo.%d %s/v%d %.8f\n",i,bits256_str(str,utxos[i]->U.txid),utxos[i]->U.vout,dstr(utxos[i]->U.value));
ignore_cltverr = 0;
suppress_pubkeys = 1;
scriptlen = bitcoin_standardspend(script,0,G.LP_myrmd160);
@ -1196,11 +1322,11 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pubkey33,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf,int32_t delay,bits256 privkey,uint8_t *changermd160,char *vinaddr)
{
struct iguana_info *coin; int32_t len,retval=-1; char *retstr,*hexstr; cJSON *argjson,*outputs,*item,*retjson,*obj;
if ( (coin= rawtx->coin) == 0 )
if ( (coin= LP_coinfind(rawtx->symbol)) == 0 )
return(-1);
if ( strcmp(coin->smartaddr,vinaddr) != 0 )
{
printf("basilisk_rawtx_gen mismatched vinaddr.%s != %s\n",vinaddr,coin->smartaddr);
printf("???????????????????????? basilisk_rawtx_gen mismatched %s %s vinaddr.%s != (%s)\n",rawtx->symbol,coin->symbol,vinaddr,coin->smartaddr);
return(-1);
}
argjson = cJSON_CreateObject();
@ -1578,36 +1704,44 @@ int32_t basilisk_swapuserdata(uint8_t *userdata,bits256 privkey,int32_t ifpath,b
int32_t basilisk_bobpayment_reclaim(struct basilisk_swap *swap,int32_t delay)
{
uint8_t userdata[512]; int32_t retval,i,len = 0; static bits256 zero;
//printf("basilisk_bobpayment_reclaim\n");
len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[1],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen);
memcpy(swap->I.userdata_bobreclaim,userdata,len);
swap->I.userdata_bobreclaimlen = len;
if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.wiftaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->bobreclaim,&swap->bobpayment,swap->I.myprivs[1],0,userdata,len,1,swap->changermd160,swap->bobpayment.I.destaddr,swap->bobcoin.zcash)) == 0 )
{
for (i=0; i<swap->bobreclaim.I.datalen; i++)
printf("%02x",swap->bobreclaim.txbytes[i]);
printf(" <- bobreclaim\n");
//basilisk_txlog(swap,&swap->bobreclaim,delay);
return(retval);
}
static bits256 zero;
uint8_t userdata[512]; int32_t retval,i,len = 0; struct iguana_info *coin;
if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 )
{
//printf("basilisk_bobpayment_reclaim\n");
len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[1],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen);
memcpy(swap->I.userdata_bobreclaim,userdata,len);
swap->I.userdata_bobreclaimlen = len;
if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->bobreclaim,&swap->bobpayment,swap->I.myprivs[1],0,userdata,len,1,swap->changermd160,swap->bobpayment.I.destaddr,coin->zcash)) == 0 )
{
for (i=0; i<swap->bobreclaim.I.datalen; i++)
printf("%02x",swap->bobreclaim.txbytes[i]);
printf(" <- bobreclaim\n");
//basilisk_txlog(swap,&swap->bobreclaim,delay);
return(retval);
}
} else printf("basilisk_bobpayment_reclaim cant find (%s)\n",swap->I.bobstr);
return(-1);
}
int32_t basilisk_bobdeposit_refund(struct basilisk_swap *swap,int32_t delay)
{
uint8_t userdata[512]; int32_t i,retval,len = 0; char str[65];
len = basilisk_swapuserdata(userdata,swap->I.privBn,0,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
memcpy(swap->I.userdata_bobrefund,userdata,len);
swap->I.userdata_bobrefundlen = len;
if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.wiftaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0,swap->changermd160,swap->bobdeposit.I.destaddr,swap->bobcoin.zcash)) == 0 )
{
for (i=0; i<swap->bobrefund.I.datalen; i++)
printf("%02x",swap->bobrefund.txbytes[i]);
printf(" <- bobrefund.(%s)\n",bits256_str(str,swap->bobrefund.I.txid));
//basilisk_txlog(swap,&swap->bobrefund,delay);
return(retval);
}
uint8_t userdata[512]; int32_t i,retval,len = 0; char str[65]; struct iguana_info *coin;
if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 )
{
len = basilisk_swapuserdata(userdata,swap->I.privBn,0,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
memcpy(swap->I.userdata_bobrefund,userdata,len);
swap->I.userdata_bobrefundlen = len;
if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0,swap->changermd160,swap->bobdeposit.I.destaddr,coin->zcash)) == 0 )
{
for (i=0; i<swap->bobrefund.I.datalen; i++)
printf("%02x",swap->bobrefund.txbytes[i]);
printf(" <- bobrefund.(%s)\n",bits256_str(str,swap->bobrefund.I.txid));
//basilisk_txlog(swap,&swap->bobrefund,delay);
return(retval);
}
} else printf("basilisk_bobdeposit_refund cant find (%s)\n",swap->I.bobstr);
return(-1);
}
@ -1624,17 +1758,6 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u
vout = jitem(vouts,v);
if ( valuep != 0 )
*valuep = LP_value_extract(vout,1);
//printf("VOUT.(%s)\n",jprint(vout,0));
/*if ( (skey= jobj(vout,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 )
{
item = jitem(addresses,0);
//printf("item.(%s)\n",jprint(item,0));
if ( (addr= jstr(item,0)) != 0 )
{
safecopy(coinaddr,addr,64);
//printf("extracted.(%s)\n",coinaddr);
}
}*/
LP_destaddr(coinaddr,vout);
}
free_json(txobj);
@ -1643,81 +1766,84 @@ void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,u
int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,int32_t genflag)
{
int32_t j; char coinaddr[64],checkaddr[64];
bitcoin_address(coinaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->changermd160,20);
if ( genflag != 0 && swap->I.iambob == 0 )
printf("basilisk_bobscripts_set WARNING: alice generating BOB tx\n");
if ( depositflag == 0 )
{
swap->bobpayment.I.spendlen = basilisk_bobscript(swap->bobpayment.I.rmd160,swap->bobpayment.redeemscript,&swap->bobpayment.I.redeemlen,swap->bobpayment.spendscript,0,&swap->bobpayment.I.locktime,&swap->bobpayment.I.secretstart,&swap->I,0);
bitcoin_address(swap->bobpayment.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen);
strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr);
//LP_importaddress(swap->bobcoin.symbol,swap->bobpayment.I.destaddr);
//int32_t i; for (i=0; i<swap->bobpayment.I.redeemlen; i++)
// printf("%02x",swap->bobpayment.redeemscript[i]);
//printf(" <- bobpayment redeem %d %s\n",i,swap->bobpayment.I.destaddr);
if ( genflag != 0 && bits256_nonz(*(bits256 *)swap->I.secretBn256) != 0 && swap->bobpayment.I.datalen == 0 )
{
basilisk_rawtx_gen(swap->ctx,"payment",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobpayment,swap->bobpayment.I.locktime,swap->bobpayment.spendscript,swap->bobpayment.I.spendlen,swap->bobpayment.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr);
if ( swap->bobpayment.I.spendlen == 0 || swap->bobpayment.I.datalen == 0 )
{
printf("error bob generating %p payment.%d\n",swap->bobpayment.txbytes,swap->bobpayment.I.spendlen);
sleep(DEX_SLEEP);
}
else
int32_t j; char coinaddr[64],checkaddr[64]; struct iguana_info *coin;
if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 )
{
bitcoin_address(coinaddr,coin->taddr,coin->pubtype,swap->changermd160,20);
if ( genflag != 0 && swap->I.iambob == 0 )
printf("basilisk_bobscripts_set WARNING: alice generating BOB tx\n");
if ( depositflag == 0 )
{
swap->bobpayment.I.spendlen = basilisk_bobscript(swap->bobpayment.I.rmd160,swap->bobpayment.redeemscript,&swap->bobpayment.I.redeemlen,swap->bobpayment.spendscript,0,&swap->bobpayment.I.locktime,&swap->bobpayment.I.secretstart,&swap->I,0);
bitcoin_address(swap->bobpayment.p2shaddr,coin->taddr,coin->p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen);
strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr);
//LP_importaddress(coin->symbol,swap->bobpayment.I.destaddr);
//int32_t i; for (i=0; i<swap->bobpayment.I.redeemlen; i++)
// printf("%02x",swap->bobpayment.redeemscript[i]);
//printf(" <- bobpayment redeem %d %s\n",i,swap->bobpayment.I.destaddr);
if ( genflag != 0 && bits256_nonz(*(bits256 *)swap->I.secretBn256) != 0 && swap->bobpayment.I.datalen == 0 )
{
for (j=0; j<swap->bobpayment.I.datalen; j++)
printf("%02x",swap->bobpayment.txbytes[j]);
printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen);
for (j=0; j<swap->bobpayment.I.redeemlen; j++)
printf("%02x",swap->bobpayment.redeemscript[j]);
printf(" <- redeem.%d\n",swap->bobpayment.I.redeemlen);
printf(" <- GENERATED BOB PAYMENT.%d destaddr.(%s)\n",swap->bobpayment.I.datalen,swap->bobpayment.I.destaddr);
LP_swap_coinaddr(&swap->bobcoin,checkaddr,0,swap->bobpayment.txbytes,swap->bobpayment.I.datalen,0);
if ( strcmp(swap->bobpayment.I.destaddr,checkaddr) != 0 )
basilisk_rawtx_gen(swap->ctx,"payment",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobpayment,swap->bobpayment.I.locktime,swap->bobpayment.spendscript,swap->bobpayment.I.spendlen,coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr);
if ( swap->bobpayment.I.spendlen == 0 || swap->bobpayment.I.datalen == 0 )
{
printf("BOBPAYMENT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobpayment.I.destaddr,checkaddr);
return(-1);
printf("error bob generating %p payment.%d\n",swap->bobpayment.txbytes,swap->bobpayment.I.spendlen);
sleep(DEX_SLEEP);
}
else
{
for (j=0; j<swap->bobpayment.I.datalen; j++)
printf("%02x",swap->bobpayment.txbytes[j]);
printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen);
for (j=0; j<swap->bobpayment.I.redeemlen; j++)
printf("%02x",swap->bobpayment.redeemscript[j]);
printf(" <- redeem.%d\n",swap->bobpayment.I.redeemlen);
printf(" <- GENERATED BOB PAYMENT.%d destaddr.(%s)\n",swap->bobpayment.I.datalen,swap->bobpayment.I.destaddr);
LP_swap_coinaddr(coin,checkaddr,0,swap->bobpayment.txbytes,swap->bobpayment.I.datalen,0);
if ( strcmp(swap->bobpayment.I.destaddr,checkaddr) != 0 )
{
printf("BOBPAYMENT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobpayment.I.destaddr,checkaddr);
return(-1);
}
LP_unspents_mark(coin->symbol,swap->bobpayment.vins);
//printf("bobscripts set completed\n");
return(0);
}
LP_unspents_mark(swap->bobcoin.symbol,swap->bobpayment.vins);
//printf("bobscripts set completed\n");
return(0);
}
}
}
else
{
swap->bobdeposit.I.spendlen = basilisk_bobscript(swap->bobdeposit.I.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.I.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.I.locktime,&swap->bobdeposit.I.secretstart,&swap->I,1);
bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr);
//int32_t i; for (i=0; i<swap->bobdeposit.I.redeemlen; i++)
// printf("%02x",swap->bobdeposit.redeemscript[i]);
//printf(" <- bobdeposit redeem %d %s\n",i,swap->bobdeposit.I.destaddr);
if ( genflag != 0 && (swap->bobdeposit.I.datalen == 0 || swap->bobrefund.I.datalen == 0) )
else
{
basilisk_rawtx_gen(swap->ctx,"deposit",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobdeposit,swap->bobdeposit.I.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.I.spendlen,swap->bobdeposit.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr);
if ( swap->bobdeposit.I.datalen == 0 || swap->bobdeposit.I.spendlen == 0 )
{
printf("error bob generating %p deposit.%d\n",swap->bobdeposit.txbytes,swap->bobdeposit.I.spendlen);
sleep(DEX_SLEEP);
}
else
swap->bobdeposit.I.spendlen = basilisk_bobscript(swap->bobdeposit.I.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.I.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.I.locktime,&swap->bobdeposit.I.secretstart,&swap->I,1);
bitcoin_address(swap->bobdeposit.p2shaddr,coin->taddr,coin->p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr);
//int32_t i; for (i=0; i<swap->bobdeposit.I.redeemlen; i++)
// printf("%02x",swap->bobdeposit.redeemscript[i]);
//printf(" <- bobdeposit redeem %d %s\n",i,swap->bobdeposit.I.destaddr);
if ( genflag != 0 && (swap->bobdeposit.I.datalen == 0 || swap->bobrefund.I.datalen == 0) )
{
for (j=0; j<swap->bobdeposit.I.datalen; j++)
printf("%02x",swap->bobdeposit.txbytes[j]);
printf(" <- GENERATED BOB DEPOSIT.%d (%s)\n",swap->bobdeposit.I.datalen,swap->bobdeposit.I.destaddr);
LP_swap_coinaddr(&swap->bobcoin,checkaddr,0,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen,0);
if ( strcmp(swap->bobdeposit.I.destaddr,checkaddr) != 0 )
basilisk_rawtx_gen(swap->ctx,"deposit",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobdeposit,swap->bobdeposit.I.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.I.spendlen,coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr);
if ( swap->bobdeposit.I.datalen == 0 || swap->bobdeposit.I.spendlen == 0 )
{
printf("BOBDEPOSIT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobdeposit.I.destaddr,checkaddr);
return(-1);
printf("error bob generating %p deposit.%d\n",swap->bobdeposit.txbytes,swap->bobdeposit.I.spendlen);
sleep(DEX_SLEEP);
}
else
{
for (j=0; j<swap->bobdeposit.I.datalen; j++)
printf("%02x",swap->bobdeposit.txbytes[j]);
printf(" <- GENERATED BOB DEPOSIT.%d (%s)\n",swap->bobdeposit.I.datalen,swap->bobdeposit.I.destaddr);
LP_swap_coinaddr(coin,checkaddr,0,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen,0);
if ( strcmp(swap->bobdeposit.I.destaddr,checkaddr) != 0 )
{
printf("BOBDEPOSIT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobdeposit.I.destaddr,checkaddr);
return(-1);
}
LP_unspents_mark(coin->symbol,swap->bobdeposit.vins);
printf("bobscripts set completed\n");
return(0);
}
LP_unspents_mark(swap->bobcoin.symbol,swap->bobdeposit.vins);
printf("bobscripts set completed\n");
return(0);
}
}
}
} else printf("bobscripts set cant find (%s)\n",swap->I.bobstr);
return(0);
}
@ -1728,7 +1854,7 @@ int32_t basilisk_alicepayment_spend(struct basilisk_swap *swap,struct basilisk_r
{
int32_t i,retval;
printf("alicepayment_spend\n");
swap->alicepayment.I.spendlen = basilisk_alicescript(swap->alicepayment.redeemscript,&swap->alicepayment.I.redeemlen,swap->alicepayment.spendscript,0,swap->alicepayment.I.destaddr,swap->alicecoin.p2shtype,swap->I.pubAm,swap->I.pubBn);
swap->alicepayment.I.spendlen = basilisk_alicescript(swap->alicepayment.redeemscript,&swap->alicepayment.I.redeemlen,swap->alicepayment.spendscript,0,swap->alicepayment.I.destaddr,coin->p2shtype,swap->I.pubAm,swap->I.pubBn);
printf("alicepayment_spend len.%d\n",swap->alicepayment.I.spendlen);
if ( swap->I.iambob == 0 )
{
@ -1740,7 +1866,7 @@ int32_t basilisk_alicepayment_spend(struct basilisk_swap *swap,struct basilisk_r
memcpy(swap->I.userdata_bobspend,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen);
swap->I.userdata_bobspendlen = swap->alicepayment.I.spendlen;
}
if ( (retval= basilisk_rawtx_sign(swap->alicecoin.symbol,swap->alicecoin.pubtype,swap->alicecoin.p2shtype,swap->alicecoin.isPoS,swap->alicecoin.wiftype,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1,swap->changermd160)) == 0 )
if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1,swap->changermd160)) == 0 )
{
for (i=0; i<dest->I.datalen; i++)
printf("%02x",dest->txbytes[i]);
@ -1765,84 +1891,94 @@ void basilisk_alicepayment(struct basilisk_swap *swap,struct iguana_info *coin,s
int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)
{
char coinaddr[64]; int32_t i,retval = -1;
if ( swap->alicepayment.I.datalen == 0 )
basilisk_alicepayment(swap,swap->alicepayment.coin,&swap->alicepayment,swap->I.pubAm,swap->I.pubBn);
if ( swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.spendlen == 0 )
printf("error alice generating payment.%d\n",swap->alicepayment.I.spendlen);
else
char coinaddr[64]; int32_t i,retval = -1; struct iguana_info *coin;
if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 )
{
bitcoin_address(swap->alicepayment.I.destaddr,swap->alicecoin.taddr,swap->alicecoin.p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen);
//LP_importaddress(swap->alicecoin.symbol,swap->alicepayment.I.destaddr);
strcpy(swap->alicepayment.p2shaddr,swap->alicepayment.I.destaddr);
retval = 0;
for (i=0; i<swap->alicepayment.I.datalen; i++)
printf("%02x",swap->alicepayment.txbytes[i]);
printf(" ALICE PAYMENT created.(%s)\n",swap->alicepayment.I.destaddr);
LP_unspents_mark(swap->alicecoin.symbol,swap->alicepayment.vins);
//LP_importaddress(swap->alicecoin.symbol,swap->alicepayment.I.destaddr);
//basilisk_txlog(swap,&swap->alicepayment,-1);
}
if ( swap->myfee.I.datalen == 0 )
{
printf("generate fee %.8f\n",dstr(strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee));
bitcoin_address(coinaddr,swap->alicecoin.taddr,swap->alicecoin.pubtype,swap->changermd160,20);
if ( basilisk_rawtx_gen(swap->ctx,"myfee",swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,swap->myfee.I.locktime,swap->myfee.spendscript,swap->myfee.I.spendlen,strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr) == 0 )
{
printf("rawtxsend %s %.8f\n",swap->myfee.coin->symbol,dstr(strcmp(swap->myfee.coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : swap->myfee.coin->txfee));
swap->I.statebits |= LP_swapdata_rawtxsend(pairsock,swap,0x80,data,maxlen,&swap->myfee,0x40,0);
LP_unspents_mark(swap->I.iambob!=0?swap->bobcoin.symbol:swap->alicecoin.symbol,swap->myfee.vins);
//basilisk_txlog(swap,&swap->myfee,-1);
for (i=0; i<swap->myfee.I.datalen; i++)
printf("%02x",swap->myfee.txbytes[i]);
printf(" <- fee state.%x\n",swap->I.statebits);
swap->I.statebits |= 0x40;
}
if ( swap->alicepayment.I.datalen == 0 )
basilisk_alicepayment(swap,coin,&swap->alicepayment,swap->I.pubAm,swap->I.pubBn);
if ( swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.spendlen == 0 )
printf("error alice generating payment.%d\n",swap->alicepayment.I.spendlen);
else
{
printf("error creating myfee\n");
return(-2);
bitcoin_address(swap->alicepayment.I.destaddr,coin->taddr,coin->p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen);
//LP_importaddress(coin->symbol,swap->alicepayment.I.destaddr);
strcpy(swap->alicepayment.p2shaddr,swap->alicepayment.I.destaddr);
retval = 0;
for (i=0; i<swap->alicepayment.I.datalen; i++)
printf("%02x",swap->alicepayment.txbytes[i]);
printf(" ALICE PAYMENT created.(%s)\n",swap->alicepayment.I.destaddr);
LP_unspents_mark(coin->symbol,swap->alicepayment.vins);
//LP_importaddress(coin->symbol,swap->alicepayment.I.destaddr);
//basilisk_txlog(swap,&swap->alicepayment,-1);
}
}
if ( swap->alicepayment.I.datalen != 0 && swap->alicepayment.I.spendlen > 0 && swap->myfee.I.datalen != 0 && swap->myfee.I.spendlen > 0 )
{
printf("fee sent\n");
return(0);
}
if ( swap->myfee.I.datalen == 0 )
{
printf("%s generate fee %.8f from.%s\n",coin->symbol,dstr(strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee),coin->smartaddr);
bitcoin_address(coinaddr,coin->taddr,coin->pubtype,swap->changermd160,20);
if ( basilisk_rawtx_gen(swap->ctx,"myfee",swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,swap->myfee.I.locktime,swap->myfee.spendscript,swap->myfee.I.spendlen,strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr) == 0 )
{
printf("rawtxsend %s %.8f\n",coin->symbol,dstr(strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee));
swap->I.statebits |= LP_swapdata_rawtxsend(pairsock,swap,0x80,data,maxlen,&swap->myfee,0x40,0);
LP_unspents_mark(swap->I.iambob!=0?coin->symbol:coin->symbol,swap->myfee.vins);
//basilisk_txlog(swap,&swap->myfee,-1);
for (i=0; i<swap->myfee.I.datalen; i++)
printf("%02x",swap->myfee.txbytes[i]);
printf(" <- fee state.%x\n",swap->I.statebits);
swap->I.statebits |= 0x40;
}
else
{
printf("error creating myfee\n");
return(-2);
}
}
if ( swap->alicepayment.I.datalen != 0 && swap->alicepayment.I.spendlen > 0 && swap->myfee.I.datalen != 0 && swap->myfee.I.spendlen > 0 )
{
printf("fee sent\n");
return(0);
}
} else printf("basilisk alicetx cant find (%s)\n",swap->I.alicestr);
return(-1);
}
int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t datalen)
{
int32_t diff;
if ( LP_rawtx_spendscript(swap,swap->bobcoin.longestchain,&swap->otherfee,0,data,datalen,0) == 0 )
{
printf("otherfee amount %.8f -> %s vs %s locktime %u vs %u\n",dstr(swap->otherfee.I.amount),swap->otherfee.p2shaddr,swap->otherfee.I.destaddr,swap->otherfee.I.locktime,swap->I.started+1);
if ( strcmp(swap->otherfee.I.destaddr,swap->otherfee.p2shaddr) == 0 )
{
diff = swap->otherfee.I.locktime - (swap->I.started+1);
if ( diff < 0 )
diff = -diff;
if ( diff < 10 )
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);
} else printf("destaddress mismatch in other fee, reject (%s) vs (%s)\n",swap->otherfee.I.destaddr,swap->otherfee.p2shaddr);
}
int32_t diff; struct iguana_info *coin;
if ( (coin= LP_coinfind(swap->I.iambob != 0 ? swap->I.alicestr : swap->I.bobstr)) != 0 )
{
if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->otherfee,0,data,datalen,0) == 0 )
{
printf("otherfee amount %.8f -> %s vs %s locktime %u vs %u\n",dstr(swap->otherfee.I.amount),swap->otherfee.p2shaddr,swap->otherfee.I.destaddr,swap->otherfee.I.locktime,swap->I.started+1);
if ( strcmp(swap->otherfee.I.destaddr,swap->otherfee.p2shaddr) == 0 )
{
diff = swap->otherfee.I.locktime - (swap->I.started+1);
if ( diff < 0 )
diff = -diff;
if ( diff < 10 )
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);
} else printf("destaddress mismatch in other fee, reject (%s) vs (%s)\n",swap->otherfee.I.destaddr,swap->otherfee.p2shaddr);
}
} else printf("cant find other coin iambob.%d\n",swap->I.iambob);
return(-1);
}
int32_t LP_verify_alicespend(struct basilisk_swap *swap,uint8_t *data,int32_t datalen)
{
if ( LP_rawtx_spendscript(swap,swap->bobcoin.longestchain,&swap->alicespend,0,data,datalen,0) == 0 )
struct iguana_info *coin;
if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 )
{
printf("alicespend amount %.8f -> %s vs %s\n",dstr(swap->alicespend.I.amount),swap->alicespend.p2shaddr,swap->alicespend.I.destaddr);
if ( strcmp(swap->alicespend.I.destaddr,swap->alicespend.p2shaddr) == 0 )
if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->alicespend,0,data,datalen,0) == 0 )
{
printf("alicespend verified\n");
return(0);
printf("alicespend amount %.8f -> %s vs %s\n",dstr(swap->alicespend.I.amount),swap->alicespend.p2shaddr,swap->alicespend.I.destaddr);
if ( strcmp(swap->alicespend.I.destaddr,swap->alicespend.p2shaddr) == 0 )
{
printf("alicespend verified\n");
return(0);
}
}
}
} else printf("verify alicespend cant find (%s)\n",swap->I.alicestr);
return(-1);
}
@ -1855,109 +1991,120 @@ int32_t LP_verify_alicespend(struct basilisk_swap *swap,uint8_t *data,int32_t da
int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t datalen)
{
uint8_t userdata[512]; int32_t retval=-1,len = 0; static bits256 zero;
if ( LP_rawtx_spendscript(swap,swap->bobcoin.longestchain,&swap->bobdeposit,0,data,datalen,0) == 0 )
{
swap->aliceclaim.utxovout = 0;
swap->bobdeposit.I.signedtxid = LP_broadcast_tx(swap->bobdeposit.name,swap->bobcoin.symbol,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen);
if ( bits256_nonz(swap->bobdeposit.I.signedtxid) != 0 )
swap->depositunconf = 1;
else swap->bobdeposit.I.signedtxid = swap->bobdeposit.I.actualtxid;
len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
swap->aliceclaim.utxotxid = swap->bobdeposit.I.signedtxid;
memcpy(swap->I.userdata_aliceclaim,userdata,len);
swap->I.userdata_aliceclaimlen = len;
bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr);
basilisk_dontforget_update(swap,&swap->bobdeposit);
//int32_t i; char str[65]; for (i=0; i<swap->bobdeposit.I.datalen; i++)
// printf("%02x",swap->bobdeposit.txbytes[i]);
//printf(" <- bobdeposit.%d %s\n",swap->bobdeposit.I.datalen,bits256_str(str,swap->bobdeposit.I.signedtxid));
//for (i=0; i<swap->bobdeposit.I.redeemlen; i++)
// printf("%02x",swap->bobdeposit.redeemscript[i]);
//printf(" <- bobdeposit redeem %d %s suppress.%d\n",i,swap->bobdeposit.I.destaddr,swap->aliceclaim.I.suppress_pubkeys);
memcpy(swap->aliceclaim.redeemscript,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
swap->aliceclaim.I.redeemlen = swap->bobdeposit.I.redeemlen;
memcpy(swap->aliceclaim.I.pubkey33,swap->persistent_pubkey33,33);
bitcoin_address(swap->aliceclaim.I.destaddr,swap->alicecoin.taddr,swap->alicecoin.pubtype,swap->persistent_pubkey33,33);
retval = 0;
if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.wiftaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobdeposit.I.destaddr,swap->bobcoin.zcash)) == 0 )
{
int32_t i; for (i=0; i<swap->bobdeposit.I.datalen; i++)
printf("%02x",swap->bobdeposit.txbytes[i]);
printf(" <- bobdeposit\n");
for (i=0; i<swap->aliceclaim.I.datalen; i++)
printf("%02x",swap->aliceclaim.txbytes[i]);
printf(" <- aliceclaim\n");
//basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration);
return(LP_waitmempool(swap->bobcoin.symbol,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,60));
} else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr);
}
static bits256 zero;
uint8_t userdata[512]; int32_t retval=-1,len = 0; struct iguana_info *coin;
if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 )
{
if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->bobdeposit,0,data,datalen,0) == 0 )
{
swap->aliceclaim.utxovout = 0;
swap->bobdeposit.I.signedtxid = LP_broadcast_tx(swap->bobdeposit.name,coin->symbol,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen);
if ( bits256_nonz(swap->bobdeposit.I.signedtxid) != 0 )
swap->depositunconf = 1;
else swap->bobdeposit.I.signedtxid = swap->bobdeposit.I.actualtxid;
len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
swap->aliceclaim.utxotxid = swap->bobdeposit.I.signedtxid;
memcpy(swap->I.userdata_aliceclaim,userdata,len);
swap->I.userdata_aliceclaimlen = len;
bitcoin_address(swap->bobdeposit.p2shaddr,coin->taddr,coin->p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr);
basilisk_dontforget_update(swap,&swap->bobdeposit);
//int32_t i; char str[65]; for (i=0; i<swap->bobdeposit.I.datalen; i++)
// printf("%02x",swap->bobdeposit.txbytes[i]);
//printf(" <- bobdeposit.%d %s\n",swap->bobdeposit.I.datalen,bits256_str(str,swap->bobdeposit.I.signedtxid));
//for (i=0; i<swap->bobdeposit.I.redeemlen; i++)
// printf("%02x",swap->bobdeposit.redeemscript[i]);
//printf(" <- bobdeposit redeem %d %s suppress.%d\n",i,swap->bobdeposit.I.destaddr,swap->aliceclaim.I.suppress_pubkeys);
memcpy(swap->aliceclaim.redeemscript,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen);
swap->aliceclaim.I.redeemlen = swap->bobdeposit.I.redeemlen;
memcpy(swap->aliceclaim.I.pubkey33,swap->persistent_pubkey33,33);
bitcoin_address(swap->aliceclaim.I.destaddr,coin->taddr,coin->pubtype,swap->persistent_pubkey33,33);
retval = 0;
if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobdeposit.I.destaddr,coin->zcash)) == 0 )
{
int32_t i; for (i=0; i<swap->bobdeposit.I.datalen; i++)
printf("%02x",swap->bobdeposit.txbytes[i]);
printf(" <- bobdeposit\n");
for (i=0; i<swap->aliceclaim.I.datalen; i++)
printf("%02x",swap->aliceclaim.txbytes[i]);
printf(" <- aliceclaim\n");
//basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration);
return(LP_waitmempool(coin->symbol,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,60));
} else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr);
}
} else printf("verify bob depositcant find bob coin (%s)\n",swap->I.bobstr);
printf("error with bobdeposit\n");
return(retval);
}
int32_t LP_verify_alicepayment(struct basilisk_swap *swap,uint8_t *data,int32_t datalen)
{
if ( LP_rawtx_spendscript(swap,swap->alicecoin.longestchain,&swap->alicepayment,0,data,datalen,0) == 0 )
{
swap->bobspend.utxovout = 0;
swap->bobspend.utxotxid = swap->alicepayment.I.signedtxid = LP_broadcast_tx(swap->alicepayment.name,swap->alicecoin.symbol,swap->alicepayment.txbytes,swap->alicepayment.I.datalen);
bitcoin_address(swap->alicepayment.p2shaddr,swap->alicecoin.taddr,swap->alicecoin.p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen);
strcpy(swap->alicepayment.I.destaddr,swap->alicepayment.p2shaddr);
if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 )
swap->aliceunconf = 1;
basilisk_dontforget_update(swap,&swap->alicepayment);
return(LP_waitmempool(swap->alicecoin.symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,60));
//printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr);
//LP_importaddress(swap->alicecoin.symbol,swap->alicepayment.p2shaddr);
return(0);
}
struct iguana_info *coin;
if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 )
{
if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->alicepayment,0,data,datalen,0) == 0 )
{
swap->bobspend.utxovout = 0;
swap->bobspend.utxotxid = swap->alicepayment.I.signedtxid = LP_broadcast_tx(swap->alicepayment.name,coin->symbol,swap->alicepayment.txbytes,swap->alicepayment.I.datalen);
bitcoin_address(swap->alicepayment.p2shaddr,coin->taddr,coin->p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen);
strcpy(swap->alicepayment.I.destaddr,swap->alicepayment.p2shaddr);
if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 )
swap->aliceunconf = 1;
basilisk_dontforget_update(swap,&swap->alicepayment);
return(LP_waitmempool(coin->symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,60));
//printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr);
//LP_importaddress(coin->symbol,swap->alicepayment.p2shaddr);
return(0);
}
} else printf("verify alicepayment couldnt find coin.(%s)\n",swap->I.alicestr);
printf("error validating alicepayment\n");
return(-1);
}
int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t datalen)
{
uint8_t userdata[512]; int32_t i,retval=-1,len = 0; bits256 revAm;
memset(revAm.bytes,0,sizeof(revAm));
if ( LP_rawtx_spendscript(swap,swap->bobcoin.longestchain,&swap->bobpayment,0,data,datalen,0) == 0 )
{
swap->alicespend.utxovout = 0;
swap->alicespend.utxotxid = swap->bobpayment.I.signedtxid = LP_broadcast_tx(swap->bobpayment.name,swap->bobpayment.coin->symbol,swap->bobpayment.txbytes,swap->bobpayment.I.datalen);
if ( bits256_nonz(swap->bobpayment.I.signedtxid) != 0 )
swap->paymentunconf = 1;
for (i=0; i<32; i++)
revAm.bytes[i] = swap->I.privAm.bytes[31-i];
len = basilisk_swapuserdata(userdata,revAm,0,swap->I.myprivs[0],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen);
bitcoin_address(swap->bobpayment.p2shaddr,swap->bobcoin.taddr,swap->bobcoin.p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen);
strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr);
basilisk_dontforget_update(swap,&swap->bobpayment);
//LP_importaddress(swap->bobcoin.symbol,swap->bobpayment.I.destaddr);
/*for (i=0; i<swap->bobpayment.I.datalen; i++)
printf("%02x",swap->bobpayment.txbytes[i]);
printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen);
for (i=0; i<swap->bobpayment.I.redeemlen; i++)
printf("%02x",swap->bobpayment.redeemscript[i]);
printf(" <- bobpayment redeem %d %s %s\n",i,swap->bobpayment.I.destaddr,bits256_str(str,swap->bobpayment.I.signedtxid));*/
memcpy(swap->I.userdata_alicespend,userdata,len);
swap->I.userdata_alicespendlen = len;
retval = 0;
memcpy(swap->alicespend.I.pubkey33,swap->persistent_pubkey33,33);
bitcoin_address(swap->alicespend.I.destaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->persistent_pubkey33,33);
//char str[65],str2[65]; printf("bobpaid privAm.(%s) myprivs[0].(%s)\n",bits256_str(str,swap->I.privAm),bits256_str(str2,swap->I.myprivs[0]));
if ( (retval= basilisk_rawtx_sign(swap->bobcoin.symbol,swap->bobcoin.wiftaddr,swap->bobcoin.taddr,swap->bobcoin.pubtype,swap->bobcoin.p2shtype,swap->bobcoin.isPoS,swap->bobcoin.wiftype,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->alicepayment.I.destaddr,swap->bobcoin.zcash)) == 0 )
uint8_t userdata[512]; int32_t i,retval=-1,len = 0; bits256 revAm; struct iguana_info *coin;
if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 )
{
memset(revAm.bytes,0,sizeof(revAm));
if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->bobpayment,0,data,datalen,0) == 0 )
{
swap->alicespend.utxovout = 0;
swap->alicespend.utxotxid = swap->bobpayment.I.signedtxid = LP_broadcast_tx(swap->bobpayment.name,coin->symbol,swap->bobpayment.txbytes,swap->bobpayment.I.datalen);
if ( bits256_nonz(swap->bobpayment.I.signedtxid) != 0 )
swap->paymentunconf = 1;
for (i=0; i<32; i++)
revAm.bytes[i] = swap->I.privAm.bytes[31-i];
len = basilisk_swapuserdata(userdata,revAm,0,swap->I.myprivs[0],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen);
bitcoin_address(swap->bobpayment.p2shaddr,coin->taddr,coin->p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen);
strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr);
basilisk_dontforget_update(swap,&swap->bobpayment);
//LP_importaddress(coin->symbol,swap->bobpayment.I.destaddr);
/*for (i=0; i<swap->bobpayment.I.datalen; i++)
printf("%02x",swap->bobpayment.txbytes[i]);
printf(" <- bobpayment\n");
for (i=0; i<swap->alicespend.I.datalen; i++)
printf("%02x",swap->alicespend.txbytes[i]);
printf(" <- alicespend\n\n");*/
swap->I.alicespent = 1;
return(LP_waitmempool(swap->bobcoin.symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,60));
} else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->alicespend.I.suppress_pubkeys,swap->bobpayment.I.destaddr);
}
printf("%02x",swap->bobpayment.txbytes[i]);
printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen);
for (i=0; i<swap->bobpayment.I.redeemlen; i++)
printf("%02x",swap->bobpayment.redeemscript[i]);
printf(" <- bobpayment redeem %d %s %s\n",i,swap->bobpayment.I.destaddr,bits256_str(str,swap->bobpayment.I.signedtxid));*/
memcpy(swap->I.userdata_alicespend,userdata,len);
swap->I.userdata_alicespendlen = len;
retval = 0;
memcpy(swap->alicespend.I.pubkey33,swap->persistent_pubkey33,33);
bitcoin_address(swap->alicespend.I.destaddr,coin->taddr,coin->pubtype,swap->persistent_pubkey33,33);
//char str[65],str2[65]; printf("bobpaid privAm.(%s) myprivs[0].(%s)\n",bits256_str(str,swap->I.privAm),bits256_str(str2,swap->I.myprivs[0]));
if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->alicepayment.I.destaddr,coin->zcash)) == 0 )
{
/*for (i=0; i<swap->bobpayment.I.datalen; i++)
printf("%02x",swap->bobpayment.txbytes[i]);
printf(" <- bobpayment\n");
for (i=0; i<swap->alicespend.I.datalen; i++)
printf("%02x",swap->alicespend.txbytes[i]);
printf(" <- alicespend\n\n");*/
swap->I.alicespent = 1;
return(LP_waitmempool(coin->symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,60));
} else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->alicespend.I.suppress_pubkeys,swap->bobpayment.I.destaddr);
}
} else printf("verify bobpayment cant find (%s)\n",swap->I.bobstr);
printf("error validating bobpayment\n");
return(-1);
}

286
iguana/exchanges/LP_utxo.c

@ -18,6 +18,148 @@
// marketmaker
//
struct LP_inuse_info
{
bits256 txid,otherpub;
uint32_t expiration;
int32_t vout,ind;
} LP_inuse[1024];
int32_t LP_numinuse;
struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout)
{
int32_t i;
if ( bits256_nonz(txid) != 0 )
{
for (i=0; i<LP_numinuse; i++)
if ( vout == LP_inuse[i].vout && bits256_cmp(LP_inuse[i].txid,txid) == 0 )
return(&LP_inuse[i]);
}
return(0);
}
int32_t _LP_inuse_delete(bits256 txid,int32_t vout)
{
struct LP_inuse_info *lp; int32_t ind;
if ( (lp= _LP_inuse_find(txid,vout)) != 0 )
{
ind = lp->ind;
*lp = LP_inuse[--LP_numinuse];
lp->ind = ind;
memset(&LP_inuse[LP_numinuse],0,sizeof(struct LP_inuse_info));
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);
return(-1);
}
struct LP_inuse_info *_LP_inuse_add(uint32_t expiration,bits256 otherpub,bits256 txid,int32_t vout)
{
struct LP_inuse_info *lp; int32_t i,n,oldesti; uint32_t now,oldest;
if ( LP_numinuse >= sizeof(LP_inuse)/sizeof(*LP_inuse) )
{
now = (uint32_t)time(NULL);
n = 0;
oldesti = -1;
oldest = 0;
for (i=0; i<sizeof(LP_inuse)/sizeof(*LP_inuse); i++)
{
lp = &LP_inuse[i];
if ( now > lp->expiration )
_LP_inuse_delete(lp->txid,lp->vout), n++;
else if ( oldest == 0 || lp->expiration < oldest )
{
oldest = lp->expiration;
oldesti = i;
}
}
if ( n == 0 )
{
printf("_LP_inuse_add out of slots error, pick oldesti %d\n",oldesti);
lp = &LP_inuse[oldesti];
_LP_inuse_delete(lp->txid,lp->vout);
} else printf("expired %d inuse slots\n",n);
}
if ( bits256_nonz(txid) != 0 )
{
if ( (lp= _LP_inuse_find(txid,vout)) == 0 )
{
lp = &LP_inuse[LP_numinuse];
memset(lp,0,sizeof(*lp));
lp->txid = txid;
lp->vout = vout;
lp->expiration = expiration;
lp->otherpub = otherpub;
lp->ind = LP_numinuse++;
}
else
{
if ( bits256_nonz(otherpub) != 0 )
lp->otherpub = otherpub;
if ( expiration > lp->expiration || expiration == 0 )
lp->expiration = expiration;
}
return(lp);
} else printf("_LP_inuse_add [%d] overflow\n",LP_numinuse);
return(0);
}
int32_t LP_reservation_check(bits256 txid,int32_t vout,bits256 pubkey)
{
struct LP_inuse_info *lp; int32_t retval = -1;
if ( bits256_nonz(pubkey) != 0 )
{
portable_mutex_lock(&LP_inusemutex);
if ( (lp= _LP_inuse_find(txid,vout)) != 0 )
{
if ( bits256_cmp(lp->otherpub,pubkey) == 0 )
retval = 0;
}
portable_mutex_unlock(&LP_inusemutex);
}
return(retval);
}
uint32_t LP_allocated(bits256 txid,int32_t vout)
{
struct LP_inuse_info *lp; uint32_t now,duration = 0;
now = (uint32_t)time(NULL);
portable_mutex_lock(&LP_inusemutex);
if ( (lp= _LP_inuse_find(txid,vout)) != 0 )
{
if ( lp->expiration != 0 && now < lp->expiration )
duration = (lp->expiration - now);
}
portable_mutex_unlock(&LP_inusemutex);
return(duration);
}
void LP_unavailableset(bits256 txid,int32_t vout,uint32_t expiration,bits256 otherpub)
{
portable_mutex_lock(&LP_inusemutex);
_LP_inuse_add(expiration,otherpub,txid,vout);
portable_mutex_unlock(&LP_inusemutex);
}
void LP_availableset(bits256 txid,int32_t vout)
{
portable_mutex_lock(&LP_inusemutex);
_LP_inuse_delete(txid,vout);
portable_mutex_unlock(&LP_inusemutex);
}
int32_t LP_isavailable(struct LP_utxoinfo *utxo)
{
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);
}
uint64_t LP_value_extract(cJSON *obj,int32_t addinterest)
{
double val = 0.; uint64_t value = 0; int32_t electrumflag;
@ -116,43 +258,16 @@ int32_t LP_address_minmax(uint64_t *balancep,uint64_t *minp,uint64_t *maxp,struc
return(n);
}
struct LP_utxoinfo *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_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct LP_address *ap,char *coinaddr)
{
struct LP_address_utxo *up,*tmp; struct LP_transaction *tx; cJSON *txout; int32_t n = 0;
//printf("LP_address_utxo_ptrs for (%s).(%s)\n",ap->coinaddr,coinaddr);
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);
//LP_listunspent_issue(coin->symbol,coin->smartaddr,2);
//portable_mutex_lock(&LP_utxomutex);
DL_FOREACH_SAFE(ap->utxos,up,tmp)
{
//char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%p\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout));
//char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout));
if ( up->spendheight <= 0 && LP_RTmetrics_avoidtxid(up->U.txid) < 0 )
{
if ( coin->electrum == 0 )
@ -189,12 +304,12 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a
continue;
}
}
if ( LP_allocated(up->U.txid,up->U.vout) == 0 && (iambob == 0 || (_LP_utxofind(iambob,up->U.txid,up->U.vout) == 0 && _LP_utxo2find(iambob,up->U.txid,up->U.vout) == 0)) )
if ( LP_allocated(up->U.txid,up->U.vout) == 0 )
{
utxos[n++] = up;
if ( n >= max )
break;
}
} //else printf("LP_allocated skip\n");
}
else
{
@ -202,8 +317,8 @@ int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_a
tx->outpoints[up->U.vout].spendheight = 1;
}
}
portable_mutex_unlock(&LP_utxomutex);
//printf("return n.%d\n",n);
//portable_mutex_unlock(&LP_utxomutex);
//printf("return n.%d for %s %s\n",n,coin->symbol,coinaddr);
return(n);
}
@ -239,7 +354,7 @@ void LP_mark_spent(char *symbol,bits256 txid,int32_t vout)
}
}
int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight)
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)
{
struct LP_address *ap; cJSON *txobj; struct LP_transaction *tx; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; //char str[65];
if ( coin == 0 )
@ -262,7 +377,8 @@ int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,b
up->spendheight = spendheight, flag |= 4;
if ( value != 0 && up->U.value == 0 && up->U.value != value )
up->U.value = value, flag |= 8;
//printf("found >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value));
//up->timestamp = timestamp;
//char str[65]; printf("found >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value));
break;
}
}
@ -272,7 +388,7 @@ int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,b
{
if ( (txobj= LP_gettxout(coin->symbol,coinaddr,txid,vout)) == 0 )
{
//printf("prevent utxoadd since gettxout %s %s %s/v%d missing\n",coin->symbol,coinaddr,bits256_str(str,txid),vout);
//char str[65]; printf("prevent utxoadd since gettxout %s %s %s/v%d missing\n",coin->symbol,coinaddr,bits256_str(str,txid),vout);
return(0);
} else free_json(txobj);
}
@ -282,21 +398,79 @@ int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,b
up->U.height = height;
up->U.value = value;
up->spendheight = spendheight;
portable_mutex_lock(&coin->addrmutex);
DL_APPEND(ap->utxos,up);
portable_mutex_unlock(&coin->addrmutex);
//up->timestamp = timestamp;
retval = 1;
if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->SPV > 0 )
{
up->SPV = tx->SPV;
//printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value));
}
char str[65];
if ( 0 && strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 )
printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value));
portable_mutex_lock(&coin->addrmutex);
DL_APPEND(ap->utxos,up);
portable_mutex_unlock(&coin->addrmutex);
}
} // else printf("cant get ap %s %s\n",coin->symbol,coinaddr);
//printf("done %s add addr.%s ht.%d\n",coin->symbol,coinaddr,height);
return(retval);
}
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;
LP_address(coin,coin->smartaddr);
LP_listunspent_issue(coin->symbol,coin->smartaddr,2);
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 )
{
DL_FOREACH_SAFE(ap->utxos,up,tmp)
{
portable_mutex_lock(&coin->addrmutex);
DL_DELETE(ap->utxos,up);
portable_mutex_unlock(&coin->addrmutex);
portable_mutex_lock(&LP_gcmutex);
up->spendheight = (int32_t)time(NULL);
DL_APPEND(LP_garbage_collector2,up);
portable_mutex_unlock(&LP_gcmutex);
}
now = (uint32_t)time(NULL);
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
char str[65];
for (i=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);
}
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));
}
printf("added %d from listunspents\n",n);
}
free_json(array);
}
return(ap);
}
cJSON *LP_address_item(struct iguana_info *coin,struct LP_address_utxo *up,int32_t electrumret)
{
cJSON *item = cJSON_CreateObject();
@ -345,7 +519,10 @@ cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrum
}
if ( up->spendheight <= 0 && up->U.value != 0 )
{
if ( coin->electrum == 0 || up->SPV > 0 )
char str[65];
if ( LP_allocated(up->U.txid,up->U.vout) != 0 )
printf("%s %s/v%d allocated\n",coin->symbol,bits256_str(str,up->U.txid),up->U.vout);
else if ( coin->electrum == 0 || up->SPV > 0 )
{
jaddi(array,LP_address_item(coin,up,electrumret));
n++;
@ -391,6 +568,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
balance += LP_value_extract(item,1);
}
}
free_json(array);
}
}
else
@ -409,6 +587,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
balance += j64bits(item,"value");
}
}
free_json(array);
}
}
}
@ -422,7 +601,7 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array)
{
int32_t i,n,v,ht,errs,height,count=0; uint64_t value,val; cJSON *item,*txobj; bits256 txid;
int32_t i,n,v,errs,height,count=0; uint64_t value,val; cJSON *item,*txobj; bits256 txid;
if ( (n= cJSON_GetArraySize(array)) <= 0 )
return(0);
//printf("%s %s LP_unspents.(%s)\n",coin->symbol,coinaddr,jprint(array,0));
@ -442,7 +621,7 @@ int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array)
char str[65]; printf("REJECT %s %s/v%d value.%llu vs %llu (%s)\n",coin->symbol,bits256_str(str,txid),v,(long long)value,(long long)val,jprint(txobj,0));
errs++;
}
ht = LP_txheight(coin,txid);
//ht = LP_txheight(coin,txid);
//if ( coin->height != 0 )
// ht = LP_getheight(coin) - jint(txobj,"confirmations") + 1;
//else ht = 0;
@ -456,7 +635,7 @@ int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array)
if ( errs == 0 )
{
//printf("from LP_unspents_array\n");
LP_address_utxoadd("LP_unspents_array",coin,coinaddr,txid,v,val,height,-1);
LP_address_utxoadd((uint32_t)time(NULL),"LP_unspents_array",coin,coinaddr,txid,v,val,height,-1);
count++;
}
}
@ -580,7 +759,7 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS
tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest");
LP_destaddr(tx->outpoints[i].coinaddr,vout);
//printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value));
LP_address_utxoadd("LP_transactioninit iter0",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1);
LP_address_utxoadd((uint32_t)time(NULL),"LP_transactioninit iter0",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1);
}
//printf("numvouts.%d\n",numvouts);
}
@ -602,7 +781,7 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS
tx->outpoints[spentvout].spendtxid = txid;
tx->outpoints[spentvout].spendvini = i;
tx->outpoints[spentvout].spendheight = height > 0 ? height : 1;
LP_address_utxoadd("LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1);
LP_address_utxoadd((uint32_t)time(NULL),"LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1);
if ( 0 && strcmp(coin->symbol,"REVS") == 0 )
printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height);
}
@ -765,13 +944,12 @@ uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout)
}
else if ( coin->electrum == 0 )
{
uint64_t value; char _coinaddr[64];
uint64_t value;
if ( (txobj= LP_gettxout(coin->symbol,coinaddr,txid,vout)) != 0 )
{
value = LP_value_extract(txobj,0);//SATOSHIDEN * (jdouble(txobj,"value") + jdouble(txobj,"interest"));
if ( coinaddr == 0 )
coinaddr = _coinaddr;
LP_destaddr(coinaddr,txobj);
if ( coinaddr != 0 )
LP_destaddr(coinaddr,txobj);
//printf("pruned node? LP_txvalue couldnt find %s tx %s, but gettxout %.8f\n",coin->symbol,bits256_str(str,txid),dstr(value));
if ( value != 0 )
{
@ -788,7 +966,7 @@ uint64_t LP_txvalue(char *coinaddr,char *symbol,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)
{
uint64_t val,val2=0,txfee,threshold=0; cJSON *txobj; int32_t bypass = 0; char destaddr[64],destaddr2[64]; struct LP_transaction *tx; struct LP_address_utxo *up; struct iguana_info *coin = LP_coinfind(symbol);
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);
if ( bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 )
{
printf("null txid not eligible\n");
@ -821,7 +999,7 @@ 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 ( coin->electrum != 0 )
{
if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts && tx->outpoints[vout].spendheight > 0 )
{
@ -844,7 +1022,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
return(0);
}
}
else
else*/
{
if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 )
return(0);

97
iguana/exchanges/LP_utxos.c

@ -19,8 +19,6 @@
//
int32_t LP_ismine(struct LP_utxoinfo *utxo)
{
if ( utxo != 0 && bits256_cmp(utxo->pubkey,G.LP_mypub25519) == 0 )
@ -28,15 +26,6 @@ int32_t LP_ismine(struct LP_utxoinfo *utxo)
else 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_isunspent(struct LP_utxoinfo *utxo)
{
struct LP_address_utxo *up; struct _LP_utxoinfo u; struct iguana_info *coin;
@ -88,6 +77,41 @@ int32_t LP_utxoaddptrs(struct LP_utxoinfo *ptrs[],int32_t n,struct LP_utxoinfo *
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;
@ -170,6 +194,7 @@ void LP_availableset(struct LP_utxoinfo *utxo)
}
}
}
*/
cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo)
{
@ -208,8 +233,8 @@ cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo)
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->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);
@ -235,14 +260,14 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis)
printf("LP_utxo_bestfit error symbol.%p %.8f\n",symbol,dstr(destsatoshis));
return(0);
}
// jl777 remove mempool
HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp)
{
//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);
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 )
{
@ -266,6 +291,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis)
}
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 )
@ -273,7 +299,7 @@ struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis)
continue;
}
bestutxo = utxo;
} // else printf("skip alice utxo %.8f vs dest %.8f\n",dstr(utxo->S.satoshis),dstr(destsatoshis));
} //else printf("skip alice utxo %.8f vs dest %.8f, bestsize.%d %p\n",dstr(utxo->S.satoshis),dstr(destsatoshis),bestsize,bestutxo);
}
}
return(bestutxo);
@ -412,7 +438,7 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t
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 <<<<<<<<<<<<<<<\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);
//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 )
@ -490,7 +516,7 @@ cJSON *LP_inventory(char *symbol)
{
//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));
//printf("%s %s ineligible %.8f %.8f\n",utxo->coin,bits256_str(str,u.txid),dstr(val),dstr(val2));
continue;
}
//if ( iambob != 0 )
@ -536,25 +562,19 @@ int32_t LP_nearestvalue(int32_t iambob,uint64_t *values,int32_t n,uint64_t targe
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,depositval,value,total = 0; int64_t targetval;
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 ( bits256_cmp(myprivkey,coin->lastprivkey) == 0 && time(NULL) < coin->lastprivkeytime+60 )
return(0);
coin->lastprivkey = myprivkey;
coin->lastprivkeytime = (uint32_t)time(NULL);
if ( coin->privkeydepth > 0 )
return(0);
coin->privkeydepth++;
LP_address(coin,coin->smartaddr);
//printf("privkey init.(%s) %s depth.%d\n",coin->symbol,coin->smartaddr,coin->privkeydepth);
if ( coin->inactive == 0 )
LP_listunspent_issue(coin->symbol,coin->smartaddr,0);
array = LP_listunspent(coin->symbol,coin->smartaddr);
//printf("unspent array %ld\n",strlen(jprint(array,0)));
if ( array != 0 )
{
txfee = LP_txfeecalc(coin,0,0);
@ -615,15 +635,15 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
depositvout = juint(item,"tx_pos");
script = coin->smartaddr;
}
depositval = values[i];
biggerval = values[i];
values[i] = 0, used++;
if ( iambob == 0 )
targetval = (depositval / 776) + txfee;
else targetval = (depositval / 9) * 8 + 2*txfee;
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(depositval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval));
if ( depositval < (1+LP_MINSIZE_TXFEEMULT)*txfee )
//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 )
@ -635,7 +655,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
}
if ( i >= 0 || (i= LP_nearestvalue(iambob,values,n,targetval)) >= 0 )
{
//printf("iambob.%d i.%d %.8f target %.8f\n",iambob,i,dstr(depositval),dstr(targetval));
//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 )
@ -658,14 +678,14 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
portable_mutex_lock(&LP_UTXOmutex);
if ( iambob != 0 )
{
if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,depositval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 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,depositval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 )
if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,biggerval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,biggerval)) != 0 )
{
}
}
@ -680,7 +700,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
}
}
free_json(array);
if ( flag != 0 )
if ( 0 && flag != 0 )
LP_postutxos(coin->symbol,coin->smartaddr);
}
if ( values != 0 )
@ -794,7 +814,8 @@ bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguan
printf("cant importprivkey.%s -> (%s), abort session\n",coin->symbol,jprint(retjson,1));
exit(-1);
}
} else free_json(retjson);
free_json(retjson);
}
coin->importedprivkey = (uint32_t)time(NULL);
}
vcalc_sha256(0,checkkey.bytes,privkey.bytes,sizeof(privkey));
@ -827,8 +848,10 @@ void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase)
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 && (rand() % 10) == 0 )
LP_postutxos(coin->symbol,coin->smartaddr);
if ( LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (LP_rand() % 10) == 0 )
{
//LP_postutxos(coin->symbol,coin->smartaddr);
}
}
}
}

2
iguana/exchanges/install

@ -1,5 +1,5 @@
#!/bin/bash
cp 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 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/invreset

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
source passphrase
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"inventory\",\"coin\":\"KMD\",\"reset\":1,\"passphrase\":\"$passphrase\"}"

8
iguana/exchanges/mm.c

@ -19,11 +19,14 @@
// Copyright © 2017 SuperNET. All rights reserved.
//
void PNACL_message(char *arg,...)
{
}
#define FROM_MARKETMAKER
#include <stdio.h>
#include <stdint.h>
#ifndef NATIVE_WINDOWS
@ -32,7 +35,6 @@ void PNACL_message(char *arg,...)
#include "../../crypto777/OS_portable.h"
#endif // !_WIN_32
#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"
@ -74,7 +76,7 @@ struct mmpending_order
int32_t dir;
uint32_t pending,completed,canceled,cancelstarted,reported;
cJSON *errorjson;
char exchange[16],base[16],rel[16],orderid[64];
char exchange[16],base[65],rel[65],orderid[64];
} *Pending_orders;
int32_t Num_Pending;
@ -415,7 +417,7 @@ void marketmaker_pendingupdate(char *exchange,char *base,char *rel)
void marketmaker_pendinginit(char *exchange,char *base,char *rel)
{
char *retstr,*orderid,*pairstr,relbase[64]; cJSON *retjson,*array,*item; int32_t i,j,n,dir; struct mmpending_order *ptr;
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 )
{

8
iguana/exchanges/stats.c

@ -32,7 +32,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char
char *stats_validmethods[] =
{
"psock", "getprices", "listunspent", "notify", "getpeers", "uitem", // from issue_
"psock", "getprices", "notify", "getpeers", // from issue_ "uitem", "listunspent",
"orderbook", "help", "getcoins", "pricearray", "balance", "tradestatus"
};
@ -62,7 +62,7 @@ char CURRENCIES[][8] = { "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", // end of currencies
};
char ASSETCHAINS_SYMBOL[16] = { "KV" };
char ASSETCHAINS_SYMBOL[65] = { "KV" };
struct komodo_state
{
@ -529,7 +529,7 @@ char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *po
free(retstr);
}
#endif
//printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),cJSON_Print(json),*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);
@ -1090,7 +1090,7 @@ int32_t komodo_parsestatefile(FILE *logfp,struct komodo_state *sp,FILE *fp,char
int32_t stats_stateupdate(FILE *logfp,char *destdir,char *statefname,int32_t maxseconds,char *komodofile)
{
static long lastpos[2];
char symbol[64],base[64]; int32_t iter,n; FILE *fp; uint32_t starttime; struct komodo_state *sp;
char symbol[65],base[65]; int32_t iter,n; FILE *fp; uint32_t starttime; struct komodo_state *sp;
starttime = (uint32_t)time(NULL);
strcpy(base,"KV");
strcpy(symbol,"KV");

2
iguana/m_mm

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

3
includes/cJSON.h

@ -73,6 +73,7 @@ extern "C"
double valuedouble; /* The item's number, if type==cJSON_Number */
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
uint32_t cjsonid;
} cJSON;
typedef struct cJSON_Hooks {
@ -218,6 +219,8 @@ extern "C"
char *nxt64str2(uint64_t nxt64bits);
cJSON *addrs_jsonarray(uint64_t *addrs,int32_t num);
int32_t myatoi(char *str,int32_t range);
void cJSON_register(cJSON *item);
void cJSON_unregister(cJSON *item);
char *stringifyM(char *str);
#define replace_backslashquotes unstringify

8
marketmaker.vcxproj

@ -87,7 +87,7 @@
<WarningLevel>Level2</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_DEBUG;_CONSOLE;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StructMemberAlignment>1Byte</StructMemberAlignment>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
<AdditionalIncludeDirectories>.\iguana;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
@ -104,7 +104,7 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;NATIVE_WINDOWS;WIN32;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StructMemberAlignment>1Byte</StructMemberAlignment>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -122,7 +122,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StructMemberAlignment>1Byte</StructMemberAlignment>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
@ -142,7 +142,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN64;_WIN64;_CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StructMemberAlignment>1Byte</StructMemberAlignment>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>

82
marketmaker_build_32_64.cmd

@ -0,0 +1,82 @@
@echo off
@REM Check for Visual Studio
call set "VSPATH="
if defined VS140COMNTOOLS ( if not defined VSPATH (
call set "VSPATH=%%VS140COMNTOOLS%%"
) )
@REM check if we already have the tools in the environment
if exist "%VCINSTALLDIR%" (
goto compile
)
if not defined VSPATH (
echo You need Microsoft Visual Studio 15 installed
pause
exit
)
@REM set up the environment
if exist "%VSPATH%..\..\vc\vcvarsall.bat" (
call "%%VSPATH%%..\..\vc\vcvarsall.bat" amd64
goto compile
)
echo Unable to set up the environment
pause
exit
:compile
rem MSBuild /help
MSBuild marketmaker.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64
MSBuild marketmaker.sln /t:Rebuild /p:Configuration=Release /p:Platform=x86
rem Obtain version number and latest git commit number
FOR /F "tokens=* USEBACKQ" %%F IN (`find /i "LP_MAJOR_VERSION" "iguana\exchanges\LP_include.h"`) DO (
SET LP_MAJOR_VERSION_STR=%%F
)
FOR /F "tokens=* USEBACKQ" %%F IN (`find /i "LP_MINOR_VERSION" "iguana\exchanges\LP_include.h"`) DO (
SET LP_MINOR_VERSION_STR=%%F
)
FOR /F "tokens=* USEBACKQ" %%F IN (`find /i "LP_BUILD_NUMBER" "iguana\exchanges\LP_include.h"`) DO (
SET LP_BUILD_NUMBER_STR=%%F
)
for /f delims^=^"^ tokens^=2 %%a in ('echo %LP_MAJOR_VERSION_STR%') do (
set LP_MAJOR_VERSION=%%a
)
for /f delims^=^"^ tokens^=2 %%a in ('echo %LP_MINOR_VERSION_STR%') do (
set LP_MINOR_VERSION=%%a
)
for /f delims^=^"^ tokens^=2 %%a in ('echo %LP_BUILD_NUMBER_STR%') do (
set LP_BUILD_NUMBER=%%a
)
rem Check if git command exist and if does - receive latest GIT_COMMIT
git --version >nul 2>&1 && (
for /f "tokens=1" %%a in ('git rev-parse --short HEAD') do (
set GIT_COMMIT=_%%a
)
) || (
set GIT_COMMIT=
)
rem echo Marketmaker_%LP_MAJOR_VERSION%.%LP_MINOR_VERSION%_%LP_BUILD_NUMBER%%GIT_COMMIT%
rem Using to add in marketmaker_release.7z
set host=%COMPUTERNAME%
IF "%host%"=="VM-81" (
mkdir package_content\win32
mkdir package_content\win64
copy /y Release\marketmaker.exe package_content\win32
copy /y x64\Release\marketmaker.exe package_content\win64
echo Marketmaker_%LP_MAJOR_VERSION%.%LP_MINOR_VERSION%_%LP_BUILD_NUMBER%%GIT_COMMIT% > package_content\version.txt
cd package_content
"C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z win32\marketmaker.exe
"C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z win64\marketmaker.exe
"C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z version.txt
cd ..
rd package_content /s /q
)
Loading…
Cancel
Save