From 2c06ac84781bc3d93b86a43ee2b9269cec7c5051 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Mar 2017 18:34:15 +0200 Subject: [PATCH 1/2] Estimatefee for BTC added to dex get info --- iguana/dpow/dpow_rpc.c | 10 ++++++++++ iguana/tests/dexlistunspent | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/iguana/dpow/dpow_rpc.c b/iguana/dpow/dpow_rpc.c index 4f344119c..f8ffded08 100755 --- a/iguana/dpow/dpow_rpc.c +++ b/iguana/dpow/dpow_rpc.c @@ -36,6 +36,16 @@ cJSON *dpow_getinfo(struct supernet_info *myinfo,struct iguana_info *coin) { json = cJSON_Parse(retstr); free(retstr); + if ( strcmp(coin->symbol,"BTC") == 0 ) + { + sprintf(buf,"[%d]",2); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"estimatefee",buf)) != 0 ) + { + if ( atof(retstr) > SMALLVAL ) + jaddnum(json,"estimatefee",atof(retstr)); + free(retstr); + } + } } return(json); } diff --git a/iguana/tests/dexlistunspent b/iguana/tests/dexlistunspent index 5cd82cdaa..c6ede1cca 100755 --- a/iguana/tests/dexlistunspent +++ b/iguana/tests/dexlistunspent @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RDKb3QykRJNfLKWLcbbv9z7xqbtxwB54GC\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RCownUMXktAgPvzwpALnGimCA1RDJoTvx1\",\"symbol\":\"KMD\"}" From f4c6d87f518ec6ea093ace34a23c96ae2957bdaf Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 2 Mar 2017 19:46:34 +0200 Subject: [PATCH 2/2] Autocalc txfee for BTC if txfee == 0 --- basilisk/basilisk.c | 3 +- basilisk/basilisk_bitcoin.c | 104 +++++++++++++++++++++++++++++------- iguana/iguana_payments.c | 6 ++- iguana/tests/amlp | 2 +- iguana/tests/dexlistunspent | 2 +- iguana/tests/utxorawtx | 2 +- includes/iguana_structs.h | 1 + 7 files changed, 95 insertions(+), 25 deletions(-) diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index 3ab1ea6a3..9e717e99e 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -1166,8 +1166,7 @@ STRING_ARRAY_OBJ_STRING(basilisk,utxorawtx,symbol,utxos,vals,ignore) changeaddr = jstr(vals,"changeaddr"); if ( destaddr != 0 && changeaddr != 0 && symbol != 0 && (coin= iguana_coinfind(symbol)) != 0 ) { - if ( (txfee= jdouble(vals,"txfee") * SATOSHIDEN) == 0 ) - txfee = coin->txfee; + txfee = jdouble(vals,"txfee") * SATOSHIDEN; return(iguana_utxorawtx(myinfo,coin,timelock,destaddr,changeaddr,satoshis,txfee,&completed,sendflag,utxos)); } return(clonestr("{\"error\":\"invalid coin or address specified\"}")); diff --git a/basilisk/basilisk_bitcoin.c b/basilisk/basilisk_bitcoin.c index c6bdadf34..e42ab5146 100755 --- a/basilisk/basilisk_bitcoin.c +++ b/basilisk/basilisk_bitcoin.c @@ -473,6 +473,23 @@ void *basilisk_getinfo(struct basilisk_item *Lptr,struct supernet_info *myinfo,s return(ptr); } +int64_t iguana_getestimatedfee(struct supernet_info *myinfo,struct iguana_info *coin) +{ + char *retstr; cJSON *retjson; double x; int64_t txfeeperbyte = 200; + if ( (retstr= _dex_getinfo(myinfo,coin->symbol)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (x= jdouble(retjson,"estimatefee")) > SMALLVAL ) + txfeeperbyte = 1 + (x * SATOSHIDEN) / 1024; + printf("SET txfeeperbyte %lld (%s)\n",(long long)txfeeperbyte,retstr); + free(retjson); + } + free(retstr); + } + return(txfeeperbyte); +} + int32_t basilisk_voutvin_validate(struct iguana_info *coin,char *rawtx,uint64_t inputsum,uint64_t amount,uint64_t txfee) { //static int counter; @@ -543,13 +560,32 @@ int32_t basilisk_vins_validate(struct supernet_info *myinfo,struct iguana_info * return(retval); } +int64_t iguana_esttxfee(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx,char *signedtx,int32_t numvins) +{ + int64_t txfee = 0; + if ( coin->estimatedfee == 0 ) + coin->estimatedfee = iguana_getestimatedfee(myinfo,coin); + if ( signedtx != 0 ) + { + txfee = coin->estimatedfee * (strlen(signedtx) + numvins); + free(signedtx); + } + else if ( rawtx != 0 ) + { + txfee = coin->estimatedfee * (strlen(rawtx) + numvins * 110); + free(rawtx); + } + return(txfee); +} + char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *pubkey33,uint64_t satoshis,int32_t duplicates,int32_t *completedp,bits256 *signedtxidp,int32_t sendflag,cJSON *addresses) { - uint8_t script[35]; int32_t i,spendlen; cJSON *txobj=0,*vins=0; char *rawtx=0,*signedtx,changeaddr[64]; + uint8_t script[35]; int64_t txfee; int32_t i,spendlen; cJSON *txobj=0,*vins=0; char *rawtx=0,*signedtx=0,changeaddr[64]; *completedp = 0; if ( signedtxidp != 0 ) memset(signedtxidp,0,sizeof(*signedtxidp)); bitcoin_address(changeaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); + txfee = 10 * (coin->txfee + duplicates*coin->txfee/5); if ( (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,0,1,0)) != 0 ) { if ( duplicates <= 0 ) @@ -557,19 +593,28 @@ char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coi spendlen = bitcoin_pubkeyspend(script,0,pubkey33); for (i=0; itxfee + duplicates*coin->txfee/5,addresses,0,0,0,0,"127.0.0.1",0,1); + rawtx = iguana_calcrawtx(myinfo,coin,&vins,txobj,satoshis * duplicates,changeaddr,txfee,addresses,0,0,0,0,"127.0.0.1",0,1); + if ( cJSON_GetArraySize(vins) > duplicates/4 ) + { + free(rawtx); + rawtx = 0; + fprintf(stderr,"No point to recycle utxo when trying to create utxo duplicates, numvins.%d vs duplicates.%d\n",cJSON_GetArraySize(vins),duplicates); + free_json(vins); + return(rawtx); + } //printf("duplicatesTX.(%s)\n",rawtx); if ( signedtxidp != 0 ) { if ( (signedtx= iguana_signrawtx(myinfo,coin,0,signedtxidp,completedp,vins,rawtx,0,0)) != 0 ) { - free(rawtx); - if ( *completedp != 0 && sendflag != 0 ) + if ( *completedp != 0 ) { printf("splitfunds signedtx.(%s)\n",signedtx); - iguana_sendrawtransaction(myinfo,coin,signedtx); + if ( sendflag != 0 ) + iguana_sendrawtransaction(myinfo,coin,signedtx); + free(rawtx); + rawtx = signedtx, signedtx = 0; } - rawtx = signedtx; } else printf("error signing raw utxoduplicates tx\n"); } } @@ -615,7 +660,7 @@ int64_t iguana_verifytimelock(struct supernet_info *myinfo,struct iguana_info *c char *iguana_utxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t timelock,char *destaddr,char *changeaddr,uint64_t satoshis,uint64_t txfee,int32_t *completedp,int32_t sendflag,cJSON *utxos) { - uint8_t script[35],p2shscript[128],rmd160[20],addrtype; bits256 txid; int32_t p2shlen,spendlen; cJSON *retjson,*txobj=0,*vins=0; char *rawtx=0,*signedtx=0; uint32_t timelocked = 0; + uint8_t script[35],p2shscript[128],rmd160[20],addrtype; bits256 txid; int32_t p2shlen,iter,spendlen; cJSON *retjson,*txcopy,*txobj=0,*vins=0; char *rawtx=0,*signedtx=0; uint32_t timelocked = 0; *completedp = 0; if ( iguana_addressvalidate(coin,&addrtype,destaddr) < 0 || iguana_addressvalidate(coin,&addrtype,changeaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); @@ -625,6 +670,8 @@ char *iguana_utxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,int bitcoin_addr2rmd160(&addrtype,rmd160,destaddr); if ( addrtype != coin->chain->pubtype ) return(clonestr("{\"error\":\"invalid dest address type\"}")); + if ( txfee == 0 && strcmp(coin->symbol,"BTC") != 0 && (txfee= coin->txfee) == 0 ) + txfee = coin->chain->txfee; retjson = cJSON_CreateObject(); if ( (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,0,1,0)) != 0 ) { @@ -641,23 +688,42 @@ char *iguana_utxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,int printf("timelock.%d spend timelocked %u\n",timelock,timelocked); } bitcoin_txoutput(txobj,script,spendlen,satoshis); - if ( (rawtx= iguana_calcutxorawtx(myinfo,coin,&vins,txobj,satoshis,changeaddr,txfee,utxos,"",0,0)) != 0 ) + for (iter=0; iter<2; iter++) { - jaddstr(retjson,"rawtx",rawtx); - if ( (signedtx= iguana_signrawtx(myinfo,coin,0,&txid,completedp,vins,rawtx,0,0)) != 0 ) + txcopy = jduplicate(txobj); + if ( (rawtx= iguana_calcutxorawtx(myinfo,coin,&vins,txobj,satoshis,changeaddr,txfee,utxos,"",0,0)) != 0 ) { - if ( *completedp != 0 ) + if ( iter == 1 || txfee != 0 ) + jaddstr(retjson,"rawtx",rawtx); + if ( (signedtx= iguana_signrawtx(myinfo,coin,0,&txid,completedp,vins,rawtx,0,0)) != 0 ) { - jaddbits256(retjson,"txid",txid); - jaddstr(retjson,"signedtx",signedtx); - if ( sendflag != 0 ) + if ( (iter == 1 || txfee != 0) && *completedp != 0 ) { - //printf("send signedtx.(%s)\n",signedtx); - txid = iguana_sendrawtransaction(myinfo,coin,signedtx); - jaddbits256(retjson,"sent",txid); + jaddbits256(retjson,"txid",txid); + jaddstr(retjson,"signedtx",signedtx); + if ( sendflag != 0 ) + { + //printf("send signedtx.(%s)\n",signedtx); + txid = iguana_sendrawtransaction(myinfo,coin,signedtx); + jaddbits256(retjson,"sent",txid); + } } - } - } else printf("error signing raw utxoduplicates tx\n"); + } else printf("error signing raw utxorawtx tx\n"); + } else printf("null rawtx from calcutxorawtx\n"); + if ( txfee != 0 ) + { + free_json(txcopy); + break; + } + else // must be BTC and txfee == 0 + { + txfee = iguana_esttxfee(myinfo,coin,rawtx,signedtx,cJSON_GetArraySize(vins)); + free_json(vins); + rawtx = signedtx = 0; + vins = 0; + *completedp = 0; + txobj = txcopy; + } } } if ( timelock != 0 ) diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c index 6aca69045..fbe9ba5b5 100755 --- a/iguana/iguana_payments.c +++ b/iguana/iguana_payments.c @@ -534,7 +534,11 @@ char *iguana_calcutxorawtx(struct supernet_info *myinfo,struct iguana_info *coin for (i=0; i 16 ) + { + + } + else if ( (sobj= jobj(item,"scriptPubKey")) == 0 && (spendscriptstr= jstr(sobj,"hex")) == 0 ) { printf("no spendscript (%s)\n",jprint(item,0)); continue; diff --git a/iguana/tests/amlp b/iguana/tests/amlp index 4a771e030..76856c320 100755 --- a/iguana/tests/amlp +++ b/iguana/tests/amlp @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"amlp\",\"blocktrail\":\"blocktrail_apikey\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"amlp\",\"blocktrail\":\"e5ddfdceb58fa6c1bf9411aaeff4b6ee28cbc370\"}" diff --git a/iguana/tests/dexlistunspent b/iguana/tests/dexlistunspent index c6ede1cca..4e353d69b 100755 --- a/iguana/tests/dexlistunspent +++ b/iguana/tests/dexlistunspent @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RCownUMXktAgPvzwpALnGimCA1RDJoTvx1\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\",\"symbol\":\"BTC\"}" diff --git a/iguana/tests/utxorawtx b/iguana/tests/utxorawtx index a157a3ee9..57d252129 100755 --- a/iguana/tests/utxorawtx +++ b/iguana/tests/utxorawtx @@ -1,2 +1,2 @@ #!/bin/bash -curl --url "http://127.0.0.1:7778" --data "{\"symbol\":\"KMD\",\"agent\":\"basilisk\",\"method\":\"utxorawtx\",\"vals\":{\"timelock\":0,\"changeaddr\":\"RNmvQtThVZAbc1tFEFmKAnJZrc9XqciNog\",\"destaddr\":\"RHfraY22xd9aAuuUJ6Yjb6HFUXh535z6Lg\",\"txfee\":0.00011,\"amount\":0.01,\"sendflag\":0},\"utxos\":[{\"bestblock\":\"000000a7d7b317af7169a156f6b4b9538293da2a3707a69aa3048998a87fbf2c\",\"confirmations\":0,\"value\":0.02,\"scriptPubKey\":{\"asm\":\"OP_DUP OP_HASH160 b7128d2ee837cf03e30a2c0e3e0181f7b9669bb6 OP_EQUALVERIFY OP_CHECKSIG\",\"hex\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\",\"reqSigs\":1,\"type\":\"pubkeyhash\",\"addresses\":[\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\"]},\"version\":1,\"coinbase\":false,\"randipbits\":3350674129,\"coin\":\"KMD\",\"txid\":\"9329814cc4c7a8cabf83627d4228c1a2090e776d669c585d824d912ce2e13b13\",\"vout\":1,\"amount\":0.02}]}" +curl --url "http://127.0.0.1:7778" --data "{\"symbol\":\"BTC\",\"agent\":\"basilisk\",\"method\":\"utxorawtx\",\"vals\":{\"timelock\":0,\"changeaddr\":\"1P3rU1Nk1pmc2BiWC8dEy9bZa1ZbMp5jfg\",\"destaddr\":\"1P3rU1Nk1pmc2BiWC8dEy9bZa1ZbMp5jfg\",\"txfee\":0,\"amount\":0.0001,\"sendflag\":0},\"utxos\":[{\"value\":0.00100000,\"address\":\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\",\"scriptPubKey\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\",\"confirmations\":23351,\"spendable\":true}]}" diff --git a/includes/iguana_structs.h b/includes/iguana_structs.h index ea665ef85..813bd77a7 100755 --- a/includes/iguana_structs.h +++ b/includes/iguana_structs.h @@ -531,6 +531,7 @@ struct iguana_info uint32_t utxoaddrlastcount,*utxoaddroffsets,lastunspentsupdate; uint8_t *utxoaddrtable; bits256 utxoaddrhash; FILE *utxofp; bits256 markedunspents[1024]; + uint64_t estimatedfee; char seedipaddr[64]; uint32_t lastbesthashtime; bits256 lastbesthash; int32_t lastbestheight; struct iguana_block *RTblocks[65536]; uint8_t *RTrawdata[65536]; int32_t RTrecvlens[65536],RTnumtx[65536];