Browse Source

Merge branch 'spvdex' of https://github.com/jl777/SuperNET into dev-decker-spvdex

etomic
DeckerSU 7 years ago
parent
commit
df1b5937c1
  1. 4
      basilisk/basilisk_bitcoin.c
  2. 3
      iguana/dPoW.h
  3. 7
      iguana/dpow/dpow_fsm.c
  4. 10
      iguana/dpow/dpow_network.c
  5. 16
      iguana/dpow/dpow_rpc.c
  6. 67
      iguana/exchanges/LP_commands.c
  7. 3
      iguana/exchanges/LP_include.h
  8. 86
      iguana/exchanges/LP_nativeDEX.c
  9. 31
      iguana/exchanges/LP_network.c
  10. 55
      iguana/exchanges/LP_ordermatch.c
  11. 108
      iguana/exchanges/LP_portfolio.c
  12. 7
      iguana/exchanges/LP_prices.c
  13. 77
      iguana/exchanges/LP_remember.c
  14. 16
      iguana/exchanges/LP_rpc.c
  15. 23
      iguana/exchanges/LP_socket.c
  16. 42
      iguana/exchanges/LP_transaction.c
  17. 62
      iguana/exchanges/LP_utxo.c
  18. 3
      iguana/exchanges/LP_utxos.c
  19. 89
      iguana/exchanges/assetchains.old
  20. 10
      iguana/exchanges/autoprice
  21. 1
      iguana/exchanges/enable
  22. 1
      iguana/exchanges/profile
  23. 3
      iguana/exchanges/recentswaps
  24. 3
      iguana/exchanges/stop
  25. 2
      iguana/iguana777.h
  26. 28
      iguana/iguana_mofn.c
  27. 138
      iguana/iguana_notary.c
  28. 2
      iguana/m_mm
  29. 1
      iguana/m_splitfund
  30. 8
      iguana/main.c

4
basilisk/basilisk_bitcoin.c

@ -602,7 +602,7 @@ char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coi
free_json(vins);
return(rawtx);
}
printf("splitfunds tx.(%s) vins.(%s)\n",rawtx,jprint(vins,0));
printf("%s splitfunds tx.(%s) vins.(%s)\n",coin->symbol,rawtx,jprint(vins,0));
if ( signedtxidp != 0 )
{
if ( (signedtx= iguana_signrawtx(myinfo,coin,0,signedtxidp,completedp,vins,rawtx,0,0)) != 0 )
@ -615,7 +615,7 @@ char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coi
free(rawtx);
rawtx = signedtx, signedtx = 0;
}
} else printf("error signing raw utxoduplicates tx\n");
} else printf("error signing raw %s utxoduplicates tx\n",coin->symbol);
}
}
if ( vins != 0 )

3
iguana/dPoW.h

@ -20,6 +20,7 @@
#define DPOW_CHECKPOINTFREQ 10
#define DPOW_MINSIGS 13
#define DPOW_MIN_ASSETCHAIN_SIGS 11
//#define DPOW_M(bp) ((bp)->minsigs) // (((bp)->numnotaries >> 1) + 1)
#define DPOW_MODIND(bp,offset) (((((bp)->height / DPOW_CHECKPOINTFREQ) % (bp)->numnotaries) + (offset)) % (bp)->numnotaries)
#define DPOW_VERSION 0x0781
@ -132,7 +133,7 @@ struct dpow_info
char symbol[16],dest[16]; uint8_t minerkey33[33],minerid; uint64_t lastrecvmask;
struct dpow_checkpoint checkpoint,last,destchaintip,srcfifo[DPOW_FIFOSIZE],destfifo[DPOW_FIFOSIZE];
struct dpow_hashheight approved[DPOW_FIFOSIZE],notarized[DPOW_FIFOSIZE];
bits256 srctx[DPOW_MAXTX],desttx[DPOW_MAXTX];
bits256 activehash,lastnotarized,srctx[DPOW_MAXTX],desttx[DPOW_MAXTX];
uint32_t SRCREALTIME,destupdated,srcconfirms,numdesttx,numsrctx,lastsplit,cancelratify;
int32_t lastheight,maxblocks,SRCHEIGHT,SHORTFLAG,ratifying;
struct pax_transaction *PAX;

7
iguana/dpow/dpow_fsm.c

@ -326,7 +326,7 @@ void dpow_statemachinestart(void *ptr)
return;
}
bp->myind = myind;
printf("[%d] statemachinestart %s->%s %s ht.%d minsigs.%d duration.%d start.%u\n",bp->myind,dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height,minsigs,duration,checkpoint.timestamp);
printf("[%d] notarize %s->%s %s ht.%d minsigs.%d duration.%d start.%u\n",bp->myind,dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height,minsigs,duration,checkpoint.timestamp);
if ( bp->isratify != 0 && memcmp(bp->notaries[0].pubkey,bp->ratified_pubkeys[0],33) != 0 )
{
for (i=0; i<33; i++)
@ -447,6 +447,11 @@ void dpow_statemachinestart(void *ptr)
dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,0,bp->height,(void *)"ping",0);
dpow_nanomsg_update(myinfo);
}
else
{
dp->lastnotarized = bp->srctxid;
printf("notarized %s %s\n",dp->symbol,bits256_str(str,bp->srctxid));
}
if ( 0 && dp->cancelratify != 0 && bp->isratify != 0 )
{
printf("abort pending ratify\n");

10
iguana/dpow/dpow_network.c

@ -170,7 +170,7 @@ int32_t signed_nn_recv(void **freeptrp,struct supernet_info *myinfo,uint8_t nota
vcalc_sha256(0,packethash.bytes,(void *)&sigpacket->nonce,(int32_t)(sigpacket->packetlen+sizeof(sigpacket->nonce)+sizeof(sigpacket->packetlen)));
if ( bits256_cmp(packethash,sigpacket->packethash) == 0 && sigpacket->packethash.bytes[0] == 0 )
{
if ( bitcoin_recoververify(myinfo->ctx,"nnrecv",sigpacket->sig64,sigpacket->packethash,pubkey33,33) == 0 )
if ( bitcoin_recoververify(myinfo->ctx[1],"nnrecv",sigpacket->sig64,sigpacket->packethash,pubkey33,33) == 0 )
{
char *notary0 = "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828";
// expand to official notaries
@ -2020,7 +2020,7 @@ void dpow_send(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_blo
pfd.events = NN_POLLOUT;
if ( nn_poll(&pfd,1,100) > 0 )
{
sentbytes = signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->dpowsock,np,size);
sentbytes = signed_nn_send(myinfo,myinfo->ctx[2],myinfo->persistent_priv,myinfo->dpowsock,np,size);
break;
}
usleep(1000);
@ -2168,13 +2168,13 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo)
//printf("REP got %d crc.%08x\n",size,calc_crc32(0,(void *)dexp,size));
if ( (retstr= dex_response(&broadcastflag,myinfo,dexp)) != 0 )
{
signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->repsock,retstr,(int32_t)strlen(retstr)+1);
signed_nn_send(myinfo,myinfo->ctx[3],myinfo->persistent_priv,myinfo->repsock,retstr,(int32_t)strlen(retstr)+1);
//printf("send back[%ld]\n",strlen(retstr)+1);
free(retstr);
if ( broadcastflag != 0 )
{
printf("BROADCAST dexp request.[%d]\n",size);
signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->dexsock,dexp,size);
signed_nn_send(myinfo,myinfo->ctx[4],myinfo->persistent_priv,myinfo->dexsock,dexp,size);
//signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->pubsock,dexp,size);
}
}
@ -2183,7 +2183,7 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo)
if ( (m= myinfo->numdpowipbits) > 0 )
{
r = myinfo->dpowipbits[rand() % m];
signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->repsock,&r,sizeof(r));
signed_nn_send(myinfo,myinfo->ctx[5],myinfo->persistent_priv,myinfo->repsock,&r,sizeof(r));
printf("REP.%08x <- rand ip m.%d %x\n",dexp->crc32,m,r);
} else printf("illegal state without dpowipbits?\n");
if ( dex_packetcheck(myinfo,dexp,size) == 0 )

16
iguana/dpow/dpow_rpc.c

@ -177,7 +177,7 @@ bits256 dpow_getbestblockhash(struct supernet_info *myinfo,struct iguana_info *c
memset(blockhash.bytes,0,sizeof(blockhash));
if ( coin->FULLNODE < 0 )
{
if ( coin->lastbesthashtime+20 > time(NULL) && bits256_nonz(coin->lastbesthash) != 0 )
if ( coin->lastbesthashtime+2 > time(NULL) && bits256_nonz(coin->lastbesthash) != 0 )
return(coin->lastbesthash);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getbestblockhash","")) != 0 )
{
@ -1154,10 +1154,11 @@ void dpow_issuer_voutupdate(struct dpow_info *dp,char *symbol,int32_t isspecial,
}
}
int32_t dpow_issuer_tx(struct dpow_info *dp,struct iguana_info *coin,int32_t height,int32_t txi,char *txidstr,uint32_t port)
int32_t dpow_issuer_tx(int32_t *isspecialp,struct dpow_info *dp,struct iguana_info *coin,int32_t height,int32_t txi,char *txidstr,uint32_t port)
{
char *retstr,params[256],*hexstr; uint8_t script[16384]; cJSON *json,*oldpub,*newpub,*result,*vouts,*item,*sobj; int32_t vout,n,len,isspecial,retval = -1; uint64_t value; bits256 txid;
char *retstr,params[256],*hexstr; uint8_t script[16384]; cJSON *json,*oldpub,*newpub,*result,*vouts,*item,*sobj; int32_t vout,n,len,retval = -1; uint64_t value; bits256 txid;
sprintf(params,"[\"%s\", 1]",txidstr);
*isspecialp = 0;
if ( (retstr= dpow_issuemethod(coin->chain->userpass,(char *)"getrawtransaction",params,port)) != 0 )
{
if ( (json= cJSON_Parse(retstr)) != 0 )
@ -1170,7 +1171,6 @@ int32_t dpow_issuer_tx(struct dpow_info *dp,struct iguana_info *coin,int32_t hei
retval = 0;
if ( oldpub == 0 && newpub == 0 && (vouts= jarray(&n,result,(char *)"vout")) != 0 )
{
isspecial = 0;
txid = jbits256(result,(char *)"txid");
for (vout=0; vout<n; vout++)
{
@ -1182,11 +1182,11 @@ int32_t dpow_issuer_tx(struct dpow_info *dp,struct iguana_info *coin,int32_t hei
{
len = (int32_t)strlen(hexstr) >> 1;
if ( vout == 0 && ((memcmp(&hexstr[2],CRYPTO777_PUBSECPSTR,66) == 0 && len == 35) || (memcmp(&hexstr[6],CRYPTO777_RMD160STR,40) == 0 && len == 25)) )
isspecial = 1;
*isspecialp = 1;
else if ( len <= sizeof(script) )
{
decode_hex(script,len,hexstr);
dpow_issuer_voutupdate(dp,coin->symbol,isspecial,height,txi,txid,vout,n,value,script,len);
dpow_issuer_voutupdate(dp,coin->symbol,*isspecialp,height,txi,txid,vout,n,value,script,len);
}
}
}
@ -1202,7 +1202,7 @@ int32_t dpow_issuer_tx(struct dpow_info *dp,struct iguana_info *coin,int32_t hei
int32_t dpow_issuer_block(struct dpow_info *dp,struct iguana_info *coin,int32_t height,uint16_t port)
{
char *retstr,*retstr2,params[128],*txidstr; int32_t i,n,retval = -1; cJSON *json,*tx=0,*result=0,*result2;
char *retstr,*retstr2,params[128],*txidstr; int32_t i,isspecial,n,retval = -1; cJSON *json,*tx=0,*result=0,*result2;
sprintf(params,"[%d]",height);
if ( (retstr= dpow_issuemethod(coin->chain->userpass,(char *)"getblockhash",params,port)) != 0 )
{
@ -1219,7 +1219,7 @@ int32_t dpow_issuer_block(struct dpow_info *dp,struct iguana_info *coin,int32_t
if ( (result2= jobj(json,(char *)"result")) != 0 && (tx= jarray(&n,result2,(char *)"tx")) != 0 )
{
for (i=0; i<n; i++)
if ( dpow_issuer_tx(dp,coin,height,i,jstri(tx,i),port) < 0 )
if ( dpow_issuer_tx(&isspecial,dp,coin,height,i,jstri(tx,i),port) < 0 )
break;
if ( i == n )
retval = 0;

67
iguana/exchanges/LP_commands.c

@ -97,7 +97,7 @@ char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *r
available localhost RPC commands: * means it needs to be a signed request\n \
pricearray(base, rel, firsttime=0, lasttime=-1, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\
setprice(base, rel, price)*\n\
autoprice(base, rel, price, margin, type)*\n\
autoprice(base, rel, minprice, margin, refbase, refrel, factor, offset)*\n\
goal(coin=*, val=<autocalc>)*\n\
myprice(base, rel)\n\
enable(coin)*\n\
@ -110,6 +110,7 @@ sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)*\n\
withdraw(coin, outputs[])*\n\
sendrawtransaction(coin, signedtx)\n\
swapstatus()*\n\
recentswaps(limit=3)\n\
swapstatus(requestid, quoteid)*\n\
public API:\n \
getcoins()\n\
@ -123,14 +124,15 @@ trust(pubkey, trust)*\n\
balance(coin, address)\n\
orderbook(base, rel, duration=3600)\n\
getprices(base, rel)\n\
sendmessage(base=coin, rel="", pubkey=zero, <argjson method2>)*\n\
getmessages(firsti=0, num=100)*\n\
deletemessages(firsti=0, num=100)*\n\
sendmessage(base=coin, rel="", pubkey=zero, <argjson method2>)\n\
getmessages(firsti=0, num=100)\n\
deletemessages(firsti=0, num=100)\n\
secretaddresses(prefix='secretaddress', passphrase, num=10, pubtype=60, taddr=0)\n\
electrum(coin, ipaddr, port)*\n\
snapshot(coin, height)\n\
snapshot_balance(coin, height, addresses[])\n\
dividends(coin, height, <args>)\n\
stop()\n\
\"}"));
//sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\
@ -153,24 +155,29 @@ dividends(coin, height, <args>)\n\
jdelete(argjson,"userpass");
if ( strcmp(method,"sendmessage") == 0 )
{
//*
if ( jobj(argjson,"method2") == 0 )
{
printf("broadcast message\n");
LP_broadcast_message(LP_mypubsock,base!=0?base:jstr(argjson,"coin"),rel,jbits256(argjson,"pubkey"),jprint(argjson,0));
}
return(clonestr("{\"result\":\"success\"}"));
}
else if ( strcmp(method,"recentswaps") == 0 )
{
return(LP_recent_swaps(jint(argjson,"limit")));
}
else if ( strcmp(method,"stop") == 0 )
{
printf("DEBUG stop\n");
exit(0);
}
else if ( strcmp(method,"getmessages") == 0 )
{
//*
if ( (retjson= LP_getmessages(jint(argjson,"firsti"),jint(argjson,"num"))) != 0 )
return(jprint(retjson,1));
else return(clonestr("{\"error\":\"null messages\"}"));
}
else if ( strcmp(method,"deletemessages") == 0 )
{
//*
LP_deletemessages(jint(argjson,"firsti"),jint(argjson,"num"));
return(clonestr("{\"result\":\"success\"}"));
}
@ -205,9 +212,9 @@ dividends(coin, height, <args>)\n\
price = jdouble(argjson,"price");
if ( strcmp(method,"setprice") == 0 )
{
//*
if ( price > SMALLVAL )
{
//LP_signature_add(argjson,base,rel,(uint64_t)price * SATOSHIDEN);
if ( LP_mypriceset(&changed,base,rel,price) < 0 )
return(clonestr("{\"error\":\"couldnt set price\"}"));
//else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 )
@ -217,8 +224,8 @@ dividends(coin, height, <args>)\n\
}
else if ( strcmp(method,"autoprice") == 0 )
{
//*
if ( LP_autoprice(base,rel,price,jdouble(argjson,"margin"),jstr(argjson,"type")) < 0 )
//LP_signature_add(argjson,base,rel,(uint64_t)price * SATOSHIDEN);
if ( LP_autoprice(base,rel,argjson) < 0 )
return(clonestr("{\"error\":\"couldnt set autoprice\"}"));
else return(clonestr("{\"result\":\"success\"}"));
}
@ -269,18 +276,32 @@ dividends(coin, height, <args>)\n\
//*
if ( (ptr= LP_coinsearch(coin)) != 0 )
{
if ( ptr->userpass[0] == 0 )
{
cJSON *retjson = cJSON_CreateObject();
jaddstr(retjson,"error","couldnt find coin locally installed");
jaddstr(retjson,"coin",coin);
return(jprint(retjson,1));
}
if ( LP_conflicts_find(ptr) == 0 )
{
ptr->inactive = 0;
else return(clonestr("{\"error\":\"coin port conflicts with existing coin\"}"));
}
return(jprint(LP_coinsjson(0),1));
cJSON *array = cJSON_CreateArray();
jaddi(array,LP_coinjson(ptr,0));
return(jprint(array,1));
} else return(clonestr("{\"error\":\"coin port conflicts with existing coin\"}"));
} else return(clonestr("{\"error\":\"couldnt find coin\"}"));
}
else if ( strcmp(method,"disable") == 0 )
{
//*
if ( (ptr= LP_coinsearch(coin)) != 0 )
{
ptr->inactive = (uint32_t)time(NULL);
return(jprint(LP_coinsjson(0),1));
cJSON *array = cJSON_CreateArray();
jaddi(array,LP_coinjson(ptr,0));
return(jprint(array,1));
} else return(clonestr("{\"error\":\"couldnt find coin\"}"));
}
else if ( strcmp(method,"electrum") == 0 )
{
@ -446,6 +467,7 @@ dividends(coin, height, <args>)\n\
{
if ( coinaddr[0] != 0 )
{
LP_address(ptr,coinaddr);
LP_listunspent_issue(coin,coinaddr,1);
if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_mypriv25519) != 0 )
{
@ -467,15 +489,11 @@ dividends(coin, height, <args>)\n\
return(jprint(LP_address_balance(ptr,jstr(argjson,"address"),1),1));
else return(clonestr("{\"error\":\"cant find coind\"}"));
}
else if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 )
return(clonestr("{\"result\":\"at least one of coins disabled\"}"));
else if ( IAMLP == 0 && LP_isdisabled(jstr(argjson,"coin"),0) != 0 )
retstr = clonestr("{\"result\":\"coin is disabled\"}");
else if ( strcmp(method,"checktxid") == 0 )
retstr = LP_spentcheck(argjson);
else if ( strcmp(method,"addr_unspents") == 0 )
{
//printf("GOT ADDR_UNSPENTS\n");
//printf("GOT ADDR_UNSPENTS %s %s\n",jstr(argjson,"coin"),jstr(argjson,"address"));
if ( (ptr= LP_coinsearch(jstr(argjson,"coin"))) != 0 )
{
char *coinaddr; //cJSON *array,*item,*req; int32_t i,n,vout,height; bits256 zero,txid; uint64_t value;
@ -483,9 +501,10 @@ dividends(coin, height, <args>)\n\
{
if ( coinaddr[0] != 0 )
{
LP_address(ptr,coinaddr);
if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_mypriv25519) != 0 )
{
//printf("%s %s is my address being asked for!\n",ptr->symbol,coinaddr);
//printf("ADDR_UNSPENTS %s %s is my address being asked for!\n",ptr->symbol,coinaddr);
ptr->addr_listunspent_requested = (uint32_t)time(NULL);
}
}
@ -493,6 +512,10 @@ dividends(coin, height, <args>)\n\
}
retstr = clonestr("{\"result\":\"success\"}");
}
//else if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 )
// return(clonestr("{\"result\":\"at least one of coins disabled\"}"));
//else if ( IAMLP == 0 && LP_isdisabled(jstr(argjson,"coin"),0) != 0 )
// retstr = clonestr("{\"result\":\"coin is disabled\"}");
else if ( strcmp(method,"getcoins") == 0 )
return(jprint(LP_coinsjson(0),1));
else if ( strcmp(method,"encrypted") == 0 )
@ -547,7 +570,7 @@ dividends(coin, height, <args>)\n\
else
{
memset(zero.bytes,0,sizeof(zero));
//printf("broadcast.(%s)\n",msg);
//printf("broadcast.(%s)\n",Broadcaststr);
LP_reserved_msg(base!=0?base:jstr(argjson,"coin"),rel,zero,jprint(reqjson,0));
}
retstr = clonestr("{\"result\":\"success\"}");

3
iguana/exchanges/LP_include.h

@ -35,7 +35,7 @@
#define MIN_PSOCK_PORT 10000
#define LP_MEMPOOL_TIMEINCR 10
#define LP_GETINFO_INCR 30
#define LP_ORDERBOOK_DURATION 3600
#define LP_ORDERBOOK_DURATION 120
#define LP_HTTP_TIMEOUT 2 // 1 is too small due to edge cases of time(NULL)
#define LP_MAXPEER_ERRORS 3
@ -316,6 +316,7 @@ struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid)
cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJSON *txobj);
int32_t LP_mempoolscan(char *symbol,bits256 searchtxid);
int32_t LP_txheight(struct iguana_info *coin,bits256 txid);
int32_t LP_numpeers();
int32_t LP_address_utxoadd(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);
cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret);

86
iguana/exchanges/LP_nativeDEX.c

@ -18,12 +18,15 @@
// LP_nativeDEX.c
// marketmaker
//
// sign critical api calls
// stats
// dPoW security -> 2: KMD notarized, 3: BTC notarized
// add interest to KMD withdraw
// verify portfolio, pricearray, withdraw
// dPoW security -> 4: KMD notarized, 5: BTC notarized
// sign critical api calls (pubkey reg, listunspent, orders?)
//
// process stats.log local file
//
// handles <-> pubkeys, deal with offline pubkeys, reputations, bonds etc.
//
// alice only coins GAME UNO BTM ANC: GAME BTCD PPC RDD XZC POT EAC FTC BASH SPR WDC UNO XPM XCN BELA CHC DIME MEC NAUT MED AUR MAX DGC RIC EB3 DOT BTM GEO ANC CANN ICASH WBB SRC PTC ADZ TIPS EQT START EFL FST FJC NYC GCN
// verify portfolio, pricearray, interest to KMD withdraw
#include <stdio.h>
@ -241,7 +244,19 @@ int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int
break;
if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 )
{
//printf("RECV.(%s)\n",(char *)ptr);
if ( 0 )
{
cJSON *recvjson; char *mstr,*cstr;
if ( (recvjson= cJSON_Parse((char *)ptr)) != 0 )
{
if ( (mstr= jstr(recvjson,"method")) != 0 && strcmp(mstr,"uitem") == 0 &&
(cstr= jstr(recvjson,"coin")) != 0 && strcmp(cstr,"REVS") == 0 )
{
printf("%s RECV.(%s)\n",typestr,(char *)ptr);
}
free_json(recvjson);
}
}
nonz++;
if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,ptr,recvlen,sock)) != 0 )
free(retstr);
@ -278,7 +293,7 @@ int32_t LP_nanomsg_recvs(void *ctx)
if ( (origipaddr= LP_myipaddr) == 0 )
origipaddr = "127.0.0.1";
milli = OS_milliseconds();
if ( lastmilli > 0. && milli > lastmilli+1000 )
if ( lastmilli > 0. && milli > lastmilli+3000 )
fprintf(stderr,">>>>>>>>>>>>>>>>> BIG latency lag %.3f milliseconds\n",milli-lastmilli);
lastmilli = milli;
//portable_mutex_lock(&LP_nanorecvsmutex);
@ -325,6 +340,8 @@ void command_rpcloop(void *myipaddr)
usleep(1000);
else usleep(10000);
}
else if ( IAMLP == 0 )
usleep(1000);
}
}
@ -346,27 +363,24 @@ void LP_smartutxos_push(struct iguana_info *coin)
vout = jint(item,"tx_pos");
value = j64bits(item,"value");
height = jint(item,"height");
if ( 0 )
if ( (rand() % 100) == 0 && IAMLP == 0 )
{
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( (retstr= issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,vout,height,value)) != 0 )
free(retstr);
}
}
else
{
req = cJSON_CreateObject();
jaddstr(req,"method","uitem");
jaddstr(req,"coin",coin->symbol);
jaddstr(req,"coinaddr",coin->smartaddr);
jaddbits256(req,"txid",txid);
jaddnum(req,"vout",vout);
jaddnum(req,"ht",height);
jadd64bits(req,"value",value);
//printf("ADDR_UNSPENTS[] <- %s\n",jprint(req,0));
LP_reserved_msg("","",zero,jprint(req,1));
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
if ( (retstr= issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,vout,height,value)) != 0 )
free(retstr);
}
}
req = cJSON_CreateObject();
jaddstr(req,"method","uitem");
jaddstr(req,"coin",coin->symbol);
jaddstr(req,"coinaddr",coin->smartaddr);
jaddbits256(req,"txid",txid);
jaddnum(req,"vout",vout);
jaddnum(req,"ht",height);
jadd64bits(req,"value",value);
//printf("ADDR_UNSPENTS[] <- %s\n",jprint(req,0));
LP_reserved_msg("","",zero,jprint(req,1));
}
}
free_json(array);
@ -561,7 +575,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
memset(&zero,0,sizeof(zero));
if ( coin->addr_listunspent_requested != 0 )
{
//printf("addr_listunspent_requested %u\n",coin->addr_listunspent_requested);
//printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested);
LP_smartutxos_push(coin);
coin->addr_listunspent_requested = 0;
}
@ -699,16 +713,28 @@ void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint
int32_t LP_reserved_msgs()
{
bits256 zero; int32_t n = 0;
bits256 zero; int32_t n = 0; //struct nn_pollfd pfd;
memset(zero.bytes,0,sizeof(zero));
portable_mutex_lock(&LP_reservedmutex);
while ( num_Reserved_msgs > 0 )
if ( num_Reserved_msgs > 0 )
{
/*memset(&pfd,0,sizeof(pfd));
pfd.fd = LP_mypubsock;
pfd.events = NN_POLLOUT;
if ( nn_poll(&pfd,1,1) != 1 )
break;*/
num_Reserved_msgs--;
//printf("BROADCASTING RESERVED.(%s)\n",Reserved_msgs[num_Reserved_msgs]);
#ifdef __APPLE__
// printf("%d BROADCASTING RESERVED.(%s)\n",num_Reserved_msgs,Reserved_msgs[num_Reserved_msgs]);
#endif
LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[num_Reserved_msgs]);
Reserved_msgs[num_Reserved_msgs] = 0;
n++;
#ifdef __APPLE__
usleep(5000);
#else
usleep(100);
#endif
}
portable_mutex_unlock(&LP_reservedmutex);
return(n);

31
iguana/exchanges/LP_network.c

@ -87,7 +87,7 @@ void _LP_sendqueueadd(uint32_t crc32,int32_t sock,uint8_t *msg,int32_t msglen,in
int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32)
{
static uint32_t crcs[8192]; static unsigned long dup,total;
static uint32_t crcs[64]; static unsigned long dup,total;
int32_t i;
*duplicatep = 0;
if ( ind < 0 )
@ -158,7 +158,9 @@ void queue_loop(void *ignore)
{
if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen )
printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen);
//else printf("%d %p qsent %u msglen.%d peerind.%d (%s)\n",n,ptr,ptr->crc32,ptr->msglen,ptr->peerind,ptr->msg);
#ifdef __APPLE__
//else printf("%d %p qsent %u msglen.%d peerind.%d (%s)\n",n,ptr,ptr->crc32,ptr->msglen,ptr->peerind,ptr->msg);
#endif
ptr->sock = -1;
if ( ptr->peerind > 0 )
ptr->starttime = (uint32_t)time(NULL);
@ -175,7 +177,7 @@ void queue_loop(void *ignore)
printf("found.%u Q.%d err.%d match.%d\n",ptr->crc32,LP_Qenqueued,LP_Qerrors,LP_Qfound);
flag = 1;
}
else
else if ( 0 ) // too much beyond duplicate filter when network is busy
{
printf("couldnt find.%u peerind.%d Q.%d err.%d match.%d\n",ptr->crc32,ptr->peerind,LP_Qenqueued,LP_Qerrors,LP_Qfound);
ptr->peerind++;
@ -201,21 +203,23 @@ void queue_loop(void *ignore)
// printf("LP_Q.[%d]\n",n);
if ( nonz == 0 )
usleep(5000);
else if ( IAMLP == 0 )
usleep(1000);
}
}
void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32_t msglen,int32_t needack)
{
int32_t sentbytes,peerind = 0;
int32_t maxind,peerind = 0; //sentbytes,
if ( sock0 >= 0 || sock1 >= 0 )
{
if ( sock0 >= 0 && LP_sockcheck(sock0) > 0 )
/* if ( sock0 >= 0 && LP_sockcheck(sock0) > 0 )
{
if ( (sentbytes= nn_send(sock0,msg,msglen,0)) != msglen )
printf("_LP_queuesend0 sent %d instead of %d\n",sentbytes,msglen);
else
{
//printf("Q sent %u msglen.%d (%s)\n",crc32,msglen,msg);
printf("Q sent %u msglen.%d (%s)\n",crc32,msglen,msg);
sock0 = -1;
}
}
@ -223,14 +227,20 @@ void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32
{
if ( (sentbytes= nn_send(sock1,msg,msglen,0)) != msglen )
printf("_LP_queuesend1 sent %d instead of %d\n",sentbytes,msglen);
else sock1 = -1;
else
{
printf("Q sent1 %u msglen.%d (%s)\n",crc32,msglen,msg);
sock1 = -1;
}
}
if ( sock0 < 0 && sock1 < 0 )
return;
return;*/
}
else
{
peerind = 1;
if ( (maxind= LP_numpeers()) > 0 )
peerind = (rand() % maxind);
else peerind = 0;
sock0 = LP_peerindsock(&peerind);
}
if ( sock0 >= 0 )
@ -272,6 +282,9 @@ void LP_broadcast_finish(int32_t pubsock,char *base,char *rel,uint8_t *msg,cJSON
free(msg);
jdelete(argjson,"method");
jaddstr(argjson,"method","broadcast");
if ( jobj(argjson,"timestamp") == 0 )
jaddnum(argjson,"timestamp",(uint32_t)time(NULL));
// add signature here
msg = (void *)jprint(argjson,0);
msglen = (int32_t)strlen((char *)msg) + 1;
LP_queuesend(crc32,-1,base,rel,msg,msglen);

55
iguana/exchanges/LP_ordermatch.c

@ -348,10 +348,9 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str
return(-14);
if ( butxo != 0 )
{
//qprice 2259.01692494 <- 10.34279604/0.00457845 txfees.(0.00042631 0.00010000) vs (0.00042791 0.00010000)
if ( qp->satoshis < (srcvalue / LP_MINVOL) || srcvalue < qp->txfee*LP_MINSIZE_TXFEEMULT )
{
printf("utxo payment %.8f is less than %f covered by Q %.8f or <10x txfee %.8f\n",dstr(srcvalue),1./LP_MINVOL,dstr(qp->satoshis),dstr(qp->txfee));
printf("utxo payment %.8f is less than %f covered by Q %.8f or <10x txfee %.8f [%d %d]\n",dstr(srcvalue),1./LP_MINVOL,dstr(qp->satoshis),dstr(qp->txfee),qp->satoshis < (srcvalue / LP_MINVOL),srcvalue < qp->txfee*LP_MINSIZE_TXFEEMULT);
return(-12);
}
}
@ -443,9 +442,9 @@ int32_t LP_nanobind(void *ctx,char *pairstr)
return(pairsock);
}
int32_t LP_nearest_utxovalue(struct iguana_info *coin,struct LP_address_utxo **utxos,int32_t n,uint64_t targetval)
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; char str[65]; int64_t dist; uint64_t mindist = (1LL << 60);
int32_t i,oldht,mini = -1; struct LP_address_utxo *up; struct electrum_info *backupep=0,*ep; char str[65]; int64_t dist; uint64_t mindist = (1LL << 60);
if ( (ep= coin->electrum) != 0 )
{
if ( (backupep= ep->prev) == 0 )
@ -462,15 +461,24 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,struct LP_address_utxo **u
{
if ( coin->electrum != 0 )
{
if (up->SPV <= 0 )
if ( up->SPV == 0 || up->SPV == -1 )
up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height);
if ( up->SPV < 0 )
if ( up->SPV == 0 || up->SPV == -1 )
{
printf("SPV failure for %s %s\n",coin->symbol,bits256_str(str,up->U.txid));
if ( up->SPV == -1 )
{
oldht = up->U.height;
LP_txheight_check(coin,coinaddr,up);
if ( oldht != up->U.height )
up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height);
if ( up->SPV < 0 )
up->SPV = -2;
}
continue;
} else printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV);
} //else printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV);
}
if ( dist >= 0 && dist < mindist )
if ( (coin->electrum == 0 || up->SPV > 0) && dist >= 0 && dist < mindist )
{
//printf("(%.8f %.8f %.8f).%d ",dstr(up->U.value),dstr(dist),dstr(mindist),mini);
mini = i;
@ -496,7 +504,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **
struct LP_address *ap; uint64_t targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; struct LP_utxoinfo *utxo = 0;
if ( coin != 0 && (ap= LP_addressfind(coin,coinaddr)) != 0 )
{
if ( (m= LP_address_utxo_ptrs(iambob,utxos,max,ap)) > 1 )
if ( (m= LP_address_utxo_ptrs(iambob,utxos,max,ap,coinaddr)) > 1 )
{
targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee);
if ( 0 )
@ -507,7 +515,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **
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,utxos,m,targetval)) >= 0 )
if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval)) >= 0 )
{
up = utxos[mini];
utxos[mini] = 0;
@ -516,7 +524,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **
if ( (double)up->U.value/targetval < LP_MINVOL-1 )
{
if ( (mini= LP_nearest_utxovalue(coin,utxos,m,targetval2 * 1.01)) >= 0 )
if ( (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval2 * 1.01)) >= 0 )
{
if ( up != 0 && (up2= utxos[mini]) != 0 )
{
@ -531,7 +539,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **
} 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 utxos pass LP_address_utxo_ptrs filter\n");
} else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr);
} else printf("couldnt find %s %s\n",coin->symbol,coinaddr);
return(0);
}
@ -769,6 +777,7 @@ char *LP_bestfit(char *rel,double relvolume)
struct LP_quoteinfo LP_Alicequery;
double LP_Alicemaxprice;
uint32_t Alice_expiration;
char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration)
{
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;
@ -779,7 +788,7 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q
}
price = 0.;
LP_query(ctx,myipaddr,mypubsock,"request",qp);
LP_Alicequery = *qp, LP_Alicemaxprice = maxprice;
LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout;
return(clonestr("{\"result\":\"success\"}"));
}
@ -793,7 +802,14 @@ int32_t LP_quotecmp(struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2)
void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp)
{
double price,maxprice = LP_Alicemaxprice;
if ( LP_quotecmp(qp,&LP_Alicequery) == 0 )
if ( time(NULL) > Alice_expiration )
{
printf("time expired for Alice_request\n");
memset(&LP_Alicequery,0,sizeof(LP_Alicequery));
LP_Alicemaxprice = 0.;
Alice_expiration = 0;
}
else if ( LP_quotecmp(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 )
@ -812,6 +828,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
{
LP_quoteparse(&Q,argjson);
LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-2*Q.txfee,Q.destcoin,Q.destsatoshis-2*Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector);
LP_tradecommand_log(argjson);
printf("LP_tradecommand: check received method %s\n",method);
retval = 1;
if ( strcmp(method,"reserved") == 0 )
@ -1049,7 +1066,7 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
LP_txfees(&txfee,&desttxfee,base,rel);
destsatoshis = SATOSHIDEN * relvolume + 2*desttxfee;
if ( (autxo= LP_utxo_bestfit(rel,destsatoshis)) == 0 )
return(clonestr("{\"error\":\"cant find utxo that is big enough\"}"));
return(clonestr("{\"error\":\"cant find alice utxo that is big enough\"}"));
if ( destsatoshis < autxo->S.satoshis )
autxo->S.satoshis = destsatoshis;
while ( 1 )
@ -1057,14 +1074,14 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 )
{
printf("bestutxo.%p ordermatchprice %.8f bestdestsatoshis %.8f\n",bestutxo,ordermatchprice,dstr(bestdestsatoshis));
return(clonestr("{\"error\":\"cant find ordermatch utxo\"}"));
return(clonestr("{\"error\":\"cant find ordermatch utxo, need to change relvolume to be closer to available\"}"));
}
pubkeys[numpubs++] = bestutxo->pubkey;
if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestsatoshis,bestdestsatoshis) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote\"}"));
if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,G.LP_mypub25519,autxo->coinaddr) < 0 )
return(clonestr("{\"error\":\"cant set ordermatch quote info\"}"));
maxiters = 100;
maxiters = 200;
qprice = 1. / SMALLVAL;
for (i=0; i<maxiters; i++)
{
@ -1076,7 +1093,9 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
if ( qprice/ordermatchprice < 1.+SMALLVAL )
{
printf("i.%d/%d qprice %.8f < ordermatchprice %.8f\n",i,maxiters,qprice,ordermatchprice);
Q.satoshis *= 0.9999;
if ( strcmp("BTC",Q.destcoin) == 0 || strcmp("BTC",Q.srccoin) == 0 )
Q.satoshis *= 0.999;
else Q.satoshis *= 0.9999;
} else break;
}
if ( i == maxiters || qprice > maxprice )

