diff --git a/iguana/SuperNET.h b/iguana/SuperNET.h index 4a963b279..1d8ef048a 100755 --- a/iguana/SuperNET.h +++ b/iguana/SuperNET.h @@ -78,7 +78,8 @@ struct supernet_info char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay; uint32_t expiration,dirty; int32_t Debuglevel,readyflag,dead,POLLTIMEOUT; char rpcsymbol[16],LBpoint[64],PUBpoint[64]; //int32_t pullsock,subclient,lbclient,lbserver,servicesock,pubglobal,pubrelays,numservers; - bits256 privkey,persistent_priv,BTCmarkerhash; char secret[2048],NXTAPIURL[512],permanentfile[1024]; + bits256 privkey,persistent_priv,BTCmarkerhash,instantdex_category,pangea_category; + char secret[2048],NXTAPIURL[512],permanentfile[1024]; uint8_t *recvbuf[6]; struct supernet_address myaddr; int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay; diff --git a/iguana/SuperNET_category.c b/iguana/SuperNET_category.c index c56bce779..f8c570169 100755 --- a/iguana/SuperNET_category.c +++ b/iguana/SuperNET_category.c @@ -204,11 +204,18 @@ char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag void category_init(struct supernet_info *myinfo) { - bits256 pangeahash; + bits256 pangeahash,instantdexhash; category_subscribe(myinfo,GENESIS_PUBKEY,GENESIS_PUBKEY); pangeahash = calc_categoryhashes(0,"pangea",0); + myinfo->pangea_category = pangeahash; category_subscribe(myinfo,pangeahash,GENESIS_PUBKEY); category_processfunc(pangeahash,GENESIS_PUBKEY,pangea_hexmsg); category_chain_functions(myinfo,pangeahash,GENESIS_PUBKEY,sizeof(bits256),sizeof(bits256),0,0,0,0,0,0); - exchanges777_init(myinfo,0,0); + instantdexhash = calc_categoryhashes(0,"InstantDEX",0); + myinfo->instantdex_category = instantdexhash; + category_subscribe(myinfo,instantdexhash,GENESIS_PUBKEY); + category_processfunc(instantdexhash,GENESIS_PUBKEY,InstantDEX_hexmsg); + category_processfunc(instantdexhash,myinfo->myaddr.persistent,InstantDEX_hexmsg); + + //exchanges777_init(myinfo,0,0); } diff --git a/iguana/exchanges/bitcoin.c b/iguana/exchanges/bitcoin.c index 36fa64470..9e728fa31 100755 --- a/iguana/exchanges/bitcoin.c +++ b/iguana/exchanges/bitcoin.c @@ -45,7 +45,7 @@ int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr memcpy(rmd160,buf+1,20); if ( (buf[len - 4]&0xff) == hash.bytes[31] && (buf[len - 3]&0xff) == hash.bytes[30] &&(buf[len - 2]&0xff) == hash.bytes[29] &&(buf[len - 1]&0xff) == hash.bytes[28] ) { - //printf("coinaddr.(%s) valid checksum\n",coinaddr); + printf("coinaddr.(%s) valid checksum addrtype.%02x\n",coinaddr,*addrtypep); return(20); } else @@ -67,9 +67,6 @@ char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160, calc_rmd160_sha256(data+1,pubkey_or_rmd160,len); else memcpy(data+1,pubkey_or_rmd160,20); //btc_convrmd160(checkaddr,addrtype,data+1); - //for (i=0; i<20; i++) - // printf("%02x",data[i+1]); - //printf(" RMD160 len.%d\n",len); data[0] = addrtype; hash = bits256_doublesha256(0,data,21); for (i=0; i<4; i++) @@ -455,7 +452,7 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha jaddnum(json,"volume",volume); jaddstr(json,"BTC",myinfo->myaddr.BTC); jaddnum(json,"minperc",jdouble(argjson,"minperc")); - //printf("trade dir.%d (%s/%s) %.6f vol %.8f\n",dir,base,"BTC",price,volume); + printf("trade dir.%d (%s/%s) %.6f vol %.8f\n",dir,base,"BTC",price,volume); if ( (str= instantdex_createaccept(myinfo,&ap,exchange,base,"BTC",price,volume,-dir,dir > 0 ? "BTC" : base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,0,jdouble(argjson,"minperc"))) != 0 && ap != 0 ) retstr = instantdex_checkoffer(myinfo,&txid,exchange,ap,json), free(str); else printf("null return queueaccept\n"); diff --git a/iguana/exchanges777.h b/iguana/exchanges777.h index c0b042a4d..18a3eddce 100755 --- a/iguana/exchanges777.h +++ b/iguana/exchanges777.h @@ -115,7 +115,7 @@ struct instantdex_offer struct instantdex_accept { - struct queueitem DL; + struct queueitem DL; uint8_t peerhas[IGUANA_MAXPEERS/8]; uint64_t pendingvolume64,orderid; uint32_t dead; int32_t didstate; struct instantdex_offer offer; diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 517455d8a..9c1d51267 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -628,8 +628,9 @@ void iguana_helper(void *arg) void iguana_coinloop(void *arg) { struct iguana_info *coin,**coins = arg; - struct iguana_bundle *bp; int32_t flag,i,n,bundlei; bits256 zero; char str[2065]; - uint32_t now; + struct iguana_bundle *bp; struct supernet_info *myinfo; int32_t flag,i,n,bundlei; + bits256 zero; char str[2065]; uint32_t now; + myinfo = SuperNET_MYINFO(0); n = (int32_t)(long)coins[0]; coins++; printf("begin coinloop[%d]\n",n); @@ -709,7 +710,7 @@ void iguana_coinloop(void *arg) } if ( coin->longestchain+10000 > coin->blocks.maxbits ) iguana_recvalloc(coin,coin->longestchain + 100000); - flag += iguana_processrecv(coin); + flag += iguana_processrecv(myinfo,coin); } coin->idletime = (uint32_t)time(NULL); } diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 0c097f9ba..7f5b72ac5 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -145,8 +145,9 @@ extern int32_t IGUANA_NUMHELPERS; #define MSG_TX 1 #define MSG_BLOCK 2 #define MSG_FILTERED_BLOCK 3 -#define MSG_BUNDLE_HEADERS 255 +#define MSG_QUOTE 253 #define MSG_BUNDLE 254 +#define MSG_BUNDLE_HEADERS 255 #define IGUANA_MAXLOCATORS 64 #define IGUANA_MAXINV 50000 @@ -610,6 +611,7 @@ uint64_t iguana_miningreward(struct iguana_info *coin,uint32_t blocknum); // tx int32_t iguana_rwtx(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp,int32_t isvpncoin); void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *txids,int32_t n); +void iguana_gotquotesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *quotes,int32_t n); void iguana_gotunconfirmedM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgtx *tx,uint8_t *data,int32_t datalen); void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *blockhashes,int32_t n); @@ -630,7 +632,7 @@ int32_t ramcoder_decompress(uint8_t *data,int32_t maxlen,uint8_t *bits,uint32_t int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 seed); uint64_t hconv_bitlen(uint64_t bitlen); struct iguana_block *iguana_blockptr(char *debugstr,struct iguana_info *coin,int32_t height); -int32_t iguana_processrecv(struct iguana_info *coin); // single threaded +int32_t iguana_processrecv(struct supernet_info *myinfo,struct iguana_info *coin); // single threaded void iguana_recvalloc(struct iguana_info *coin,int32_t numitems); void iguana_coins(void *arg); int32_t iguana_savehdrs(struct iguana_info *coin); @@ -755,7 +757,7 @@ struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,st int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi); int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,uint32_t *unspentindp,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s); struct iguana_info *iguana_coinselect(); -void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr); +void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr); struct iguana_peer *iguana_peerslot(struct iguana_info *coin,uint64_t ipbits,int32_t forceflag); void iguana_dedicatedglue(void *arg); void SuperNET_remotepeer(struct supernet_info *myinfo,struct iguana_info *coin,char *symbol,char *ipaddr,int32_t supernetflag); @@ -920,10 +922,10 @@ int32_t iguana_blast(struct iguana_info *coin,struct iguana_peer *addr); int32_t iguana_validated(struct iguana_info *coin); void iguana_volatilesalloc(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t copyflag); int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr); -int32_t iguana_process_msgrequestQ(struct iguana_info *coin); +int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_info *coin); uint32_t iguana_fastfindinit(struct iguana_info *coin); int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *scriptlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi); -int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,uint8_t rmd160[20],char *address); +int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,char *address); int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag); bits256 iguana_str2priv(struct supernet_info *myinfo,struct iguana_info *coin,char *str); int32_t iguana_spentflag(struct iguana_info *coin,int64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,int16_t spent_hdrsi,uint32_t spent_unspentind,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount); @@ -961,6 +963,10 @@ cJSON *iguana_privkeysjson(struct supernet_info *myinfo,struct iguana_info *coin char *iguana_inputaddress(struct iguana_info *coin,char *coinaddr,cJSON *vinobj); struct iguana_waddress *iguana_getaccountaddress(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,char *coinaddr,char *account); int32_t iguana_uvaltxid(struct supernet_info *myinfo,bits256 *txidp,struct iguana_info *coin,int16_t hdrsi,uint32_t unspentind); +struct instantdex_accept *instantdex_quotefind(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 encodedhash); +int32_t instantdex_quoterequest(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_peer *addr,bits256 encodedhash); +int32_t instantdex_peerhas_clear(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr); +int32_t instantdex_quote(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,int32_t recvlen); extern int32_t HDRnet,netBLOCKS; diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c index 6a5f15ea8..48125c532 100755 --- a/iguana/iguana_accept.c +++ b/iguana/iguana_accept.c @@ -14,6 +14,7 @@ ******************************************************************************/ #include "iguana777.h" +#include "exchanges777.h" struct iguana_accept { struct queueitem DL; char ipaddr[64]; uint32_t ipbits; int32_t sock; uint16_t port; }; @@ -175,9 +176,9 @@ void iguana_msgrequestQ(struct iguana_info *coin,struct iguana_peer *addr,int32_ queue_enqueue("msgrequest",&coin->msgrequestQ,&msg->DL,0); } -int32_t iguana_process_msgrequestQ(struct iguana_info *coin) +int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_info *coin) { - struct iguana_peermsgrequest *msg; int32_t height,len,flag = 0; bits256 checktxid; struct iguana_txid *tx,T; + struct iguana_peermsgrequest *msg; struct instantdex_accept *ap; int32_t height,len,flag = 0; bits256 checktxid; struct iguana_txid *tx,T; if ( (msg= queue_dequeue(&coin->msgrequestQ,0)) != 0 ) { flag = 1; @@ -222,6 +223,20 @@ int32_t iguana_process_msgrequestQ(struct iguana_info *coin) { } + else if ( msg->type == MSG_QUOTE ) + { + if ( (ap= instantdex_quotefind(myinfo,coin,msg->addr,msg->hash2)) == 0 ) + { + if ( GETBIT(ap->peerhas,msg->addr->addrind) == 0 ) + { + if ( (len= instantdex_quoterequest(myinfo,coin,&coin->blockspace[sizeof(struct iguana_msghdr)],sizeof(coin->blockspace),msg->addr,msg->hash2)) > 0 ) + { + iguana_queue_send(coin,msg->addr,0,coin->blockspace,"quote",len,0,0); + SETBIT(ap->peerhas,msg->addr->addrind); + } + } + } + } } free(msg); } diff --git a/iguana/iguana_exchanges.c b/iguana/iguana_exchanges.c index c9484f9a9..9037e022f 100755 --- a/iguana/iguana_exchanges.c +++ b/iguana/iguana_exchanges.c @@ -933,7 +933,7 @@ struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSO void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sleepflag) { - int32_t i,n; cJSON *argjson,*item; bits256 instantdexhash; struct exchange_info *exchange; + int32_t i,n; cJSON *argjson,*item; struct exchange_info *exchange; if ( (exchange= exchanges777_find("bitcoin")) == 0 && (exchange= exchange_create("bitcoin",0)) != 0 ) myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; if ( 0 && exchanges != 0 ) @@ -959,11 +959,6 @@ void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sle } free_json(argjson); } - instantdexhash = calc_categoryhashes(0,"InstantDEX",0); - printf("InstantDEX:\n"); - category_subscribe(myinfo,instantdexhash,GENESIS_PUBKEY); - category_processfunc(instantdexhash,GENESIS_PUBKEY,InstantDEX_hexmsg); - category_processfunc(instantdexhash,myinfo->myaddr.persistent,InstantDEX_hexmsg); } #include "../includes/iguana_apidefs.h" @@ -973,9 +968,12 @@ THREE_STRINGS_AND_THREE_INTS(InstantDEX,orderbook,exchange,base,rel,depth,allfie struct exchange_info *ptr; if ( remoteaddr == 0 ) { - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qprices(ptr,base,rel,juint(json,"maxseconds"),allfields,depth,json,0,ptr->commission)); - else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( exchange != 0 && exchange[0] != 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qprices(ptr,base,rel,juint(json,"maxseconds"),allfields,depth,json,0,ptr->commission)); + else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no exchange specified\"}")); } else return(clonestr("{\"error\":\"no remote for this API\"}")); } diff --git a/iguana/iguana_instantdex.c b/iguana/iguana_instantdex.c index d1a579cf8..185d28524 100755 --- a/iguana/iguana_instantdex.c +++ b/iguana/iguana_instantdex.c @@ -320,15 +320,14 @@ bits256 instantdex_rwoffer(int32_t rwflag,int32_t *lenp,uint8_t *serialized,stru char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *offer,cJSON *argjson,char *cmdstr,bits256 desthash,int32_t hops,void *extraser,int32_t extralen) { - char *reqstr,*hexstr,*retstr; struct instantdex_msghdr *msg; bits256 instantdexhash,orderhash; + char *reqstr,*hexstr,*retstr; struct instantdex_msghdr *msg; bits256 orderhash; int32_t i,olen,slen,datalen; uint8_t serialized[sizeof(*offer) + 2]; uint64_t nxt64bits; - instantdexhash = calc_categoryhashes(0,"InstantDEX",0); - category_subscribe(myinfo,instantdexhash,GENESIS_PUBKEY); + category_subscribe(myinfo,myinfo->instantdex_category,GENESIS_PUBKEY); jaddstr(argjson,"cmd",cmdstr); jaddstr(argjson,"agent","SuperNET"); jaddstr(argjson,"method","DHT"); jaddstr(argjson,"handle",myinfo->handle); - jaddbits256(argjson,"categoryhash",instantdexhash); + jaddbits256(argjson,"categoryhash",myinfo->instantdex_category); jaddbits256(argjson,"traderpub",myinfo->myaddr.persistent); orderhash = instantdex_rwoffer(1,&olen,serialized,offer); if ( 1 ) @@ -362,7 +361,7 @@ char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *o printf(">>>>>>>>>>>> instantdex send.(%s) datalen.%d allocsize.%d crc.%x\n",cmdstr,datalen,msg->sig.allocsize,calc_crc32(0,(void *)((long)msg + 8),datalen-8)); hexstr = malloc(msg->sig.allocsize*2 + 1); init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize); - retstr = SuperNET_categorymulticast(myinfo,0,instantdexhash,desthash,hexstr,0,hops,1,argjson,0); + retstr = SuperNET_categorymulticast(myinfo,0,myinfo->instantdex_category,desthash,hexstr,0,hops,1,argjson,0); free_json(argjson), free(hexstr), free(msg); return(retstr); } @@ -674,6 +673,8 @@ struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinf struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t requeue) { struct instantdex_accept PAD,*ap,*retap = 0; uint32_t now; cJSON *item,*offerobj; char *type; + if ( exchange == 0 ) + return(0); now = (uint32_t)time(NULL); memset(&PAD,0,sizeof(PAD)); queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0); @@ -693,9 +694,9 @@ struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,stru //printf("item.(%s)\n",jprint(item,0)); if ( (offerobj= jobj(item,"offer")) != 0 && (type= jstr(offerobj,"type")) != 0 ) { - if ( strcmp(type,"bid") == 0 && bids != 0 ) + if ( bids != 0 && strcmp(type,"bid") == 0 ) jaddi(bids,jduplicate(offerobj)); - else if ( strcmp(type,"ask") == 0 && asks != 0 ) + else if ( asks != 0 && strcmp(type,"ask") == 0 ) jaddi(asks,jduplicate(offerobj)); } free_json(item); @@ -710,6 +711,122 @@ struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,stru return(retap); } +int32_t instantdex_peerhas_clear(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr) +{ + struct instantdex_accept PAD,*ap; struct exchange_info *exchange; int32_t ind,num = 0; + if ( addr != 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) + { + //printf("clear all bits for addrind.%d\n",addr->addrind); + ind = addr->addrind; + memset(&PAD,0,sizeof(PAD)); + queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0); + while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD ) + { + CLEARBIT(ap->peerhas,ind); + queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); + } + } + return(num); +} + +uint64_t instantdex_basebits(char *base) +{ + if ( is_decimalstr(base) != 0 ) + return(calc_nxt64bits(base)); + else return(stringbits(base)); +} + +int32_t instantdex_unbasebits(char *base,uint64_t basebits) +{ + char tmp[9]; + unstringbits(tmp,basebits); + if ( iguana_coinfind(tmp) == 0 ) + { + sprintf(base,"%lld",(long long)basebits); + return(1); + } + else + { + strcmp(base,tmp); + return(0); + } +} + +uint64_t instantdex_decodehash(char *base,char *rel,int64_t *pricep,bits256 encodedhash) +{ + instantdex_unbasebits(base,encodedhash.ulongs[1]); + instantdex_unbasebits(rel,encodedhash.ulongs[2]); + *pricep = encodedhash.ulongs[3]; + return(encodedhash.ulongs[0]); +} + +bits256 instantdex_encodehash(char *base,char *rel,int64_t price,uint64_t orderid) +{ + bits256 encodedhash; + encodedhash.ulongs[0] = orderid; + encodedhash.ulongs[1] = instantdex_basebits(base); + encodedhash.ulongs[2] = instantdex_basebits(rel); + encodedhash.ulongs[3] = price; + return(encodedhash); +} + +struct instantdex_accept *instantdex_quotefind(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 encodedhash) +{ + char base[9],rel[9]; int64_t pricetoshis; uint64_t orderid; + orderid = instantdex_decodehash(base,rel,&pricetoshis,encodedhash); + return(instantdex_offerfind(myinfo,exchanges777_find("bitcoin"),0,0,orderid,base,rel,1)); +} + +int32_t instantdex_quoterequest(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_peer *addr,bits256 encodedhash) +{ + struct instantdex_accept *ap; int32_t olen; bits256 orderhash; + if ( (ap= instantdex_quotefind(myinfo,coin,addr,encodedhash)) != 0 ) + { + orderhash = instantdex_rwoffer(1,&olen,serialized,&ap->offer); + if ( orderhash.ulongs[0] == ap->orderid ) + return(olen); + else return(-1); + } + return(0); +} + +int32_t instantdex_quote(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,int32_t recvlen) +{ + bits256 orderhash,encodedhash; int32_t checklen; struct instantdex_accept A,*ap; + memset(&A,0,sizeof(A)); + orderhash = instantdex_rwoffer(0,&checklen,serialized,&A.offer); + if ( checklen == recvlen ) + { + encodedhash = instantdex_encodehash(A.offer.base,A.offer.rel,A.offer.price64,A.orderid); + if ( (ap= instantdex_quotefind(myinfo,coin,addr,encodedhash)) == 0 ) + { + init_hexbytes_noT(addr->TXDATA.ptr,serialized,recvlen); + SuperNET_hexmsgadd(myinfo,myinfo->instantdex_category,GENESIS_PUBKEY,addr->TXDATA.ptr,tai_now(),addr->ipaddr); + } + else + { + SETBIT(ap->peerhas,addr->addrind); + printf("instantdex_quote: got %llx which was already there\n",(long long)encodedhash.txid); + } + } else printf("instantdex_quote: checklen.%d != recvlen.%d\n",checklen,recvlen); + return(checklen); +} + +void instantdex_propagate(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap) +{ + bits256 orderhash; uint8_t serialized[8192]; int32_t i,len; struct iguana_peer *addr; struct iguana_info *coin; + orderhash = instantdex_rwoffer(1,&len,&serialized[sizeof(struct iguana_msghdr)],&ap->offer); + if ( (coin= iguana_coinfind("BTCD")) != 0 && coin->peers.numranked > 0 ) + { + for (i=0; ipeers.numranked; i++) + if ( (addr= coin->peers.ranked[i]) != 0 && addr->supernet != 0 && addr->usock >= 0 && GETBIT(ap->peerhas,addr->addrind) == 0 ) + { + SETBIT(ap->peerhas,addr->addrind); + iguana_queue_send(coin,addr,0,serialized,"quote",len,0,0); + } + } +} + struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,double minperc) { struct instantdex_accept PAD,*ap,*retap = 0; double aveprice;//,retvals[4]; @@ -1134,6 +1251,7 @@ char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_acc printf("myside.(%s) != base.%s or rel.%s\n",mysidestr,base,rel); } instantdex_acceptset(ap,base,rel,duration,myside,acceptdir,price,basevolume,offerer,0,minperc); + instantdex_propagate(myinfo,exchange,ap); if ( queueflag != 0 ) { printf("acceptableQ <- %llu\n",(long long)ap->orderid); @@ -1147,10 +1265,9 @@ char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_acc void instantdex_update(struct supernet_info *myinfo) { - struct instantdex_msghdr *pm; struct category_msg *m; bits256 instantdexhash; char *str,remote[64]; queue_t *Q; struct queueitem *item; struct category_info *cat; - instantdexhash = calc_categoryhashes(0,"InstantDEX",0); - //char str2[65]; printf("instantdexhash.(%s)\n",bits256_str(str2,instantdexhash)); - if ( (Q= category_Q(&cat,instantdexhash,myinfo->myaddr.persistent)) != 0 && queue_size(Q) > 0 && (item= Q->list) != 0 ) + struct instantdex_msghdr *pm; struct category_msg *m; char *str,remote[64]; queue_t *Q; struct queueitem *item; struct category_info *cat; + //char str2[65]; printf("myinfo->instantdex_category.(%s)\n",bits256_str(str2,myinfo->instantdex_category)); + if ( (Q= category_Q(&cat,myinfo->instantdex_category,myinfo->myaddr.persistent)) != 0 && queue_size(Q) > 0 && (item= Q->list) != 0 ) { m = (void *)item; m = queue_dequeue(Q,0); diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index e21f5e8ff..732842d99 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -502,10 +502,10 @@ int32_t iguana_send_hashes(struct iguana_info *coin,char *command,struct iguana_ return(retval); } -int32_t iguana_intvectors(struct iguana_info *coin,struct iguana_peer *addr,int32_t processflag,uint8_t *data,int32_t datalen) +int32_t iguana_intvectors(struct iguana_info *coin,struct iguana_peer *addr,int32_t processflag,uint8_t *data,int32_t datalen) // other side needs to be a bit smart about what hashes are sents in { - uint32_t type; bits256 *txids=0,*blockhashes=0,hash; int32_t i,n,m,len; uint64_t x; - len = n = m = 0; + uint32_t type; bits256 *txids=0,*quotes=0,*blockhashes=0,hash; int32_t i,n,q,m,len; uint64_t x; + len = n = m = q = 0; len += iguana_rwvarint(0,&data[len],&x); for (i=0; i 0 ) + { + if ( q != x ) + quotes = myrealloc('q',quotes,(int32_t)((x+1)*sizeof(*quotes)),(q+1)*sizeof(*quotes)); + if ( processflag != 0 ) + iguana_gotquotesM(coin,addr,quotes,q), quotes = 0; + } if ( txids != 0 ) myfree(txids,sizeof(*txids) * (x+1)); if ( blockhashes != 0 ) @@ -559,29 +575,47 @@ int32_t iguana_intvectors(struct iguana_info *coin,struct iguana_peer *addr,int3 int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen) { - uint8_t serialized[16384]; char *retstr; + uint8_t serialized[16384]; char *retstr; struct supernet_info *myinfo = SuperNET_MYINFO(0); int32_t i,retval,ishost,delay,srvmsg,bloom,sendlen=0,intvectors,len= -100; uint64_t nonce,x; bits256 hash2; bloom = intvectors = srvmsg = -1; if ( addr != 0 ) { addr->lastcontact = (uint32_t)time(NULL); strcpy(addr->lastcommand,H->command); - } - retval = 0; - //printf("iguana_msgparser from (%s) parse.(%s) len.%d\n",addr->ipaddr,H->command,recvlen); - if ( strncmp(H->command,"SuperNET",strlen("SuperNET")) == 0 ) - { - addr->supernet = 1; - addr->msgcounts.verack++; - len = recvlen; - if ( (retstr= SuperNET_p2p(coin,addr,&delay,addr->ipaddr,data,recvlen,H->command[strlen("SuperNET")]=='b')) != 0 ) + //printf("iguana_msgparser from (%s) parse.(%s) len.%d\n",addr->ipaddr,H->command,recvlen); + if ( strncmp(H->command,"SuperNET",strlen("SuperNET")) == 0 ) { - iguana_send_supernet(coin,addr,retstr,delay); - free(retstr); + addr->supernet = 1; + addr->msgcounts.verack++; + len = recvlen; + if ( (retstr= SuperNET_p2p(coin,addr,&delay,addr->ipaddr,data,recvlen,H->command[strlen("SuperNET")]=='b')) != 0 ) + { + iguana_send_supernet(coin,addr,retstr,delay); + free(retstr); + } + //printf("GOT.(%s) [%s] len.%d from %s -> (%s)\n",H->command,data,recvlen,addr->ipaddr,retstr==0?"null":retstr); + return(0); + } + else if ( strcmp(H->command,"InstantDEX") == 0 ) + { + init_hexbytes_noT(addr->TXDATA.ptr,data,recvlen); + SuperNET_hexmsgadd(myinfo,myinfo->instantdex_category,GENESIS_PUBKEY,addr->TXDATA.ptr,tai_now(),addr->ipaddr); + return(0); + } + else if ( strcmp(H->command,"pangea") == 0 ) + { + init_hexbytes_noT(addr->TXDATA.ptr,data,recvlen); + SuperNET_hexmsgadd(myinfo,myinfo->pangea_category,GENESIS_PUBKEY,addr->TXDATA.ptr,tai_now(),addr->ipaddr); + return(0); + } + else if ( strcmp(H->command,"quote") == 0 ) + { + instantdex_quote(myinfo,coin,addr,data,recvlen); + return(0); } - //printf("GOT.(%s) [%s] len.%d from %s -> (%s)\n",H->command,data,recvlen,addr->ipaddr,retstr==0?"null":retstr); } - else if ( (ishost= (strcmp(H->command,"getblocks") == 0)) || strcmp(H->command,"block") == 0 ) + retval = 0; + if ( (ishost= (strcmp(H->command,"getblocks") == 0)) || strcmp(H->command,"block") == 0 ) { if ( addr != 0 ) { @@ -597,11 +631,11 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc } else len = iguana_peergetrequest(coin,addr,data,recvlen,1); } } - else if ( (ishost= (strcmp(H->command,"getdata") == 0)) || strcmp(H->command,"inv") == 0 ) + else if ( (ishost= (strncmp(H->command,"inv",3) == 0)) || strcmp(H->command,"getdata") == 0 ) { if ( addr != 0 ) { - if ( ishost != 0 ) + if ( ishost == 0 ) { addr->msgcounts.getdata++; len = iguana_peerdatarequest(coin,addr,data,recvlen); @@ -609,7 +643,7 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc else { intvectors = 'I', addr->msgcounts.inv++; - len = iguana_intvectors(coin,addr,1,data,recvlen); + len = iguana_intvectors(coin,addr,1,data,recvlen); // indirectly issues getdata } } } @@ -617,23 +651,26 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc { struct iguana_msgblock msg; struct iguana_block *blocks; uint32_t n=0; len = 0; - if ( ishost == 0 ) + if ( addr != 0 ) { - len = iguana_rwvarint32(0,data,&n); - if ( n <= IGUANA_MAXINV ) + if ( ishost == 0 ) { - blocks = mycalloc('i',1,sizeof(*blocks) * n); - for (i=0; imsgcounts.headers++; - } else printf("got unexpected n.%d for headers\n",n); - } else len = iguana_peergetrequest(coin,addr,data,recvlen,0); + blocks = mycalloc('i',1,sizeof(*blocks) * n); + for (i=0; imsgcounts.headers++; + } else printf("got unexpected n.%d for headers\n",n); + } else len = iguana_peergetrequest(coin,addr,data,recvlen,0); + } } else if ( (ishost= (strcmp(H->command,"version") == 0)) || strcmp(H->command,"verack") == 0 ) { @@ -711,14 +748,20 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc } else if ( strcmp(H->command,"notfound") == 0 ) { - printf("%s SERVER notfound\n",addr->ipaddr); - intvectors = 'N', addr->msgcounts.notfound++; - len = iguana_intvectors(coin,addr,1,data,recvlen); + if ( addr != 0 ) + { + printf("%s SERVER notfound\n",addr->ipaddr); + intvectors = 'N', addr->msgcounts.notfound++; + len = iguana_intvectors(coin,addr,1,data,recvlen); + } } else if ( strcmp(H->command,"mempool") == 0 ) { - printf("%s SERVER mempool\n",addr->ipaddr); - srvmsg = 'M', addr->msgcounts.mempool++; + if ( addr != 0 ) + { + printf("%s SERVER mempool\n",addr->ipaddr); + srvmsg = 'M', addr->msgcounts.mempool++; + } } else if ( strcmp(H->command,"tx") == 0 ) { @@ -726,11 +769,14 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc iguana_memreset(rawmem); tx = iguana_memalloc(rawmem,sizeof(*tx),1);//mycalloc('u',1,sizeof(*tx)); len = iguana_rwtx(0,rawmem,data,tx,recvlen,&tx->txid,coin->chain->hastimestamp,strcmp(coin->symbol,"VPN")==0); - iguana_gotunconfirmedM(coin,addr,tx,data,recvlen); - printf("tx recvlen.%d vs len.%d\n",recvlen,len); - addr->msgcounts.tx++; + if ( addr != 0 ) + { + iguana_gotunconfirmedM(coin,addr,tx,data,recvlen); + printf("tx recvlen.%d vs len.%d\n",recvlen,len); + addr->msgcounts.tx++; + } } - else if ( strcmp(H->command,"ConnectTo") == 0 ) + else if ( addr != 0 && strcmp(H->command,"ConnectTo") == 0 ) { iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); len = 6; diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c index e8a6bfbcb..3fdbbbe92 100755 --- a/iguana/iguana_payments.c +++ b/iguana/iguana_payments.c @@ -300,22 +300,24 @@ char *iguana_signunspents(struct supernet_info *myinfo,struct iguana_info *coin, if ( (txobj= bitcoin_txcreate(coin,locktime)) != 0 ) { iguana_createvins(myinfo,coin,txobj,vins); - if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + if ( iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) { free_json(vins), free_json(privkeys), free_json(txobj); printf("illegal destination address.(%s)\n",coinaddr); return(0); } + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); spendlen = bitcoin_standardspend(spendscript,0,rmd160); bitcoin_txoutput(coin,txobj,spendscript,spendlen,satoshis); if ( change > 0 ) { - if ( iguana_addressvalidate(coin,&addrtype,rmd160,changeaddr) < 0 ) + if ( iguana_addressvalidate(coin,&addrtype,changeaddr) < 0 ) { free_json(vins), free_json(privkeys), free_json(txobj); printf("illegal destination address.(%s)\n",changeaddr); return(0); } + bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); spendlen = bitcoin_standardspend(spendscript,0,rmd160); bitcoin_txoutput(coin,txobj,spendscript,spendlen,change); } @@ -350,11 +352,11 @@ char *iguana_signunspents(struct supernet_info *myinfo,struct iguana_info *coin, char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint64_t satoshis,uint64_t txfee,char *comment,char *comment2,int32_t minconf,char *account) { - uint8_t addrtype,rmd160[20]; int32_t i,j,num,completed,numwaddrs; struct iguana_waddress **waddrs,*waddr; uint64_t *unspents,value,avail=0; char *signedtx = 0; cJSON *retjson; + uint8_t addrtype; int32_t i,j,num,completed,numwaddrs; struct iguana_waddress **waddrs,*waddr; uint64_t *unspents,value,avail=0; char *signedtx = 0; cJSON *retjson; //sendtoaddress [comment] [comment-to] is a real and is rounded to 8 decimal places. Returns the transaction ID if successful. Y if ( coinaddr != 0 && coinaddr[0] != 0 && satoshis != 0 ) { - if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + if ( iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); waddrs = (struct iguana_waddress **)coin->blockspace; numwaddrs = iguana_unspentslists(myinfo,coin,waddrs,(int32_t)(sizeof(coin->blockspace)/sizeof(*waddrs)),(uint64_t)1 << 62,minconf,account); @@ -441,7 +443,7 @@ ZERO_ARGS(bitcoinrpc,makekeypair) STRING_ARG(bitcoinrpc,validatepubkey,pubkeystr) { - uint8_t rmd160[20],pubkey[65],addrtype = 0; int32_t plen; char coinaddr[128],*str; cJSON *retjson; + uint8_t pubkey[65],addrtype = 0; int32_t plen; char coinaddr[128],*str; cJSON *retjson; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); plen = (int32_t)strlen(pubkeystr) >> 1; @@ -451,7 +453,7 @@ STRING_ARG(bitcoinrpc,validatepubkey,pubkeystr) decode_hex(pubkey,plen,pubkeystr); if ( (str= bitcoin_address(coinaddr,addrtype,pubkey,plen)) != 0 ) { - if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + if ( iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 74243e12f..4ccdb20e4 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -679,7 +679,7 @@ void iguana_startconnection(void *arg) coin->peers.ranked[0] = addr; #ifdef IGUANA_DEDICATED_THREADS //iguana_launch("recv",iguana_dedicatedrecv,addr,IGUANA_RECVTHREAD); - iguana_dedicatedloop(coin,addr); + iguana_dedicatedloop(SuperNET_MYINFO(0),coin,addr); #endif } } @@ -1042,7 +1042,7 @@ int32_t iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,in return(0); } -void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) +void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr) { static uint32_t lastping; struct pollfd fds; struct iguana_bundlereq *req; uint8_t *buf; uint32_t ipbits; @@ -1052,6 +1052,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) printf("error creating peer's files\n"); return; } + instantdex_peerhas_clear(myinfo,coin,addr); #ifdef IGUANA_PEERALLOC int32_t i; int64_t remaining; struct OS_memspace *mem[sizeof(addr->SEROUT)/sizeof(*addr->SEROUT)]; for (i=0; iSEROUT)/sizeof(*addr->SEROUT); i++) @@ -1224,7 +1225,7 @@ void iguana_dedicatedglue(void *arg) printf("iguana_dedicatedglue nullptrs addr.%p coin.%p\n",addr,coin); return; } - iguana_dedicatedloop(coin,addr); + iguana_dedicatedloop(SuperNET_MYINFO(0),coin,addr); } void iguana_peersloop(void *ptr) diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index b3dc5a749..0263f80be 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -494,6 +494,15 @@ void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } +void iguana_gotquotesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *quotes,int32_t n) +{ + struct iguana_bundlereq *req; + //printf("got %d txids from %s\n",n,addr->ipaddr); + req = iguana_bundlereq(coin,addr,'Q',0); + req->hashes = quotes, req->n = n; + queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); +} + void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n) { struct iguana_bundlereq *req; int32_t i,num; @@ -1554,7 +1563,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) return(flag); } -int32_t iguana_processrecv(struct iguana_info *coin) // single threaded +int32_t iguana_processrecv(struct supernet_info *myinfo,struct iguana_info *coin) // single threaded { int32_t i,newhwm = 0,hwmheight,flag = 0; char str[2000]; hwmheight = coin->blocks.hwmchain.height; @@ -1594,7 +1603,7 @@ int32_t iguana_processrecv(struct iguana_info *coin) // single threaded } } coin->RTramchain_busy = 0;//(coin->RTgenesis == 0); - flag += iguana_process_msgrequestQ(coin); + flag += iguana_process_msgrequestQ(myinfo,coin); iguana_jsonQ(); if ( hwmheight != coin->blocks.hwmchain.height ) flag = 1; diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index cad87cf94..6a7b228d4 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -277,13 +277,22 @@ struct iguana_waddress *iguana_ismine(struct supernet_info *myinfo,struct iguana return(waddr); } -int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,uint8_t rmd160[20],char *address) +int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,char *address) { - char checkaddr[64]; + char checkaddr[64]; uint8_t rmd160[20]; + *addrtypep = 0; + memset(rmd160,0,sizeof(rmd160)); bitcoin_addr2rmd160(addrtypep,rmd160,address); + //int32_t i; for (i=0; i<20; i++) + // printf("%02x",rmd160[i]); // 764692cd5473f62ffa8a93e55d876f567623de07 + //printf(" rmd160 addrtype.%02x\n",*addrtypep); if ( bitcoin_address(checkaddr,*addrtypep,rmd160,20) == checkaddr && strcmp(address,checkaddr) == 0 && (*addrtypep == coin->chain->pubtype || *addrtypep == coin->chain->p2shtype) ) return(0); - else return(-1); + else + { + //printf(" checkaddr.(%s) address.(%s) type.%02x vs (%02x %02x)\n",checkaddr,address,*addrtypep,coin->chain->pubtype,coin->chain->p2shtype); + return(-1); + } } cJSON *iguana_waddressjson(cJSON *item,struct iguana_waddress *waddr) @@ -312,12 +321,12 @@ cJSON *iguana_waddressjson(cJSON *item,struct iguana_waddress *waddr) char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrp,char *account,char *coinaddr,char *redeemScript) { - uint8_t addrtype,rmd160[20]; struct iguana_waddress *waddr=0; + uint8_t addrtype; struct iguana_waddress *waddr=0; if ( waddrp != 0 ) *waddrp = 0; if ( coinaddr != 0 && coinaddr[0] != 0 && account != 0 && account[0] != 0 ) { - if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + if ( iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); if ( (waddr= iguana_waccountswitch(myinfo,coin,account,coinaddr,redeemScript)) != 0 ) { @@ -332,8 +341,8 @@ char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,struct ig char *getaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) { - struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint8_t addrtype,rmd160[20]; cJSON *retjson; - if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint8_t addrtype; cJSON *retjson; + if ( iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) == 0 ) return(clonestr("{\"result\":\"no account for address\"}")); @@ -473,10 +482,10 @@ cJSON *iguana_walletjson(struct supernet_info *myinfo) { if ( bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0 ) { - free_json(account); - free_json(wallet); - printf("found a null privkey in wallet, abort saving\n"); - return(0); + //free_json(account); + //free_json(wallet); + //printf("found a null privkey in wallet, abort saving\n"); + //return(0); } if ( waddr->scriptlen != 0 ) { @@ -852,8 +861,10 @@ STRING_ARG(bitcoinrpc,validateaddress,address) cJSON *retjson; int32_t i; uint8_t addrtype,rmd160[20],pubkey[65]; struct iguana_info *other; char str[256]; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( iguana_addressvalidate(coin,&addrtype,rmd160,address) < 0 ) + if ( iguana_addressvalidate(coin,&addrtype,address) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); + bitcoin_addr2rmd160(&addrtype,rmd160,address); + retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jaddnum(retjson,"addrtype",addrtype); @@ -1113,7 +1124,7 @@ TWOSTRINGS_AND_INT(bitcoinrpc,importprivkey,wif,account,rescan) STRING_ARG(bitcoinrpc,dumpprivkey,address) { - cJSON *retjson; int32_t len,p2shflag=0; struct iguana_waddress *waddr; struct iguana_waccount *wacct; uint8_t addrtype,type,redeemScript[IGUANA_MAXSCRIPTSIZE],rmd160[20]; char *coinaddr; struct vin_info V; bits256 debugtxid; + cJSON *retjson; int32_t len,p2shflag=0; struct iguana_waddress *waddr; struct iguana_waccount *wacct; uint8_t addrtype,type,redeemScript[IGUANA_MAXSCRIPTSIZE]; char *coinaddr; struct vin_info V; bits256 debugtxid; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); if ( myinfo->expiration == 0 ) @@ -1131,7 +1142,7 @@ STRING_ARG(bitcoinrpc,dumpprivkey,address) coinaddr = V.coinaddr; } } - if ( strlen(coinaddr) > sizeof(V.coinaddr) || iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + if ( strlen(coinaddr) > sizeof(V.coinaddr) || iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) return(clonestr(p2shflag == 0 ? "{\"error\":\"invalid address\"}" : "{\"error\":\"invalid P2SH address\"}")); if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) != 0 ) { diff --git a/iguana/main.c b/iguana/main.c index 23bad9107..dc5f365b2 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -53,7 +53,7 @@ int32_t myfclose(FILE *fp) // ALL globals must be here! char *Iguana_validcommands[] = { - "SuperNET", "SuperNETb", + "SuperNET", "SuperNETb", "inv2", "InstantDEX", "pangea", "quote", "ConnectTo", "version", "verack", "getaddr", "addr", "inv", "getdata", "notfound", "getblocks", "getheaders", "headers", "tx", "block", "mempool", "ping", "pong", "reject", "filterload", "filteradd", "filterclear", "merkleblock", "alert", "" }; @@ -1153,7 +1153,7 @@ void iguana_appletests(struct supernet_info *myinfo) //int32_t iguana_schnorr_test(void *ctx); //iguana_schnorr_test(myinfo->ctx); getchar(); - if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":1}"),0,myinfo->rpcport)) != 0 ) + if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTC\",\"active\":1,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) { free(str); if ( 0 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":1024,\"maxpeers\":256,\"newcoin\":\"BTCD\",\"active\":1}"),0,myinfo->rpcport)) != 0 ) diff --git a/iguana/mini-gmp.c b/iguana/mini-gmp.c index 86b2d6250..e4aac5673 100644 --- a/iguana/mini-gmp.c +++ b/iguana/mini-gmp.c @@ -4420,7 +4420,7 @@ int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr) } zeroes = 0; for (p=coinaddr; *p==base58_chars[0]; p++) - zeroes++; + data[zeroes++] = 0; mpz_export(data+zeroes,&count,1,sizeof(data[0]),-1,0,bn); if ( count >= 2 && data[count - 1] == 0 && data[count - 2] >= 0x80 ) count--; @@ -4428,7 +4428,7 @@ int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr) //memset(data,0,be_sz); //for (i=0; i 0 ) + struct table_info *tp; char str[65]; + if ( (tp= category_info(myinfo->pangea_category,tablehash)) == 0 && N > 0 ) { tp = pangea_tablealloc(0,N); memset(tp,0,sizeof(*tp)); @@ -197,8 +196,8 @@ struct table_info *pangea_table(bits256 tablehash,int32_t N) } if ( tp != 0 ) { - category_subscribe(SuperNET_MYINFO(0),pangeahash,tablehash); - if ( category_infoset(pangeahash,tablehash,tp) == 0 ) + category_subscribe(SuperNET_MYINFO(0),myinfo->pangea_category,tablehash); + if ( category_infoset(myinfo->pangea_category,tablehash,tp) == 0 ) printf("error: couldnt set table.(%s)\n",bits256_str(str,tablehash)), tp = 0; //else tp->G.allocsize = allocsize; } @@ -220,11 +219,9 @@ struct player_info *pangea_playerfind(struct supernet_info *myinfo,struct table_ char *pangea_jsondatacmd(struct supernet_info *myinfo,bits256 tablehash,struct pangea_msghdr *pm,cJSON *json,char *cmdstr,char *ipaddr) { - cJSON *argjson; char *reqstr,hexstr[8192]; uint64_t nxt64bits; - struct table_info *tp; int32_t i,datalen; bits256 pangeahash; - pangeahash = calc_categoryhashes(0,"pangea",0); - category_subscribe(myinfo,pangeahash,GENESIS_PUBKEY); - category_subscribe(myinfo,pangeahash,tablehash); + cJSON *argjson; char *reqstr,hexstr[8192]; uint64_t nxt64bits; struct table_info *tp; int32_t i,datalen; + category_subscribe(myinfo,myinfo->pangea_category,GENESIS_PUBKEY); + category_subscribe(myinfo,myinfo->pangea_category,tablehash); argjson = json != 0 ? jduplicate(json) : cJSON_CreateObject(); jaddstr(argjson,"cmd",cmdstr); if ( myinfo->ipaddr[0] == 0 || strncmp(myinfo->ipaddr,"127.0.0.1",strlen("127.0.0.1")) == 0 ) @@ -232,13 +229,13 @@ char *pangea_jsondatacmd(struct supernet_info *myinfo,bits256 tablehash,struct p jaddstr(argjson,"agent","SuperNET"); jaddstr(argjson,"method","DHT"); jaddstr(argjson,"playeripaddr",ipaddr); - jaddbits256(argjson,"categoryhash",pangeahash); + jaddbits256(argjson,"categoryhash",myinfo->pangea_category); jaddbits256(argjson,"subhash",tablehash); jaddbits256(argjson,"mypub",myinfo->myaddr.pubkey); jaddbits256(argjson,"playerpub",myinfo->myaddr.persistent); jaddstr(argjson,"handle",jstr(json,"handle")); nxt64bits = acct777_nxt64bits(myinfo->myaddr.persistent); - if ( (tp= pangea_table(tablehash,9)) != 0 && tp->G.numactive < tp->G.maxplayers ) + if ( (tp= pangea_table(myinfo,tablehash,9)) != 0 && tp->G.numactive < tp->G.maxplayers ) { for (i=0; iG.numactive; i++) if ( tp->G.P[i].nxt64bits == nxt64bits ) @@ -263,7 +260,7 @@ char *pangea_jsondatacmd(struct supernet_info *myinfo,bits256 tablehash,struct p { printf("pangea send.(%s)\n",cmdstr); init_hexbytes_noT(hexstr,(uint8_t *)pm,pm->sig.allocsize); - return(SuperNET_categorymulticast(myinfo,0,pangeahash,tablehash,hexstr,0,2,1,argjson,0)); + return(SuperNET_categorymulticast(myinfo,0,myinfo->pangea_category,tablehash,hexstr,0,2,1,argjson,0)); } else { @@ -408,7 +405,7 @@ void pangea_parse(struct supernet_info *myinfo,struct pangea_msghdr *pm,cJSON *a { bits256 tablehash; char *method; struct table_info *tp; tablehash = jbits256(argjson,"subhash"); - tp = pangea_table(tablehash,9); + tp = pangea_table(myinfo,tablehash,9); if ( (method= jstr(argjson,"cmd")) != 0 ) { if ( strcmp(method,"lobby") == 0 ) @@ -504,7 +501,7 @@ char *pangea_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void } else { - if ( (tp= pangea_table(tablehash,9)) != 0 && pangea_rwdata(0,pm->serialized,len-(int32_t)((long)pm->serialized-(long)pm),pm->serialized) > 0 ) + if ( (tp= pangea_table(myinfo,tablehash,9)) != 0 && pangea_rwdata(0,pm->serialized,len-(int32_t)((long)pm->serialized-(long)pm),pm->serialized) > 0 ) { cmdbits = stringbits(pm->cmd); for (i=0; ipangea_category,GENESIS_PUBKEY)) != 0 ) { pm = (struct pangea_msghdr *)m->msg; if ( m->remoteipbits != 0 ) @@ -713,7 +709,7 @@ HASH_ARG(pangea,call,tablehash) struct table_info *tp; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else return(pangea_submitaction(myinfo,tp,0,CARDS777_CALL,"call")); } @@ -723,7 +719,7 @@ HASH_AND_INT(pangea,raise,tablehash,numchips) struct table_info *tp; int64_t value; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else { @@ -737,7 +733,7 @@ HASH_ARG(pangea,allin,tablehash) struct table_info *tp; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else return(pangea_submitaction(myinfo,tp,0,CARDS777_ALLIN,"allin")); } @@ -747,7 +743,7 @@ HASH_AND_INT(pangea,bet,tablehash,numchips) struct table_info *tp; int64_t value; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else { @@ -761,7 +757,7 @@ HASH_ARG(pangea,check,tablehash) struct table_info *tp; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else return(pangea_submitaction(myinfo,tp,0,CARDS777_CHECK,"check")); } @@ -771,7 +767,7 @@ HASH_ARG(pangea,fold,tablehash) struct table_info *tp; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else return(pangea_submitaction(myinfo,tp,0,CARDS777_FOLD,"fold")); } @@ -781,7 +777,7 @@ HASH_ARG(pangea,status,tablehash) struct table_info *tp; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else return(jprint(pangea_tablestatus(myinfo,tp),1)); } @@ -812,8 +808,7 @@ ZERO_ARGS(pangea,lobby) //cJSON *retjson,*argjson; char *retstr,*result; uint8_t *buf; int32_t flag,len; struct pangea_msghdr *pm; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - bits256 pangeahash = calc_categoryhashes(0,"pangea",0); - category_subscribe(myinfo,pangeahash,GENESIS_PUBKEY); + category_subscribe(myinfo,myinfo->pangea_category,GENESIS_PUBKEY); pangea_update(myinfo); return(jprint(pangea_lobbyjson(myinfo),1)); } @@ -824,7 +819,7 @@ INT_AND_ARRAY(pangea,host,minplayers,params) if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); OS_randombytes(tablehash.bytes,sizeof(tablehash)); - tp = pangea_table(tablehash,9); + tp = pangea_table(myinfo,tablehash,9); if ( tp != 0 ) { pangea_gamecreate(&tp->G,(uint32_t)time(NULL),tablehash,json); @@ -846,7 +841,7 @@ HASH_AND_INT(pangea,buyin,tablehash,numchips) uint8_t space[sizeof(struct pangea_msghdr) + 4096]; struct table_info *tp; int64_t value; cJSON *fundsjson; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else { @@ -862,7 +857,7 @@ HASH_ARG(pangea,start,tablehash) struct table_info *tp; int32_t allocsize; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,9)) != 0 ) + if ( (tp= pangea_table(myinfo,tablehash,9)) != 0 ) { if ( tp->G.numactive >= tp->G.minplayers && pangea_tableismine(myinfo,tp) >= 0 ) { diff --git a/iguana/swaps/iguana_BTCswap.c b/iguana/swaps/iguana_BTCswap.c index 9b8a7b9d1..4749ba77b 100755 --- a/iguana/swaps/iguana_BTCswap.c +++ b/iguana/swaps/iguana_BTCswap.c @@ -155,7 +155,7 @@ int32_t instantdex_feetxverify(struct supernet_info *myinfo,struct iguana_info * if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->otherfee->txbytes)) != 0 ) { insurance = swap->insurance;//instantdex_insurance(coin,swap->BTCsatoshis); - if ( strcmp(coin->symbol,"BTCD") == 0 ) + if ( strcmp(coin->symbol,"BTC") != 0 ) insurance *= IGUANA_BTCDMULT; n = instantdex_outputinsurance(script,0,insurance,swap->matched64); if ( n == msgtx.vouts[0].pk_scriptlen ) diff --git a/iguana/tests/buy b/iguana/tests/buy new file mode 100755 index 000000000..33df543a6 --- /dev/null +++ b/iguana/tests/buy @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"dotrade\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"buy\",\"base\":\"BTCD\",\"rel\":\"BTC\",\"price\":0.001,\"volume\":1.0}" diff --git a/iguana/tests/openorders b/iguana/tests/openorders new file mode 100755 index 000000000..8f3e4db9d --- /dev/null +++ b/iguana/tests/openorders @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"openorders\",\"base\":\"BTCD\",\"rel\":\"BTC\"}" diff --git a/iguana/tests/orderbook b/iguana/tests/orderbook new file mode 100755 index 000000000..cd74d5584 --- /dev/null +++ b/iguana/tests/orderbook @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"orderbook\",\"base\":\"BTCD\",\"rel\":\"BTC\"}"