From 4af4dbba377245c45849b158c1842f8649f4ba96 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 7 Aug 2016 11:36:57 -0300 Subject: [PATCH] test --- iguana/iguana_payments.c | 16 ++- iguana/iguana_rpc.c | 2 +- iguana/iguana_sign.c | 223 ++++++++++++++++++++++-------- iguana/tests/d | 1 + iguana/tests/decoderawtransaction | 2 +- includes/iguana_apideclares.h | 3 +- 6 files changed, 181 insertions(+), 66 deletions(-) create mode 100755 iguana/tests/d diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c index 1df562678..55dfcb952 100755 --- a/iguana/iguana_payments.c +++ b/iguana/iguana_payments.c @@ -971,13 +971,21 @@ STRING_AND_INT(bitcoinrpc,validaterawtransaction,rawtx,suppress) uint8_t *extraspace; char *retstr; struct iguana_msgtx msgtx; int32_t extralen=65536; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); + cJSON *txobj; char *teststr= "{\"version\":1,\"locktime\":0,\"vin\":[{\"userdata\":\"20ae439d344513eab8e718d8214fe6ae8133b8b5b594afd64da21d0e40b9c37cdd00\",\"txid\":\"2c1320315f4fb519cbf2b4d7b67855013b9a09a85e515df43b41d407a0083b09\",\"vout\":0,\"scriptPubKey\":{\"hex\":\"a9142e7674400d04217f770f2222126dc7fee44b06b487\"},\"suppress\":1,\"redeemScript\":\"63041686a657b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a914ed74c61c27656abc6c20687c3a9212ffdc6f34cd88210398a4cb9f6ea7c52a4e27455028a95e2e4e397a110fb75f072c2c58a8bdcbf4baac68\"}],\"vout\":[{\"satoshis\":\"16733\",\"scriptPubkey\":{\"hex\":\"76a91454a752f0d71b89d7c014ed0be29ca231c9546f9f88ac\"}}]}"; extraspace = calloc(1,extralen); - retstr = iguana_validaterawtx(myinfo,coin,&msgtx,extraspace,extralen,rawtx,0,suppress); + if ( (txobj= cJSON_Parse(teststr)) != 0 ) + { + bits256 txid; + rawtx = bitcoin_json2hex(myinfo,coin,&txid,txobj,0); + txobj = bitcoin_hex2json(coin,&txid,0,rawtx,extraspace,extralen,0,0,suppress); + printf("RAWTX.(%s) -> (%s)\n",rawtx,jprint(txobj,0)); + } + //retstr = iguana_validaterawtx(myinfo,coin,&msgtx,extraspace,extralen,rawtx,0,suppress); free(extraspace); - return(retstr); + return(rawtx); } -STRING_ARG(bitcoinrpc,decoderawtransaction,rawtx) +STRING_AND_INT(bitcoinrpc,decoderawtransaction,rawtx,suppress) { cJSON *txobj = 0; bits256 txid; uint8_t *extraspace; int32_t extralen = 65536; if ( remoteaddr != 0 ) @@ -987,7 +995,7 @@ STRING_ARG(bitcoinrpc,decoderawtransaction,rawtx) if ( (strlen(rawtx) & 1) != 0 ) return(clonestr("{\"error\":\"rawtx hex has odd length\"}")); extraspace = calloc(1,extralen); - txobj = bitcoin_hex2json(coin,&txid,0,rawtx,extraspace,extralen,0,0,0); + txobj = bitcoin_hex2json(coin,&txid,0,rawtx,extraspace,extralen,0,0,suppress); free(extraspace); //char str[65]; printf("got txid.(%s)\n",bits256_str(str,txid)); } diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index f334fcdc2..0bb381740 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -519,7 +519,7 @@ static char *createrawtransaction(RPCARGS) static char *decoderawtransaction(RPCARGS) { - return(sglue1(0,CALLGLUE,"bitcoinrpc","decoderawtransaction","rawtx",params[0])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","decoderawtransaction","rawtx",params[0],"suppress",params[1])); } static char *validaterawtransaction(RPCARGS) diff --git a/iguana/iguana_sign.c b/iguana/iguana_sign.c index 8b39d1434..711bbfe40 100755 --- a/iguana/iguana_sign.c +++ b/iguana/iguana_sign.c @@ -125,13 +125,35 @@ cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin,bits256 return(json); } +int32_t iguana_parsehexstr(uint8_t **destp,uint16_t *lenp,uint8_t *dest2,int32_t *len2p,uint8_t *serialized,char *hexstr) +{ + int32_t n; + n = (int32_t)strlen(hexstr) >> 1; + printf("addhex.(%s) %d\n",hexstr,n); + if ( serialized == 0 ) + serialized = *destp; + if ( serialized != 0 ) + { + decode_hex(serialized,n,hexstr); + *destp = serialized; + *lenp = n; + if ( dest2 != 0 && len2p != 0 ) + { + *len2p = n; + memcpy(dest2,serialized,n); + } + } + return(n); +} + int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvin *vin,cJSON *vinobj,struct vin_info *V) { - struct iguana_waddress *waddr; struct iguana_waccount *wacct; int32_t i,n,plen,len = 0; char *userdata,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0; + struct iguana_waddress *waddr; struct iguana_waccount *wacct; uint32_t tmp=0; int32_t i,n,suppress_pubkeys,siglen,plen,rwflag=1,len = 0; char *userdata,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0; //printf("PARSEVIN.(%s) vin.%p\n",jprint(vinobj,0),vin); if ( V == 0 ) memset(vin,0,sizeof(*vin)); vin->prev_vout = -1; + suppress_pubkeys = juint(vinobj,"suppress"); if ( jobj(vinobj,"sequence") != 0 ) vin->sequence = juint(vinobj,"sequence"); else vin->sequence = 0xffffffff; @@ -157,14 +179,8 @@ int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin userdata = jstr(obj,"hex"); } } - if ( hexstr != 0 ) - { - n = (int32_t)strlen(hexstr) >> 1; - decode_hex(serialized,n,hexstr); - vin->vinscript = serialized; - vin->scriptlen = n; - len += n; - } //else printf("iguana_parsevinobj: hex script missing (%s)\n",jprint(vinobj,0)); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(vin->prev_hash),vin->prev_hash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(vin->prev_vout),&vin->prev_vout); if ( V != 0 ) { if ( vin->vinscript == 0 ) @@ -178,73 +194,141 @@ int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin //printf("V %.8f (%s) spendscript.[%d]\n",dstr(V->amount),V->coinaddr,V->spendlen); } } - if ( (pubkeysjson= jarray(&n,vinobj,"pubkeys")) != 0 ) + } + if ( hexstr != 0 ) + tmp += (int32_t)strlen(hexstr) >> 1; + if ( suppress_pubkeys == 0 && (pubkeysjson= jarray(&n,vinobj,"pubkeys")) != 0 ) + { + for (i=0; i> 1) > 0 ) + tmp += (plen + 1); + } + } + if ( userdata != 0 ) + tmp += (int32_t)strlen(userdata) >> 1; + if ( redeemstr != 0 ) + { + n = (int32_t)strlen(redeemstr) >> 1; + tmp += n; + if ( n < 76 ) + tmp++; + else if ( n <= 0xff ) + tmp += 2; + else tmp += 3; + } + len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); + serialized += len; + if ( hexstr != 0 ) + { + n = (int32_t)strlen(hexstr) >> 1; + printf("add.(%s) offset.%d\n",hexstr,len); + decode_hex(serialized,n,hexstr); + vin->vinscript = serialized; + vin->scriptlen = n; + if ( V != 0 ) { - if ( vin->vinscript == 0 ) + i = 0; + while ( len < n ) { - vin->vinscript = serialized; - vin->vinscript[0] = 0; - vin->scriptlen = 1; + siglen = serialized[len++]; + memcpy(V->signers[i].sig,&serialized[len],siglen); + len += siglen; + vin->scriptlen += (siglen + 1); + i++; } - for (i=0; ivinscript == 0 ) + { + printf("null vinscript case\n"); + vin->vinscript = serialized; + vin->vinscript[0] = 0; + vin->scriptlen = 0; + } + for (i=0; i> 1) > 0 ) { - if ( (pubkeystr= jstr(jitem(pubkeysjson,i),0)) != 0 && (plen= (int32_t)strlen(pubkeystr) >> 1) > 0 ) + if ( V != 0 ) + memcpy(V->signers[i].pubkey,&vin->vinscript[vin->scriptlen],plen); + if ( suppress_pubkeys == 0 ) { + printf("addpub.(%s)\n",pubkeystr); vin->vinscript[vin->scriptlen++] = plen; decode_hex(&vin->vinscript[vin->scriptlen],plen,pubkeystr); - memcpy(V->signers[i].pubkey,&vin->vinscript[vin->scriptlen],plen); vin->scriptlen += plen; + *serialized++ = plen; + memcpy(serialized,&vin->vinscript[vin->scriptlen],plen); + serialized += plen; + len += (1 + plen); } } } - if ( vin->vinscript != 0 ) - serialized = &vin->vinscript[vin->scriptlen]; - len += vin->scriptlen; - if ( userdata != 0 ) - { - n = (int32_t)strlen(userdata) >> 1; - decode_hex(serialized,n,userdata); - vin->userdata = serialized; - V->userdatalen = vin->userdatalen = n; - memcpy(V->userdata,serialized,n); - serialized += n; - } - if ( redeemstr != 0 ) + } + printf("len.%d: ",len); + if ( userdata != 0 ) + { + n = iguana_parsehexstr(&vin->userdata,&vin->userdatalen,V!=0?V->userdata:0,V!=0?&V->userdatalen:0,serialized,userdata); + len += n, serialized += n; + } + printf("len.%d: ",len); + if ( redeemstr != 0 ) + { + n = (int32_t)strlen(redeemstr) >> 1; + len++; + if ( n < 76 ) + *serialized++ = n; + else if ( n <= 0xff ) { - n = (int32_t)strlen(redeemstr) >> 1; - decode_hex(serialized,n,redeemstr); - vin->redeemscript = serialized; - V->p2shlen = vin->p2shlen = n; - memcpy(V->p2shscript,serialized,n); - serialized += n; + *serialized++ = 0x4c; + *serialized++ = n; + len++; } - if ( spendstr != 0 ) + else { - n = (int32_t)strlen(spendstr) >> 1; - decode_hex(serialized,n,spendstr); - vin->spendscript = serialized; - vin->spendlen = n; + *serialized++ = 0x4d; + *serialized++ = n & 0xff; + *serialized++ = (n >> 8) & 0xff; + len += 2; } - len += vin->spendlen; + n = iguana_parsehexstr(&vin->redeemscript,&vin->p2shlen,V!=0?V->p2shscript:0,V!=0?&V->p2shlen:0,serialized,redeemstr); + len += n, serialized += n; + } + printf("len.%d: ",len); + if ( spendstr != 0 ) + { + n = iguana_parsehexstr(&vin->spendscript,&vin->spendlen,V!=0?V->spendscript:0,V!=0?&V->spendlen:0,0,spendstr); } + printf("output sequence.[%d] <- %x\n",len,vin->sequence); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(vin->sequence),&vin->sequence); return(len); } int32_t iguana_parsevoutobj(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvout *vout,cJSON *voutobj) { - int32_t len = 0; cJSON *skey; char *hexstr; + int32_t n,len = 0,rwflag = 1; cJSON *skey; char *hexstr; memset(vout,0,sizeof(*vout)); if ( jobj(voutobj,"satoshis") != 0 ) vout->value = j64bits(voutobj,"satoshis"); else vout->value = jdouble(voutobj,"value") * SATOSHIDEN; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(vout->value),&vout->value); if ( (skey= jobj(voutobj,"scriptPubKey")) != 0 ) { if ( (hexstr= jstr(skey,"hex")) != 0 ) { - len = (int32_t)strlen(hexstr) >> 1; - decode_hex(serialized,len,hexstr); - vout->pk_script = serialized; - vout->pk_scriptlen = len; + n = (int32_t)strlen(hexstr) >> 1; + vout->pk_scriptlen = n; + len += iguana_rwvarint32(rwflag,&serialized[len],&vout->pk_scriptlen); + decode_hex(&serialized[len],n,hexstr); + vout->pk_script = &serialized[len]; + len += n; } } return(len); @@ -373,9 +457,10 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8 } for (i=0; itx_in; i++) { + printf("vin.%d starts offset.%d\n",i,len); if ( (n= iguana_vinparse(coin,rwflag,&serialized[len],&msg->vins[i])) < 0 ) return(-1); - //printf("vin.%d n.%d len.%d\n",i,n,len); + printf("vin.%d n.%d len.%d\n",i,n,len); len += n; if ( len > maxsize ) { @@ -420,12 +505,13 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8 } for (i=0; itx_out; i++) { + printf("vout.%d starts %d\n",i,len); if ( (n= iguana_voutparse(rwflag,&serialized[len],&msg->vouts[i])) < 0 ) return(-1); len += n; if ( len > maxsize ) { - printf("invalid tx_out.%d len.%d vs maxsize.%d\n",msg->tx_out,len,maxsize); + printf("invalid tx_out.%d len.%d vs maxsize.%d n.%d\n",msg->tx_out,len,maxsize,n); return(-1); } if ( array != 0 ) @@ -472,54 +558,72 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8 bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *txstartp,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj,struct vin_info *V) { - int32_t i,numvins,numvouts,len = 0; cJSON *array=0; bits256 txid; char vpnstr[64]; + int32_t i,numvins,numvouts,len = 0,rwflag=1; cJSON *array=0; bits256 txid; char vpnstr[64]; memset(&txid,0,sizeof(txid)); + memset(msg,0,sizeof(*msg)); + *txstartp = 0; if ( txobj == 0 ) return(txid); - memset(msg,0,sizeof(*msg)); vpnstr[0] = 0; if ( (msg->version= juint(txobj,"version")) == 0 ) msg->version = 1; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); if ( coin->chain->isPoS != 0 ) { if ( (msg->timestamp= juint(txobj,"timestamp")) == 0 ) msg->timestamp = (uint32_t)time(NULL); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); } if ( (array= jarray(&numvins,txobj,"vin")) != 0 ) { msg->tx_in = numvins; + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); if ( len + sizeof(struct iguana_msgvin)*msg->tx_in > maxsize ) - return(msg->txid); + return(txid); maxsize -= (sizeof(struct iguana_msgvin) * msg->tx_in); msg->vins = (struct iguana_msgvin *)&serialized[maxsize]; if ( msg->tx_in > 0 && msg->tx_in*sizeof(struct iguana_msgvin) < maxsize ) { for (i=0; itx_in; i++) + { + printf("vinobj.%d starts offset.%d\n",i,len); len += iguana_parsevinobj(myinfo,coin,&serialized[len],maxsize,&msg->vins[i],jitem(array,i),V!=0?&V[i]:0); + } } } if ( (array= jarray(&numvouts,txobj,"vout")) != 0 ) { msg->tx_out = numvouts; + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out); if ( len + sizeof(struct iguana_msgvout)*msg->tx_out > maxsize ) - return(msg->txid); + return(txid); maxsize -= (sizeof(struct iguana_msgvout) * msg->tx_out); msg->vouts = (struct iguana_msgvout *)&serialized[maxsize]; if ( msg->tx_out > 0 && msg->tx_out*sizeof(struct iguana_msgvout) < maxsize ) { for (i=0; itx_out; i++) + { + printf("parsevout.%d starts %d\n",i,len); len += iguana_parsevoutobj(coin,&serialized[len],maxsize,&msg->vouts[i],jitem(array,i)); + } } } msg->lock_time = jint(txobj,"locktime"); - msg->txid = jbits256(txobj,"txid"); - *txstartp = len; - if ( (msg->allocsize= iguana_rwmsgtx(coin,1,0,&serialized[len],maxsize-len,msg,&txid,vpnstr,0,0,0,V!=0?V->suppress_pubkeys:0)) < 0 ) + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); + //msg->txid = jbits256(txobj,"txid"); + *txstartp = 0; + msg->allocsize = len; + msg->txid = txid = bits256_doublesha256(0,serialized,len); + for (i=0; isuppress_pubkeys:0)) != msg->allocsize ) { - memset(txid.bytes,0,sizeof(txid)); - printf("error parsing txobj\n"); - msg->allocsize = 0; + //memset(txid.bytes,0,sizeof(txid)); + printf("error parsing txobj: expected %d got %d\n",msg->allocsize,len); + //msg->allocsize = 0; } + msg->txid = txid;*/ //char str[65]; printf("json -> %s\n",bits256_str(str,txid)); return(txid); } @@ -571,6 +675,7 @@ cJSON *bitcoin_data2json(struct iguana_info *coin,bits256 *txidp,struct iguana_m memset(txidp,0,sizeof(*txidp)); if ( (n= iguana_rwmsgtx(coin,0,txobj,serialized,len,msgtx,txidp,vpnstr,extraspace,extralen,vins,suppress_pubkeys)) <= 0 ) { + printf("errortxobj.(%s)\n",jprint(txobj,0)); free_json(txobj); txobj = cJSON_CreateObject(); jaddstr(txobj,"error","couldnt decode transaction"); diff --git a/iguana/tests/d b/iguana/tests/d new file mode 100755 index 000000000..38e1a7291 --- /dev/null +++ b/iguana/tests/d @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"method\":\"decoderawtransaction\",\"params\":[\"0100000001093b08a007d4413bf45d515ea8099a3b015578b6d7b4f2cb19b54f5f3120132c00000000f6483045022100fa96a98d128fd59fdbf236445766324d17676e19e235dee7e00a35ed3a5c44d4022039dae3cab9f507a22a6a474323e14b8272d27d0d3f32b3015b2e2ea21a222a3d0120ae439d344513eab8e718d8214fe6ae8133b8b5b594afd64da21d0e40b9c37cdd004c6763041686a657b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a914ed74c61c27656abc6c20687c3a9212ffdc6f34cd88210398a4cb9f6ea7c52a4e27455028a95e2e4e397a110fb75f072c2c58a8bdcbf4baac6820ae439d344513eab8e718d8214fe6ae8133b8b5b594afd64da21d0e40b9c37cdd00ffffffff0000000000\", 1]}" diff --git a/iguana/tests/decoderawtransaction b/iguana/tests/decoderawtransaction index 87ef3eb80..beca415db 100755 --- a/iguana/tests/decoderawtransaction +++ b/iguana/tests/decoderawtransaction @@ -1 +1 @@ -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"decoderawtransaction\",\"params\":[\"010000002ec9a45701048f2f330b71f5cbef5d7b1cd161b1cf2dee06ddb15b670d46a41fca3a25beed00000000904730440220039cc97a4b266bef6802db4ae6219637842e97db025529240c01ea207cbd317502204d3796090624c86c43ee150cdc99e313483fe41c6d630d22d167e828688caaeb014730440220388f36c50854292d4a62d631d012b33d1f02fdd8623180151548947eacc06a4002207fe79c455ba5860b15e7b74fa31cf25c4a0f93c1e488f446d3322712067fb73d01ffffffff01706f9800000000001976a91454a752f0d71b89d7c014ed0be29ca231c9546f9f88ac00000000\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"method\":\"decoderawtransaction\",\"params\":[\"0100000001a9c0e4255aaf9f0ff89525c87bcb14c3b423637f1920d158ff94d0f0603f665a000000008a012025c6a612a7477796ccc138eadcbfbf29abbce43bf89376a914b7128d2ee837cf034c67e30a2c0e3e0181f7b9669bb688ac0100000001a9c0e4255aaf9f0ff89525c87bcb14c3b423637f1920d158ff94d0f0603f665a000000008a012025c6a612a7477796ccc138eadcbfbf29abbce43bf89376a914b7128d2ee837cf034c6735b19ab3739d8afdac68ffffffff0117380000000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac00000000\", 1]}" diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index e067a9d86..3231e5b62 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -67,7 +67,8 @@ HASH_AND_TWOINTS(bitcoinrpc,gettxout,txid,vout,mempool); TWOINTS_AND_ARRAY(bitcoinrpc,listunspent,minconf,maxconf,array); STRING_ARG(bitcoinrpc,decodescript,scriptstr); -STRING_ARG(bitcoinrpc,decoderawtransaction,rawtx); +//STRING_ARG(bitcoinrpc,decoderawtransaction,rawtx); +STRING_AND_INT(bitcoinrpc,decoderawtransaction,rawtx,suppress); STRING_AND_INT(bitcoinrpc,validaterawtransaction,rawtx,suppress); ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime);