diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 9944c63a8..57c628c1e 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -316,7 +316,7 @@ void SaM_PrepareIndices(); struct iguana_msghdr { uint8_t netmagic[4]; char command[12]; uint8_t serdatalen[4],hash[4]; } __attribute__((packed)); int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); -int32_t iguana_validatehdr(struct iguana_msghdr *H); +int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H); int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp); int32_t iguana_sethdr(struct iguana_msghdr *H,const uint8_t netmagic[4],char *command,uint8_t *data,int32_t datalen); uint8_t *iguana_varint16(int32_t rwflag,uint8_t *serialized,uint16_t *varint16p); diff --git a/crypto777/iguana_serdes.c b/crypto777/iguana_serdes.c index 38aad09a7..03a9c8e09 100755 --- a/crypto777/iguana_serdes.c +++ b/crypto777/iguana_serdes.c @@ -52,18 +52,22 @@ int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endian return(len); } -int32_t iguana_validatehdr(struct iguana_msghdr *H) +int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H) { - int32_t i,len; - for (i=0; Iguana_validcommands[i]!=0&&Iguana_validcommands[i][0]!=0; i++) - if ( strcmp(H->command,Iguana_validcommands[i]) == 0 ) - { - iguana_rwnum(0,H->serdatalen,sizeof(H->serdatalen),(uint32_t *)&len); - if ( len > IGUANA_MAXPACKETSIZE ) - return(-1); - return(len); - } - return(-1); + int32_t i = 0,len = -1; + if ( strcmp(symbol,"VPN") != 0 ) + { + for (i=0; Iguana_validcommands[i]!=0&&Iguana_validcommands[i][0]!=0; i++) + if ( strcmp(H->command,Iguana_validcommands[i]) == 0 ) + break; + } + if ( Iguana_validcommands[i][0] != 0 ) + { + iguana_rwnum(0,H->serdatalen,sizeof(H->serdatalen),(uint32_t *)&len); + if ( len > IGUANA_MAXPACKETSIZE ) + return(-1); + } + return(len); } int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 61e930f0b..e2629dfd7 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -196,7 +196,19 @@ struct iguana_msgversion char strSubVer[80]; uint32_t nStartingHeight; uint8_t relayflag; -}; +} __attribute__((packed)); + +struct iguana_VPNversion +{ + uint32_t nVersion; + uint64_t nServices; + int64_t nTime; + struct iguana_msgaddress addrTo,addrFrom; + uint64_t nonce; + char strSubVer[80]; + uint32_t nStartingHeight; + uint32_t iVer,v_Network_id; uint16_t wPort; uint8_t bIsGui; uint16_t wCtPort,wPrPort; +} __attribute__((packed)); struct iguana_msgblockhdr { @@ -484,7 +496,7 @@ void iguana_blockconv(struct iguana_block *dest,struct iguana_msgblock *msg,bits int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t datalen); // send message -int32_t iguana_validatehdr(struct iguana_msghdr *H); +int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H); int32_t iguana_sethdr(struct iguana_msghdr *H,const uint8_t netmagic[4],char *command,uint8_t *data,int32_t datalen); int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices); int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_txblock *txblock,int32_t *lenp,uint8_t *data,int32_t datalen); @@ -707,6 +719,8 @@ cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t hei char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid); cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int32_t txi); cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin); +char *iguana_rawtxbytes(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t datalen); +int32_t iguana_send_VPNversion(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices); extern queue_t bundlesQ; diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index 5bbd7f615..b06ab97a9 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -54,7 +54,8 @@ static struct iguana_chain Chains[] = "btcd", "BTCD", PUBKEY_ADDRESS_BTCD, SCRIPT_ADDRESS_BTCD, PRIVKEY_ADDRESS_BTCD, "\xe4\xc2\xd8\xe6", - "0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46","0100000000000000000000000000000000000000000000000000000000000000000000002b5b9d8cdd624d25ce670a7aa34726858388da010d4ca9ec8fd86369cc5117fd0132a253ffff0f1ec58c7f0000", + "0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46", + "0100000000000000000000000000000000000000000000000000000000000000000000002b5b9d8cdd624d25ce670a7aa34726858388da010d4ca9ec8fd86369cc5117fd0132a253ffff0f1ec58c7f0000", // "0100000000000000000000000000000000000000000000000000000000000000000000002b5b9d8cdd624d25ce670a7aa34726858388da010d4ca9ec8fd86369cc5117fd0132a253ffff0f1ec58c7f0001010000000132a253010000000000000000000000000000000000000000000000000000000000000000ffffffff4100012a3d3138204a756e652032303134202d204269746f696e20796f75722077617920746f206120646f75626c6520657370726573736f202d20636e6e2e636f6dffffffff010000000000000000000000000000", 14631,14632,1, }, @@ -65,7 +66,7 @@ static struct iguana_chain Chains[] = "\xfb\xc0\xb6\xdb", // pchMessageStart main.cpp "3b27c25b333e890fbb6cd912fcdfb07bf17245def80410a0a05a8eae070b2060", //"00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99", // hashGenesisBlock main.h - "01000000000000000000000000000000000000000000000000000000000000000000000028581b3ba53e73adaaf957bced1d42d46ed0d84a86b34f7a5a49cdcaa1938a697f9c0854ffff0f1e0004de0300", // need to extract from valid blk0001.dat + "01000000000000000000000000000000000000000000000000000000000000000000000028581b3ba53e73adaaf957bced1d42d46ed0d84a86b34f7a5a49cdcaa1938a6940540854ffff0f1e78b20100010100000040540854010000000000000000000000000000000000000000000000000000000000000000ffffffff2404ffff001d01041c5468752c20342053657020323031342031323a30303a303020474d54ffffffff01000000000000000000000000000000", // need to extract from valid blk0001.dat 1920,1921,1,0x1e // port and rpcport vpncoin.conf }, }; diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index ab04f98f2..e3a936ad1 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -83,8 +83,10 @@ bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain) { bits256_str(str,hash2); printf("genesis mismatch? calculated %s vs %s\n",str,(char *)chain->genesis_hex); - memset(hash2.bytes,0,sizeof(hash2)); - return(hash2); + hash2 = bits256_conv("00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99"); + + //memset(hash2.bytes,0,sizeof(hash2)); + //return(hash2); } bits256_str(str,hash2); printf("genesis.(%s) len.%d hash.%s\n",chain->genesis_hex,(int32_t)sizeof(msg.H),str); diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index 617b31d5b..a84044d63 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -688,6 +688,7 @@ STRING_ARG(SuperNET,bitcoinrpc,setcoin) { strcpy(myinfo->rpcsymbol,setcoin); touppercase(myinfo->rpcsymbol); + iguana_launchcoin(myinfo->rpcsymbol,json); return(clonestr("{\"result\":\"set bitcoin RPC coin\"}")); } else return(clonestr("{\"error\":\"bitcoinrpc needs setcoin value\"}")); } diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index e2c9033fd..421687307 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -45,7 +45,7 @@ int32_t iguana_rwversion(int32_t rwflag,uint8_t *serialized,struct iguana_msgver len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->nStartingHeight),&msg->nStartingHeight); if ( readsize == 117 ) { - uint32_t iVer,v_Network_id; uint16_t wPort,wCtPort,wPrPort; uint8_t bIsGui; + uint32_t iVer = 1132,v_Network_id=0; uint16_t wPort=0,wCtPort=0,wPrPort=0; uint8_t bIsGui=0; len += iguana_rwnum(rwflag,&serialized[len],sizeof(iVer),&iVer); len += iguana_rwnum(rwflag,&serialized[len],sizeof(v_Network_id),&v_Network_id); len += iguana_rwnum(rwflag,&serialized[len],sizeof(wPort),&wPort); @@ -66,8 +66,9 @@ int32_t iguana_rwversion(int32_t rwflag,uint8_t *serialized,struct iguana_msgver if (!vRecv.empty()){ vRecv >> pfrom->vBitNet.v_P2P_proxy_port; } //-- 2014.12.28 add */ printf("iVer.%d v_Network_id.%d wPort.%u bIsGui.%d wCtPort.%u wPrPort.%u\n",iVer,v_Network_id,wPort,bIsGui,wCtPort,wPrPort); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->relayflag),&msg->relayflag); } - if ( msg->nVersion > 70000 ) + else if ( msg->nVersion > 70000 ) len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->relayflag),&msg->relayflag); //if ( rwflag == 0 ) printf("readsize.%d %-15s v.%llu srv.%llx %u ht.%llu [%s].R%d nonce.%llx\n",readsize,ipaddr,(long long)msg->nVersion,(long long)msg->nServices,(uint32_t)msg->nTime,(long long)msg->nStartingHeight,msg->strSubVer,msg->relayflag,(long long)msg->nonce); @@ -186,6 +187,20 @@ int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,ui return(iguana_queue_send(coin,addr,0,serialized,"version",len,0,1)); } +int32_t iguana_send_VPNversion(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices) +{ + int32_t len; struct iguana_VPNversion msg; uint8_t serialized[sizeof(struct iguana_msghdr)+sizeof(msg)]; + memset(&msg,0,sizeof(msg)); + msg.nVersion = PROTOCOL_VERSION; + msg.nServices = myservices; + msg.nTime = (int64_t)time(NULL); + msg.nonce = coin->instance_nonce; + sprintf(msg.strSubVer,"/Satoshi:0.11.99/"); + msg.nStartingHeight = coin->blocks.hwmchain.height; + len = iguana_rwversion(1,&serialized[sizeof(struct iguana_msghdr)],(void *)&msg,addr->ipaddr,117); + return(iguana_queue_send(coin,addr,0,serialized,"version",len,0,1)); +} + void iguana_gotverack(struct iguana_info *coin,struct iguana_peer *addr) { uint8_t serialized[sizeof(struct iguana_msghdr)]; @@ -462,6 +477,19 @@ int32_t iguana_txskip(struct iguana_info *coin,cJSON *json,uint8_t *serialized,s return(len); } +char *iguana_rawtxbytes(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t datalen) +{ + int32_t n; char *txbytes; struct iguana_msgtx tx; + //char str[65]; printf("%d of %d: %s\n",i,msg.txn_count,bits256_str(str,tx.txid)); + if ( (n= iguana_txskip(coin,json,data,&tx,datalen,&tx.txid,coin->chain->hastimestamp)) > 0 ) + { + txbytes = malloc(n*2+1); + init_hexbytes_noT(txbytes,data,n); + return(txbytes); + } + return(0); +} + char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid) { struct iguana_msgtx tx; bits256 hash2; struct iguana_block block; struct iguana_msgblock msg; int32_t i,n,len; char *txbytes; @@ -617,11 +645,7 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc } else if ( strcmp(H->command,"ConnectTo") == 0 ) { - if ( addr != 0 ) - { - iguana_gotverack(coin,addr); - addr->msgcounts.verack++; - } + iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); len = 6; } else if ( strcmp(H->command,"ping") == 0 ) @@ -666,7 +690,7 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc addr->lastgotaddr = (uint32_t)time(NULL); addr->msgcounts.addr++; } - //printf("%s -> addr recvlen.%d num.%d\n",addr->ipaddr,recvlen,(int32_t)x); + printf("%s -> addr recvlen.%d num.%d\n",addr->ipaddr,recvlen,(int32_t)x); } else if ( strcmp(H->command,"headers") == 0 ) { @@ -815,9 +839,9 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc myfree(txids,sizeof(*txids) * (x+1)); if ( blockhashes != 0 ) myfree(blockhashes,sizeof(*blockhashes) * (x+1)); - //printf("intvectors.%c recvlen.%d\n",intvectors,recvlen); + printf("intvectors.%c recvlen.%d\n",intvectors,recvlen); } - if ( len != recvlen && len != recvlen-1 ) + if ( len != recvlen && len != recvlen-1 && len != recvlen-2 ) { //printf("error.(%s) (%s): len.%d != recvlen.%d\n",H->command,addr->ipaddr,len,recvlen); //for (i=0; icommand,"addr") != 0 ) printf("%s.%s len mismatch %d != %d\n",addr!=0?addr->ipaddr:"local",H->command,len,recvlen); } - else if ( len == recvlen-1 ) + else if ( len != recvlen ) { - printf("extra byte.[%02x] command.%s len.%d recvlen.%d\n",data[recvlen-1],H->command,len,recvlen); + printf("%s extra byte.[%02x] command.%s len.%d recvlen.%d\n",addr->ipaddr,data[recvlen-1],H->command,len,recvlen); //retval = -1; } return(retval); diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index e95ac5f33..3eefba819 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -399,7 +399,7 @@ int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *s } } addr->totalsent += len; - //printf(" %s sent.%d bytes to %s\n",(char *)&serialized[4],len,addr->ipaddr);// getchar(); + printf(" %s sent.%d bytes to %s\n",(char *)&serialized[4],len,addr->ipaddr);// getchar(); return(len); } @@ -505,9 +505,9 @@ void _iguana_processmsg(struct iguana_info *coin,int32_t usock,struct iguana_pee return; { iguana_rwnum(0,H.serdatalen,sizeof(H.serdatalen),(uint32_t *)&len); - //printf("%08x got.(%s) recvlen.%d from %s | usock.%d ready.%u dead.%u len.%d\n",(uint32_t)addr->ipbits,H.command,recvlen,addr->ipaddr,addr->usock,addr->ready,addr->dead,len); + printf("%08x got.(%s) recvlen.%d from %s | usock.%d ready.%u dead.%u len.%d\n",(uint32_t)addr->ipbits,H.command,recvlen,addr->ipaddr,addr->usock,addr->ready,addr->dead,len); } - if ( (len= iguana_validatehdr(&H)) >= 0 ) + if ( (len= iguana_validatehdr(coin->symbol,&H)) >= 0 ) { if ( len > 0 ) { @@ -528,9 +528,9 @@ void _iguana_processmsg(struct iguana_info *coin,int32_t usock,struct iguana_pee } } // 79 22 e3 b4 80 07 - //int32_t i; for (i=0; ipossibleQ,queueitem(ipaddr),1); return((uint32_t)time(NULL)); } @@ -958,7 +958,10 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) bufsize = IGUANA_MAXPACKETSIZE; buf = mycalloc('r',1,bufsize); if ( strcmp(coin->symbol,"VPN") == 0 ) - iguana_send_ConnectTo(coin,addr); + { + addr->msgcounts.verack++; + iguana_send_VPNversion(coin,addr,coin->myservices); + } else { iguana_send_version(coin,addr,coin->myservices); diff --git a/iguana/main.c b/iguana/main.c index cc574121e..b887e350f 100644 --- a/iguana/main.c +++ b/iguana/main.c @@ -28,7 +28,6 @@ char *Iguana_validcommands[] = { "SuperNET", "SuperNETb", - "ConnectTo", "version", "verack", "getaddr", "addr", "inv", "getdata", "notfound", "getblocks", "getheaders", "headers", "tx", "block", "mempool", "ping", "pong", "reject", "filterload", "filteradd", "filterclear", "merkleblock", "alert", "" }; @@ -442,6 +441,7 @@ void iguana_main(void *arg) jaddbits256(json,"persistent_pub",myinfo->myaddr.persistent); compressed = calloc(1,maxsize); serialized = calloc(1,maxsize); + char *str = jprint(json,0); if ( strcmp("confs/iguana.conf",fname) != 0 ) { //sprintf(fname,"confs/iguana.%llu",(long long)wallet2shared.txid); @@ -451,14 +451,14 @@ void iguana_main(void *arg) printf("save (%s) <- %d\n",fname,complen); if ( (fp= fopen(fname,"wb")) != 0 ) { - fwrite(compressed,1,complen,fp); + fwrite(str,1,strlen(str),fp); + //fwrite(compressed,1,complen,fp); fclose(fp); } }// else printf("error saving.(%s) json2bits.(%s)\n",fname,jprint(json,0)); } else { - char *str = jprint(json,0); //sprintf(fname,"confs/iguana.conf"); printf("save (%s) <- (%s)\n",fname,str); if ( (fp= fopen(fname,"wb")) != 0 ) @@ -466,8 +466,8 @@ void iguana_main(void *arg) fwrite(str,1,strlen(str),fp); fclose(fp); } - free(str); } + free(str); free(compressed), free(serialized); free_json(json); } @@ -500,7 +500,7 @@ void iguana_main(void *arg) #ifdef __APPLE__ sleep(1); char *str; - if ( (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"wallet\":\"password\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":0,\"maxpeers\":3,\"newcoin\":\"BTCD\",\"active\":0}"),0)) != 0 ) + if ( (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"wallet\":\"password\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":129,\"maxpeers\":32,\"newcoin\":\"VPN\",\"active\":0}"),0)) != 0 ) { printf("got.(%s)\n",str); free(str); diff --git a/iguana/ramchain_api.c b/iguana/ramchain_api.c index 997a642a3..af5a487ec 100755 --- a/iguana/ramchain_api.c +++ b/iguana/ramchain_api.c @@ -26,7 +26,8 @@ char *iguana_APIrequest(struct iguana_info *coin,bits256 blockhash,bits256 txid, { for (i=0; iAPIblockstr != 0 ) { retstr = coin->APIblockstr; @@ -41,6 +42,13 @@ char *iguana_APIrequest(struct iguana_info *coin,bits256 blockhash,bits256 txid, return(0); } +INT_ARG(ramchain,getblockhash,height) +{ + cJSON *retjson = cJSON_CreateObject(); + jaddbits256(retjson,"result",iguana_blockhash(coin,height)); + return(jprint(retjson,1)); +} + HASH_AND_INT(ramchain,getblock,blockhash,remoteonly) { int32_t len; char hexstr[(sizeof(uint32_t)+sizeof(struct iguana_msgblock))*2+1],*blockstr; @@ -66,7 +74,7 @@ HASH_AND_INT(ramchain,getblock,blockhash,remoteonly) else { memset(txid.bytes,0,sizeof(txid)); - if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,10)) != 0 ) + if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,5)) != 0 ) { jaddstr(retjson,"result",blockstr); free(blockstr); @@ -97,7 +105,7 @@ HASH_AND_INT(ramchain,getrawtransaction,txid,verbose) { int32_t datalen; uint8_t *data; char *blockstr; bits256 blockhash; blockhash = iguana_blockhash(coin,height); - if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,10)) != 0 ) + if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,2)) != 0 ) { datalen = (int32_t)(strlen(blockstr) >> 1); data = malloc(datalen); @@ -119,6 +127,18 @@ HASH_AND_INT(ramchain,getrawtransaction,txid,verbose) return(clonestr("{\"error\":\"cant find txid\"}")); } +STRING_ARG(ramchain,decoderawtransaction,rawtx) +{ + char *str; uint8_t *data; int32_t datalen; cJSON *retjson = cJSON_CreateObject(); + datalen = (int32_t)strlen(rawtx) >> 1; + data = malloc(datalen); + decode_hex(data,datalen,rawtx); + if ( (str= iguana_rawtxbytes(coin,retjson,data,datalen)) != 0 ) + free(str); + free(data); + return(jprint(retjson,1)); +} + HASH_ARG(ramchain,gettransaction,txid) { return(ramchain_getrawtransaction(IGUANA_CALLARGS,txid,1)); @@ -201,12 +221,6 @@ TWO_ARRAYS(ramchain,createrawtransaction,vins,vouts) return(jprint(retjson,1)); } -STRING_ARG(ramchain,decoderawtransaction,rawtx) -{ - cJSON *retjson = cJSON_CreateObject(); - return(jprint(retjson,1)); -} - STRING_AND_TWOARRAYS(ramchain,signrawtransaction,rawtx,vins,privkeys) { cJSON *retjson = cJSON_CreateObject(); diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index df474b174..ae888a886 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -14,6 +14,7 @@ ******************************************************************************/ STRING_ARG(SuperNET,bitcoinrpc,setcoin); +INT_ARG(ramchain,getblockhash,height); HASH_AND_INT(ramchain,getblock,blockhash,remoteonly); HASH_AND_INT(ramchain,getrawtransaction,txid,verbose); HASH_ARG(ramchain,gettransaction,txid);