diff --git a/iguana/SuperNET.h b/iguana/SuperNET.h index a61cb40b0..308f7ad82 100644 --- a/iguana/SuperNET.h +++ b/iguana/SuperNET.h @@ -122,7 +122,7 @@ struct category_msg { struct queueitem DL; struct tai t; uint64_t remoteipbits; struct exchange_quote { uint64_t satoshis,orderid,offerNXT,exchangebits; double price,volume; uint32_t timestamp,val; }; -struct bitcoin_unspent { bits256 txid,privkeys[16]; uint64_t value; int32_t vout; }; +struct bitcoin_unspent { bits256 txid,privkeys[16]; uint64_t value; int32_t vout; uint8_t addrtype,rmd160[20],script[512]; }; struct bitcoin_spend { char changeaddr[64]; diff --git a/iguana/exchanges/bitcoin.c b/iguana/exchanges/bitcoin.c index a1db8fdb3..d6f6bc5ee 100755 --- a/iguana/exchanges/bitcoin.c +++ b/iguana/exchanges/bitcoin.c @@ -31,6 +31,11 @@ static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijk #define IGUANA_SCRIPT_DATA 11 #define IGUANA_SCRIPT_STRANGE 15 +char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params) +{ + return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params)); +} + int32_t bitcoin_pubkeylen(const uint8_t *pubkey) { if ( pubkey[0] == 2 || pubkey[0] == 3 ) @@ -1440,6 +1445,54 @@ rawtxstr = refstr; return(cJSON_Parse("{\"error\":\"testing bitcoin txbytes\"}")); } +uint64_t bitcoin_parseunspent(struct bitcoin_unspent *unspent,double minconfirms,char *account,cJSON *item) +{ + uint64_t value = 0; char *hexstr; + // struct bitcoin_unspent { bits256 txid,privkey; uint64_t value; int32_t vout; }; + memset(unspent,0,sizeof(*unspent)); + if ( jstr(item,"address") != 0 ) + bitcoin_addr2rmd160(&unspent->addrtype,unspent->rmd160,jstr(item,"address")); + if ( (account == 0 || jstr(item,"account") == 0 || strcmp(account,jstr(item,"account")) == 0) && (minconfirms < 0 || juint(item,"confirmations") >= minconfirms-SMALLVAL) ) + { + if ( (hexstr= jstr(item,"scriptPubKey")) != 0 && strlen(hexstr) < sizeof(unspent->script)/2 ) + decode_hex(unspent->script,(int32_t)strlen(hexstr),hexstr); + unspent->txid = jbits256(item,"txid"); + unspent->value = j64bits(item,"amount"); + unspent->vout = jint(item,"vout"); + } + return(value); +} + +struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *account) +{ + char params[128],*retstr; uint64_t value,total = 0; struct bitcoin_unspent *unspents=0; cJSON *utxo; int32_t i,n; + if ( account != 0 && account[0] == 0 ) + account = 0; + *numunspentsp = 0; + if ( retstrp != 0 ) + *retstrp = 0; + sprintf(params,"%.0f, 99999999",minconfirms); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",params)) != 0 ) + { + if ( (utxo= cJSON_Parse(retstr)) != 0 ) + { + if ( (*numunspentsp= cJSON_GetArraySize(utxo)) > 0 ) + { + unspents = calloc(*numunspentsp,sizeof(*unspents)); + for (i=n=0; i<*numunspentsp; i++) + if ( (value= bitcoin_parseunspent(&unspents[n],minconfirms,account,jitem(utxo,i))) != 0 ) + total += value, n++; + } + free_json(utxo); + } + if ( retstrp != 0 ) + *retstrp = retstr; + else free(retstr); + } + *balancep = dstr(total); + return(unspents); +} + #define EXCHANGE_NAME "bitcoin" #define UPDATE bitcoin ## _price #define SUPPORTS bitcoin ## _supports @@ -1476,14 +1529,49 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson) { - //struct supernet_info *myinfo = SuperNET_accountfind(argjson); - return(clonestr("{\"error\":\"bitcoin is not yet\"}")); + cJSON *item; + *balancep = 0; + if ( (item= jobj(argjson,coinstr)) != 0 ) + { + *balancep = jdouble(item,"balance"); + return(jprint(item,0)); + } + return(clonestr("{\"error\":\"no item for specified coin\"}")); } cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson) { - //struct supernet_info *myinfo = SuperNET_accountfind(argjson); - return(cJSON_Parse("{\"error\":\"bitcoin is not yet\"}")); + double balance; char *retstr; int32_t i,numunspents,minconfirms; struct iguana_info *coin; + struct supernet_info *myinfo; struct bitcoin_unspent *unspents; cJSON *item,*retjson,*utxo; + retjson = cJSON_CreateArray(); + myinfo = SuperNET_accountfind(argjson); + for (i=0; ichain->serverport[0] != 0 ) + { + balance = 0.; + minconfirms = juint(argjson,"minconfirms"); + if ( minconfirms < coin->minconfirms ) + minconfirms = coin->minconfirms; + if ( (unspents= iguana_unspentsget(myinfo,coin,&retstr,&balance,&numunspents,minconfirms,0)) != 0 ) + { + item = cJSON_CreateObject(); + jaddnum(retjson,"balance",balance); + if ( retstr != 0 ) + { + if ( (utxo= cJSON_Parse(retstr)) != 0 ) + { + jadd(item,"unspents",utxo); + jaddnum(item,"numunspents",numunspents); + } + free(retstr); + } + free(unspents); + jadd(retjson,coin->symbol,item); + } + } + } + return(retjson); } int32_t is_valid_BTCother(char *other) @@ -1567,34 +1655,38 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha char *ORDERSTATUS(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson) { - struct instantdex_accept *ap; cJSON *retjson; + struct instantdex_accept *ap; cJSON *retjson = cJSON_CreateObject(); struct supernet_info *myinfo = SuperNET_accountfind(argjson); - if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1)) != 0 ) - { - retjson = cJSON_CreateObject(); + if ( (ap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) + jadd(retjson,"result",instantdex_statemachinejson(ap)); + else if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1)) != 0 ) jadd(retjson,"result",instantdex_acceptjson(ap)); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"couldnt find orderid\"}")); + else if ( (ap= instantdex_historyfind(myinfo,exchange,orderid)) != 0 ) + jadd(retjson,"result",instantdex_historyjson(ap)); + else jaddstr(retjson,"error","couldnt find orderid"); + return(jprint(retjson,1)); } char *CANCELORDER(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson) { - struct instantdex_accept *ap; cJSON *retjson; + struct instantdex_accept *ap = 0; cJSON *retjson; struct supernet_info *myinfo = SuperNET_accountfind(argjson); + retjson = cJSON_CreateObject(); if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1)) != 0 ) + jadd(retjson,"orderid",instantdex_acceptjson(ap)); + else if ( (ap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) + jadd(retjson,"orderid",instantdex_statemachinejson(ap)); + if ( ap != 0 ) { ap->dead = (uint32_t)time(NULL); - retjson = cJSON_CreateObject(); jaddstr(retjson,"result","killed orderid, but might have pending"); - jadd(retjson,"order",instantdex_acceptjson(ap)); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"couldnt find orderid\"}")); + } else jaddstr(retjson,"error","couldnt find orderid"); + return(jprint(retjson,1)); } char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson) { - cJSON *retjson,*bids,*asks; - struct supernet_info *myinfo = SuperNET_accountfind(argjson); + cJSON *retjson,*bids,*asks; struct supernet_info *myinfo = SuperNET_accountfind(argjson); bids = cJSON_CreateArray(); asks = cJSON_CreateArray(); instantdex_offerfind(myinfo,exchange,bids,asks,0,"*","*",1); @@ -1607,14 +1699,22 @@ char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson) char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson) { - //struct supernet_info *myinfo = SuperNET_accountfind(argjson); - return(clonestr("{\"error\":\"bitcoin is not yet\"}")); + struct instantdex_accept PAD,*ap; cJSON *retjson = cJSON_CreateArray(); + memset(&PAD,0,sizeof(PAD)); + queue_enqueue("historyQ",&exchange->historyQ,&PAD.DL,0); + while ( (ap= queue_dequeue(&exchange->historyQ,0)) != 0 && ap != &PAD ) + { + jaddi(retjson,instantdex_historyjson(ap)); + queue_enqueue("historyQ",&exchange->historyQ,&ap->DL,0); + } + return(jprint(retjson,1)); } char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson) { //struct supernet_info *myinfo = SuperNET_accountfind(argjson); - return(clonestr("{\"error\":\"bitcoin is not yet\"}")); + // invoke conversion or transfer! + return(clonestr("{\"error\":\"what does it mean to withdraw bitcoins that are in your wallet\"}")); } struct exchange_funcs bitcoin_funcs = EXCHANGE_FUNCS(bitcoin,EXCHANGE_NAME); diff --git a/iguana/exchanges777.h b/iguana/exchanges777.h index 66ed6149f..f5977720a 100755 --- a/iguana/exchanges777.h +++ b/iguana/exchanges777.h @@ -52,7 +52,7 @@ struct exchange_info uint32_t exchangeid,pollgap,lastpoll; uint64_t lastnonce,exchangebits; double commission; void *privatedata; - CURL *cHandle; queue_t requestQ,pricesQ,statemachineQ,tradebotsQ,acceptableQ; + CURL *cHandle; queue_t requestQ,pricesQ,statemachineQ,tradebotsQ,acceptableQ,historyQ; }; struct instantdex_msghdr @@ -100,6 +100,8 @@ struct instantdex_accept 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); cJSON *instantdex_acceptjson(struct instantdex_accept *ap); +cJSON *instantdex_statemachinejson(struct instantdex_accept *ap); +cJSON *instantdex_historyjson(struct instantdex_accept *ap); struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,uint64_t offerbits,double minperc); void *curl_post(void **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3); @@ -122,5 +124,7 @@ void instantdex_update(struct supernet_info *myinfo); char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *offer,cJSON *argjson,char *cmdstr,bits256 desthash,int32_t hops,void *extra,int32_t extralen); char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson); // Bob sending to network (Alice) char *instantdex_selectqueue(struct exchange_info *exchange,struct instantdex_accept *ap,char *retstr); +struct instantdex_accept *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid); +struct instantdex_accept *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid,int32_t requeueflag); #endif diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 80678d46d..96f2c73fb 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -18,6 +18,8 @@ #include "../crypto777/OS_portable.h" #include "SuperNET.h" +typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); + #define IGUANA_MAXSCRIPTSIZE 8192 //#define IGUANA_DISABLEPEERS @@ -182,7 +184,11 @@ struct iguana_chain uint8_t genesis_hashdata[32],minconfirms; uint16_t ramchainport,bundlesize,hasheaders; char gethdrsmsg[16]; - uint64_t txfee,minoutput; + uint64_t txfee,minoutput,dust; + blockhashfunc hashalgo; + char userhome[512],serverport[128],userpass[1024]; + char use_addmultisig,do_opreturn; + int32_t estblocktime; }; struct iguana_msgaddress { uint32_t nTime; uint64_t nServices; uint8_t ip[16]; uint16_t port; } __attribute__((packed)); @@ -725,7 +731,7 @@ cJSON *SuperNET_bits2json(uint8_t *serialized,int32_t datalen); int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 destpub,bits256 mypriv,bits256 mypub,uint8_t *msg,int32_t len,uint8_t *data,int32_t delaymillis); int32_t category_peer(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 category,bits256 subhash); int32_t btc_wif2priv(uint8_t *addrtypep,uint8_t privkey[32],char *wifstr); -bits256 iguana_chaingenesis(int32_t version,uint32_t timestamp,uint32_t nBits,uint32_t nonce,bits256 merkle_root); +bits256 iguana_chaingenesis(char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root); int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr); cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height,struct vin_info *V); char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid); @@ -743,7 +749,7 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3 //int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey); void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen); int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime); -struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t satoshis,int64_t insurance); +struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t satoshis,int64_t insurance,char *account); cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes); cJSON *iguana_signtx(struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj); cJSON *bitcoin_createtx(struct iguana_info *coin,int32_t locktime); @@ -754,6 +760,7 @@ int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **si char *bitcoin_json2hex(struct iguana_info *coin,bits256 *txidp,cJSON *txjson); int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); char *issue_startForging(struct supernet_info *myinfo,char *secret); +struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *account); extern queue_t bundlesQ; diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index 910295b67..5403bfaa5 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -94,9 +94,39 @@ static struct iguana_chain Chains[] = "genesis":{"version":1,"timestamp":1403138561,"nBits":"1e0fffff","nonce":8359109,"hash":"0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46","merkle":"fd1751cc6963d88feca94c0d01da8883852647a37a0a67ce254d62dd8c9d5b2b"} }*/ -bits256 iguana_chaingenesis(int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root) + +int32_t blockhash_sha256(uint8_t *blockhashp,uint8_t *serialized,int32_t len) +{ + bits256 hash; + vcalc_sha256(0,hash.bytes,serialized,len); + vcalc_sha256(0,blockhashp,hash.bytes,sizeof(hash)); + return(sizeof(bits256)); +} + +int32_t blockhash_scrypt(uint8_t *blockhashp,uint8_t *serialized,int32_t len) +{ + bits256 hash; + vcalc_sha256(0,hash.bytes,serialized,len); + printf("need to implement scrypt hash here\n"); + exit(-1); + return(sizeof(bits256)); +} + +blockhashfunc iguana_hashalgo(char *hashalgostr) +{ + if ( hashalgostr == 0 || hashalgostr[0] == 0 || strcmp(hashalgostr,"sha256") == 0 ) + return(blockhash_sha256); + else if ( strcmp(hashalgostr,"scrypt") == 0 ) + return(blockhash_scrypt); + else printf("unsupported blockhash algo.(%s)\n",hashalgostr); + return(0); +} + +bits256 iguana_chaingenesis(char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root) { - struct iguana_msgblock msg; int32_t len; bits256 hash2; uint8_t serialized[1024]; char hexstr[2049]; + struct iguana_msgblock msg; int32_t len,blockhashlen; bits256 hash2; + char blockhashstr[256]; uint8_t serialized[1024],blockhash[256]; + int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); memset(&msg,0,sizeof(msg)); msg.H.version = version; msg.H.merkle_root = merkle_root; @@ -104,28 +134,127 @@ bits256 iguana_chaingenesis(int32_t version,uint32_t timestamp,uint32_t bits,uin msg.H.bits = bits; msg.H.nonce = nonce; len = iguana_rwblock(1,&hash2,serialized,&msg); - init_hexbytes_noT(hexstr,serialized,len); - char str[65],str2[65]; printf("v.%d t.%u bits.%x nonce.%u merkle.(%s) genesis.(%s) hash.(%s) size.%ld\n",version,timestamp,bits,nonce,bits256_str(str2,merkle_root),hexstr,bits256_str(str,hash2),strlen(hexstr)/2); + blockhashstr[0] = 0; + if ( hashalgostr != 0 && strcmp(hashalgostr,"sha256") != 0 && (hashalgo= iguana_hashalgo(hashalgostr)) != 0 ) + { + if ( (blockhashlen= (*hashalgo)(blockhash,serialized,len)) > 0 ) + init_hexbytes_noT(blockhashstr,blockhash,blockhashlen); + } + init_hexbytes_noT(genesisblock,serialized,len); + char str[65],str2[65]; printf("v.%d t.%u bits.%x nonce.%u merkle.(%s) genesis.(%s) hash2.(%s) blockhash.(%s) size.%ld\n",version,timestamp,bits,nonce,bits256_str(str2,merkle_root),genesisblock,bits256_str(str,hash2),blockhashstr,strlen(genesisblock)/2); return(hash2); } +char *parse_conf_line(char *line,char *field) +{ + line += strlen(field); + for (; *line!='='&&*line!=0; line++) + break; + if ( *line == 0 ) + return(0); + if ( *line == '=' ) + line++; + _stripwhite(line,0); + if ( Debuglevel > 0 ) + printf("[%s]\n",line); + return(clonestr(line)); +} + +char *default_coindir(char *confname,char *coinstr) +{ + int32_t i; +#ifdef __APPLE__ + char *coindirs[][3] = { {"BTC","Bitcoin","bitcoin"}, {"BTCD","BitcoinDark"}, {"LTC","Litecoin","litecoin"}, {"VRC","Vericoin","vericoin"}, {"OPAL","OpalCoin","opalcoin"}, {"BITS","Bitstar","bitstar"}, {"DOGE","Dogecoin","dogecoin"}, {"DASH","Dash","dash"}, {"BC","Blackcoin","blackcoin"}, {"FIBRE","Fibre","fibre"}, {"VPN","Vpncoin","vpncoin"} }; +#else + char *coindirs[][3] = { {"BTC",".bitcoin"}, {"BTCD",".BitcoinDark"}, {"LTC",".litecoin"}, {"VRC",".vericoin"}, {"OPAL",".opalcoin"}, {"BITS",".Bitstar"}, {"DOGE",".dogecoin"}, {"DASH",".dash"}, {"BC",".blackcoin"}, {"FIBRE",".Fibre"}, {"VPN",".vpncoin"} }; +#endif + for (i=0; i<(int32_t)(sizeof(coindirs)/sizeof(*coindirs)); i++) + if ( strcmp(coindirs[i][0],coinstr) == 0 ) + { + if ( coindirs[i][2] != 0 ) + strcpy(confname,coindirs[i][2]); + else strcpy(confname,coindirs[i][1] + (coindirs[i][1][0] == '.')); + return(coindirs[i][1]); + } + return(coinstr); +} + +void set_coinconfname(char *fname,char *coinstr,char *userhome,char *coindir,char *confname) +{ + char buf[64]; + if ( coindir == 0 || coindir[0] == 0 ) + coindir = default_coindir(buf,coinstr); + if ( confname == 0 || confname[0] == 0 ) + { + confname = buf; + sprintf(confname,"%s.conf",buf); + } + printf("userhome.(%s) coindir.(%s) confname.(%s)\n",userhome,coindir,confname); + sprintf(fname,"%s/%s/%s",userhome,coindir,confname); +} + +uint16_t extract_userpass(char *serverport,char *userpass,char *coinstr,char *userhome,char *coindir,char *confname) +{ + FILE *fp; uint16_t port = 0; + char fname[2048],line[1024],*rpcuser,*rpcpassword,*rpcport,*str; + if ( strcmp(coinstr,"NXT") == 0 ) + return(0); + serverport[0] = userpass[0] = 0; + set_coinconfname(fname,coinstr,userhome,coindir,confname); + printf("set_coinconfname.(%s)\n",fname); + if ( (fp= fopen(OS_compatible_path(fname),"r")) != 0 ) + { + if ( Debuglevel > 1 ) + printf("extract_userpass from (%s)\n",fname); + rpcuser = rpcpassword = rpcport = 0; + while ( fgets(line,sizeof(line),fp) != 0 ) + { + if ( line[0] == '#' ) + continue; + //printf("line.(%s) %p %p\n",line,strstr(line,"rpcuser"),strstr(line,"rpcpassword")); + if ( (str= strstr(line,"rpcuser")) != 0 ) + rpcuser = parse_conf_line(str,"rpcuser"); + else if ( (str= strstr(line,"rpcpassword")) != 0 ) + rpcpassword = parse_conf_line(str,"rpcpassword"); + else if ( (str= strstr(line,"rpcport")) != 0 ) + rpcport = parse_conf_line(str,"rpcport"); + } + if ( rpcuser != 0 && rpcpassword != 0 ) + { + if ( userpass[0] == 0 ) + sprintf(userpass,"%s:%s",rpcuser,rpcpassword); + } + if ( rpcport != 0 ) + { + port = atoi(rpcport); + if ( serverport[0] == 0 ) + sprintf(serverport,"127.0.0.1:%s",rpcport); + free(rpcport); + } + if ( Debuglevel > 1 ) + printf("-> (%s):(%s) userpass.(%s) serverport.(%s)\n",rpcuser,rpcpassword,userpass,serverport); + if ( rpcuser != 0 ) + free(rpcuser); + if ( rpcpassword != 0 ) + free(rpcpassword); + fclose(fp); + } else printf("extract_userpass cant open.(%s)\n",fname); + return(port); +} + void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders) { chain->hasheaders = hasheaders; chain->minoutput = 10000; + chain->hashalgo = blockhash_sha256; if ( strcmp(chain->symbol,"BTC") == 0 ) { chain->unitval = 0x1d; chain->txfee = 10000; } - else - { - if ( strcmp(chain->symbol,"LTC") == 0 ) - chain->txfee = 100000; - else chain->txfee = 1000000; - if ( chain->unitval == 0 ) - chain->unitval = 0x1e; - } + else chain->txfee = 1000000; + if ( chain->unitval == 0 ) + chain->unitval = 0x1e; if ( hasheaders != 0 ) { strcpy(chain->gethdrsmsg,"getheaders"); @@ -189,42 +318,80 @@ uint64_t iguana_miningreward(struct iguana_info *coin,uint32_t blocknum) return(reward); } -struct iguana_chain *iguana_createchain(cJSON *json) +void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) { - char *symbol,*name,*hexstr; cJSON *rewards,*rpair,*item; int32_t i,m,n; struct iguana_chain *chain = 0; - if ( (symbol= jstr(json,"name")) != 0 && strlen(symbol) < 8 ) + char *path,*conf,*hexstr,genesisblock[1024],str[65]; bits256 hash; uint16_t port; cJSON *rpair,*genesis,*rewards,*item; int32_t i,n,m; + if ( strcmp(chain->symbol,"NXT") != 0 ) { - chain = mycalloc('C',1,sizeof(*chain)); - strcpy(chain->symbol,symbol); - if ( (name= jstr(json,"description")) != 0 && strlen(name) < 32 ) - strcpy(chain->name,name); - if ( (hexstr= jstr(json,"pubval")) != 0 && strlen(hexstr) == 2 ) + if ( strcmp(chain->symbol,"BTC") != 0 ) + { + if ( strcmp(chain->symbol,"LTC") == 0 ) + chain->pubtype = 48, chain->p2shtype = 5, chain->minconfirms = 1, chain->txfee = 100000; + else if ( strcmp(chain->symbol,"BTCD") == 0 ) + chain->pubtype = 60, chain->p2shtype = 85; + else if ( strcmp(chain->symbol,"DOGE") == 0 ) + chain->pubtype = 30, chain->p2shtype = 35, chain->txfee = SATOSHIDEN; + else if ( strcmp(chain->symbol,"VRC") == 0 ) + chain->pubtype = 70, chain->p2shtype = 85; + else if ( strcmp(chain->symbol,"OPAL") == 0 ) + chain->pubtype = 115, chain->p2shtype = 28; + else if ( strcmp(chain->symbol,"BITS") == 0 ) + chain->pubtype = 25, chain->p2shtype = 8; + } + chain->minoutput = j64bits(argjson,"minoutput"); + chain->minconfirms = juint(argjson,"minconfirms"); + chain->estblocktime = juint(argjson,"estblocktime"); + path = jstr(argjson,"path"); + conf = jstr(argjson,"conf"); + chain->dust = j64bits(argjson,"dust"); + if ( jobj(argjson,"txfee_satoshis") != 0 ) + chain->txfee = j64bits(argjson,"txfee_satoshis"); + if ( chain->txfee == 0 ) + chain->txfee = (uint64_t)(SATOSHIDEN * jdouble(argjson,"txfee")); + chain->use_addmultisig = juint(argjson,"useaddmultisig"); + chain->do_opreturn = juint(argjson,"do_opreturn"); + if ( jobj(argjson,"oldtx_format") != 0 ) + chain->hastimestamp = !juint(argjson,"oldtx_format"); + if ( (port= extract_userpass(chain->serverport,chain->userpass,chain->symbol,chain->userhome,path,conf)) != 0 ) + chain->portrpc = port; + printf("COIN.%s serverport.(%s) userpass.(%s) port.%u\n",chain->symbol,chain->serverport,chain->userpass,chain->portrpc); + if ( (hexstr= jstr(argjson,"pubval")) != 0 && strlen(hexstr) == 2 ) decode_hex((uint8_t *)&chain->pubtype,1,hexstr); - if ( (hexstr= jstr(json,"scriptval")) != 0 && strlen(hexstr) == 2 ) + if ( (hexstr= jstr(argjson,"scriptval")) != 0 && strlen(hexstr) == 2 ) decode_hex((uint8_t *)&chain->p2shtype,1,hexstr); - if ( (hexstr= jstr(json,"wiftype")) != 0 && strlen(hexstr) == 2 ) + if ( (hexstr= jstr(argjson,"wiftype")) != 0 && strlen(hexstr) == 2 ) decode_hex((uint8_t *)&chain->wiftype,1,hexstr); - if ( (hexstr= jstr(json,"netmagic")) != 0 && strlen(hexstr) == 8 ) + if ( (hexstr= jstr(argjson,"netmagic")) != 0 && strlen(hexstr) == 8 ) decode_hex((uint8_t *)chain->netmagic,1,hexstr); - if ( (hexstr= jstr(json,"unitval")) != 0 && strlen(hexstr) == 2 ) + if ( (hexstr= jstr(argjson,"unitval")) != 0 && strlen(hexstr) == 2 ) decode_hex((uint8_t *)&chain->unitval,1,hexstr); - if ( (hexstr= jstr(json,"genesishash")) != 0 ) + if ( (genesis= jobj(argjson,"genesis")) != 0 ) { - chain->genesis_hash = mycalloc('G',1,strlen(hexstr)+1); - strcpy(chain->genesis_hash,hexstr); + chain->hashalgo = iguana_hashalgo(jstr(genesis,"hashalgo")); + hash = iguana_chaingenesis(genesisblock,jstr(genesis,"hashalgo"),juint(genesis,"version"),juint(genesis,"timestamp"),juint(genesis,"nbits"),juint(genesis,"nonce"),jbits256(genesis,"merkle_root")); + chain->genesis_hash = clonestr(bits256_str(str,hash)); + chain->genesis_hex = clonestr(genesisblock); } - if ( (hexstr= jstr(json,"genesisblock")) != 0 ) + else { - chain->genesis_hex = mycalloc('G',1,strlen(hexstr)+1); - strcpy(chain->genesis_hex,hexstr); + if ( (hexstr= jstr(argjson,"genesishash")) != 0 ) + { + chain->genesis_hash = mycalloc('G',1,strlen(hexstr)+1); + strcpy(chain->genesis_hash,hexstr); + } + if ( (hexstr= jstr(argjson,"genesisblock")) != 0 ) + { + chain->genesis_hex = mycalloc('G',1,strlen(hexstr)+1); + strcpy(chain->genesis_hex,hexstr); + } } - chain->portp2p = juint(json,"p2p"); - if ( (chain->ramchainport= juint(json,"ramchain")) == 0 ) + chain->portp2p = juint(argjson,"p2p"); + if ( (chain->ramchainport= juint(argjson,"ramchain")) == 0 ) chain->ramchainport = chain->portp2p - 1; - if ( (chain->portrpc= juint(json,"rpc")) == 0 ) + if ( (chain->portrpc= juint(argjson,"rpc")) == 0 ) chain->portrpc = chain->portp2p + 1; - chain->hastimestamp = juint(json,"hastimestamp"); - if ( (rewards= jarray(&n,json,"rewards")) != 0 ) + chain->hastimestamp = juint(argjson,"hastimestamp"); + if ( (rewards= jarray(&n,argjson,"rewards")) != 0 ) { for (i=0; isymbol,symbol); + if ( (name= jstr(json,"description")) != 0 && strlen(name) < 32 ) + strcpy(chain->name,name); iguana_chaininit(chain,juint(json,"hasheaders")); + iguana_chainparms(chain,json); } return(chain); } diff --git a/iguana/iguana_exchanges.c b/iguana/iguana_exchanges.c index 4391c2a02..02663db6b 100755 --- a/iguana/iguana_exchanges.c +++ b/iguana/iguana_exchanges.c @@ -890,6 +890,7 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson) iguana_initQ(&exchange->requestQ,"request"); iguana_initQ(&exchange->acceptableQ,"acceptable"); iguana_initQ(&exchange->tradebotsQ,"tradebots"); + iguana_initQ(&exchange->historyQ,"history"); iguana_initQ(&exchange->statemachineQ,"statemachineQ"); exchange->exchangeid = exchangeid; safecopy(exchange->name,exchangestr,sizeof(exchange->name)); diff --git a/iguana/iguana_instantdex.c b/iguana/iguana_instantdex.c index 2982cb70a..afa0e7b1f 100755 --- a/iguana/iguana_instantdex.c +++ b/iguana/iguana_instantdex.c @@ -27,6 +27,7 @@ #define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" #define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" #define INSTANTDEX_MINPERC 50. +#define INSTANTDEX_DECKSIZE 1000 struct instantdex_event { char cmdstr[24],sendcmd[16]; int16_t nextstateind; }; @@ -41,9 +42,9 @@ struct instantdex_stateinfo struct bitcoin_swapinfo { - bits256 privkeys[777],mypubs[2],otherpubs[2],privAm,pubAm,privBn,pubBn; + bits256 privkeys[INSTANTDEX_DECKSIZE+2],mypubs[2],otherpubs[2],privAm,pubAm,privBn,pubBn; bits256 orderhash,deposittxid,paymenttxid,altpaymenttxid,myfeetxid,otherfeetxid,othertrader; - uint64_t otherscut[777][2],deck[777][2],satoshis[2],insurance,bidid,askid; + uint64_t otherscut[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2],satoshis[2],insurance,bidid,askid,initiator64; int32_t isbob,choosei,otherschoosei,cutverified,otherverifiedcut; char altmsigaddr[64],expectedcmdstr[16],*deposit,*payment,*altpayment,*myfeetx,*otherfeetx; double minperc,depositconfirms,paymentconfirms,altpaymentconfirms,myfeeconfirms,otherfeeconfirms; @@ -479,44 +480,146 @@ double instantdex_avehbla(struct supernet_info *myinfo,double retvals[4],char *b else return(0); } -int32_t instantdex_bidaskdir(struct instantdex_accept *ap) +int32_t instantdex_bidaskdir(struct instantdex_offer *offer) { - if ( ap->offer.myside == 0 && ap->offer.acceptdir > 0 ) // base + if ( offer->myside == 0 && offer->acceptdir > 0 ) // base return(-1); - else if ( ap->offer.myside == 1 && ap->offer.acceptdir < 0 ) // rel + else if ( offer->myside == 1 && offer->acceptdir < 0 ) // rel return(1); else return(0); } -cJSON *instantdex_acceptjson(struct instantdex_accept *ap) +cJSON *instantdex_offerjson(struct instantdex_offer *offer) { - int32_t dir; - cJSON *item = cJSON_CreateObject(); - jadd64bits(item,"orderid",ap->orderid); - jadd64bits(item,"offerer",ap->offer.offer64); - if ( ap->dead != 0 ) - jadd64bits(item,"dead",ap->dead); - if ( (dir= instantdex_bidaskdir(ap)) > 0 ) + int32_t dir; cJSON *item = cJSON_CreateObject(); + jadd64bits(item,"offerer",offer->offer64); + if ( (dir= instantdex_bidaskdir(offer)) > 0 ) jaddstr(item,"type","bid"); else if ( dir < 0 ) jaddstr(item,"type","ask"); else { jaddstr(item,"type","strange"); - jaddnum(item,"acceptdir",ap->offer.acceptdir); - jaddnum(item,"myside",ap->offer.myside); + jaddnum(item,"acceptdir",offer->acceptdir); + jaddnum(item,"myside",offer->myside); } - jaddstr(item,"base",ap->offer.base); - jaddstr(item,"rel",ap->offer.rel); - jaddnum(item,"timestamp",ap->offer.expiration); - jaddnum(item,"price",dstr(ap->offer.price64)); - jaddnum(item,"volume",dstr(ap->offer.basevolume64)); - jaddnum(item,"nonce",ap->offer.nonce); + jaddstr(item,"base",offer->base); + jaddstr(item,"rel",offer->rel); + jaddnum(item,"timestamp",offer->expiration); + jaddnum(item,"price",dstr(offer->price64)); + jaddnum(item,"volume",dstr(offer->basevolume64)); + jaddnum(item,"nonce",offer->nonce); + jaddnum(item,"expiresin",offer->expiration - time(NULL)); + return(item); +} + +cJSON *instantdex_acceptjson(struct instantdex_accept *ap) +{ + cJSON *item = cJSON_CreateObject(); + jadd64bits(item,"orderid",ap->orderid); jaddnum(item,"pendingvolume",dstr(ap->pendingvolume64)); - jaddnum(item,"expiresin",ap->offer.expiration - time(NULL)); + if ( ap->dead != 0 ) + jadd64bits(item,"dead",ap->dead); + jadd(item,"offer",instantdex_offerjson(&ap->offer)); + if ( ap->otherorderid != 0 ) + { + jadd64bits(item,"otherid",ap->orderid); + jadd(item,"otheroffer",instantdex_offerjson(&ap->otheroffer)); + } return(item); } +cJSON *instantdex_statemachinejson(struct instantdex_accept *ap) +{ + struct bitcoin_swapinfo *swap = ap->info; cJSON *confirms,*retjson,*txs; + retjson = cJSON_CreateObject(); + if ( swap != 0 ) + { + jaddnum(retjson,"isbob",swap->isbob); + jaddbits256(retjson,"privAm",swap->privAm); + jaddbits256(retjson,"pubAm",swap->pubAm); + jaddbits256(retjson,"privBn",swap->privBn); + jaddbits256(retjson,"pubBn",swap->pubBn); + jaddbits256(retjson,"othertrader",swap->othertrader); + jaddbits256(retjson,"orderhash",swap->orderhash); + if ( swap->isbob == 0 ) + { + jaddbits256(retjson,"pubA0",swap->mypubs[0]); + jaddbits256(retjson,"pubA1",swap->mypubs[1]); + jaddbits256(retjson,"pubB0",swap->otherpubs[0]); + jaddbits256(retjson,"pubB1",swap->otherpubs[1]); + } + else + { + jaddbits256(retjson,"pubB0",swap->mypubs[0]); + jaddbits256(retjson,"pubB1",swap->mypubs[1]); + jaddbits256(retjson,"pubA0",swap->otherpubs[0]); + jaddbits256(retjson,"pubA1",swap->otherpubs[1]); + } + jaddnum(retjson,"choosei",swap->choosei); + jaddnum(retjson,"otherschoosei",swap->otherschoosei); + jaddnum(retjson,"otherschoosei",swap->otherschoosei); + jaddnum(retjson,"cutverified",swap->cutverified); + jaddnum(retjson,"otherverifiedcut",swap->otherverifiedcut); + + jaddnum(retjson,"expiration",swap->expiration); + jaddnum(retjson,"minperc",swap->minperc * 100.); + jaddnum(retjson,"insurance",dstr(swap->insurance)); + jaddnum(retjson,"baseamount",dstr(swap->satoshis[0])); + jaddnum(retjson,"BTCamount",dstr(swap->satoshis[1])); + jadd64bits(retjson,"bidid",swap->bidid); + jadd64bits(retjson,"askid",swap->askid); + jaddstr(retjson,"altmsigaddr",swap->altmsigaddr); + if ( swap->state != 0 ) + jaddstr(retjson,"state",swap->state->name); + jaddstr(retjson,"expected",swap->expectedcmdstr); + confirms = cJSON_CreateObject(); + jaddnum(confirms,"deposit",swap->depositconfirms); + jaddnum(confirms,"payment",swap->paymentconfirms); + jaddnum(confirms,"altpayment",swap->altpaymentconfirms); + jaddnum(confirms,"myfee",swap->myfeeconfirms); + jaddnum(confirms,"otherfee",swap->otherfeeconfirms); + jadd(retjson,"confirms",confirms); + txs = cJSON_CreateObject(); + if ( swap->deposit != 0 ) + jaddstr(txs,"deposit",swap->deposit), jaddbits256(txs,"deposittxid",swap->deposittxid); + if ( swap->payment != 0 ) + jaddstr(txs,"payment",swap->payment), jaddbits256(txs,"paymenttxid",swap->paymenttxid); + if ( swap->altpayment != 0 ) + jaddstr(txs,"altpayment",swap->altpayment), jaddbits256(txs,"altpaymenttxid",swap->altpaymenttxid); + if ( swap->myfeetx != 0 ) + jaddstr(txs,"myfee",swap->myfeetx), jaddbits256(txs,"myfeetxid",swap->myfeetxid);; + if ( swap->otherfeetx != 0 ) + jaddstr(txs,"otherfee",swap->otherfeetx), jaddbits256(txs,"otherfeetxid",swap->otherfeetxid); + jadd(retjson,"txs",confirms); + jaddbits256(retjson,"othertrader",swap->othertrader); + } + jadd(retjson,"swap",instantdex_acceptjson(ap)); + return(retjson); +} + +cJSON *instantdex_historyjson(struct instantdex_accept *ap) +{ + // need to make sure accepts are put onto history queue when they are completed or deaded + // also to make permanent copy (somewhere) + return(instantdex_acceptjson(ap)); +} + +struct instantdex_accept *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid) +{ + struct instantdex_accept PAD,*ap,*retap = 0; uint32_t now; + now = (uint32_t)time(NULL); + memset(&PAD,0,sizeof(PAD)); + queue_enqueue("historyQ",&exchange->historyQ,&PAD.DL,0); + while ( (ap= queue_dequeue(&exchange->historyQ,0)) != 0 && ap != &PAD ) + { + if ( orderid == ap->orderid ) + retap = ap; + queue_enqueue("historyQ",&exchange->historyQ,&ap->DL,0); + } + return(retap); +} + struct instantdex_accept *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid,int32_t requeueflag) { struct instantdex_accept PAD,*ap,*retap = 0; uint32_t now; @@ -595,14 +698,14 @@ struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,str now = (uint32_t)time(NULL); memset(&PAD,0,sizeof(PAD)); queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0); - offerdir = instantdex_bidaskdir(A); + offerdir = instantdex_bidaskdir(&A->offer); minvol = A->offer.basevolume64 * minperc * .01; while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD ) { //printf("check offerbits.%llu vs %llu: %d %d %d %d %d %d %d %d\n",(long long)offerbits,(long long)ap->offer.offer64,A->offer.basevolume64 > 0.,strcmp(A->offer.base,"*") == 0 ,strcmp(A->offer.base,ap->offer.base) == 0, strcmp(A->offer.rel,"*") == 0 ,strcmp(A->offer.rel,ap->offer.rel) == 0,A->offer.basevolume64 <= (ap->offer.basevolume64 - ap->pendingvolume64),offerdir,instantdex_bidaskdir(ap)); if ( now < ap->offer.expiration && ap->dead == 0 && (offerbits == 0 || offerbits != ap->offer.offer64) ) { - if ( A->offer.basevolume64 > 0. && (strcmp(A->offer.base,"*") == 0 || strcmp(A->offer.base,ap->offer.base) == 0) && (strcmp(A->offer.rel,"*") == 0 || strcmp(A->offer.rel,ap->offer.rel) == 0) && minvol <= (ap->offer.basevolume64 - ap->pendingvolume64) && offerdir*instantdex_bidaskdir(ap) < 0 ) + if ( A->offer.basevolume64 > 0. && (strcmp(A->offer.base,"*") == 0 || strcmp(A->offer.base,ap->offer.base) == 0) && (strcmp(A->offer.rel,"*") == 0 || strcmp(A->offer.rel,ap->offer.rel) == 0) && minvol <= (ap->offer.basevolume64 - ap->pendingvolume64) && offerdir*instantdex_bidaskdir(&ap->offer) < 0 ) { //printf("aveprice %.8f %.8f offerdir.%d first cmp: %d %d %d\n",aveprice,dstr(ap->offer.price64),offerdir,A->offer.price64 == 0,(offerdir > 0 && ap->offer.price64 >= A->offer.price64),(offerdir < 0 && ap->offer.price64 <= A->offer.price64)); if ( offerdir == 0 || A->offer.price64 == 0 || ((offerdir < 0 && ap->offer.price64 >= A->offer.price64) || (offerdir > 0 && ap->offer.price64 <= A->offer.price64)) ) @@ -731,7 +834,7 @@ char *instantdex_swapset(struct supernet_info *myinfo,struct instantdex_accept * if ( (coinbtc= iguana_coinfind("BTC")) == 0 ) return(clonestr("{\"error\":\"no BTC found\"}")); insurance = (satoshis[1] * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee prevents papercut attack - offerdir = instantdex_bidaskdir(ap); + offerdir = instantdex_bidaskdir(&ap->offer); vcalc_sha256(0,orderhash.bytes,(void *)&ap->offer,sizeof(ap->offer)); if ( 0 ) { @@ -855,7 +958,7 @@ char *instantdex_gotoffer(struct supernet_info *myinfo,struct exchange_info *exc swap->isbob = (ap->offer.myside ^ 1); if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 ) return(retstr); - if ( instantdex_pubkeyargs(swap,newjson,2+777,myinfo->persistent_priv,swap->orderhash,0x02 + swap->isbob) != 2+777 ) + if ( instantdex_pubkeyargs(swap,newjson,2+INSTANTDEX_DECKSIZE,myinfo->persistent_priv,swap->orderhash,0x02 + swap->isbob) != 2+INSTANTDEX_DECKSIZE ) return(clonestr("{\"error\":\"instantdex_BTCswap error creating pubkeyargs\"}")); char str[65]; printf("GOT OFFER! orderid.%llu %p (%s/%s) other.%s myside.%d\n",(long long)ap->orderid,ap->info,ap->offer.base,ap->offer.rel,bits256_str(str,traderpub),swap->isbob); if ( (newjson= instantdex_parseargjson(myinfo,exchange,ap,argjson,1)) == 0 ) diff --git a/iguana/iguana_tx.c b/iguana/iguana_tx.c index b9d156b16..689e14c17 100755 --- a/iguana/iguana_tx.c +++ b/iguana/iguana_tx.c @@ -371,19 +371,11 @@ struct bitcoin_unspent *iguana_bestfit(struct iguana_info *coin,struct bitcoin_u return(vin); } -struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numunspentsp) -{ - struct bitcoin_unspent *ups = calloc(1,sizeof(*ups)); //uint8_t addrtype; - // struct bitcoin_unspent { bits256 txid,privkey; uint64_t value; int32_t vout; }; - *numunspentsp = 0; - return(ups); -} - -struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t amount,int64_t txfee) +struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t amount,int64_t txfee,char *account) { int32_t i,mode,numunspents,maxinputs = 1024; int64_t remains; struct bitcoin_unspent *ptr,*up; - struct bitcoin_unspent *ups; struct bitcoin_spend *spend; - if ( (ups= iguana_unspentsget(myinfo,coin,&numunspents)) == 0 ) + struct bitcoin_unspent *ups; struct bitcoin_spend *spend; double balance; + if ( (ups= iguana_unspentsget(myinfo,coin,0,&balance,&numunspents,coin->chain->minconfirms,account)) == 0 ) return(0); spend = calloc(1,sizeof(*spend) + sizeof(*spend->inputs) * maxinputs); spend->txfee = txfee; diff --git a/iguana/main.c b/iguana/main.c index b60a7db62..2db2872ef 100644 --- a/iguana/main.c +++ b/iguana/main.c @@ -1076,7 +1076,8 @@ void iguana_main(void *arg) } //iguana_chaingenesis(1,1403138561,0x1e0fffff,8359109,bits256_conv("fd1751cc6963d88feca94c0d01da8883852647a37a0a67ce254d62dd8c9d5b2b")); // BTCD //iguana_chaingenesis(1,1409839200,0x1e0fffff,64881664,bits256_conv("698a93a1cacd495a7a4fb3864ad8d06ed4421dedbc57f9aaad733ea53b1b5828")); // VPN - iguana_chaingenesis(1,1317972665,0x1e0ffff0,2084524493,bits256_conv("97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9")); // LTC + char genesisblock[1024]; + iguana_chaingenesis(genesisblock,"sha256",1,1317972665,0x1e0ffff0,2084524493,bits256_conv("97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9")); // LTC iguana_initQ(&helperQ,"helperQ"); OS_ensure_directory("help"); diff --git a/iguana/swaps/iguana_BTCswap.c b/iguana/swaps/iguana_BTCswap.c index 5d853aa3e..ca0e34038 100755 --- a/iguana/swaps/iguana_BTCswap.c +++ b/iguana/swaps/iguana_BTCswap.c @@ -14,7 +14,6 @@ ******************************************************************************/ #include "../exchanges/bitcoin.h" -#define INSTANTDEX_DECKSIZE 1000 /* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271 https://bitcointalk.org/index.php?topic=1364951 Tier Nolan's approach is followed with the following changes: @@ -104,7 +103,7 @@ char *instantdex_feetx(struct supernet_info *myinfo,bits256 *txidp,struct instan if ( (coinbtc= iguana_coinfind("BTC")) != 0 ) { insurance = instantdex_insurance(coinbtc,instantdex_BTCsatoshis(A->offer.price64,A->offer.basevolume64)); - if ( (spend= iguana_spendset(myinfo,coinbtc,insurance,coinbtc->chain->txfee)) != 0 ) + if ( (spend= iguana_spendset(myinfo,coinbtc,insurance,coinbtc->chain->txfee,0)) != 0 ) { txobj = bitcoin_createtx(coinbtc,0); n = instantdex_outputinsurance(coinbtc,txobj,insurance,A->orderid); @@ -117,7 +116,6 @@ char *instantdex_feetx(struct supernet_info *myinfo,bits256 *txidp,struct instan else { printf("no unspents to spend\n"); - feetx = clonestr("deadbeefdeadbeef"); } } return(feetx); @@ -127,7 +125,6 @@ int32_t instantdex_feetxverify(struct supernet_info *myinfo,struct iguana_info * { cJSON *txobj; bits256 txid; uint32_t n; int32_t i,retval = -1; int64_t insurance; struct iguana_msgtx msgtx; uint8_t script[512]; - return(0); if ( swap->otherfeetx != 0 ) { if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->otherfeetx)) != 0 ) @@ -165,7 +162,7 @@ char *instantdex_bobtx(struct supernet_info *myinfo,struct iguana_info *coin,bit locktime = (uint32_t)(reftime + INSTANTDEX_LOCKTIME * (1 + depositflag)); txobj = bitcoin_createtx(coin,locktime); insurance = instantdex_insurance(coin,amount); - if ( (spend= iguana_spendset(myinfo,coin,amount + insurance,coin->chain->txfee)) != 0 ) + if ( (spend= iguana_spendset(myinfo,coin,amount + insurance,coin->chain->txfee,0)) != 0 ) { calc_rmd160_sha256(secret,priv.bytes,sizeof(priv)); n = instantdex_bobscript(script,0,&secretstart,locktime,pub1,secret,pub2); @@ -258,7 +255,7 @@ int32_t instantdex_altpaymentverify(struct supernet_info *myinfo,struct iguana_i char *instantdex_alicetx(struct supernet_info *myinfo,struct iguana_info *altcoin,char *msigaddr,bits256 *txidp,bits256 pubAm,bits256 pubBn,int64_t amount) { cJSON *txobj; int32_t n; char *signedtx = 0; uint8_t script[1024]; struct bitcoin_spend *spend; - if ( altcoin != 0 && (spend= iguana_spendset(myinfo,altcoin,amount,altcoin->chain->txfee)) != 0 ) + if ( altcoin != 0 && (spend= iguana_spendset(myinfo,altcoin,amount,altcoin->chain->txfee,0)) != 0 ) { txobj = bitcoin_createtx(altcoin,0); n = instantdex_alicescript(script,0,msigaddr,altcoin->chain->p2shtype,pubAm,pubBn); @@ -794,8 +791,8 @@ struct instantdex_stateinfo *BTC_initFSM(int32_t *n) instantdex_addevent(s,*n,"BOB_sentpayment","poll","poll","BOB_sentpayment"); { double startmillis = OS_milliseconds(); - instantdex_FSMtest(s,*n,10000000); - printf("elapsed %.3f ave %.6f\n",OS_milliseconds() - startmillis,(OS_milliseconds() - startmillis)/10000000); + instantdex_FSMtest(s,*n,1000); + printf("elapsed %.3f ave %.6f\n",OS_milliseconds() - startmillis,(OS_milliseconds() - startmillis)/1000); } return(s); }