108
iguana/exchanges/LP_portfolio.c

@ -198,7 +198,12 @@ char *LP_portfolio_goal(char *symbol,double goal)
} else return(clonestr("{\"error\":\"cant set goal for inactive coin\"}"));
}
int32_t LP_autoprices;
int32_t LP_autoprices,num_LP_autorefs;
struct LP_autoprice_ref
{
char refbase[16],refrel[16],base[16],rel[16];
} LP_autorefs[100];
/*int32_t LP_autofill(char *base,char *rel,double maxprice,double totalrelvolume)
{
@ -213,38 +218,88 @@ int32_t LP_autoprices;
return(-1);
}*/
int32_t LP_autoprice(char *base,char *rel,double minprice,double margin,char *type)
int32_t LP_autoprice(char *base,char *rel,cJSON *argjson)
{
struct LP_priceinfo *basepp,*relpp;
//curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.1,\"refbase\":\"KMD\",\refrel\":\"BTC\",\"factor\":15000,\"margin\":0.01}"
struct LP_priceinfo *basepp,*relpp; int32_t i; char *refbase,*refrel; double minprice,margin,offset,factor;
//printf("autoprice.(%s %s) %s\n",base,rel,jprint(argjson,0));
if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{
if ( jobj(argjson,"minprice") != 0 )
minprice = jdouble(argjson,"minprice");
else minprice = 0.;
margin = jdouble(argjson,"margin");
offset = jdouble(argjson,"offset");
factor = jdouble(argjson,"factor");
basepp->minprices[relpp->ind] = minprice;
basepp->margins[relpp->ind] = margin;
basepp->offsets[relpp->ind] = offset;
basepp->factors[relpp->ind] = factor;
if ( (refbase= jstr(argjson,"refbase")) != 0 && (refrel= jstr(argjson,"refrel")) != 0 )
{
for (i=0; i<num_LP_autorefs; i++)
{
if ( strcmp(base,LP_autorefs[i].base) == 0 && strcmp(rel,LP_autorefs[i].rel) == 0 )
{
safecopy(LP_autorefs[i].refbase,refbase,sizeof(LP_autorefs[i].refbase));
safecopy(LP_autorefs[i].refrel,refrel,sizeof(LP_autorefs[i].refrel));
printf("%d Update ref %s/%s for %s/%s factor %.8f offset %.8f\n",i,refbase,refrel,base,rel,factor,offset);
break;
}
}
if ( i == num_LP_autorefs && num_LP_autorefs < sizeof(LP_autorefs)/sizeof(*LP_autorefs) )
{
safecopy(LP_autorefs[num_LP_autorefs].refbase,refbase,sizeof(LP_autorefs[num_LP_autorefs].refbase));
safecopy(LP_autorefs[num_LP_autorefs].refrel,refrel,sizeof(LP_autorefs[num_LP_autorefs].refrel));
safecopy(LP_autorefs[num_LP_autorefs].base,base,sizeof(LP_autorefs[num_LP_autorefs].base));
safecopy(LP_autorefs[num_LP_autorefs].rel,rel,sizeof(LP_autorefs[num_LP_autorefs].rel));
printf("%d Using ref %s/%s for %s/%s factor %.8f, offset %.8f, margin %.8f\n",num_LP_autorefs,refbase,refrel,base,rel,factor,offset,margin);
num_LP_autorefs++;
}
}
LP_autoprices++;
return(0);
}
return(-1);
}
void LP_autopriceset(void *ctx,int32_t dir,struct LP_priceinfo *relpp,struct LP_priceinfo *basepp,double price)
void LP_autopriceset(void *ctx,int32_t dir,struct LP_priceinfo *basepp,struct LP_priceinfo *relpp,double price,char *refbase,char *refrel)
{
double margin,minprice,oppomargin; int32_t changed;
double margin,minprice,newprice,oppomargin,factor,offset; double bid,ask; int32_t changed;
margin = basepp->margins[relpp->ind];
oppomargin = relpp->margins[basepp->ind];
if ( margin != 0. || oppomargin != 0. )
{
if ( margin == 0. )
margin = oppomargin;
//printf("min %.8f %s/%s %.8f dir.%d margin %.8f (%.8f %.8f)\n",basepp->minprices[relpp->ind],relpp->symbol,basepp->symbol,price,dir,margin,1. / (price * (1. - margin)),(price * (1. + margin)));
if ( dir > 0 )
price = 1. / (price * (1. - margin));
else price = (price * (1. + margin));
if ( (minprice= basepp->minprices[relpp->ind]) == 0. || price >= minprice )
offset = basepp->offsets[relpp->ind];
factor = basepp->factors[relpp->ind];
if ( fabs(price) < SMALLVAL && refbase != 0 && refrel != 0 )
{
LP_mypriceset(&changed,relpp->symbol,basepp->symbol,price);
//printf("changed.%d\n",changed);
if ( changed != 0 )
LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,price);
price = LP_myprice(&bid,&ask,refbase,refrel);
//printf("%s/%s USE ref %s/%s %.8f factor %.8f offset %.8f margin %.8f\n",basepp->symbol,relpp->symbol,refbase,refrel,price,factor,offset,margin);
}
if ( LP_pricevalid(price) > 0 )
{
if ( factor > SMALLVAL )
{
//double tmp = (price * factor) + offset;
//printf("price %.8f -> %.8f factor %.8f offset %.8f margin %.8f [%.8f %.8f] [%.8f %.8f]\n",price,tmp,factor,offset,margin,(tmp * (1. + margin)),1./(tmp * (1. - margin)),(tmp * (1. - margin)),1./(tmp * (1. + margin)));
price = (price * factor) + offset;
}
if ( margin == 0. )
margin = oppomargin;
//printf("min %.8f %s/%s %.8f dir.%d margin %.8f (%.8f %.8f)\n",basepp->minprices[relpp->ind],relpp->symbol,basepp->symbol,price,dir,margin,1. / (price * (1. - margin)),(price * (1. + margin)));
if ( dir > 0 )
newprice = (1. / price) * (1. + margin);
else newprice = (price * (1. + margin));
//newprice = 1. / (price * (1. - margin));
if ( (minprice= basepp->minprices[relpp->ind]) == 0. || price >= minprice )
{
LP_mypriceset(&changed,relpp->symbol,basepp->symbol,newprice);
//printf("changed.%d %s/%s <- %.8f\n",changed,basepp->symbol,relpp->symbol,price);
if ( changed != 0 )
LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,newprice);
}
}
}
}
@ -325,8 +380,8 @@ double LP_pricesparse(void *ctx,int32_t trexflag,char *retstr,struct LP_priceinf
//printf("have trex: iter.%d trexflag.%d %s %.8f %.8f\n",iter,trexflag,symbol,coinpp->bid[1],coinpp->ask[1]);
continue;
}
LP_autopriceset(ctx,1,refpp,coinpp,price);
LP_autopriceset(ctx,-1,coinpp,refpp,price);
LP_autopriceset(ctx,1,coinpp,refpp,price,0,0);
LP_autopriceset(ctx,-1,refpp,coinpp,price,0,0);
}
}
}
@ -358,7 +413,7 @@ static char *assetids[][3] =
void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp)
{
char *retstr; cJSON *retjson,*bid,*ask; uint64_t bidsatoshis,asksatoshis; int32_t i; double nxtkmd,price; struct LP_priceinfo *kmdpp,*fiatpp,*nxtpp;
char *retstr; cJSON *retjson,*bid,*ask; uint64_t bidsatoshis,asksatoshis; int32_t i; double nxtkmd,price; struct LP_priceinfo *kmdpp,*fiatpp,*nxtpp,*basepp,*relpp;
if ( (retstr= issue_curlt("https://bittrex.com/api/v1.1/public/getmarketsummaries",LP_HTTP_TIMEOUT*10)) == 0 )
{
printf("trex error getting marketsummaries\n");
@ -385,8 +440,8 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp)
{
//printf("(%s %.8f %.8f) ",CURRENCIES[i],jdouble(retjson,"price"),jdouble(retjson,"invprice"));
price = jdouble(retjson,"price");
LP_autopriceset(ctx,1,kmdpp,fiatpp,price);
LP_autopriceset(ctx,-1,fiatpp,kmdpp,price);
LP_autopriceset(ctx,1,fiatpp,kmdpp,price,0,0);
LP_autopriceset(ctx,-1,kmdpp,fiatpp,price,0,0);
free_json(retjson);
}
}
@ -409,14 +464,21 @@ void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp)
if ( bidsatoshis != 0 && asksatoshis != 0 )
price = 0.5 * dstr(bidsatoshis + asksatoshis) * nxtkmd;
}
LP_autopriceset(ctx,1,kmdpp,nxtpp,price);
LP_autopriceset(ctx,-1,nxtpp,kmdpp,price);
LP_autopriceset(ctx,1,nxtpp,kmdpp,price,0,0);
LP_autopriceset(ctx,-1,kmdpp,nxtpp,price,0,0);
//printf("%s %s -> (%s) nxtkmd %.8f %.8f %.8f\n",assetids[i][1],assetids[i][0],jprint(retjson,0),nxtkmd,0.5*dstr(bidsatoshis + asksatoshis),price);
free_json(retjson);
}
}
}
}
for (i=0; i<num_LP_autorefs; i++)
{
basepp = LP_priceinfofind(LP_autorefs[i].base);
relpp = LP_priceinfofind(LP_autorefs[i].rel);
if ( basepp != 0 && relpp != 0 )
LP_autopriceset(ctx,1,basepp,relpp,0,LP_autorefs[i].refbase,LP_autorefs[i].refrel);
}
}
int32_t LP_portfolio_trade(void *ctx,uint32_t *requestidp,uint32_t *quoteidp,struct iguana_info *buy,struct iguana_info *sell,double relvolume,int32_t setbaserel,char *gui)

