diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 37309023f..61e930f0b 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -447,7 +447,7 @@ struct iguana_info int32_t initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,polltimeout,numreqtxids; bits256 reqtxids[64]; void *launched,*started; uint64_t bloomsearches,bloomhits,bloomfalse,collisions; uint8_t blockspace[IGUANA_MAXPACKETSIZE + 8192]; struct OS_memspace blockMEM; - struct iguana_blocks blocks; bits256 APIblockhash; char *APIblockstr; + struct iguana_blocks blocks; bits256 APIblockhash,APItxid; char *APIblockstr; struct iguana_waccount *wallet; }; @@ -512,7 +512,7 @@ int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newbloc uint64_t iguana_miningreward(struct iguana_info *coin,uint32_t blocknum); // tx -int32_t iguana_rwtx(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t height,int32_t hastimestamp); +int32_t iguana_rwtx(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp); void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *txids,int32_t n); void iguana_gotunconfirmedM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgtx *tx,uint8_t *data,int32_t datalen); void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *blockhashes,int32_t n); @@ -657,7 +657,7 @@ void iguana_bundleiclear(struct iguana_info *coin,struct iguana_bundle *bp,int32 int32_t hcalc_bitsize(uint64_t x); struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_pkhash *p,uint8_t rmd160[20]); struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid); -int32_t iguana_scriptgen(struct iguana_info *coin,uint8_t *script,char *asmstr,struct iguana_bundle *bp,struct iguana_pkhash *p,uint8_t type); +int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,int32_t txi); int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s); struct iguana_info *iguana_coinselect(); void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr); @@ -702,6 +702,11 @@ int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,s int32_t category_peer(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 category,bits256 subhash); int32_t btc_wif2priv(uint8_t *addrtypep,uint8_t privkey[32],char *wifstr); bits256 iguana_chaingenesis(int32_t version,uint32_t timestamp,uint32_t nBits,uint32_t nonce,bits256 merkle_root); +int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr); +cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height); +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); extern queue_t bundlesQ; diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index 785091dec..5bbd7f615 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -66,7 +66,7 @@ static struct iguana_chain Chains[] = "3b27c25b333e890fbb6cd912fcdfb07bf17245def80410a0a05a8eae070b2060", //"00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99", // hashGenesisBlock main.h "01000000000000000000000000000000000000000000000000000000000000000000000028581b3ba53e73adaaf957bced1d42d46ed0d84a86b34f7a5a49cdcaa1938a697f9c0854ffff0f1e0004de0300", // need to extract from valid blk0001.dat - 11920,11921,1,0x1e // port and rpcport vpncoin.conf + 1920,1921,1,0x1e // port and rpcport vpncoin.conf }, }; diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index 106ebc15a..e2c9033fd 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -32,7 +32,7 @@ int32_t iguana_rwaddr(int32_t rwflag,uint8_t *serialized,struct iguana_msgaddres return(len); } -int32_t iguana_rwversion(int32_t rwflag,uint8_t *serialized,struct iguana_msgversion *msg,char *ipaddr) +int32_t iguana_rwversion(int32_t rwflag,uint8_t *serialized,struct iguana_msgversion *msg,char *ipaddr,int32_t readsize) { int32_t len = 0; len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->nVersion),&msg->nVersion); @@ -43,10 +43,35 @@ int32_t iguana_rwversion(int32_t rwflag,uint8_t *serialized,struct iguana_msgver len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->nonce),&msg->nonce); len += iguana_rwstr(rwflag,&serialized[len],sizeof(msg->strSubVer),msg->strSubVer); 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; + 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); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(bIsGui),&bIsGui); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(wCtPort),&wCtPort); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(wPrPort),&wPrPort); + /*int iVer = BitNet_Version; + unsigned short wPort = GetListenPort(); + unsigned char bIsGui = 0; // 2014.12.18 add + unsigned short wCtPort = 0; + unsigned short wPrPort = 0; + vRecv >> iVer; + pfrom->vBitNet.v_iVersion = iVer; + vRecv >> pfrom->vBitNet.; + if (!vRecv.empty()){ vRecv >> pfrom->vBitNet.v_ListenPort; } + if (!vRecv.empty()){ vRecv >> pfrom->vBitNet.v_IsGuiNode; } //-- 2014.12.18 add + if (!vRecv.empty()){ vRecv >> pfrom->vBitNet.v_iVpnServiceCtrlPort; } //-- 2014.12.28 add + 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); + } if ( msg->nVersion > 70000 ) len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->relayflag),&msg->relayflag); //if ( rwflag == 0 ) - // printf("%-15s v.%llu srv.%llx %u ht.%llu [%s].R%d nonce.%llx\n",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); + 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); + // 6e ea 00 00 01 00 00 00 00 00 00 00 86 5f a8 56 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff b5 2f b7 bc c6 83 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff 67 e5 7e c2 07 80 00 00 00 00 00 00 00 00 10 2f 42 69 74 4e 65 74 3a 31 2e 31 2e 33 2e 32 2f 92 d0 09 00 6c 04 00 00 01 00 00 00 80 07 01 9a 03 9b 03 01 return(len); } @@ -127,7 +152,7 @@ int32_t iguana_rwblockhash(int32_t rwflag,uint8_t *serialized,uint32_t *nVersion void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgversion *vers) { uint8_t serialized[sizeof(struct iguana_msghdr)]; - //printf("gotversion from %s\n",addr->ipaddr); + printf("gotversion from %s: starting height.%d services.%llx proto.%d\n",addr->ipaddr,vers->nStartingHeight,(long long)vers->nServices,vers->nVersion); if ( (vers->nServices & NODE_NETWORK) != 0 )//&& vers->nonce != coin->instance_nonce ) { addr->protover = (vers->nVersion < PROTOCOL_VERSION) ? vers->nVersion : PROTOCOL_VERSION; @@ -157,7 +182,7 @@ int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,ui sprintf(msg.strSubVer,"/Satoshi:0.11.99/"); msg.nStartingHeight = coin->blocks.hwmchain.height; iguana_gotdata(coin,addr,msg.nStartingHeight); - len = iguana_rwversion(1,&serialized[sizeof(struct iguana_msghdr)],&msg,addr->ipaddr); + len = iguana_rwversion(1,&serialized[sizeof(struct iguana_msghdr)],&msg,addr->ipaddr,0); return(iguana_queue_send(coin,addr,0,serialized,"version",len,0,1)); } @@ -219,6 +244,15 @@ int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr) return(iguana_queue_send(coin,addr,0,serialized,"ping",len,0,0)); } +int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr) +{ + int32_t len; uint32_t r; uint16_t port = 1920; uint8_t serialized[sizeof(struct iguana_msghdr) + 6]; + r = rand(); + len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint32_t),&r); + len += iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)+len],sizeof(port),&port); + return(iguana_queue_send(coin,addr,0,serialized,"ConnectTo",len,0,0)); +} + void iguana_gotpong(struct iguana_info *coin,struct iguana_peer *addr,uint64_t nonce) { if ( addr->sendmillis != 0 ) @@ -294,7 +328,7 @@ int32_t iguana_rwvout(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized return(len); } -int32_t iguana_rwtx(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t height,int32_t hastimestamp) +int32_t iguana_rwtx(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp) { int32_t i,len = 0; uint8_t *txstart = serialized; char txidstr[65]; len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); @@ -335,6 +369,124 @@ int32_t iguana_rwtx(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,s return(len); } +int32_t iguana_vinskip(uint8_t *serialized,struct iguana_msgvin *msg) +{ + int32_t len = 0,rwflag = 0; + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->prev_hash),msg->prev_hash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->prev_vout),&msg->prev_vout); + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->scriptlen); + msg->script = &serialized[len]; + len += msg->scriptlen; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence); + return(len); +} + +int32_t iguana_voutskip(uint8_t *serialized,struct iguana_msgvout *msg) +{ + int32_t len = 0,rwflag = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->value),&msg->value); + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->pk_scriptlen); + msg->pk_script = &serialized[len]; + len += msg->pk_scriptlen; + return(len); +} + +int32_t iguana_txskip(struct iguana_info *coin,cJSON *json,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp) +{ + int32_t i,len = 0,rwflag = 0; uint8_t *txstart = serialized; char txidstr[65]; cJSON *array=0; + struct iguana_msgvin vin; struct iguana_msgvout vout; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); + if ( json != 0 ) + { + jaddnum(json,"version",msg->version); + array = cJSON_CreateArray(); + } + if ( hastimestamp != 0 ) + { + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); + if ( json != 0 ) + jaddnum(json,"timestamp",msg->timestamp); + } + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); + if ( msg->tx_in > 0 && msg->tx_out*100 < maxsize ) + { + for (i=0; itx_in; i++) + { + memset(&vin,0,sizeof(vin)); + len += iguana_vinskip(&serialized[len],&vin); + if ( array != 0 ) + jaddi(array,iguana_vinjson(coin,&vin)); + } + } + else + { + printf("invalid tx_in.%d\n",msg->tx_in); + return(-1); + } + if ( array != 0 ) + { + jadd(json,"vins",array); + jaddnum(json,"numvins",msg->tx_in); + array = cJSON_CreateArray(); + } + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out); + if ( msg->tx_out > 0 && msg->tx_out*32 < maxsize ) + { + for (i=0; itx_out; i++) + { + memset(&vout,0,sizeof(vout)); + len += iguana_voutskip(&serialized[len],&vout); + if ( array != 0 ) + jaddi(array,iguana_voutjson(coin,&vout,i)); + } + } + else + { + printf("invalid tx_out.%d\n",msg->tx_out); + return(-1); + } + if ( array != 0 ) + { + jadd(json,"vouts",array); + jaddnum(json,"numvouts",msg->tx_out); + } + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); + *txidp = bits256_doublesha256(txidstr,txstart,len); + if ( json != 0 ) + { + jaddnum(json,"locktime",msg->lock_time); + jaddnum(json,"size",len); + jaddbits256(json,"txid",*txidp); + } + msg->allocsize = len; + return(len); +} + +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; + memset(&msg,0,sizeof(msg)); + len = iguana_rwblock(0,&hash2,data,&msg); + iguana_blockconv(&block,&msg,hash2,-1); + for (i=0; ichain->hastimestamp)) < 0 ) + break; + //char str[65]; printf("%d of %d: %s\n",i,msg.txn_count,bits256_str(str,tx.txid)); + if ( bits256_cmp(txid,tx.txid) == 0 ) + { + if ( (n= iguana_txskip(coin,json,&data[len],&tx,recvlen - len,&tx.txid,coin->chain->hastimestamp)) > 0 ) + { + txbytes = malloc(n*2+1); + init_hexbytes_noT(txbytes,&data[len],n); + return(txbytes); + } + } + len += n; + } + return(0); +} + int32_t iguana_txbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts) { int32_t i,rwflag=1,len = 0; char asmstr[512],txidstr[65]; @@ -382,7 +534,7 @@ int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struc tx = iguana_memalloc(mem,msg.txn_count*sizeof(*tx),1); for (i=numvins=numvouts=0; iblock.height,coin->chain->hastimestamp)) < 0 ) + if ( (n= iguana_rwtx(0,mem,&data[len],&tx[i],recvlen - len,&tx[i].txid,coin->chain->hastimestamp)) < 0 ) break; numvouts += tx[i].tx_out; numvins += tx[i].tx_in; @@ -447,8 +599,8 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc struct iguana_msgversion recvmv; if ( addr != 0 ) { - len = iguana_rwversion(0,data,&recvmv,addr->ipaddr); - if ( len == recvlen ) + len = iguana_rwversion(0,data,&recvmv,addr->ipaddr,recvlen); + if ( len <= recvlen ) iguana_gotversion(coin,addr,&recvmv); //printf("deser.(%s) len.%d recvlen.%d\n",recvmv.H.command,len,recvlen); addr->msgcounts.version++; @@ -463,6 +615,15 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc } len = 0; } + else if ( strcmp(H->command,"ConnectTo") == 0 ) + { + if ( addr != 0 ) + { + iguana_gotverack(coin,addr); + addr->msgcounts.verack++; + } + len = 6; + } else if ( strcmp(H->command,"ping") == 0 ) { if ( recvlen == sizeof(uint64_t) && addr != 0 ) @@ -531,7 +692,7 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc struct iguana_msgtx *tx; iguana_memreset(rawmem); tx = iguana_memalloc(rawmem,sizeof(*tx),1);//mycalloc('u',1,sizeof(*tx)); - len = iguana_rwtx(0,rawmem,data,tx,recvlen,&tx->txid,-1,coin->chain->hastimestamp); + len = iguana_rwtx(0,rawmem,data,tx,recvlen,&tx->txid,coin->chain->hastimestamp); iguana_gotunconfirmedM(coin,addr,tx,data,recvlen); printf("tx recvlen.%d vs len.%d\n",recvlen,len); addr->msgcounts.tx++; diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 51c8c99a2..e95ac5f33 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -343,9 +343,17 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,int32_t len) { - int32_t numsent,remains,usock; - if ( addr == 0 && coin->peers.numranked > 1 ) - addr = coin->peers.ranked[rand() % coin->peers.numranked]; + int32_t numsent,remains,usock,r,i; + if ( addr == 0 ) + { + r = rand(); + for (i=0; ipeers.active[(i + r) % IGUANA_MAXPEERS]; + if ( addr->usock >= 0 && addr->msgcounts.verack > 0 ) + break; + } + } if ( addr == 0 ) return(-1); usock = addr->usock; @@ -358,7 +366,7 @@ int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *s { //printf(" >>>>>>> send.(%s) %d bytes to %s supernet.%d\n",(char *)&serialized[4],len,addr->ipaddr,addr->supernet); } - else if ( addr->msgcounts.verack == 0 && (strcmp((char *)&serialized[4],"version") != 0 && strcmp((char *)&serialized[4],"verack") != 0) != 0 ) + else if ( addr->msgcounts.verack == 0 && (strcmp((char *)&serialized[4],"version") != 0 && strcmp((char *)&serialized[4],"ConnectTo") != 0 && strcmp((char *)&serialized[4],"verack") != 0) != 0 ) { printf("skip.(%s) since no verack yet\n",(char *)&serialized[4]); return(-1); @@ -497,7 +505,7 @@ 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("%p got.(%s) recvlen.%d from %s | usock.%d ready.%u dead.%u len.%d\n",addr,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 ) { @@ -519,6 +527,10 @@ void _iguana_processmsg(struct iguana_info *coin,int32_t usock,struct iguana_pee return; } } + // 79 22 e3 b4 80 07 + //int32_t i; for (i=0; iipaddr,addr->pending,addr->usock,addr->addrind); + //printf("startconnection.(%s) pending.%u usock.%d addrind.%d\n",addr->ipaddr,addr->pending,addr->usock,addr->addrind); addr->pending = (uint32_t)time(NULL); if ( (port= (uint16_t)(addr->ipbits >> 32)) == 0 ) port = coin->chain->portp2p; @@ -921,7 +933,7 @@ int64_t iguana_peerallocated(struct iguana_info *coin,struct iguana_peer *addr) void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) { static uint32_t lastping; - struct pollfd fds; uint8_t *buf,serialized[64]; struct iguana_bundlereq *req; + struct pollfd fds; struct iguana_bundlereq *req; uint8_t *buf;//,serialized[64]; uint32_t ipbits; int32_t bufsize,flag,run,timeout = coin->polltimeout == 0 ? 10 : coin->polltimeout; #ifdef IGUANA_PEERALLOC int32_t i; int64_t remaining; struct OS_memspace *mem[sizeof(addr->SEROUT)/sizeof(*addr->SEROUT)]; @@ -945,10 +957,15 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) addr->maxfilehash2 = IGUANA_MAXFILEITEMS; bufsize = IGUANA_MAXPACKETSIZE; buf = mycalloc('r',1,bufsize); - printf("send version myservices.%llu to (%s)\n",(long long)coin->myservices,addr->ipaddr); - iguana_send_version(coin,addr,coin->myservices); - sleep(1+(rand()%5)); - iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); + if ( strcmp(coin->symbol,"VPN") == 0 ) + iguana_send_ConnectTo(coin,addr); + else + { + iguana_send_version(coin,addr,coin->myservices); + //printf("send version myservices.%llu to (%s)\n",(long long)coin->myservices,addr->ipaddr); + } + //sleep(1+(rand()%5)); + //iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); run = 0; while ( addr->usock >= 0 && addr->dead == 0 && coin->peers.shuttingdown == 0 ) { diff --git a/iguana/iguana_pubkeys.c b/iguana/iguana_pubkeys.c index 0898eb01a..17b63aed5 100755 --- a/iguana/iguana_pubkeys.c +++ b/iguana/iguana_pubkeys.c @@ -902,9 +902,10 @@ int32_t iguana_calcrmd160(struct iguana_info *coin,uint8_t rmd160[20],uint8_t ms } return(IGUANA_SCRIPT_7688AC); } + // 21035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055eac else if ( pk_script[0] > 0 && pk_script[0] < 76 && pk_script[pk_scriptlen-1] == 0xac && pk_script[0] == pk_scriptlen-2 ) { - //printf("minus2\n"); + printf("minus2\n"); vcalc_sha256(0,sha256,&pk_script[1],pk_script[0]); calc_rmd160(0,rmd160,sha256,sizeof(sha256)); return(IGUANA_SCRIPT_76AC); @@ -978,16 +979,19 @@ int32_t iguana_calcrmd160(struct iguana_info *coin,uint8_t rmd160[20],uint8_t ms return(type); } -int32_t iguana_scriptgen(struct iguana_info *coin,uint8_t *script,char *asmstr,struct iguana_bundle *bp,struct iguana_pkhash *p,uint8_t type) +int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,int32_t txi) { - char coinaddr[65]; uint8_t addrtype; int32_t scriptlen = 0; + uint8_t addrtype; int32_t scriptlen = 0; if ( type == IGUANA_SCRIPT_7688AC || type == IGUANA_SCRIPT_76AC ) addrtype = coin->chain->pubtype; else addrtype = coin->chain->p2shtype; - btc_convrmd160(coinaddr,addrtype,p->rmd160); + btc_convrmd160(coinaddr,addrtype,rmd160); switch ( type ) { - case IGUANA_SCRIPT_NULL: strcpy(asmstr,"coinbase"); break; + case IGUANA_SCRIPT_NULL: + strcpy(asmstr,txi == 0 ? "coinbase" : "PoSbase"); + coinaddr[0] = 0; + break; case IGUANA_SCRIPT_76AC: sprintf(asmstr,"OP_DUP %s OP_CHECKSIG",coinaddr); break; @@ -996,7 +1000,7 @@ int32_t iguana_scriptgen(struct iguana_info *coin,uint8_t *script,char *asmstr,s break; case IGUANA_SCRIPT_P2SH: script[0] = 0xa9, script[1] = 0x14; - memcpy(&script[2],p->rmd160,20); + memcpy(&script[2],rmd160,20); script[22] = 0x87; sprintf(asmstr,"OP_HASH160 %s OP_EQUAL",coinaddr); scriptlen = 23; diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 79b3a00f9..4ff52bc87 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -173,7 +173,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i struct iguana_txblock *checktxdata; struct OS_memspace checkmem; int32_t checkbundlei; memset(&checkmem,0,sizeof(checkmem)); iguana_meminit(&checkmem,"checkmem",0,txdata->datalen + 4096,0); - if ( (checktxdata= iguana_peertxdata(coin,&checkbundlei,fname,&checkmem,addr->ipbits,txdata->block.RO.hash2)) != 0 ) + if ( (checktxdata= iguana_peertxdata(coin,&checkbundlei,fname,&checkmem,(uint32_t)addr->ipbits,txdata->block.RO.hash2)) != 0 ) { printf("check datalen.%d bundlei.%d T.%d U.%d S.%d P.%d X.%d\n",checktxdata->datalen,checkbundlei,checktxdata->numtxids,checktxdata->numunspents,checktxdata->numspends,checktxdata->numpkinds,checktxdata->numexternaltxids); } diff --git a/iguana/iguana_tx.c b/iguana/iguana_tx.c index 3d6b096b6..70ae42ccc 100755 --- a/iguana/iguana_tx.c +++ b/iguana/iguana_tx.c @@ -16,34 +16,39 @@ #include "iguana777.h" #include "SuperNET.h" -cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,char *asmstr) +cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int32_t txi) { + // 035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055e OP_CHECKSIG static bits256 zero; - char scriptstr[8192+1],coinaddr[65]; int32_t i,M,N; uint8_t rmd160[20],msigs160[16][20],addrtype; + char scriptstr[8192+1],coinaddr[65],asmstr[16384]; int32_t i,M,N,asmtype; + uint8_t rmd160[20],msigs160[16][20],addrtype,space[8192]; cJSON *addrs,*json = cJSON_CreateObject(); jaddnum(json,"value",dstr(vout->value)); - if ( asmstr[0] != 0 ) - jaddstr(json,"asm",asmstr); if ( vout->pk_script != 0 && vout->pk_scriptlen*2+1 < sizeof(scriptstr) ) { - if ( iguana_calcrmd160(coin,rmd160,msigs160,&M,&N,vout->pk_script,vout->pk_scriptlen,zero) > 0 ) - addrtype = coin->chain->p2shtype; - else addrtype = coin->chain->pubtype; - btc_convrmd160(coinaddr,addrtype,rmd160); - jaddstr(json,"address",coinaddr); - init_hexbytes_noT(scriptstr,vout->pk_script,vout->pk_scriptlen); - jaddstr(json,"payscript",scriptstr); - if ( N != 0 ) + if ( (asmtype= iguana_calcrmd160(coin,rmd160,msigs160,&M,&N,vout->pk_script,vout->pk_scriptlen,zero)) >= 0 ) { - jaddnum(json,"M",M); - jaddnum(json,"N",N); - addrs = cJSON_CreateArray(); - for (i=0; ipk_script,vout->pk_scriptlen); + if ( scriptstr[0] != 0 ) + jaddstr(json,"payscript",scriptstr); + if ( N != 0 ) { - btc_convrmd160(coinaddr,coin->chain->pubtype,msigs160[i]); - jaddistr(addrs,coinaddr); + jaddnum(json,"M",M); + jaddnum(json,"N",N); + addrs = cJSON_CreateArray(); + for (i=0; ichain->pubtype,msigs160[i]); + jaddistr(addrs,coinaddr); + } + jadd(json,"addrs",addrs); } - jadd(json,"addrs",addrs); } } return(json); @@ -51,9 +56,10 @@ cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,char cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) { - char scriptstr[8192+1],str[65]; cJSON *json = cJSON_CreateObject(); + char scriptstr[8192+1],str[65]; int32_t vout; cJSON *json = cJSON_CreateObject(); jaddstr(json,"prev_hash",bits256_str(str,vin->prev_hash)); - jaddnum(json,"prev_vout",vin->prev_vout); + vout = vin->prev_vout; + jaddnum(json,"prev_vout",vout); jaddnum(json,"sequence",vin->sequence); if ( vin->script != 0 && vin->scriptlen*2+1 < sizeof(scriptstr) ) { @@ -90,7 +96,7 @@ void iguana_vinset(struct iguana_info *coin,int32_t height,struct iguana_msgvin int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmstr,int32_t height,struct iguana_msgvout *vout,struct iguana_txid *tx,int32_t i) { - struct iguana_unspent *u,*U; uint32_t unspentind,scriptlen = 0; struct iguana_bundle *bp; + struct iguana_unspent *u,*U; uint32_t unspentind,scriptlen = 0; struct iguana_bundle *bp; char coinaddr[65]; struct iguana_ramchaindata *rdata; struct iguana_pkhash *P,*p; memset(vout,0,sizeof(*vout)); if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) @@ -103,7 +109,7 @@ int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmst printf("iguana_voutset: txidind mismatch %d vs %d || %d vs %d || (%d vs %d)\n",u->txidind,u->txidind,u->vout,i,u->hdrsi,height / coin->chain->bundlesize); p = &P[u->pkind]; vout->value = u->value; - scriptlen = iguana_scriptgen(coin,scriptspace,asmstr,bp,p,u->type); + scriptlen = iguana_scriptgen(coin,coinaddr,scriptspace,asmstr,p->rmd160,u->type,i); } vout->pk_scriptlen = scriptlen; return(scriptlen); @@ -125,7 +131,7 @@ cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t hei for (i=0; inumvouts; i++) { iguana_voutset(coin,space,asmstr,height,&vout,tx,i); - jaddi(vouts,iguana_voutjson(coin,&vout,asmstr)); + jaddi(vouts,iguana_voutjson(coin,&vout,i)); } jadd(json,"vouts",vouts); for (i=0; inumvins; i++) diff --git a/iguana/main.c b/iguana/main.c index 56bf9b487..8200d15bc 100644 --- a/iguana/main.c +++ b/iguana/main.c @@ -28,6 +28,7 @@ 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", "" }; @@ -499,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\":128,\"maxpeers\":128,\"newcoin\":\"VPN\",\"active\":1}"),0)) != 0 ) + if ( (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"wallet\":\"password\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":0,\"maxpeers\":3,\"newcoin\":\"BTCD\",\"active\":0}"),0)) != 0 ) { printf("got.(%s)\n",str); free(str); diff --git a/iguana/ramchain_api.c b/iguana/ramchain_api.c index edae00300..997a642a3 100755 --- a/iguana/ramchain_api.c +++ b/iguana/ramchain_api.c @@ -16,14 +16,39 @@ #include "iguana777.h" #include "../includes/iguana_apidefs.h" -HASH_AND_INT(ramchain,getblock,blockhash,localonly) +char *iguana_APIrequest(struct iguana_info *coin,bits256 blockhash,bits256 txid,int32_t seconds) { - int32_t i,len; char hexstr[(sizeof(uint32_t)+sizeof(struct iguana_msgblock))*2+1]; - uint8_t serialized[sizeof(uint32_t)+sizeof(struct iguana_msgblock)]; bits256 hash2; + int32_t i,len; char *retstr = 0; uint8_t serialized[1024]; char str[65]; + coin->APIblockhash = blockhash; + coin->APItxid = txid; + printf("request block.(%s) txid.%llx\n",bits256_str(str,blockhash),(long long)txid.txid); + if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,bits256_str(str,blockhash))) > 0 ) + { + for (i=0; iAPIblockstr != 0 ) + { + retstr = coin->APIblockstr; + coin->APIblockstr = 0; + memset(&coin->APIblockhash,0,sizeof(coin->APIblockhash)); + memset(&coin->APItxid,0,sizeof(coin->APItxid)); + return(retstr); + } + sleep(1); + } + } + return(0); +} + +HASH_AND_INT(ramchain,getblock,blockhash,remoteonly) +{ + int32_t len; char hexstr[(sizeof(uint32_t)+sizeof(struct iguana_msgblock))*2+1],*blockstr; + uint8_t serialized[sizeof(uint32_t)+sizeof(struct iguana_msgblock)]; bits256 hash2,txid; struct iguana_msgblock msg; struct iguana_block *block; cJSON *retjson = cJSON_CreateObject(); memset(&msg,0,sizeof(msg)); - if ( localonly == 0 && (block= iguana_blockfind(coin,blockhash)) != 0 ) + if ( remoteonly == 0 && (block= iguana_blockfind(coin,blockhash)) != 0 ) { msg.H.version = block->RO.version; msg.H.merkle_root = block->RO.merkle_root; @@ -40,24 +65,63 @@ HASH_AND_INT(ramchain,getblock,blockhash,localonly) jaddstr(retjson,"error","already have pending request"); else { - coin->APIblockhash = blockhash; - iguana_blockQ(coin,0,-1,blockhash,1); - for (i=0; i<10; i++) + memset(txid.bytes,0,sizeof(txid)); + if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,10)) != 0 ) + { + jaddstr(retjson,"result",blockstr); + free(blockstr); + } else jaddstr(retjson,"error","cant find blockhash"); + } + return(jprint(retjson,1)); +} + +HASH_AND_INT(ramchain,getrawtransaction,txid,verbose) +{ + struct iguana_txid *tx,T; char *txbytes; bits256 checktxid; int32_t len,height; cJSON *retjson; + if ( (tx= iguana_txidfind(coin,&height,&T,txid)) != 0 ) + { + retjson = cJSON_CreateObject(); + if ( (len= iguana_txbytes(coin,coin->blockspace,sizeof(coin->blockspace),&checktxid,tx,height,0,0)) > 0 ) + { + txbytes = mycalloc('x',1,len*2+1); + init_hexbytes_noT(txbytes,coin->blockspace,len*2+1); + jaddstr(retjson,"result",txbytes); + myfree(txbytes,len*2+1); + return(jprint(retjson,1)); + } + else if ( height >= 0 ) { if ( coin->APIblockstr != 0 ) + jaddstr(retjson,"error","already have pending request"); + else { - jaddstr(retjson,"result",coin->APIblockstr); - free(coin->APIblockstr); - memset(&coin->APIblockhash,0,sizeof(coin->APIblockhash)); - coin->APIblockstr = 0; - break; + int32_t datalen; uint8_t *data; char *blockstr; bits256 blockhash; + blockhash = iguana_blockhash(coin,height); + if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,10)) != 0 ) + { + datalen = (int32_t)(strlen(blockstr) >> 1); + data = malloc(datalen); + decode_hex(data,datalen,blockstr); + if ( (txbytes= iguana_txscan(coin,verbose != 0 ? retjson : 0,data,datalen,txid)) != 0 ) + { + jaddstr(retjson,"result",txbytes); + jaddbits256(retjson,"blockhash",blockhash); + jaddnum(retjson,"height",height); + free(txbytes); + } else jaddstr(retjson,"error","cant find txid in block"); + free(blockstr); + free(data); + } else jaddstr(retjson,"error","cant find blockhash"); + return(jprint(retjson,1)); } - sleep(1); - } - if ( i == 10 ) - jaddstr(retjson,"error","cant find blockhash"); + } else printf("height.%d\n",height); } - return(jprint(retjson,1)); + return(clonestr("{\"error\":\"cant find txid\"}")); +} + +HASH_ARG(ramchain,gettransaction,txid) +{ + return(ramchain_getrawtransaction(IGUANA_CALLARGS,txid,1)); } ZERO_ARGS(ramchain,getinfo) @@ -137,12 +201,6 @@ TWO_ARRAYS(ramchain,createrawtransaction,vins,vouts) return(jprint(retjson,1)); } -HASH_AND_INT(ramchain,getrawtransaction,txid,verbose) -{ - cJSON *retjson = cJSON_CreateObject(); - return(jprint(retjson,1)); -} - STRING_ARG(ramchain,decoderawtransaction,rawtx) { cJSON *retjson = cJSON_CreateObject(); diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index 84b15ad2f..df474b174 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -14,7 +14,10 @@ ******************************************************************************/ STRING_ARG(SuperNET,bitcoinrpc,setcoin); -HASH_AND_INT(ramchain,getblock,blockhash,localonly); +HASH_AND_INT(ramchain,getblock,blockhash,remoteonly); +HASH_AND_INT(ramchain,getrawtransaction,txid,verbose); +HASH_ARG(ramchain,gettransaction,txid); +STRING_ARG(ramchain,decoderawtransaction,rawtx); /*HASH_AND_ARRAY(pangea,userturn,tablehash,params); HASH_AND_ARRAY(pangea,status,tableid,params); @@ -107,7 +110,6 @@ STRING_ARG(ramchain,getaccount,address); STRING_ARG(ramchain,getaccountaddress,account); STRING_ARG(ramchain,dumpprivkey,address); STRING_ARG(ramchain,importwallet,filename); -STRING_ARG(ramchain,decoderawtransaction,rawtx); STRING_ARG(ramchain,decodescript,script); TWO_STRINGS(ramchain,setaccount,address,account); @@ -125,7 +127,6 @@ STRING_AND_INT(ramchain,getreceivedbyaddress,address,minconf); STRING_AND_INT(ramchain,sendrawtransaction,rawtx,allowhighfees); HASH_AND_TWOINTS(ramchain,listsinceblock,blockhash,target,flag); -HASH_AND_INT(ramchain,getrawtransaction,txid,verbose); STRING_AND_THREEINTS(ramchain,listtransactions,account,count,skip,includewatchonly);