You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

426 lines
16 KiB

8 years ago
/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_rpc.c
// marketmaker
//
8 years ago
char *LP_issue_curl(char *debugstr,char *destip,uint16_t port,char *url)
{
8 years ago
char *retstr = 0; int32_t maxerrs; struct LP_peerinfo *peer = 0;
8 years ago
peer = LP_peerfind((uint32_t)calc_ipbits(destip),port);
8 years ago
maxerrs = LP_MAXPEER_ERRORS;
8 years ago
if ( peer == 0 || (peer->errors < maxerrs || peer->good >= LP_MINPEER_GOOD) )
8 years ago
{
if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) == 0 )
{
if ( peer != 0 )
8 years ago
{
8 years ago
peer->errors++;
8 years ago
peer->good *= LP_PEERGOOD_ERRORDECAY;
} else printf("%s error on (%s:%u) without peer\n",debugstr,destip,port);
8 years ago
}
else if ( peer != 0 )
peer->good++;
8 years ago
}
return(retstr);
}
8 years ago
char *LP_isitme(char *destip,uint16_t destport)
{
if ( LP_mypeer != 0 && strcmp(destip,LP_mypeer->ipaddr) == 0 && LP_mypeer->port == destport )
{
8 years ago
//printf("no need to notify ourselves\n");
8 years ago
return(clonestr("{\"result\":\"success\"}"));
} else return(0);
}
8 years ago
char *issue_LP_getpeers(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos)
8 years ago
{
8 years ago
char url[512],*retstr;
8 years ago
sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,numpeers,numutxos);
8 years ago
retstr = LP_issue_curl("getpeers",destip,port,url);
8 years ago
//printf("%s -> getpeers.(%s)\n",destip,retstr);
8 years ago
return(retstr);
8 years ago
}
8 years ago
8 years ago
char *issue_LP_numutxos(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos)
{
char url[512],*retstr;
sprintf(url,"http://%s:%u/api/stats/numutxos?ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,numpeers,numutxos);
retstr = LP_issue_curl("numutxos",destip,port,url);
//printf("%s -> getpeers.(%s)\n",destip,retstr);
return(retstr);
}
8 years ago
char *issue_LP_getutxos(char *destip,uint16_t destport,char *coin,int32_t lastn,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos)
8 years ago
{
8 years ago
char url[512];
8 years ago
sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,coin,lastn,ipaddr,port,numpeers,numutxos);
8 years ago
return(LP_issue_curl("getutxos",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));
8 years ago
}
8 years ago
char *issue_LP_clientgetutxos(char *destip,uint16_t destport,char *coin,int32_t lastn)
8 years ago
{
8 years ago
char url[512];//,*retstr;
8 years ago
sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=127.0.0.1&port=0",destip,destport,coin,lastn);
8 years ago
return(LP_issue_curl("clientgetutxos",destip,destport,url));
//retstr = issue_curlt(url,LP_HTTP_TIMEOUT);
8 years ago
//printf("%s clientgetutxos.(%s)\n",url,retstr);
8 years ago
//return(retstr);
8 years ago
}
8 years ago
char *issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos,uint32_t sessionid)
8 years ago
{
8 years ago
char url[512],*retstr;
if ( (retstr= LP_isitme(destip,destport)) != 0 )
8 years ago
return(retstr);
8 years ago
sprintf(url,"http://%s:%u/api/stats/notify?ipaddr=%s&port=%u&numpeers=%d&numutxos=%d&session=%u",destip,destport,ipaddr,port,numpeers,numutxos,sessionid);
8 years ago
return(LP_issue_curl("notify",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));
8 years ago
}
8 years ago
/*char *issue_LP_notifyutxo(char *destip,uint16_t destport,struct LP_utxoinfo *utxo)
8 years ago
{
8 years ago
char url[4096],str[65],str2[65],str3[65],*retstr; struct _LP_utxoinfo u; uint64_t val,val2;
if ( (retstr= LP_isitme(destip,destport)) != 0 )
8 years ago
return(retstr);
8 years ago
if ( utxo->iambob == 0 )
{
printf("issue_LP_notifyutxo trying to send Alice %s/v%d\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout);
return(0);
}
8 years ago
u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee;
8 years ago
if ( LP_iseligible(&val,&val2,utxo->iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,u.txid,u.vout) > 0 )
8 years ago
{
8 years ago
sprintf(url,"http://%s:%u/api/stats/notified?iambob=%d&pubkey=%s&coin=%s&txid=%s&vout=%d&value=%llu&txid2=%s&vout2=%d&value2=%llu&script=%s&address=%s&timestamp=%u&gui=%s",destip,destport,utxo->iambob,bits256_str(str3,utxo->pubkey),utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,(long long)utxo->payment.value,bits256_str(str2,utxo->deposit.txid),utxo->deposit.vout,(long long)utxo->deposit.value,utxo->spendscript,utxo->coinaddr,(uint32_t)time(NULL),utxo->gui);
8 years ago
if ( strlen(url) > 1024 )
printf("WARNING long url.(%s)\n",url);
8 years ago
return(LP_issue_curl("notifyutxo",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));
8 years ago
}
else
{
printf("issue_LP_notifyutxo: ineligible utxo iambob.%d %.8f %.8f\n",utxo->iambob,dstr(val),dstr(val2));
8 years ago
if ( utxo->T.spentflag == 0 )
utxo->T.spentflag = (uint32_t)time(NULL);
8 years ago
return(0);
}
8 years ago
}*/
8 years ago
8 years ago
/*char *issue_LP_lookup(char *destip,uint16_t destport,bits256 pubkey)
8 years ago
{
8 years ago
char url[512],str[65];
sprintf(url,"http://%s:%u/api/stats/lookup?client=%s",destip,destport,bits256_str(str,pubkey));
//printf("getutxo.(%s)\n",url);
return(LP_issue_curl("lookup",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));
8 years ago
}*/
8 years ago
char *issue_LP_getprices(char *destip,uint16_t destport)
{
char url[512];
sprintf(url,"http://%s:%u/api/stats/getprices",destip,destport);
//printf("getutxo.(%s)\n",url);
return(LP_issue_curl("getprices",destip,destport,url));
//return(issue_curlt(url,LP_HTTP_TIMEOUT));
}
8 years ago
8 years ago
char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired)
{
8 years ago
char url[512],*retstr;
8 years ago
sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d",destip,destport,ispaired);
8 years ago
//return(LP_issue_curl("psock",destip,destport,url));
retstr = issue_curlt(url,LP_HTTP_TIMEOUT*3);
8 years ago
printf("issue_LP_psock got (%s) from %s\n",retstr,destip);
8 years ago
return(retstr);
8 years ago
}
uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired)
{
uint16_t publicport = 0; char *retstr,*addr; cJSON *retjson; struct LP_peerinfo *peer,*tmp;
HASH_ITER(hh,LP_peerinfos,peer,tmp)
{
8 years ago
connectaddr[0] = publicaddr[0] = 0;
if ( peer->errors < LP_MAXPEER_ERRORS && (retstr= issue_LP_psock(peer->ipaddr,peer->port,ispaired)) != 0 )
8 years ago
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
8 years ago
printf("from %s:%u (%s)\n",peer->ipaddr,peer->port,retstr);
8 years ago
if ( (addr= jstr(retjson,"publicaddr")) != 0 )
safecopy(publicaddr,addr,128);
if ( (addr= jstr(retjson,"connectaddr")) != 0 )
safecopy(connectaddr,addr,128);
if ( publicaddr[0] != 0 && connectaddr[0] != 0 )
publicport = juint(retjson,"publicport");
free_json(retjson);
}
8 years ago
printf("got.(%s) connect.%s public.%s\n",retstr,connectaddr,publicaddr);
8 years ago
free(retstr);
8 years ago
} else printf("error psock from %s:%u\n",peer->ipaddr,peer->port);
8 years ago
if ( publicport != 0 )
break;
}
return(publicport);
}
8 years ago
cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params)
8 years ago
{
8 years ago
char *retstr; cJSON *retjson = 0;
if ( coin != 0 )
{
8 years ago
//printf("issue.(%s, %s, %s, %s, %s)\n",coin->symbol,coin->serverport,coin->userpass,method,params);
8 years ago
if ( coin->inactive == 0 || strcmp(method,"importprivkey") == 0 )
8 years ago
{
8 years ago
retstr = bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,method,params);
if ( retstr != 0 && retstr[0] != 0 )
{
//printf("%s: %s.%s -> (%s)\n",coin->symbol,method,params,retstr);
retjson = cJSON_Parse(retstr);
free(retstr);
}
//usleep(1000);
//printf("dpow_gettxout.(%s)\n",retstr);
8 years ago
} else retjson = cJSON_Parse("{\"result\":\"disabled\"}");
8 years ago
} else printf("bitcoin_json cant talk to NULL coin\n");
8 years ago
return(retjson);
8 years ago
}
void LP_unspents_mark(char *symbol,cJSON *vins)
{
8 years ago
printf("LOCK (%s)\n",jprint(vins,0));
8 years ago
}
8 years ago
cJSON *LP_getinfo(char *symbol)
{
struct iguana_info *coin = LP_coinfind(symbol);
return(bitcoin_json(coin,"getinfo","[]"));
}
8 years ago
cJSON *LP_getmempool(char *symbol)
{
struct iguana_info *coin = LP_coinfind(symbol);
return(bitcoin_json(coin,"getrawmempool","[]"));
}
8 years ago
cJSON *LP_gettxout(char *symbol,bits256 txid,int32_t vout)
8 years ago
{
8 years ago
char buf[128],str[65]; struct iguana_info *coin = LP_coinfind(symbol);
8 years ago
sprintf(buf,"\"%s\", %d, true",bits256_str(str,txid),vout);
8 years ago
return(bitcoin_json(coin,"gettxout",buf));
8 years ago
}
8 years ago
cJSON *LP_gettx(char *symbol,bits256 txid)
8 years ago
{
8 years ago
char buf[128],str[65]; struct iguana_info *coin = LP_coinfind(symbol);
8 years ago
sprintf(buf,"[\"%s\", 1]",bits256_str(str,txid));
8 years ago
return(bitcoin_json(coin,"getrawtransaction",buf));
8 years ago
}
8 years ago
cJSON *LP_getblock(char *symbol,bits256 txid)
{
char buf[128],str[65]; struct iguana_info *coin = LP_coinfind(symbol);
sprintf(buf,"[\"%s\"]",bits256_str(str,txid));
return(bitcoin_json(coin,"getblock",buf));
}
cJSON *LP_getblockhashstr(char *symbol,char *blockhashstr)
{
char buf[128]; struct iguana_info *coin = LP_coinfind(symbol);
sprintf(buf,"[\"%s\"]",blockhashstr);
return(bitcoin_json(coin,"getblock",buf));
}
8 years ago
cJSON *LP_listunspent(char *symbol,char *coinaddr)
8 years ago
{
8 years ago
char buf[128]; struct iguana_info *coin = LP_coinfind(symbol);
8 years ago
sprintf(buf,"0, 99999999, [\"%s\"]",coinaddr);
8 years ago
return(bitcoin_json(coin,"listunspent",buf));
8 years ago
}
8 years ago
cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t count,int32_t skip)
8 years ago
{
8 years ago
char buf[128]; struct iguana_info *coin = LP_coinfind(symbol);
8 years ago
if ( count == 0 )
count = 100;
sprintf(buf,"[\"%s\", %d, %d, true]",coinaddr,count,skip);
8 years ago
return(bitcoin_json(coin,"listtransactions",buf));
8 years ago
}
8 years ago
cJSON *LP_validateaddress(char *symbol,char *address)
8 years ago
{
8 years ago
char buf[512]; struct iguana_info *coin = LP_coinfind(symbol);
sprintf(buf,"\"%s\"",address);
return(bitcoin_json(coin,"validateaddress",buf));
8 years ago
}
8 years ago
cJSON *LP_importprivkey(char *symbol,char *wifstr,char *label,int32_t flag)
8 years ago
{
char buf[512]; struct iguana_info *coin = LP_coinfind(symbol);
8 years ago
sprintf(buf,"[\"%s\", \"%s\", %s]",wifstr,label,flag < 0 ? "false" : "true");
8 years ago
return(bitcoin_json(coin,"importprivkey",buf));
}
8 years ago
int32_t LP_importaddress(char *symbol,char *address)
8 years ago
{
8 years ago
char buf[1024],*retstr; cJSON *validatejson; int32_t isvalid=0,doneflag = 0; struct iguana_info *coin = LP_coinfind(symbol);
8 years ago
if ( coin == 0 )
return(-2);
if ( (validatejson= LP_validateaddress(symbol,address)) != 0 )
8 years ago
{
8 years ago
if ( (isvalid= is_cJSON_True(jobj(validatejson,"isvalid")) != 0) != 0 )
8 years ago
{
8 years ago
if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 )
doneflag = 1;
8 years ago
}
8 years ago
free_json(validatejson);
8 years ago
}
if ( isvalid == 0 )
8 years ago
return(-1);
8 years ago
if ( doneflag != 0 )
return(0); // success
8 years ago
sprintf(buf,"[\"%s\", \"%s\", false]",address,address);
8 years ago
if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"importaddress",buf)) != 0 )
8 years ago
{
8 years ago
//printf("importaddress.(%s %s) -> (%s)\n",symbol,address,retstr);
8 years ago
free(retstr);
8 years ago
} //else printf("importaddress.(%s %s)\n",symbol,address);
8 years ago
return(1);
8 years ago
}
8 years ago
double LP_getestimatedrate(char *symbol)
8 years ago
{
8 years ago
char buf[512],*retstr; double rate = 20; struct iguana_info *coin = LP_coinfind(symbol);
8 years ago
if ( coin != 0 )
8 years ago
{
8 years ago
sprintf(buf,"[%d]",3);
8 years ago
if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"estimatefee",buf)) != 0 )
8 years ago
{
8 years ago
if ( retstr[0] != '-' )
{
8 years ago
coin->estimatedrate = rate = atof(retstr) / 1024.;
8 years ago
//printf("estimated rate.(%s) %s -> %.8f\n",symbol,retstr,rate);
8 years ago
}
8 years ago
free(retstr);
}
}
8 years ago
return(rate);
8 years ago
}
8 years ago
uint64_t LP_txfee(char *symbol)
8 years ago
{
8 years ago
uint64_t txfee = 0;
if ( strcmp(symbol,"BTC") != 0 )
8 years ago
txfee = 10000;
8 years ago
return(txfee);
8 years ago
}
8 years ago
char *LP_blockhashstr(char *symbol,int32_t height)
{
cJSON *array; char *paramstr,*retstr; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 )
return(0);
array = cJSON_CreateArray();
jaddinum(array,height);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"getblockhash",paramstr);
free(paramstr);
return(retstr);
}
8 years ago
char *LP_sendrawtransaction(char *symbol,char *signedtx)
8 years ago
{
8 years ago
cJSON *array; char *paramstr,*retstr; struct iguana_info *coin = LP_coinfind(symbol);
if ( coin == 0 )
return(0);
array = cJSON_CreateArray();
jaddistr(array,signedtx);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"sendrawtransaction",paramstr);
8 years ago
//printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr);
8 years ago
free(paramstr);
return(retstr);
8 years ago
}
8 years ago
char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkeys,struct vin_info *V)
8 years ago
{
8 years ago
cJSON *array,*json; int32_t len; uint8_t *data; char *paramstr,*retstr,*hexstr,*signedtx=0; struct iguana_info *coin = LP_coinfind(symbol);
memset(signedtxidp,0,sizeof(*signedtxidp));
*completedp = 0;
if ( coin == 0 )
8 years ago
{
printf("LP_signrawtx cant find coin.(%s)\n",symbol);
8 years ago
return(0);
8 years ago
}
8 years ago
array = cJSON_CreateArray();
jaddistr(array,rawtx);
jaddi(array,jduplicate(vins));
jaddi(array,jduplicate(privkeys));
paramstr = jprint(array,1);
//printf("signrawtransaction\n");
if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"signrawtransaction",paramstr)) != 0 )
8 years ago
{
8 years ago
if ( (json= cJSON_Parse(retstr)) != 0 )
8 years ago
{
8 years ago
if ( (hexstr= jstr(json,"hex")) != 0 )
8 years ago
{
8 years ago
len = (int32_t)strlen(hexstr);
signedtx = calloc(1,len+1);
strcpy(signedtx,hexstr);
8 years ago
*completedp = is_cJSON_True(jobj(json,"complete"));
8 years ago
data = malloc(len >> 1);
decode_hex(data,len>>1,hexstr);
*signedtxidp = bits256_doublesha256(0,data,len >> 1);
}
8 years ago
//else
printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr);
8 years ago
free_json(json);
}
free(retstr);
8 years ago
}
8 years ago
free(paramstr);
return(signedtx);
8 years ago
}
8 years ago
cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t height)
{
cJSON *json = 0; int32_t flag = 0;
if ( blockhashstr == 0 )
blockhashstr = LP_blockhashstr(symbol,height), flag = 1;
if ( blockhashstr != 0 )
{
if ( (json= LP_getblockhashstr(symbol,blockhashstr)) != 0 )
{
if ( *heightp != 0 )
{
*heightp = juint(json,"height");
if ( height >= 0 && *heightp != height )
{
printf("unexpected height %d vs %d\n",*heightp,height);
*heightp = -1;
free_json(json);
json = 0;
}
}
}
if ( flag != 0 && blockhashstr != 0 )
free(blockhashstr);
}
return(json);
}