7
iguana/exchanges/LP_prices.c

@ -31,6 +31,8 @@ struct LP_priceinfo
double myprices[LP_MAXPRICEINFOS];
double minprices[LP_MAXPRICEINFOS]; // autoprice
double margins[LP_MAXPRICEINFOS];
double offsets[LP_MAXPRICEINFOS];
double factors[LP_MAXPRICEINFOS];
//double maxprices[LP_MAXPRICEINFOS]; // autofill of base/rel
//double relvols[LP_MAXPRICEINFOS];
FILE *fps[LP_MAXPRICEINFOS];
@ -494,6 +496,7 @@ int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price)
*changedp = 0;
if ( base != 0 && rel != 0 && LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 )
{
if ( fabs(basepp->myprices[relpp->ind] - price) > SMALLVAL )
*changedp = 1;
basepp->myprices[relpp->ind] = price; // ask
@ -719,6 +722,8 @@ int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *
//printf("skip pubp since no rmd160\n");
continue;
}
if ( pubp->timestamp < oldest )
continue;
bitcoin_address(coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160));
minsatoshis = maxsatoshis = n = 0;
ap = 0;
@ -784,6 +789,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration)
jaddi(array,LP_orderbookjson(rel,bids[i]));
if ( n < 10 && bids[i]->numutxos == 0 )//|| relcoin->electrum == 0 )
{
//printf("bid ping %s %s\n",rel,bids[i]->coinaddr);
LP_address(relcoin,bids[i]->coinaddr);
if ( relcoin->electrum == 0 )
LP_listunspent_issue(rel,bids[i]->coinaddr,0);
@ -803,6 +809,7 @@ char *LP_orderbook(char *base,char *rel,int32_t duration)
jaddi(array,LP_orderbookjson(base,asks[i]));
if ( n < 10 && asks[i]->numutxos == 0 )//|| basecoin->electrum == 0 )
{
//printf("ask ping %s %s\n",base,asks[i]->coinaddr);
LP_address(basecoin,asks[i]->coinaddr);
if ( basecoin->electrum == 0 )
LP_listunspent_issue(base,asks[i]->coinaddr,0);

77
iguana/exchanges/LP_remember.c

@ -247,7 +247,7 @@ bits256 basilisk_swap_privBn_extract(bits256 *bobrefundp,char *bobcoin,bits256 b
return(privBn);
}
bits256 basilisk_swap_spendupdate(char *symbol,char *spentaddr,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t vout,char *aliceaddr,char *bobaddr,char *Adest,char *dest)
bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t vout,char *aliceaddr,char *bobaddr,char *Adest,char *dest)
{
bits256 spendtxid,txid; char destaddr[64],str[65]; struct iguana_info *coin; cJSON *histobj;
if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum != 0 )
@ -285,13 +285,13 @@ bits256 basilisk_swap_spendupdate(char *symbol,char *spentaddr,int32_t *sentflag
else
{
printf("OTHER dest spent.(%s) -> %s\n",bits256_str(str,txid),destaddr);
if ( aliceaddr != 0 )
if ( iambob == 0 )
{
sentflags[bobspent] = 1;
sentflags[alicespent] = 0;
txids[bobspent] = spendtxid;
}
else if ( bobaddr != 0 )
else
{
sentflags[alicespent] = 1;
sentflags[bobspent] = 0;
@ -914,9 +914,9 @@ cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requesti
LP_rswap_checktx(&rswap,rswap.alicecoin,BASILISK_ALICEPAYMENT);
LP_rswap_checktx(&rswap,rswap.bobcoin,BASILISK_BOBPAYMENT);
LP_rswap_checktx(&rswap,rswap.bobcoin,BASILISK_BOBDEPOSIT);
rswap.paymentspent = basilisk_swap_spendupdate(rswap.bobcoin,rswap.bobpaymentaddr,rswap.sentflags,rswap.txids,BASILISK_BOBPAYMENT,BASILISK_ALICESPEND,BASILISK_BOBRECLAIM,0,srcAdest,srcBdest,rswap.Adestaddr,rswap.destaddr);
rswap.Apaymentspent = basilisk_swap_spendupdate(rswap.alicecoin,rswap.alicepaymentaddr,rswap.sentflags,rswap.txids,BASILISK_ALICEPAYMENT,BASILISK_ALICERECLAIM,BASILISK_BOBSPEND,0,destAdest,destBdest,rswap.Adestaddr,rswap.destaddr);
rswap.depositspent = basilisk_swap_spendupdate(rswap.bobcoin,rswap.bobdepositaddr,rswap.sentflags,rswap.txids,BASILISK_BOBDEPOSIT,BASILISK_ALICECLAIM,BASILISK_BOBREFUND,0,srcAdest,srcBdest,rswap.Adestaddr,rswap.destaddr);
rswap.paymentspent = basilisk_swap_spendupdate(rswap.iambob,rswap.bobcoin,rswap.bobpaymentaddr,rswap.sentflags,rswap.txids,BASILISK_BOBPAYMENT,BASILISK_ALICESPEND,BASILISK_BOBRECLAIM,0,srcAdest,srcBdest,rswap.Adestaddr,rswap.destaddr);
rswap.Apaymentspent = basilisk_swap_spendupdate(rswap.iambob,rswap.alicecoin,rswap.alicepaymentaddr,rswap.sentflags,rswap.txids,BASILISK_ALICEPAYMENT,BASILISK_ALICERECLAIM,BASILISK_BOBSPEND,0,destAdest,destBdest,rswap.Adestaddr,rswap.destaddr);
rswap.depositspent = basilisk_swap_spendupdate(rswap.iambob,rswap.bobcoin,rswap.bobdepositaddr,rswap.sentflags,rswap.txids,BASILISK_BOBDEPOSIT,BASILISK_ALICECLAIM,BASILISK_BOBREFUND,0,srcAdest,srcBdest,rswap.Adestaddr,rswap.destaddr);
rswap.finishedflag = basilisk_swap_isfinished(rswap.iambob,rswap.txids,rswap.sentflags,rswap.paymentspent,rswap.Apaymentspent,rswap.depositspent);
LP_spends_set(&rswap);
if ( rswap.iambob == 0 )
@ -1201,5 +1201,70 @@ char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid)
return(retstr);
}
void LP_tradecommand_log(cJSON *argjson)
{
static FILE *logfp; char *jsonstr;
if ( logfp == 0 )
{
if ( (logfp= fopen("stats.log","rb+")) != 0 )
fseek(logfp,0,SEEK_END);
else logfp = fopen("stats.log","wb");
}
if ( logfp != 0 )
{
jsonstr = jprint(argjson,0);
fprintf(logfp,"%s\n",jsonstr);
free(jsonstr);
fflush(logfp);
}
}
extern struct LP_quoteinfo LP_Alicequery;
extern uint32_t Alice_expiration;
char *LP_recent_swaps(int32_t limit)
{
char fname[512]; long fsize,offset; FILE *fp; int32_t i=0; uint32_t requestid,quoteid; cJSON *array,*item,*retjson;
if ( limit <= 0 )
limit = 3;
sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname);
array = cJSON_CreateArray();
if ( (fp= fopen(fname,"rb")) != 0 )
{
fseek(fp,0,SEEK_END);
fsize = ftell(fp);
offset = (sizeof(requestid) + sizeof(quoteid));
while ( offset <= fsize && i < limit )
{
i++;
offset = i * (sizeof(requestid) + sizeof(quoteid));
fseek(fp,fsize-offset,SEEK_SET);
if ( ftell(fp) == fsize-offset )
{
if ( fread(&requestid,1,sizeof(requestid),fp) == sizeof(requestid) && fread(&quoteid,1,sizeof(quoteid),fp) == sizeof(quoteid) )
{
item = cJSON_CreateArray();
jaddinum(item,requestid);
jaddinum(item,quoteid);
jaddi(array,item);
} else break;
} else break;
}
fclose(fp);
}
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jadd(retjson,"swaps",array);
if ( time(NULL) < Alice_expiration )
{
item = cJSON_CreateObject();
jaddnum(item,"expiration",Alice_expiration);
jaddnum(item,"timeleft",Alice_expiration-time(NULL));
jaddstr(item,"base",LP_Alicequery.srccoin);
jaddnum(item,"basevalue",dstr(LP_Alicequery.satoshis));
jaddstr(item,"rel",LP_Alicequery.destcoin);
jaddnum(item,"relvalue",dstr(LP_Alicequery.destsatoshis));
jadd(retjson,"pending",item);
} else Alice_expiration = 0;
return(jprint(retjson,1));
}

16
iguana/exchanges/LP_rpc.c

@ -268,6 +268,17 @@ cJSON *LP_gettx(char *symbol,bits256 txid)
}
}
uint32_t LP_locktime(char *symbol,bits256 txid)
{
cJSON *txobj; uint32_t locktime = 0;
if ( (txobj= LP_gettx(symbol,txid)) != 0 )
{
locktime = juint(txobj,"locktime");
free_json(txobj);
}
return(locktime);
}
cJSON *LP_gettxout_json(bits256 txid,int32_t vout,int32_t height,char *coinaddr,uint64_t value)
{
cJSON *retjson,*addresses,*sobj;
@ -283,7 +294,7 @@ cJSON *LP_gettxout_json(bits256 txid,int32_t vout,int32_t height,char *coinaddr,
jaddstr(sobj,"type","pubkey");
jadd(sobj,"addresses",addresses);
jadd(retjson,"scriptPubKey",sobj);
printf("GETTXOUT.(%s)\n",jprint(retjson,0));
//printf("GETTXOUT.(%s)\n",jprint(retjson,0));
return(retjson);
}
@ -480,13 +491,14 @@ int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag)
}
else if ( IAMLP == 0 )
{
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);
//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");
}

23
iguana/exchanges/LP_socket.c

@ -350,7 +350,10 @@ int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep
}
}
if ( value != 0 || tx->height > 0 )
{
//printf("from electrum_process_array\n");
flag += LP_address_utxoadd(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");
}
@ -457,7 +460,7 @@ cJSON *electrum_address_subscribe(char *symbol,struct electrum_info *ep,cJSON **
cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr)
{
struct LP_transaction *tx; cJSON *retjson,*txobj,*item; int32_t i,n,height; bits256 txid; struct iguana_info *coin = LP_coinfind(symbol);
char str[65]; struct LP_transaction *tx; cJSON *retjson,*txobj,*item; int32_t i,n,height; bits256 txid; struct iguana_info *coin = LP_coinfind(symbol);
retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_history",addr,ELECTRUM_TIMEOUT);
//printf("history.(%s)\n",jprint(retjson,0));
if ( retjson != 0 && (n= cJSON_GetArraySize(retjson)) > 0 )
@ -478,7 +481,10 @@ cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON *
{
if ( (tx= LP_transactionfind(coin,txid)) != 0 )
{
if ( tx->height > 0 && tx->height != height )
printf("update %s height.%d <- %d\n",bits256_str(str,txid),tx->height,height);
tx->height = height;
//printf("from history\n");
LP_address_utxoadd(coin,addr,txid,0,0,height,-1);
}
}
@ -488,6 +494,17 @@ cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON *
return(retjson);
}
int32_t LP_txheight_check(struct iguana_info *coin,char *coinaddr,struct LP_address_utxo *up)
{
cJSON *retjson;
if ( coin->electrum != 0 )
{
if ( (retjson= electrum_address_gethistory(coin->symbol,coin->electrum,&retjson,coinaddr)) != 0 )
free_json(retjson);
}
return(0);
}
cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr)
{
cJSON *retjson; struct iguana_info *coin = LP_coinfind(symbol);
@ -530,9 +547,9 @@ cJSON *electrum_getchunk(char *symbol,struct electrum_info *ep,cJSON **retjsonp,
cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len)
{
uint8_t *extraspace; cJSON *txobj; char str[65],str2[65]; struct iguana_msgtx msgtx; bits256 checktxid;
extraspace = calloc(1,1000000);
extraspace = calloc(1,4000000);
memset(&msgtx,0,sizeof(msgtx));
txobj = bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->height,&checktxid,&msgtx,extraspace,1000000,serialized,len,0,0);
txobj = bitcoin_data2json(coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->height,&checktxid,&msgtx,extraspace,4000000,serialized,len,0,0);
//printf("TX.(%s) match.%d\n",jprint(txobj,0),bits256_cmp(txid,checktxid));
free(extraspace);
if ( bits256_cmp(txid,checktxid) != 0 )

42
iguana/exchanges/LP_transaction.c

@ -778,10 +778,38 @@ cJSON *LP_inputjson(bits256 txid,int32_t vout,char *spendscriptstr)
return(item);
}
uint64_t _komodo_interestnew(uint64_t nValue,uint32_t nLockTime,uint32_t tiptime)
{
int32_t minutes; uint64_t interest = 0;
if ( (minutes= (tiptime - nLockTime) / 60) >= 60 )
{
if ( minutes > 365 * 24 * 60 )
minutes = 365 * 24 * 60;
minutes -= 59;
interest = ((nValue / 10512000) * minutes);
}
return(interest);
}
int64_t LP_komodo_interest(bits256 txid,int64_t value)
{
uint32_t nLockTime; uint32_t tiptime; int64_t interest = 0;
if ( value >= 10*SATOSHIDEN )
{
if ( (nLockTime= LP_locktime("KMD",txid)) >= 500000000 )
{
tiptime = (uint32_t)time(NULL) - 777;
interest = _komodo_interestnew(value,nLockTime,tiptime);
}
}
return(interest);
}
int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_t amount,struct vin_info *V,struct LP_address_utxo **utxos,int32_t numunspents,int32_t suppress_pubkeys,int32_t ignore_cltverr,bits256 privkey,cJSON *privkeys,cJSON *vins,uint8_t *script,int32_t scriptlen)
{
char wifstr[128],spendscriptstr[128]; int32_t i,n,ind,abovei,belowi,maxmode=0; struct vin_info *vp; struct LP_address_utxo *up; int64_t above,below,remains = amount,total = 0;
char wifstr[128],spendscriptstr[128]; int32_t i,n,ind,abovei,belowi,maxmode=0; struct vin_info *vp; struct LP_address_utxo *up; int64_t interest,interestsum,above,below,remains = amount,total = 0;
*totalp = 0;
interestsum = 0;
init_hexbytes_noT(spendscriptstr,script,scriptlen);
bitcoin_priv2wif(coin->wiftaddr,wifstr,privkey,coin->wiftype);
for (i=n=0; i<numunspents; i++)
@ -807,6 +835,14 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
utxos[numunspents] = 0;
total += up->U.value;
remains -= up->U.value;
//if ( coin->electrum == 0 && strcmp(coin->symbol,"KMD") == 0 )
{
if ( (interest= LP_komodo_interest(up->U.txid,up->U.value)) > 0 )
{
interestsum += interest;
char str[65]; printf("%s/%d %.8f interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum));
}
}
vp = &V[n++];
vp->N = vp->M = 1;
vp->signers[0].privkey = privkey;
@ -825,7 +861,7 @@ int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_
return(0);
}
}
*totalp = total;
*totalp = total + interestsum;
return(n);
}
@ -878,7 +914,7 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
return(0);
}
memset(utxos,0,sizeof(utxos));
if ( (numutxos= LP_address_utxo_ptrs(0,utxos,max,ap)) <= 0 )
if ( (numutxos= LP_address_utxo_ptrs(0,utxos,max,ap,coin->smartaddr)) <= 0 )
{
printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos);
return(0);

62
iguana/exchanges/LP_utxo.c

