From d13daf94e91da8bdda2582d7a63fedb8ece3fd4e Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 3 May 2016 15:12:21 -0500 Subject: [PATCH] test --- iguana/SuperNET.c | 17 +++ iguana/exchanges/bitcoin.c | 6 + iguana/iguana777.h | 2 +- iguana/iguana_sign.c | 6 +- iguana/iguana_wallet.c | 274 +++++++++++++++++++++++++--------- iguana/main.c | 2 +- iguana/ramchain_api.c | 26 ---- iguana/tests/.priv2wif.swp | Bin 0 -> 12288 bytes iguana/tests/priv2wif | 1 + includes/iguana_apideclares.h | 7 +- 10 files changed, 239 insertions(+), 102 deletions(-) create mode 100644 iguana/tests/.priv2wif.swp create mode 100755 iguana/tests/priv2wif diff --git a/iguana/SuperNET.c b/iguana/SuperNET.c index ad25dfd50..255b13b1f 100755 --- a/iguana/SuperNET.c +++ b/iguana/SuperNET.c @@ -1266,6 +1266,23 @@ STRING_ARG(SuperNET,wif2priv,wif) return(jprint(retjson,1)); } +STRING_ARG(SuperNET,priv2wif,priv) +{ + bits256 privkey; char wifstr[65]; cJSON *retjson = cJSON_CreateObject(); + if ( strlen(priv) == sizeof(bits256)*2 && is_hexstr(priv,(int32_t)sizeof(bits256)*2) == sizeof(bits256)*2 ) + { + decode_hex(privkey.bytes,sizeof(privkey),priv); + if ( bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype) == sizeof(privkey) ) + { + jaddstr(retjson,"result","success"); + jaddstr(retjson,"privkey",priv); + jaddnum(retjson,"type",coin->chain->wiftype); + jaddstr(retjson,"wif",wifstr); + } else jaddstr(retjson,"error","couldnt convert privkey"); + } else jaddstr(retjson,"error","non 32 byte hex privkey"); + return(jprint(retjson,1)); +} + STRING_ARG(SuperNET,myipaddr,ipaddr) { cJSON *retjson = cJSON_CreateObject(); diff --git a/iguana/exchanges/bitcoin.c b/iguana/exchanges/bitcoin.c index a85e2b639..9a14d672d 100755 --- a/iguana/exchanges/bitcoin.c +++ b/iguana/exchanges/bitcoin.c @@ -102,7 +102,13 @@ int32_t base58encode_checkbuf(uint8_t addrtype,uint8_t *data,int32_t data_len) { uint8_t i; bits256 hash; data[0] = addrtype; + for (i=0; i "); hash = bits256_doublesha256(0,data,(int32_t)data_len+1); + for (i=0; i<32; i++) + printf("%02x",hash.bytes[i]); + printf(" checkhash\n"); for (i=0; i<4; i++) data[data_len+i+1] = hash.bytes[31-i]; return(data_len + 5); diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 0bec6507a..e6f06e121 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -878,7 +878,7 @@ int8_t iguana_blockstatus(struct iguana_info *coin,struct iguana_block *block); int32_t iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,int32_t slotid,uint64_t ipbits); void iguana_blockunmark(struct iguana_info *coin,struct iguana_block *block,struct iguana_bundle *bp,int32_t i,int32_t deletefile); int32_t iguana_reqblocks(struct iguana_info *coin); -void iguana_walletlock(struct supernet_info *myinfo); +void iguana_walletlock(struct supernet_info *myinfo,struct iguana_info *coin); int32_t _SuperNET_encryptjson(char *destfname,char *passphrase,int32_t passsize,char *fname2fa,int32_t fnamesize,cJSON *argjson); int32_t bitcoin_pubkeylen(const uint8_t *pubkey); struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p,struct iguana_bundle *bp,int32_t i); diff --git a/iguana/iguana_sign.c b/iguana/iguana_sign.c index 8aa7382e0..828f4444b 100755 --- a/iguana/iguana_sign.c +++ b/iguana/iguana_sign.c @@ -985,8 +985,10 @@ void iguana_ensure_privkey(struct supernet_info *myinfo,struct iguana_info *coin waddr->privkey = privkey; if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->chain->wiftype) > 0 ) { - waddr->wiftype = coin->chain->wiftype; - waddr->addrtype = coin->chain->pubtype; + if ( waddr->wiftype != coin->chain->wiftype ) + printf("ensurepriv warning: mismatched wiftype %02x != %02x\n",waddr->wiftype,coin->chain->wiftype); + if ( waddr->addrtype != coin->chain->pubtype ) + printf("ensurepriv warning: mismatched wiftype %02x != %02x\n",waddr->addrtype,coin->chain->pubtype); } } } diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index 76998d535..5d0600ec9 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -33,6 +33,8 @@ struct iguana_waddress *iguana_waddressfind(struct supernet_info *myinfo,struct { struct iguana_waddress *waddr; int32_t len = (int32_t)strlen(coinaddr)+1; HASH_FIND(hh,wacct->waddr,coinaddr,len,waddr); + if ( strcmp(coin->symbol,waddr->symbol) != 0 ) + return(0); //printf("%s (%s).%d in (%s)\n",waddr==0?"couldnt find":"found",coinaddr,len,wacct->account); return(waddr); } @@ -175,8 +177,10 @@ struct iguana_waddress *iguana_waddresssearch(struct supernet_info *myinfo,struc { if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->chain->wiftype) > 0 ) { - waddr->wiftype = coin->chain->wiftype; - waddr->addrtype = coin->chain->pubtype; + if ( waddr->wiftype != coin->chain->wiftype ) + printf("waddresssearch warning: mismatched wiftype %02x != %02x\n",waddr->wiftype,coin->chain->wiftype); + if ( waddr->addrtype != coin->chain->pubtype ) + printf("waddresssearch warning: mismatched wiftype %02x != %02x\n",waddr->addrtype,coin->chain->pubtype); } } (*wacctp) = wacct; @@ -487,67 +491,6 @@ cJSON *iguana_walletjson(struct supernet_info *myinfo) return(wallet); } -void iguana_walletinitcheck(struct supernet_info *myinfo,struct iguana_info *coin) -{ - // "wallet":{"test":{"R9S7zZzzvgb4CkiBH1i7gnFcwJuL1MYbxN":"18ab9c89ce83929db720cf26b663bf762532276146cd9d3e1f89086fcdf00053"}} - cJSON *payload,*item,*array,*child; char *account,*coinaddr,*privkeystr; int32_t i,j,n,len; struct iguana_waccount *wacct,*tmp; struct iguana_waddress waddr; bits256 privkey; uint8_t addrtype,rmd160[20]; - if ( myinfo->wallet == 0 && myinfo->decryptstr != 0 && (payload= cJSON_Parse(myinfo->decryptstr)) != 0 ) - { - if ( (array= jobj(payload,"wallet")) != 0 ) - { - n = cJSON_GetArraySize(array); - //printf("item.(%s) size.%d\n",jprint(array,0),n); - item = array->child; - for (i=0; istring) != 0 ) - { - child = item->child; - while ( child != 0 ) - { - coinaddr = child->string; - privkeystr = child->valuestring; - if ( coinaddr != 0 && privkeystr != 0 ) - { - if ( (wacct= iguana_waccountcreate(myinfo,coin,account)) != 0 ) - { - if ( iguana_waddresssearch(myinfo,coin,&tmp,coinaddr) == 0 ) - { - memset(&waddr,0,sizeof(waddr)); - strcpy(waddr.coinaddr,coinaddr); - waddr.addrtype = coin->chain->p2shtype; - if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == sizeof(rmd160) && addrtype == coin->chain->p2shtype ) - iguana_waddressadd(myinfo,coin,wacct,&waddr,privkeystr); - else - { - waddr.addrtype = coin->chain->pubtype; - privkey = bits256_conv(privkeystr); - if ( iguana_waddresscalc(coin->chain->pubtype,coin->chain->wiftype,&waddr,privkey) != 0 ) - iguana_waddressadd(myinfo,coin,wacct,&waddr,0); - } - } else printf("dup.(%s) ",coinaddr); - len = (int32_t)strlen(privkeystr); - for (j=0; jnext; - } - printf("account.(%s)\n",account); - } - item = item->next; - } - } - free_json(payload); - myinfo->decryptstr = 0; - scrubfree(myinfo->decryptstr); - myinfo->dirty = 0; - } -} - int32_t iguana_walletemit(struct supernet_info *myinfo,char *fname,struct iguana_info *coin,cJSON *array) { cJSON *item,*child; uint8_t addrtype,wiftype,rmd160[20]; char p2shaddr[128],str[64],wifstr[128],*account,*coinaddr,*privkeystr; int32_t i,j,n; FILE *fp; bits256 privkey; @@ -600,13 +543,91 @@ int32_t iguana_walletemit(struct supernet_info *myinfo,char *fname,struct iguana return(0); } -void iguana_walletiterate(struct supernet_info *myinfo,int32_t flag) +char *walleterrstr[] = { "P2SH_withpriv", "P2SH_withpub", "rmd160_mismatch", "pubkey_mismatch", "missing_pubkey", "account_mismatch" }; +uint8_t iguana_waddrvalidate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,struct iguana_waddress *waddr,int32_t repairflag,int32_t *errors) +{ + struct iguana_waccount *checkwacct; struct iguana_waddress *checkwaddr; uint8_t checkpub[33],rmd160[20],addrtype,checktype,plen,flag=0; + if ( waddr != 0 ) + { + if ( (checkwaddr= iguana_waddresssearch(myinfo,coin,&checkwacct,waddr->coinaddr)) != waddr || checkwacct != wacct ) + { + errors[5]++; + flag |= (5 << 0); + if ( repairflag > 0 ) + { + printf("waddrvalidate: need to manually setaccount to fix mismatch (%s:%s) <- (%s:%s)\n",checkwacct != 0 ? checkwacct->account : "",checkwaddr != 0 ? checkwaddr->coinaddr : "",wacct != 0 ? wacct->account : "",waddr->coinaddr); + } + } + if ( waddr->scriptlen > 0 ) + { + checktype = coin->chain->p2shtype; + if ( bits256_nonz(waddr->privkey) != 0 ) + { + errors[0]++; + flag |= (1 << 0); + if ( repairflag > 0 ) + memset(&waddr->privkey,0,sizeof(waddr->privkey)); + } + if ( bitcoin_pubkeylen(waddr->pubkey) > 0 ) + { + errors[1]++; + flag |= (1 << 1); + if ( repairflag > 0 ) + memset(waddr->pubkey,0,sizeof(waddr->pubkey)); + } + } + else checktype = coin->chain->pubtype; + if ( bitcoin_addr2rmd160(&addrtype,rmd160,waddr->coinaddr) != sizeof(rmd160) || addrtype != checktype || memcmp(rmd160,waddr->rmd160,sizeof(rmd160)) != 0 ) + { + errors[2]++; + flag |= (1 << 2); + if ( repairflag > 0 ) + { + waddr->addrtype = checktype; + memcpy(waddr->rmd160,rmd160,sizeof(rmd160)); + } + } + if ( waddr->scriptlen == 0 ) + { + if ( bits256_nonz(waddr->privkey) != 0 ) + { + bitcoin_pubkey33(myinfo,checkpub,waddr->privkey); + if ( memcmp(checkpub,waddr->pubkey,sizeof(checkpub)) != 0 ) + { + errors[3]++; + flag |= (1 << 3); + if ( repairflag > 0 ) + memcpy(waddr->pubkey,checkpub,sizeof(checkpub)); + } + } + if ( (plen= bitcoin_pubkeylen(waddr->pubkey)) > 0 ) + { + calc_rmd160_sha256(rmd160,waddr->pubkey,plen); + if ( memcmp(rmd160,waddr->rmd160,sizeof(rmd160)) != 0 ) + { + errors[4]++; + flag |= (1 << 4); + if ( repairflag > 0 ) + { + printf("waddrvalidate unrecoverable error: cant determine pubkey from rmd160\n"); + } + } + } + } + } + return(flag); +} + +cJSON *iguana_walletiterate(struct supernet_info *myinfo,struct iguana_info *coin,int32_t flag,cJSON *array,int32_t *goodp,int32_t *badp,int32_t *errors) { - struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; int32_t i; + struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; uint8_t errorflags; int32_t i,good=0,bad=0,_errors[8]; cJSON *item; + if ( errors == 0 ) + errors = _errors; HASH_ITER(hh,myinfo->wallet,wacct,tmp) { HASH_ITER(hh,wacct->waddr,waddr,tmp2) { + wacct->current = waddr; if ( flag < 0 ) { memset(&waddr->privkey,0,sizeof(waddr->privkey)); @@ -621,7 +642,18 @@ void iguana_walletiterate(struct supernet_info *myinfo,int32_t flag) free(waddr); } } - //else iguana_waddrvalidate(myinfo,coin,wacct,waddr,flag); + else + { + if ( (errorflags= iguana_waddrvalidate(myinfo,coin,wacct,waddr,flag,errors)) != 0 ) + { + bad++; + if ( array != 0 && (item= cJSON_CreateObject()) != 0 ) + { + jaddnum(item,waddr->coinaddr,errorflags); + jaddi(array,item); + } + } else good++; + } } if ( flag < -1 ) { @@ -629,9 +661,93 @@ void iguana_walletiterate(struct supernet_info *myinfo,int32_t flag) free(wacct); } } + if ( goodp != 0 ) + *goodp = good; + if ( badp != 0 ) + *badp = bad; + return(array); +} + +char *iguana_walletscan(struct supernet_info *myinfo,struct iguana_info *coin,int32_t repairflag) +{ + cJSON *retjson; int32_t i,good,bad,errors[8]; + memset(errors,0,sizeof(errors)); + good = bad = 0; + retjson = cJSON_CreateObject(); + jadd(retjson,"result",iguana_walletiterate(myinfo,coin,repairflag,cJSON_CreateArray(),&good,&bad,errors)); + jaddnum(retjson,"good",good); + jaddnum(retjson,"bad",bad); + for (i=0; iwallet == 0 && myinfo->decryptstr != 0 && (payload= cJSON_Parse(myinfo->decryptstr)) != 0 ) + { + if ( (array= jobj(payload,"wallet")) != 0 ) + { + n = cJSON_GetArraySize(array); + //printf("item.(%s) size.%d\n",jprint(array,0),n); + item = array->child; + for (i=0; istring) != 0 ) + { + child = item->child; + while ( child != 0 ) + { + coinaddr = child->string; + privkeystr = child->valuestring; + if ( coinaddr != 0 && privkeystr != 0 ) + { + if ( (wacct= iguana_waccountcreate(myinfo,coin,account)) != 0 ) + { + if ( iguana_waddresssearch(myinfo,coin,&tmp,coinaddr) == 0 ) + { + memset(&waddr,0,sizeof(waddr)); + strcpy(waddr.coinaddr,coinaddr); + waddr.addrtype = coin->chain->p2shtype; + if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == sizeof(rmd160) && addrtype == coin->chain->p2shtype ) + iguana_waddressadd(myinfo,coin,wacct,&waddr,privkeystr); + else + { + waddr.addrtype = coin->chain->pubtype; + privkey = bits256_conv(privkeystr); + if ( iguana_waddresscalc(coin->chain->pubtype,coin->chain->wiftype,&waddr,privkey) != 0 ) + iguana_waddressadd(myinfo,coin,wacct,&waddr,0); + } + } else printf("dup.(%s) ",coinaddr); + len = (int32_t)strlen(privkeystr); + for (j=0; jnext; + } + printf("account.(%s)\n",account); + } + item = item->next; + } + } + free_json(payload); + myinfo->decryptstr = 0; + scrubfree(myinfo->decryptstr); + myinfo->dirty = 0; + } + iguana_walletiterate(myinfo,coin,1,0,0,0,0); +} + +void iguana_walletlock(struct supernet_info *myinfo,struct iguana_info *coin) { memset(&myinfo->persistent_priv,0,sizeof(myinfo->persistent_priv)); memset(myinfo->secret,0,sizeof(myinfo->secret)); @@ -639,7 +755,7 @@ void iguana_walletlock(struct supernet_info *myinfo) if ( myinfo->decryptstr != 0 ) scrubfree(myinfo->decryptstr), myinfo->decryptstr = 0; myinfo->expiration = 0; - iguana_walletiterate(myinfo,-2); + iguana_walletiterate(myinfo,coin,-2,0,0,0,0); } int64_t iguana_waccountbalance(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,int32_t minconf,int32_t lastheight) @@ -830,7 +946,7 @@ ZERO_ARGS(bitcoinrpc,walletlock) { if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - iguana_walletlock(myinfo); + iguana_walletlock(myinfo,coin); return(jsuccess()); } @@ -1077,6 +1193,26 @@ STRING_ARG(bitcoinrpc,importwallet,filename) return(clonestr("{\"error\":\"need to unlock wallet\"}")); } +ZERO_ARGS(bitcoinrpc,checkwallet) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + return(iguana_walletscan(myinfo,coin,1)); +} + +ZERO_ARGS(bitcoinrpc,repairwallet) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + return(iguana_walletscan(myinfo,coin,0)); +} + // multiple address STRING_AND_THREEINTS(bitcoinrpc,getbalance,account,minconf,includeempty,lastheight) { diff --git a/iguana/main.c b/iguana/main.c index cb1073bf6..fd2132634 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -419,7 +419,7 @@ void mainloop(struct supernet_info *myinfo) { //printf("main iteration\n"); if ( myinfo->expiration != 0 && time(NULL) > myinfo->expiration ) - iguana_walletlock(myinfo); + iguana_walletlock(myinfo,0); flag = 0; isRT = 1; numpeers = 0; diff --git a/iguana/ramchain_api.c b/iguana/ramchain_api.c index 306bab065..753cb8c30 100755 --- a/iguana/ramchain_api.c +++ b/iguana/ramchain_api.c @@ -261,32 +261,6 @@ SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment) return(jprint(retjson,1)); } -ZERO_ARGS(bitcoinrpc,checkwallet) -{ - cJSON *retjson; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - if ( myinfo->expiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); - myinfo->expiration++; - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - return(jprint(retjson,1)); -} - -ZERO_ARGS(bitcoinrpc,repairwallet) -{ - cJSON *retjson; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - if ( myinfo->expiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); - myinfo->expiration++; - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - return(jprint(retjson,1)); -} - #undef IGUANA_ARGS #include "../includes/iguana_apiundefs.h" diff --git a/iguana/tests/.priv2wif.swp b/iguana/tests/.priv2wif.swp new file mode 100644 index 0000000000000000000000000000000000000000..d683008b0965b4f5e110fc391edca199f88a91bb GIT binary patch literal 12288 zcmeI&&rgFe6bJCmn0PW8{Rgm~Ox*a4l8J!-C@xRl*$(vjtTkNzj*jqii6K9LS{vk)}?Gr-E`HhQ5Ex| z9}LPmljYWjY{4D3deOSGl5_4Blck)?&0utETDMsg&%sNP|FsBe5P-lx1r7-de6O2) zPS2dvlkq>-!88a!00Izz00bZa0SG`~7X?hyBky+Odq11+Z5em*-LPi}KmY;|fB*y_ z009U<00Izz00hzp0YqiR5 zdg534MlNL4+We!SVUmSW7R8$BVd8r%4#R+{i09hp!_Z5VY{M literal 0 HcmV?d00001 diff --git a/iguana/tests/priv2wif b/iguana/tests/priv2wif new file mode 100755 index 000000000..d3f94b404 --- /dev/null +++ b/iguana/tests/priv2wif @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"priv2wif\",\"params\":[\"59c56c68e3e4910385523d67fe174509da7ddb6f7f35189e0d691d3b5e98ea0a\"]}" diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index c572a0de0..0e5a9a8a2 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -61,12 +61,14 @@ INT_ARRAY_STRING(bitcoinrpc,createmultisig,M,pubkeys,ignore); INT_ARRAY_STRING(bitcoinrpc,addmultisigaddress,M,pubkeys,account); DOUBLE_ARG(bitcoinrpc,settxfee,amount); -STRING_ARG(bitcoinrpc,submitblock,rawbytes); +ZERO_ARGS(bitcoinrpc,checkwallet); +ZERO_ARGS(bitcoinrpc,repairwallet); STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash); TWO_STRINGS(bitcoinrpc,signmessage,address,message); // THREE_STRINGS(bitcoinrpc,verifymessage,address,sig,message); // STRING_AND_INT(bitcoinrpc,sendrawtransaction,rawtx,allowhighfees); // +STRING_ARG(bitcoinrpc,submitblock,rawbytes); // SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comment2); // S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment); // @@ -78,8 +80,6 @@ ZERO_ARGS(bitcoinrpc,gettxoutsetinfo); INT_AND_ARRAY(bitcoinrpc,lockunspent,flag,array); ZERO_ARGS(bitcoinrpc,listlockunspent); ZERO_ARGS(bitcoinrpc,getrawchangeaddress); -ZERO_ARGS(bitcoinrpc,checkwallet); -ZERO_ARGS(bitcoinrpc,repairwallet); SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment); STRING_ARG(iguana,initfastfind,activecoin); @@ -181,6 +181,7 @@ THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey); ZERO_ARGS(SuperNET,keypair); HASH_AND_INT(SuperNET,priv2pub,privkey,addrtype); STRING_ARG(SuperNET,wif2priv,wif); +STRING_ARG(SuperNET,priv2wif,priv); STRING_ARG(SuperNET,addr2rmd160,address); TWOHASHES_AND_STRING(SuperNET,cipher,privkey,destpubkey,message);