Browse Source

Merge pull request #463 from jl777/spvdex

electrum isnt slow
etomic
jl777 7 years ago
committed by GitHub
parent
commit
eb33114904
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      OSlibs/win/mingw.h
  2. 26
      iguana/dexscripts.win32/how_to_use.md
  3. 159
      iguana/exchanges/LP_cache.c
  4. 31
      iguana/exchanges/LP_include.h
  5. 18
      iguana/exchanges/LP_nativeDEX.c
  6. 42
      iguana/exchanges/LP_ordermatch.c
  7. 53
      iguana/exchanges/LP_socket.c
  8. 2
      iguana/exchanges/LP_tradebots.c
  9. 14
      iguana/exchanges/LP_transaction.c
  10. 17
      iguana/exchanges/LP_utxo.c
  11. 1
      marketmaker.vcxproj

19
OSlibs/win/mingw.h

@ -61,13 +61,18 @@
* @remarks - #if (defined(_M_X64) || defined(__amd64__)) && defined(WIN32)
* is equivalent to #if defined(_M_X64) as _M_X64 is defined for MSVC only
*/
#if !defined(_M_X64)
struct pollfd {
SOCKET fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
#endif
// [Decker] pollfs is already defined in winsock2.h
//#if !defined(_M_X64)
//struct pollfd {
//SOCKET fd; /* file descriptor */
//short events; /* requested events */
//short revents; /* returned events */
//};
//#endif
#if defined(_M_X64)
/*

26
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)
@ -22,3 +22,23 @@ Sample output of correct `2-getuserpass.cmd` usage is:
You should see your userpass on screen, and after it will automatically copied in userpass file. It's important to all other scripts to have this password in userpass file. If output of `2-getuserpass.cmd` is not same as showed on screen above - wait some seconds and run `2-getuserpass.cmd` again. Also make sure that you have allowed marketmaker to accept incoming connections in your Windows Firewall (first time launched system should automatically asked for it).
**4.** For using other scripts please refer to barterDEX API. Or **barterDEX API Summary by Category** document by *shossain*.
## F.A.Q. ##
**Q.** Is any simple way how i can display JSON results returned by all scripts, like orderbook and others, in human readable form?
**A.** Yes, you can use this service [JSON Editor Online](http://jsoneditoronline.org/), just copy and paste output of script in left column and see structured output in right.
**Q.** I see an output like this when i'm start `1-client.cmd` :
bind(0.0.0.0) port.7783 failed: No error sock.1468. errno.0
bind(0.0.0.0) port.7783 failed: No error sock.1516. errno.0
bind(0.0.0.0) port.7783 failed: No error sock.1444. errno.0
bind(0.0.0.0) port.7783 failed: No error sock.1484. errno.0
bind(0.0.0.0) port.7783 failed: No error sock.1412. errno.0
bind(0.0.0.0) port.7783 failed: No error sock.1524. errno.0
bind(0.0.0.0) port.7783 failed: No error sock.1008. errno.0
And nothing works.
**A.** Before run `1-client.cmd` make sure in Task Manager that you haven't already running `marketmaker.exe`. If have - kill this process via Task Manager or via command line command `taskkill /f /im taskkill.exe` .

159
iguana/exchanges/LP_cache.c

@ -35,43 +35,129 @@ cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *se
return(txobj);
}
cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len)
struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len,int32_t height,long fpos)
{
cJSON *txobj; struct LP_transaction *tx;
cJSON *txobj; bits256 spenttxid; int32_t i,spentvout,numvins,numvouts; cJSON *vout,*vin,*vins,*vouts; struct LP_transaction *tx; char str[65];
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
return(tx);
if ( (txobj= LP_transaction_fromdata(coin,txid,serialized,len)) != 0 )
{
if ( (tx= LP_transactionfind(coin,txid)) == 0 || tx->serialized == 0 )
vins = jarray(&numvins,txobj,"vin");
vouts = jarray(&numvouts,txobj,"vout");
tx = LP_transactionadd(coin,txid,height,numvouts,numvins);
tx->serialized = 0;
tx->fpos = fpos;
free(serialized);
tx->len = 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++)
{
txobj = LP_transactioninit(coin,txid,0,txobj);
LP_transactioninit(coin,txid,1,txobj);
tx = LP_transactionfind(coin,txid);
vout = jitem(vouts,i);
tx->outpoints[i].value = LP_value_extract(vout,0);
tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest");
LP_destaddr(tx->outpoints[i].coinaddr,vout);
//printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value));
LP_address_utxoadd("LP_create_transaction",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1);
}
if ( tx != 0 )
for (i=0; i<numvins; i++)
{
tx->serialized = serialized;
tx->len = len;
vin = jitem(vins,i);
spenttxid = jbits256(vin,"txid");
spentvout = jint(vin,"vout");
if ( i == 0 && bits256_nonz(spenttxid) == 0 )
continue;
if ( (tx= LP_transactionfind(coin,spenttxid)) != 0 )
{
if ( spentvout < tx->numvouts )
{
if ( tx->outpoints[spentvout].spendheight <= 0 )
{
tx->outpoints[spentvout].spendtxid = txid;
tx->outpoints[spentvout].spendvini = i;
tx->outpoints[spentvout].spendheight = height > 0 ? height : 1;
LP_address_utxoadd("LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1);
if ( 0 && strcmp(coin->symbol,"REVS") == 0 )
printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height);
}
} else printf("LP_transactioninit: %s spentvout.%d < numvouts.%d spendheight.%d\n",bits256_str(str,spenttxid),spentvout,tx->numvouts,tx->outpoints[spentvout].spendheight);
} //else printf("LP_transactioninit: couldnt find (%s) ht.%d %s\n",bits256_str(str,spenttxid),height,jprint(vin,0));
if ( bits256_cmp(spenttxid,txid) == 0 )
printf("spending same tx's %p vout ht.%d %s.[%d] s%d\n",tx,height,bits256_str(str,txid),tx!=0?tx->numvouts:0,spentvout);
}
else
free_json(txobj);
}
return(tx);
}
void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height)
{
FILE *fp; char fname[512]; struct LP_transaction *tx = 0;
if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 && tx->fpos == 0 )
{
sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname);
if ( (fp= OS_appendfile(fname)) != 0 )
{
char str[65]; printf("unexpected couldnt find tx %s %s\n",coin->symbol,bits256_str(str,txid));
free(serialized);
fwrite(&tx->txid,1,sizeof(tx->txid),fp);
fwrite(&tx->len,1,sizeof(tx->len),fp);
fwrite(&tx->height,1,sizeof(tx->height),fp);
tx->fpos = ftell(fp);
fwrite(tx->serialized,1,tx->len,fp);
fclose(fp);
}
}
return(txobj);
} //else printf("cant store %s %s tx.%p [%d] fpos.%ld SPV.%d\n",coin->symbol,bits256_str(str,txid),tx,tx!=0?tx->len:-1,tx!=0?tx->fpos:-1,tx!=0?tx->SPV:-1);
}
int32_t LP_SPV_load(struct iguana_info *coin,bits256 txid,int32_t height)
int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp)
{
bits256 txid,hash; long fpos; int32_t offset,retval,height,len; uint8_t *serialized; char str[65],str2[65];
fpos = ftell(fp);
if ( fread(&txid,1,sizeof(txid),fp) == sizeof(txid) && fread(&len,1,sizeof(len),fp) == sizeof(len) && fread(&height,1,sizeof(height),fp) == sizeof(height) && len < 100000 )
{
offset = (int32_t)(sizeof(txid) + sizeof(len) + sizeof(height));
serialized = malloc(len);
if ( (retval= (int32_t)fread(serialized,1,len,fp)) == len )
{
hash = bits256_doublesha256(0,serialized,len);
if ( bits256_cmp(hash,txid) == 0 )
{
//printf("%s validated in cache\n",bits256_str(str,hash));
LP_create_transaction(coin,txid,serialized,len,height,fpos+offset);
return((int32_t)(ftell(fp) - fpos));
}
printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,txid));
} else printf("retval.%d vs len.%d\n",retval,len);
} else printf("fread error\n");
return(-1);
}
void LP_SPV_store(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t height)
void LP_cacheptrs_init(struct iguana_info *coin)
{
struct LP_transaction *tx = 0;
if ( strcmp(coin->smartaddr,coinaddr) == 0 && (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 )
char fname[1024]; FILE *fp; int32_t count,tflag=0; long n,fsize=0,len = 0;
sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname);
fp = fopen(fname,"rb");
count = 0;
if ( fp != 0 )
{
//char str[65]; printf("store %s %s.[%d]\n",coin->symbol,bits256_str(str,txid),tx->len);
} //else printf("skip SPV store for (%s) tx.%p\n",coinaddr,tx);
fseek(fp,0,SEEK_END);
fsize = ftell(fp);
rewind(fp);
while ( len < fsize )
{
if ( (n= LP_cacheitem(coin,fp)) < 0 )
{
printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize);
tflag = 1;
break;
}
count++;
len += n;
}
printf("loaded %s %d entries total len.%ld\n",fname,count,len);
fclose(fp);
} //else printf("couldnt find.(%s)\n",fname);
if ( tflag != 0 )
OS_truncate(fname,len);
}
bits256 iguana_merkle(bits256 *tree,int32_t txn_count)
@ -142,11 +228,22 @@ bits256 LP_merkleroot(struct iguana_info *coin,struct electrum_info *ep,int32_t
return(merkleroot);
}
int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height)
int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 txid,int32_t height)
{
cJSON *merkobj,*merkles; bits256 roothash,merkleroot; int32_t retval,m,SPV = 0;
if ( strcmp(coin->smartaddr,coinaddr) == 0 && (retval= LP_SPV_load(coin,txid,height)) > 0 )
return(retval);
struct LP_transaction *tx=0; cJSON *merkobj,*merkles,*retjson; bits256 roothash,merkleroot; int32_t m,SPV = 0;
if ( height < 0 )
return(0);
if ( (tx= LP_transactionfind(coin,txid)) == 0)
{
if ( (retjson= electrum_transaction(coin->symbol,ep,&retjson,txid)) != 0 )
free_json(retjson);
}
if ( tx != 0 )
{
tx->height = height;
if ( tx->SPV > 0 )
return(tx->SPV);
}
if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 )
{
char str[65],str2[65],str3[65];
@ -161,8 +258,18 @@ int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_i
if ( bits256_cmp(merkleroot,roothash) == 0 )
{
SPV = height;
LP_SPV_store(coin,coinaddr,txid,height);
//printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,up->U.txid),up->U.height,jprint(merkobj,0),bits256_str(str2,roothash));
LP_SPV_store(coin,txid,height);
if ( tx != 0 )
{
tx->SPV = height;
if ( tx->serialized != 0 )
{
free(tx->serialized);
tx->serialized = 0;
tx->len = 0;
}
}
//printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash));
}
else 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;

31
iguana/exchanges/LP_include.h

@ -37,6 +37,7 @@ void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping
#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 30
#define ELECTRUM_TIMEOUT 7
@ -239,12 +240,20 @@ struct LP_swap_remember
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)];
};
struct LP_outpoint { bits256 spendtxid; uint64_t value,interest; int32_t spendvini,spendheight; char coinaddr[64]; };
struct LP_outpoint
{
bits256 spendtxid;
uint64_t value,interest;
int32_t spendvini,spendheight;
char coinaddr[64];
};
struct LP_transaction
{
UT_hash_handle hh;
bits256 txid; int32_t height,numvouts,numvins,len; //uint32_t timestamp;
bits256 txid;
long fpos;
int32_t height,numvouts,numvins,len,SPV;
uint8_t *serialized;
struct LP_outpoint outpoints[];
};
@ -255,7 +264,7 @@ struct iguana_info
portable_mutex_t txmutex,addrmutex; struct LP_transaction *transactions; struct LP_address *addresses;
uint64_t txfee;
int32_t numutxos,longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport;
uint32_t electrumlist,lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime;
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];
// portfolio
@ -363,6 +372,19 @@ struct LP_pubkeyinfo
uint8_t rmd160[20],sig[65],pubsecp[33],siglen;
};
struct electrum_info
{
queue_t sendQ,pendingQ;
portable_mutex_t mutex,txmutex;
struct electrum_info *prev;
int32_t bufsize,sock,*heightp,numerrors;
struct iguana_info *coin;
uint32_t stratumid,lasttime,keepalive,pending,*heighttimep;
char ipaddr[64],symbol[16];
uint16_t port;
uint8_t buf[];
};
int32_t LP_pubkey_sigcheck(struct LP_pubkeyinfo *pubp,cJSON *item);
int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp);
int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson);
@ -402,6 +424,8 @@ int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,cha
struct iguana_info *LP_coinfind(char *symbol);
int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32);
char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price);
int32_t LP_merkleproof(struct iguana_info *coin,struct electrum_info *ep,bits256 txid,int32_t height);
struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins);
void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid);
uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen);
struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr);
@ -424,6 +448,7 @@ 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);
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);
cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout);
void LP_postutxos(char *symbol,char *coinaddr);

18
iguana/exchanges/LP_nativeDEX.c

@ -467,7 +467,7 @@ void utxosQ_loop(void *myipaddr)
void LP_coinsloop(void *_coins)
{
struct LP_address *ap=0; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t oldht,j,nonz; char *coins = _coins;
struct LP_address *ap=0,*atmp; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t oldht,j,nonz; char *coins = _coins;
if ( strcmp("BTC",coins) == 0 )
{
strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop");
@ -515,18 +515,26 @@ void LP_coinsloop(void *_coins)
{
if ( (backupep= ep->prev) == 0 )
backupep = ep;
//HASH_ITER(hh,coin->addresses,ap,atmp)
if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 )
{
DL_FOREACH_SAFE(ap->utxos,up,tmp)
{
break;
if ( up->U.height > 0 && up->spendheight < 0 )
{
if ( up->SPV == 0 )
{
nonz++;
up->SPV = LP_merkleproof(coin,ap->coinaddr,backupep,up->U.txid,up->U.height);
if ( 0 && up->SPV > 0 )
printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV);
up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height);
if ( up->SPV > 0 )
{
if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && tx->SPV == 0 )
{
tx->SPV = up->SPV;
//printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV);
}
}
}
else if ( up->SPV == -1 )
{
@ -535,7 +543,7 @@ void LP_coinsloop(void *_coins)
oldht = up->U.height;
LP_txheight_check(coin,ap->coinaddr,up);
if ( oldht != up->U.height )
up->SPV = LP_merkleproof(coin,ap->coinaddr,backupep,up->U.txid,up->U.height);
up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height);
if ( up->SPV <= 0 )
up->SPV = -2;
else printf("%s %s: corrected SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV);

42
iguana/exchanges/LP_ordermatch.c

@ -647,7 +647,7 @@ int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout)
return(-1);
if ( (backupep= ep->prev) == 0 )
backupep = ep;
up->SPV = LP_merkleproof(coin,coinaddr,backupep,up->U.txid,up->U.height);
up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height);
if ( up->SPV <= 0 )
return(-1);
}
@ -666,30 +666,20 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
LP_tradecommand_log(argjson);
//printf("LP_tradecommand: check received method %s aliceid.%llx\n",method,(long long)Q.aliceid);
retval = 1;
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));
return(retval);
}
else if (LP_validSPV(Q.destcoin,Q.destaddr,Q.feetxid,Q.feevout) < 0 )
{
printf("%s dexfee %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.feetxid));
return(retval);
}
if ( strcmp(method,"reserved") == 0 )
{
if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 )
{
printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid));
return(retval);
}
else if (LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 )
{
printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2));
return(retval);
}
if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 && LP_alice_eligible() > 0 )
{
if ( LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid,Q.vout) < 0 )
{
printf("%s src %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid));
return(retval);
}
else if (LP_validSPV(Q.srccoin,Q.coinaddr,Q.txid2,Q.vout2) < 0 )
{
printf("%s src2 %s failed SPV check\n",Q.srccoin,bits256_str(str,Q.txid2));
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 )
@ -725,6 +715,16 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin);
return(retval);
}
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));
return(retval);
}
else if (LP_validSPV(Q.destcoin,Q.destaddr,Q.feetxid,Q.feevout) < 0 )
{
printf("%s dexfee %s failed SPV check\n",Q.destcoin,bits256_str(str,Q.feetxid));
return(retval);
}
price = ask;
/*if ( coin->electrum != 0 )
{

53
iguana/exchanges/LP_socket.c

@ -238,18 +238,7 @@ int32_t LP_socketrecv(int32_t sock,uint8_t *recvbuf,int32_t maxlen)
return(recvlen);
}
struct electrum_info
{
queue_t sendQ,pendingQ;
portable_mutex_t mutex,txmutex;
struct electrum_info *prev;
int32_t bufsize,sock,*heightp,numerrors;
struct iguana_info *coin;
uint32_t stratumid,lasttime,keepalive,pending,*heighttimep;
char ipaddr[64],symbol[16];
uint16_t port;
uint8_t buf[];
} *Electrums[8192];
struct electrum_info *Electrums[8192];
int32_t Num_electrums;
struct electrum_info *electrum_server(char *symbol,struct electrum_info *ep)
@ -338,7 +327,11 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep
if (tx->height <= 0 )
{
tx->height = ht;
//printf("%s %s >>>>>>>>>> set %s <- height %d\n",coin->symbol,coinaddr,bits256_str(str,txid),tx->height);
if ( ep != 0 && coin != 0 && tx->SPV == 0 )
{
tx->SPV = LP_merkleproof(coin,ep,txid,tx->height);
//printf("%s %s >>>>>>>>>> set %s <- height %d\n",coin->symbol,coinaddr,bits256_str(str,txid),tx->height);
}
}
if ( v >= 0 && v < tx->numvouts )
{
@ -607,7 +600,7 @@ cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON
{
if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 )
{
//if ( 0 && electrumflag > 1 )
if ( 0 && electrumflag > 1 )
printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0)));
updatedflag = 0;
if ( electrum_process_array(coin,ep,addr,retjson,electrumflag) != 0 )
@ -662,6 +655,31 @@ cJSON *electrum_getheader(char *symbol,struct electrum_info *ep,cJSON **retjsonp
return(electrum_intarg(symbol,ep,retjsonp,"blockchain.block.get_header",n,ELECTRUM_TIMEOUT));
}
cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len)
{
cJSON *txobj; struct LP_transaction *tx;
if ( (txobj= LP_transaction_fromdata(coin,txid,serialized,len)) != 0 )
{
if ( (tx= LP_transactionfind(coin,txid)) == 0 || tx->serialized == 0 )
{
txobj = LP_transactioninit(coin,txid,0,txobj);
LP_transactioninit(coin,txid,1,txobj);
tx = LP_transactionfind(coin,txid);
}
if ( tx != 0 )
{
tx->serialized = serialized;
tx->len = len;
}
else
{
char str[65]; printf("unexpected couldnt find tx %s %s\n",coin->symbol,bits256_str(str,txid));
free(serialized);
}
}
return(txobj);
}
cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid)
{
char *hexstr,str[65]; int32_t len; cJSON *hexjson,*txobj=0; struct iguana_info *coin; uint8_t *serialized; struct LP_transaction *tx;
@ -1029,10 +1047,15 @@ cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port)
}
else
{
printf("launched %s electrum.(%s:%u)\n",coin->symbol,ep->ipaddr,ep->port);
//printf("launched %s electrum.(%s:%u)\n",coin->symbol,ep->ipaddr,ep->port);
jaddstr(retjson,"result","success");
ep->prev = coin->electrum;
coin->electrum = ep;
if ( coin->loadedcache == 0 )
{
LP_cacheptrs_init(coin);
coin->loadedcache = (uint32_t)time(NULL);
}
}
}
else

2
iguana/exchanges/LP_tradebots.c

@ -99,7 +99,7 @@ void LP_tradebot_calcstats(struct LP_tradebot *bot)
}
//LP_tradebot_updatestats(bot,bot->trades[i]);
}
printf("completed.%d (%.8f / %.8f) pending.%d (%.8f / %.8f)\n",bot->completed,bot->basesum,bot->relsum,bot->numpending,bot->pendbasesum,bot->pendrelsum);
//printf("completed.%d (%.8f / %.8f) pending.%d (%.8f / %.8f)\n",bot->completed,bot->basesum,bot->relsum,bot->numpending,bot->pendbasesum,bot->pendrelsum);
}
double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume)

14
iguana/exchanges/LP_transaction.c

@ -247,7 +247,10 @@ int32_t iguana_msgtx_Vset(uint8_t *serialized,int32_t maxlen,struct iguana_msgtx
int32_t iguana_interpreter(struct iguana_info *coin,cJSON *logarray,int64_t nLockTime,struct vin_info *V,int32_t numvins)
{
uint8_t script[IGUANA_MAXSCRIPTSIZE],*activescript,savescript[IGUANA_MAXSCRIPTSIZE]; char str[IGUANA_MAXSCRIPTSIZE*2+1]; int32_t vini,scriptlen,activescriptlen,savelen,errs = 0; cJSON *spendscript,*item=0;
uint8_t *script,*activescript,*savescript; char *str; int32_t vini,scriptlen,activescriptlen,savelen,errs = 0; cJSON *spendscript,*item=0;
script = calloc(1,IGUANA_MAXSCRIPTSIZE);
savescript = calloc(1,IGUANA_MAXSCRIPTSIZE);
str = calloc(1,IGUANA_MAXSCRIPTSIZE*2+1);
for (vini=0; vini<numvins; vini++)
{
savelen = V[vini].spendlen;
@ -297,6 +300,9 @@ int32_t iguana_interpreter(struct iguana_info *coin,cJSON *logarray,int64_t nLoc
memcpy(V[vini].spendscript,savescript,savelen);
V[vini].spendlen = savelen;
}
free(str);
free(script);
free(savescript);
if ( errs != 0 )
return(-errs);
if ( logarray != 0 )
@ -475,7 +481,7 @@ int64_t iguana_lockval(int32_t finalized,int64_t locktime)
int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson,int32_t zcash)
{
uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; bits256 privkeys[64],privkey,txid; cJSON *item; cJSON *txobj = 0;
uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; bits256 privkeys[LP_MAXVINS],privkey,txid; cJSON *item; cJSON *txobj = 0;
maxsize = 1000000;
memset(privkey.bytes,0,sizeof(privkey));
if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize )
@ -996,7 +1002,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_info *coin,struct vin_info *V,int32_t max,bits256 privkey,cJSON *outputs,cJSON *vins,cJSON *privkeys,int64_t txfee,bits256 utxotxid,int32_t utxovout,uint32_t locktime)
{
static void *ctx;
cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[1024]; struct LP_address *ap;
cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS]; struct LP_address *ap;
if ( ctx == 0 )
ctx = bitcoin_ctx();
*numvinsp = 0;
@ -1135,7 +1141,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
safecopy(changeaddr,coin->smartaddr,sizeof(changeaddr));
safecopy(vinaddr,coin->smartaddr,sizeof(vinaddr));
privkey = LP_privkey(vinaddr,coin->taddr);
maxV = 1024;
maxV = LP_MAXVINS;
V = malloc(maxV * sizeof(*V));
for (iter=0; iter<2; iter++)
{

17
iguana/exchanges/LP_utxo.c

@ -237,7 +237,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)
{
struct LP_address *ap; cJSON *txobj; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; char str[65];
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 )
return(0);
if ( spendheight > 0 ) // dont autocreate entries for spends we dont care about
@ -282,8 +282,11 @@ int32_t LP_address_utxoadd(char *debug,struct iguana_info *coin,char *coinaddr,b
DL_APPEND(ap->utxos,up);
portable_mutex_unlock(&coin->addrmutex);
retval = 1;
if ( value == 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));
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));
}
}
} // else printf("cant get ap %s %s\n",coin->symbol,coinaddr);
//printf("done %s add addr.%s ht.%d\n",coin->symbol,coinaddr,height);
@ -529,13 +532,15 @@ struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid)
struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins)
{
struct LP_transaction *tx; int32_t i;
static long totalsize;
struct LP_transaction *tx; int32_t i; //char str[65];
if ( (tx= LP_transactionfind(coin,txid)) == 0 )
{
//char str[65]; printf("%s ht.%d u.%u NEW TXID.(%s) vouts.[%d]\n",coin->symbol,height,timestamp,bits256_str(str,txid),numvouts);
//if ( bits256_nonz(txid) == 0 && tx->height == 0 )
// getchar();
tx = calloc(1,sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts));
totalsize += sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts);
//char str[65]; printf("%s ht.%d NEW TXID.(%s) vouts.[%d] size.%ld total %ld\n",coin->symbol,height,bits256_str(str,txid),numvouts,sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts),totalsize);
for (i=0; i<numvouts; i++)
tx->outpoints[i].spendvini = -1;
tx->height = height;
@ -546,7 +551,7 @@ struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,i
portable_mutex_lock(&coin->txmutex);
HASH_ADD_KEYPTR(hh,coin->transactions,tx->txid.bytes,sizeof(tx->txid),tx);
portable_mutex_unlock(&coin->txmutex);
} // else printf("warning adding already existing txid %s\n",bits256_str(str,tx->txid));
} //else printf("warning adding already existing txid %s\n",bits256_str(str,tx->txid));
return(tx);
}

1
marketmaker.vcxproj

@ -130,6 +130,7 @@
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Ws2_32.lib;Advapi32.lib;$(SolutionDir)OSlibs\win\release\pthreadVC2.lib;libcurl.lib;nanomsg.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

Loading…
Cancel
Save