@ -151,13 +151,16 @@ struct LP_utxoinfo *LP_allocated(bits256 txid,int32_t vout)
return(0);
}
int32_t LP_address_utxo_ptrs(int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct LP_address *ap)
int32_t LP_address_utxo_ptrs(int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct LP_address *ap,char *coinaddr)
{
struct LP_address_utxo *up,*tmp; 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);
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\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout);
//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));
if ( up->spendheight <= 0 )
{
if ( LP_allocated(up->U.txid,up->U.vout) == 0 )
@ -169,13 +172,14 @@ int32_t LP_address_utxo_ptrs(int32_t iambob,struct LP_address_utxo **utxos,int32
}
}
portable_mutex_unlock(&LP_utxomutex);
//printf("return n.%d\n",n);
return(n);
}
struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout)
{
struct LP_address *ap; struct LP_address_utxo *up,*tmp;
//printf("%s add addr.%s ht.%d\n",coin->symbol,coinaddr,height);
//printf("LP_address_utxofind %s add addr.%s\n",coin->symbol,coinaddr);
if ( (ap= _LP_address(coin,coinaddr)) != 0 )
{
DL_FOREACH_SAFE(ap->utxos,up,tmp)
@ -190,12 +194,12 @@ struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coina
int32_t LP_address_utxoadd(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];
//printf("%s add addr.%s ht.%d\n",coin->symbol,coinaddr,height);
if ( coin == 0 )
return(0);
if ( spendheight > 0 ) // dont autocreate entries for spends we dont care about
ap = LP_addressfind(coin,coinaddr);
else ap = LP_address(coin,coinaddr);
//printf("%s add addr.%s ht.%d ap.%p\n",coin->symbol,coinaddr,height,ap);
if ( ap != 0 )
{
flag = 0;
@ -204,13 +208,17 @@ int32_t LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,
if ( vout == up->U.vout && bits256_cmp(up->U.txid,txid) == 0 )
{
flag = 1;
if ( up->U.height <= 0 && height > 0 && up->U.height != height )
if ( height > 0 && up->U.height != height && up->SPV <= 0 )
{
if ( up->U.height > 0 )
printf("%s SPV.%d update %s/v%d up->U.height %d <- %d\n",coin->symbol,up->SPV,bits256_str(str,up->U.txid),up->U.vout,up->U.height,height);
up->U.height = height, flag |= 2;
}
if ( spendheight > 0 && up->spendheight != spendheight )
up->spendheight = spendheight, flag |= 4;
if ( 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));
//printf("found >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value));
break;
}
}
@ -220,7 +228,7 @@ int32_t LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,
{
if ( (txobj= LP_gettxout(coin->symbol,coinaddr,txid,vout)) == 0 )
{
//printf("prevent utxoadd since gettxout %s/v%d missing\n",bits256_str(str,txid),vout);
//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);
}
@ -234,8 +242,8 @@ int32_t LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,
DL_APPEND(ap->utxos,up);
portable_mutex_unlock(&coin->addrmutex);
retval = 1;
if ( 0 && height > 0 )
printf("ADDRESS_UTXO >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value));
if ( 0 && height > 0 && strcmp("REVS",coin->symbol) == 0 )
printf("ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",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);
@ -249,7 +257,7 @@ cJSON *LP_address_item(struct iguana_info *coin,struct LP_address_utxo *up,int32
{
jaddbits256(item,"txid",up->U.txid);
jaddnum(item,"vout",up->U.vout);
jaddnum(item,"confirmations",LP_getheight(coin) - up->U.height);
jaddnum(item,"confirmations",LP_getheight(coin) - up->U.height + 1);
jaddnum(item,"amount",dstr(up->U.value));
jaddstr(item,"scriptPubKey","");
}
@ -371,11 +379,12 @@ cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrum
}
if ( up->spendheight <= 0 )
{
if ( backupep != 0 && up->SPV <= 0 )
up->SPV = LP_merkleproof(coin,backupep,up->U.txid,up->U.height);
jaddi(array,LP_address_item(coin,up,electrumret));
n++;
total += up->U.value;
if ( up->SPV >= 0 )
{
jaddi(array,LP_address_item(coin,up,electrumret));
n++;
total += up->U.value;
}
}
//printf("new array %s\n",jprint(array,0));
}
@ -463,9 +472,10 @@ 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++;
}
if ( coin->height != 0 )
ht = LP_getheight(coin) - jint(txobj,"confirmations");
else ht = 0;
ht = LP_txheight(coin,txid);
//if ( coin->height != 0 )
// ht = LP_getheight(coin) - jint(txobj,"confirmations") + 1;
//else ht = 0;
/*if ( ht != 0 && ht < height-2 )
{
printf("REJECT %s %s/v%d ht.%d vs %d confs.%d (%s)\n",symbol,bits256_str(str,txid),v,ht,height,jint(txobj,"confirmations"),jprint(item,0));
@ -475,6 +485,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(coin,coinaddr,txid,v,val,height,-1);
count++;
}
@ -622,6 +633,8 @@ uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_inf
cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJSON *txobj)
{
struct LP_transaction *tx; int32_t i,height,numvouts,numvins,spentvout; cJSON *vins,*vouts,*vout,*vin; bits256 spenttxid; char str[65];
if ( coin->inactive != 0 )
return(0);
if ( txobj != 0 || (txobj= LP_gettx(coin->symbol,txid)) != 0 )
{
if ( coin->electrum == 0 )
@ -639,7 +652,8 @@ cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJS
tx->outpoints[i].value = LP_value_extract(vout,0);
tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest");
LP_destaddr(tx->outpoints[i].coinaddr,vout);
LP_address_utxoadd(coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1);
//printf("from transaction init\n");
//LP_address_utxoadd(coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1);
}
//printf("numvouts.%d\n",numvouts);
}
@ -812,7 +826,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)
{
//struct LP_utxoinfo *utxo;
struct LP_address_utxo *up; uint64_t val,val2=0,txfee,threshold=0; int32_t bypass = 0; char destaddr[64],destaddr2[64]; struct iguana_info *coin = LP_coinfind(symbol);
struct LP_address_utxo *up; uint64_t val,val2=0,txfee,threshold=0; int32_t bypass = 0; char destaddr[64],destaddr2[64],str[65]; struct iguana_info *coin = LP_coinfind(symbol);
if ( bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 )
{
printf("null txid not eligible\n");
@ -825,9 +839,15 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
val = satoshis;
else val = LP_txvalue(destaddr,symbol,txid,vout);
if ( (up= LP_address_utxofind(coin,destaddr,txid,vout)) != 0 && up->spendheight > 0 )
{
//printf("%s/v%d spent %d\n",bits256_str(str,txid),vout,up->spendheight);
return(-2);
}
if ( (up= LP_address_utxofind(coin,destaddr,txid2,vout2)) != 0 && up->spendheight > 0 )
{
//printf("%s/v%d spent %d\n",bits256_str(str,txid2),vout2,up->spendheight);
return(-3);
}
txfee = LP_txfeecalc(LP_coinfind(symbol),0,0);
if ( val >= satoshis && val > (1+LP_MINSIZE_TXFEEMULT)*txfee )
{
@ -849,7 +869,7 @@ int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol
}
} // else printf("no val2\n");
}
char str[65],str2[65];
char str2[65];
if ( val != 0 && val2 != 0 )
printf("spent.%d %s txid or value %.8f < %.8f or val2 %.8f < %.8f, %s/v%d %s/v%d or < 10x txfee %.8f\n",iambob,symbol,dstr(val),dstr(satoshis),dstr(val2),dstr(threshold),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2,dstr(txfee));
if ( val == 0 )

3
iguana/exchanges/LP_utxos.c

@ -520,6 +520,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
//printf("privkey init.(%s) %s\n",coin->symbol,coin->smartaddr);
if ( coin->inactive == 0 )
LP_listunspent_issue(coin->symbol,coin->smartaddr,0);
LP_address(coin,coin->smartaddr);
if ( coin->inactive == 0 && (array= LP_listunspent(coin->symbol,coin->smartaddr)) != 0 )
{
txfee = LP_txfeecalc(coin,0,0);
@ -540,7 +541,7 @@ int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 mypri
txid = jbits256(item,"txid");
vout = juint(item,"vout");
value = LP_value_extract(item,0);
height = LP_getheight(coin) - jint(item,"confirmations");
height = LP_txheight(coin,txid);//LP_getheight(coin) - jint(item,"confirmations") + 1;
}
else
{

89
iguana/exchanges/assetchains.old

@ -0,0 +1,89 @@
#!/bin/bash
set -x
delay=60
source pubkey.txt
echo $pubkey
./komodod -pubkey=$pubkey -ac_name=REVS -ac_supply=1300000 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=SUPERNET -ac_supply=816061 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=DEX -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=PANGEA -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=JUMBLR -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=BET -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=CRYPTO -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=HODL -ac_supply=9999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=SHARK -ac_supply=1401 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=BOTS -ac_supply=999999 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=MGW -ac_supply=999999 -addnode=78.47.196.146 $1 &
#./komodod -pubkey=$pubkey -ac_name=MVP -ac_supply=1000000 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=COQUI -ac_supply=72000000 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=WLC -ac_supply=210000000 -addnode=148.251.190.89 $1 &
./komodod -pubkey=$pubkey -ac_name=KV -ac_supply=1000000 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=CEAL -ac_supply=366666666 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=MESH -ac_supply=1000007 -addnode=78.47.196.146 $1 &
./komodod -pubkey=$pubkey -ac_name=MNZ -ac_supply=257142858 -addnode=51.15.138.138 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=USD -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=EUR -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=JPY -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=GBP -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=AUD -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=CAD -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=CHF -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=NZD -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=CNY -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=RUB -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=MXN -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=BRL -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=INR -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=HKD -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=TRY -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=ZAR -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=PLN -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=NOK -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=SEK -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=DKK -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=CZK -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=HUF -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=ILS -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=KRW -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=MYR -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=PHP -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=RON -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=SGD -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=THB -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=BGN -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=IDR -addnode=78.47.196.146 $1 &
sleep $delay
./komodod -pubkey=$pubkey -ac_name=HRK -addnode=78.47.196.146 $1 &

10
iguana/exchanges/autoprice

@ -1,10 +1,12 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTC\",\"margin\":0.0001}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BTC\",\"rel\":\"KMD\",\"margin\":0.0001}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTC\",\"margin\":0.03}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BTC\",\"rel\":\"KMD\",\"margin\":0.03}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"HUSH\",\"margin\":0.01}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"HUSH\",\"rel\":\"KMD\",\"margin\":0.01}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"USD\",\"margin\":0.01}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"USD\",\"rel\":\"KMD\",\"margin\":0.01}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"JUMBLR\",\"margin\":0.01}"
#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"USD\",\"rel\":\"KMD\",\"margin\":0.01}"
#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"JUMBLR\",\"margin\":0.01}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"JUMBLR\",\"rel\":\"KMD\",\"margin\":0.01}"
#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.0,\"refbase\":\"BTC\",\"refrel\":\"KMD\",\"factor\":0.00006667,\"margin\":-0.2}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"MNZ\",\"offset\":0.0,\"refbase\":\"KMD\",\"refrel\":\"BTC\",\"factor\":15000,\"margin\":-0.2}"

1
iguana/exchanges/enable

@ -2,3 +2,4 @@
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"REVS\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"CHIPS\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"MNZ\"}"

1
iguana/exchanges/profile

@ -0,0 +1 @@
gprof -b ../marketmaker ../gmon.out

3
iguana/exchanges/recentswaps

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

3
iguana/exchanges/stop

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

2
iguana/iguana777.h

@ -150,7 +150,7 @@ struct supernet_info
struct queueitem *DEX_quotes; cJSON *Cunspents,*Cspends;
struct basilisk_swap *swaps[256]; int32_t numswaps;
struct basilisk_message *messagetable; portable_mutex_t messagemutex; queue_t msgQ,p2pQ;
void *ctx;
void *ctx[8];
uint8_t *pingbuf;
struct basilisk_request DEXaccept;
FILE *dexfp;

28
iguana/iguana_mofn.c

@ -238,19 +238,35 @@ int32_t gfshare_test(struct supernet_info *myinfo,int32_t M,int32_t N,int32_t da
return ok!=1;
}
void *bitcoin_ctx()
{
void *ptr;
ptr = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
secp256k1_pedersen_context_initialize(ptr);
secp256k1_rangeproof_context_initialize(ptr);
return(ptr);
}
void iguana_fixsecp(struct supernet_info *myinfo)
{
myinfo->ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
secp256k1_pedersen_context_initialize(myinfo->ctx);
secp256k1_rangeproof_context_initialize(myinfo->ctx);
int32_t i;
for (i=0; i<sizeof(myinfo->ctx)/sizeof(*myinfo->ctx); i++)
{
myinfo->ctx[i] = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
secp256k1_pedersen_context_initialize(myinfo->ctx[i]);
secp256k1_rangeproof_context_initialize(myinfo->ctx[i]);
}
}
void libgfshare_init(struct supernet_info *myinfo,uint8_t _logs[256],uint8_t _exps[510])
{
uint32_t i,x = 1;
myinfo->ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
secp256k1_pedersen_context_initialize(myinfo->ctx);
secp256k1_rangeproof_context_initialize(myinfo->ctx);
for (i=0; i<sizeof(myinfo->ctx)/sizeof(*myinfo->ctx); i++)
{
myinfo->ctx[i] = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
secp256k1_pedersen_context_initialize(myinfo->ctx[i]);
secp256k1_rangeproof_context_initialize(myinfo->ctx[i]);
}
for (i=0; i<255; i++)
{
_exps[i] = x;

138
iguana/iguana_notary.c

@ -58,9 +58,84 @@ void dpow_checkpointset(struct supernet_info *myinfo,struct dpow_checkpoint *che
checkpoint->blockhash.height = height;
}
int32_t dpow_txhasnotarization(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid)
{
cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[35]; bits256 spenttxid; uint64_t notarymask; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0;
if ( (txobj= dpow_gettransaction(myinfo,coin,txid)) != 0 )
{
if ( (vins= jarray(&numvins,txobj,"vin")) != 0 )
{
if ( numvins >= DPOW_MIN_ASSETCHAIN_SIGS )
{
notarymask = numnotaries = 0;
for (i=0; i<numvins; i++)
{
vin = jitem(vins,i);
spenttxid = jbits256(vin,"txid");
spentvout = jint(vin,"vout");
if ( (spentobj= dpow_gettransaction(myinfo,coin,spenttxid)) != 0 )
{
if ( (vouts= jarray(&numvouts,spentobj,"vout")) != 0 )
{
if ( spentvout < numvouts )
{
vout = jitem(vouts,spentvout);
if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) == sizeof(script)*2 )
{
len >>= 1;
decode_hex(script,len,hexstr);
if ( script[0] == 33 && script[34] == 0xac )
{
for (j=0; j<sizeof(Notaries_elected)/sizeof(*Notaries_elected); j++)
{
if ( strncmp(Notaries_elected[j][1],hexstr+2,66) == 0 )
{
if ( ((1LL << j) & notarymask) == 0 )
{
printf("n%d ",j);
numnotaries++;
notarymask |= (1LL << j);
break;
}
}
}
}
}
}
}
free_json(spentobj);
}
}
if ( numnotaries > 0 )
{
if ( numnotaries >= DPOW_MIN_ASSETCHAIN_SIGS )
hasnotarization = 1;
printf("numnotaries.%d %s hasnotarization.%d\n",numnotaries,coin->symbol,hasnotarization);
}
}
}
free_json(txobj);
}
return(hasnotarization);
}
int32_t dpow_hasnotarization(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *blockjson)
{
int32_t i,n,hasnotarization = 0; bits256 txid; cJSON *txarray;
if ( (txarray= jarray(&n,blockjson,"tx")) != 0 )
{
for (i=0; i<n; i++)
{
txid = jbits256i(txarray,i);
hasnotarization += dpow_txhasnotarization(myinfo,coin,txid);
}
}
return(hasnotarization);
}
void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t height,bits256 hash,uint32_t timestamp,uint32_t blocktime)
{
void **ptrs; char str[65]; struct dpow_checkpoint checkpoint; int32_t freq,minsigs; //uint8_t pubkeys[64][33];
void **ptrs; char str[65]; cJSON *blockjson; struct iguana_info *coin; struct dpow_checkpoint checkpoint; int32_t freq,minsigs; //uint8_t pubkeys[64][33];
dpow_checkpointset(myinfo,&dp->last,height,hash,timestamp,blocktime);
checkpoint = dp->srcfifo[dp->srcconfirms];
if ( strcmp("BTC",dp->dest) == 0 )
@ -71,22 +146,61 @@ void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t he
else
{
freq = 1;
minsigs = 11;
minsigs = DPOW_MIN_ASSETCHAIN_SIGS;
}
printf("%s/%s src ht.%d dest.%u nonz.%d %s minsigs.%d\n",dp->symbol,dp->dest,checkpoint.blockhash.height,dp->destupdated,bits256_nonz(checkpoint.blockhash.hash),bits256_str(str,dp->last.blockhash.hash),minsigs);
dpow_fifoupdate(myinfo,dp->srcfifo,dp->last);
if ( dp->SRCREALTIME == 0 && strcmp(dp->dest,"KMD") == 0 )
return;
if ( strcmp(dp->dest,"KMD") == 0 )
{
//if ( dp->SRCREALTIME == 0 )
// return;
if ( (coin= iguana_coinfind(dp->symbol)) != 0 )
{
hash = dpow_getbestblockhash(myinfo,coin);
if ( bits256_nonz(hash) != 0 )
{
if ( (blockjson= dpow_getblock(myinfo,coin,hash)) != 0 )
{
if ( dpow_hasnotarization(myinfo,coin,blockjson) <= 0 )
{
height = jint(blockjson,"height");
blocktime = juint(blockjson,"time");
free_json(blockjson);
if ( height > 0 && blocktime > 0 )
{
dpow_checkpointset(myinfo,&dp->last,height,hash,timestamp,blocktime);
//printf("dynamic set %s/%s %s <- height.%d\n",dp->symbol,dp->dest,bits256_str(str,hash),height);
checkpoint = dp->last;
} else return;
if ( bits256_nonz(dp->activehash) != 0 && bits256_cmp(dp->activehash,checkpoint.blockhash.hash) == 0 )
{
printf("activehash.(%s) is current checkpoint, skip\n",bits256_str(str,dp->activehash));
return;
}
else if ( bits256_nonz(dp->lastnotarized) != 0 && bits256_cmp(dp->lastnotarized,checkpoint.blockhash.hash) == 0 )
{
printf("lastnotarized.(%s) is current checkpoint, skip\n",bits256_str(str,dp->lastnotarized));
return;
}
//printf("checkpoint.(%s) is not active and not lastnotarized\n",bits256_str(str,checkpoint.blockhash.hash));
} else return;
} else return;
} else return;
} else return;
}
if ( bits256_nonz(checkpoint.blockhash.hash) != 0 && (checkpoint.blockhash.height % freq) == 0 )
{
//printf("%s/%s src ht.%d dest.%u nonz.%d %s minsigs.%d\n",dp->symbol,dp->dest,checkpoint.blockhash.height,dp->destupdated,bits256_nonz(checkpoint.blockhash.hash),bits256_str(str,dp->last.blockhash.hash),minsigs);
dpow_heightfind(myinfo,dp,checkpoint.blockhash.height + 1000);
ptrs = calloc(1,sizeof(void *)*5 + sizeof(struct dpow_checkpoint));
ptrs[0] = (void *)myinfo;
ptrs[1] = (void *)dp;
ptrs[2] = (void *)(uint64_t)minsigs;
ptrs[3] = (void *)DPOW_DURATION;
if ( strcmp(dp->dest,"KMD") == 0 )
ptrs[3] = (void *)(DPOW_DURATION * 60); // essentially try forever for assetchains
else ptrs[3] = (void *)DPOW_DURATION;
ptrs[4] = 0;
memcpy(&ptrs[5],&checkpoint,sizeof(checkpoint));
dp->activehash = checkpoint.blockhash.hash;
if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_statemachinestart,(void *)ptrs) != 0 )
{
}
@ -158,7 +272,7 @@ void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp)
if ( (height= dpow_getchaintip(myinfo,&blockhash,&blocktime,dp->desttx,&dp->numdesttx,dest)) != dp->destchaintip.blockhash.height && height >= 0 )
{
char str[65];
if ( strcmp(dp->symbol,"KMD") == 0 || height != dp->destchaintip.blockhash.height+1 )
if ( strcmp(dp->symbol,"KMD") == 0 )//|| height != dp->destchaintip.blockhash.height+1 )
printf("[%s].%d %s %s height.%d vs last.%d\n",dp->symbol,dp->SRCHEIGHT,dp->dest,bits256_str(str,blockhash),height,dp->destchaintip.blockhash.height);
if ( height <= dp->destchaintip.blockhash.height )
{
@ -176,7 +290,7 @@ void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp)
}
if ( (height= dpow_getchaintip(myinfo,&blockhash,&blocktime,dp->srctx,&dp->numsrctx,src)) != dp->last.blockhash.height && height >= 0 )
{
char str[65]; printf("[%s].%d %s %s height.%d vs last.%d\n",dp->dest,dp->SRCHEIGHT,dp->symbol,bits256_str(str,blockhash),height,dp->last.blockhash.height);
//char str[65]; printf("[%s].%d %s %s height.%d vs last.%d\n",dp->dest,dp->SRCHEIGHT,dp->symbol,bits256_str(str,blockhash),height,dp->last.blockhash.height);
if ( dp->lastheight == 0 )
dp->lastheight = height-1;
if ( height < dp->last.blockhash.height )
@ -196,7 +310,7 @@ void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp)
}
}
}
else
else if ( strcmp(dp->symbol,"KMD") == 0 )
{
while ( dp->lastheight <= height )
{
@ -204,6 +318,12 @@ void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp)
dpow_srcupdate(myinfo,dp,dp->lastheight++,blockhash,(uint32_t)time(NULL),blocktime);
}
}
else
{
dp->lastheight = height;
blockhash = dpow_getblockhash(myinfo,src,dp->lastheight);
dpow_srcupdate(myinfo,dp,dp->lastheight,blockhash,(uint32_t)time(NULL),blocktime);
}
} //else printf("error getchaintip for %s\n",dp->symbol);
} else printf("iguana_dPoWupdate missing src.(%s) %p or dest.(%s) %p\n",dp->symbol,src,dp->dest,dest);
}

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 -pg -o marketmaker -I../crypto777 exchanges/mm.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm

1
iguana/m_splitfund

@ -22,6 +22,7 @@ curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"WLC\",\"agent\":\"iguana\
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KV\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CEAL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MESH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MNZ\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"USD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"
curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"EUR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}"

8
iguana/main.c

@ -71,13 +71,17 @@ int32_t SuperNET_str2hex(uint8_t *hex,char *str)
void SuperNET_hex2str(char *str,uint8_t *hex,int32_t len)
{
init_hexbytes_noT(str,hex,len);
init_hexbytes_noT(str,hex,len);
}
void *bitcoin_ctx();
struct supernet_info *SuperNET_MYINFO(char *passphrase)
{
if ( MYINFO.ctx == 0 )
int32_t i;
if ( MYINFO.ctx[0] == 0 )
{
for (i=0; i<sizeof(MYINFO.ctx)/sizeof(*MYINFO.ctx); i++)
MYINFO.ctx[i] = bitcoin_ctx();
OS_randombytes(MYINFO.privkey.bytes,sizeof(MYINFO.privkey));
MYINFO.myaddr.pubkey = curve25519(MYINFO.privkey,curve25519_basepoint9());
printf("SuperNET_MYINFO: generate session keypair\n");

Loading…
Cancel
Save