diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index e89be5c3c..cd3bfff76 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -252,16 +252,6 @@ int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *typ return(n); } -int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr,bits256 hash2) -{ - int32_t recvlen; uint8_t *data,space[16384],*allocptr; - if ( (data= get_dataptr(BASILISK_HDROFFSET,&allocptr,&recvlen,space,sizeof(space),blockstr)) != 0 ) - gecko_blockarrived(myinfo,virt,"127.0.0.1",data,recvlen,hash2); - if ( allocptr != 0 ) - free(allocptr); - return(recvlen); -} - void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t datalen,char *type,int32_t encrypted) { uint32_t ipbits,basilisktag; int32_t msglen,len=0; void *ptr = 0; uint8_t space[8192]; bits256 senderpub; struct supernet_info *myinfo = _myinfo; @@ -359,7 +349,7 @@ struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,int32_t struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,char *CMD,int32_t blockflag,cJSON *valsobj,bits256 hash,uint8_t *data,int32_t datalen,uint32_t nBits) { - int32_t minresults,timeoutmillis,numsent,delaymillis,encryptflag; struct basilisk_item *ptr; char buf[4096],*symbol,*str = 0; struct iguana_info *virt,*btcd; + int32_t minresults,timeoutmillis,numsent,delaymillis,encryptflag,fanout; struct basilisk_item *ptr; char buf[4096],*symbol,*str = 0; struct iguana_info *virt,*btcd; if ( (btcd= iguana_coinfind("BTCD")) != 0 && btcd->RELAYNODE != 0 ) jaddnum(valsobj,"iamrelay",1); basilisk_addhexstr(&str,valsobj,buf,sizeof(buf),data,datalen); @@ -373,6 +363,9 @@ struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,char minresults = 1; if ( (timeoutmillis= jint(valsobj,"timeout")) == 0 ) timeoutmillis = BASILISK_TIMEOUT; + if ( jobj(valsobj,"fanout") == 0 ) + fanout = 1; + else fanout = jint(valsobj,"fanout"); if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) { if ( (virt= iguana_coinfind(symbol)) != 0 ) @@ -384,7 +377,7 @@ struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,char } encryptflag = jint(valsobj,"encrypt"); delaymillis = jint(valsobj,"delay"); - ptr = basilisk_issueremote(myinfo,&numsent,CMD,"BTCD",blockflag,valsobj,1,minresults,0,timeoutmillis,0,0,encryptflag,delaymillis,nBits); + ptr = basilisk_issueremote(myinfo,&numsent,CMD,"BTCD",blockflag,valsobj,fanout,minresults,0,timeoutmillis,0,0,encryptflag,delaymillis,nBits); return(ptr); } @@ -416,6 +409,24 @@ char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,bits256 ha return(jprint(retjson,1)); } +int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,char *blockstr,bits256 hash2) +{ + int32_t datalen; uint8_t *data,space[16384],*allocptr; cJSON *valsobj; char *str; + if ( (data= get_dataptr(sizeof(struct iguana_msghdr) + BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),blockstr)) != 0 ) + { + gecko_blockarrived(myinfo,virt,"127.0.0.1",data,datalen,hash2); + valsobj = cJSON_CreateObject(); + jaddnum(valsobj,"fanout",-1); + jaddstr(valsobj,"symbol",virt->symbol); + if ( (str= basilisk_standardservice("BLK",myinfo,hash2,valsobj,blockstr,0)) != 0 ) + free(str); + free_json(valsobj); + } + if ( allocptr != 0 ) + free(allocptr); + return(0); +} + #include "basilisk_bitcoin.c" #include "basilisk_nxt.c" #include "basilisk_ether.c" @@ -1021,7 +1032,7 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende symbol = "BTCD"; if ( (valsobj= cJSON_Parse((char *)data)) != 0 ) { - //printf("MSGVALS.(%s)\n",(char *)data); + printf("MSGVALS.(%s)\n",(char *)data); if ( jobj(valsobj,"coin") != 0 ) coin = iguana_coinfind(jstr(valsobj,"coin")); else if ( jobj(valsobj,"symbol") != 0 ) @@ -1071,7 +1082,7 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende CMD[i] = toupper((int32_t)CMD[i]); cmd[i] = tolower((int32_t)CMD[i]); } - //printf("MSGPROCESS.(%s) tag.%d\n",(char *)data,basilisktag); + printf("MSGPROCESS.(%s) tag.%d\n",(char *)data,basilisktag); myinfo->basilisk_busy = 1; if ( valsobj != 0 ) { diff --git a/gecko/gecko_blocks.c b/gecko/gecko_blocks.c index 64b498b70..c3218d141 100755 --- a/gecko/gecko_blocks.c +++ b/gecko/gecko_blocks.c @@ -151,7 +151,7 @@ int32_t gecko_hwmset(struct iguana_info *virt,struct iguana_txblock *txdata,stru char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2) { - struct iguana_txblock txdata; int32_t valid,adjacent,n,i,j,len = -1; struct iguana_block *block,*prev; + struct iguana_txblock txdata; int32_t height,valid,adjacent,gap,n,i,j,len = -1; struct iguana_block *block,*prev; struct iguana_txid tx; char str[65]; bits256 txid; struct iguana_msgtx *txs; memset(&txdata,0,sizeof(txdata)); iguana_memreset(&virt->TXMEM); if ( (n= iguana_gentxarray(virt,&virt->TXMEM,&txdata,&len,data,datalen)) == datalen ) @@ -161,6 +161,16 @@ char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,c printf("gecko_blockarrived: mismatched hash2\n"); return(clonestr("{\"error\":\"gecko block hash2 mismatch\"}")); } + txs = virt->TXMEM.ptr; + for (i=0; ibundlescount-1) != 0 && height >= 0 ) + { + printf("gecko_blockarrived: duplicate.[%d] txid.%s\n",i,bits256_str(str,txid)); + return(clonestr("{\"error\":\"gecko block duplicate txid\"}")); + } + } txdata.zblock.RO.allocsize = iguana_ROallocsize(virt); if ( iguana_blockvalidate(virt,&valid,(struct iguana_block *)&txdata.zblock,1) < 0 ) { @@ -182,21 +192,44 @@ char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,c if ( i == 0 ) adjacent = prev->height; //printf("i.%d prevht.%d adjacent.%d hwm.%d\n",i,prev->height,adjacent,virt->blocks.hwmchain.height); - if ( prev->height >= 0 ) + if ( prev->height >= 0 && prev->mainchain != 0 ) { - txdata.zblock.height = block->height = adjacent + 1; - if ( block->height > virt->blocks.hwmchain.height ) // longest chain wins + if ( (adjacent + 1) > virt->blocks.hwmchain.height ) // longest chain wins { //printf("new HWM %d adjacent.%d prev.%d i.%d\n",block->height,adjacent,prev->height,i); - txdata.zblock.mainchain = block->mainchain = 1; + if ( (gap= (block->height - virt->blocks.hwmchain.height)) > 1 ) + { + prev = iguana_blockfind("geckoclear",virt,virt->blocks.hwmchain.RO.prev_block); + for (j=0; jprotected,bits256_str(str,prev->RO.hash2),prev->height,block->height); + if ( prev->protected != 0 ) + { + printf("REJECT block: cant overwrite protected block\n"); + return(clonestr("{\"error\":\"gecko block cant override protected block\"}")); + } + prev->mainchain = 0; + prev = iguana_blockfind("geckoclrprev",virt,prev->RO.prev_block); + } + } prev = block; - // probably should clear mainchain bits in old path for (j=0; j<=i; j++) { if ( (prev= iguana_blockfind("geckoprev",virt,prev->RO.prev_block)) == 0 ) return(clonestr("{\"error\":\"gecko block mainchain link error\"}")); - prev->mainchain = 1; + if ( prev->protected == 0 || prev->height == (adjacent + 1 - j) ) + { + prev->mainchain = 1; + prev->height = (adjacent + 1 - j); + } + else + { + printf("REJECT block: cant change height of protected block: ht.%d vs %d\n",adjacent + 1 - j, prev->height); + return(clonestr("{\"error\":\"gecko block cant override protected block's height\"}")); + } } + txdata.zblock.height = block->height; + txdata.zblock.mainchain = block->mainchain = 1; if ( gecko_hwmset(virt,&txdata,virt->TXMEM.ptr,data,datalen,i+1) >= 0 ) return(clonestr("{\"result\":\"gecko block created\"}")); else return(clonestr("{\"error\":\"gecko error creating hwmblock\"}")); @@ -214,6 +247,12 @@ char *basilisk_respond_geckoblock(struct supernet_info *myinfo,char *CMD,void *a printf("got geckoblock len.%d from (%s) %s\n",datalen,remoteaddr!=0?remoteaddr:"",jprint(valsobj,0)); if ( (symbol= jstr(valsobj,"coin")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) { + if ( iguana_blockfind("geckoblock",virt,hash2) != 0 ) + { + char str[65]; + printf("REJECT: duplicate block %s\n",bits256_str(str,hash2)); + return(clonestr("{\"error\":\"duplicate block rejected\"}")); + } hdrsize = (virt->chain->zcash != 0) ? sizeof(struct iguana_msgblockhdr_zcash) : sizeof(struct iguana_msgblockhdr); nBits = gecko_nBits(virt,&prevtimestamp,(struct iguana_block *)&virt->blocks.hwmchain,GECKO_DIFFITERS); if ( gecko_blocknonce_verify(virt,data,hdrsize,nBits,virt->blocks.hwmchain.RO.timestamp,prevtimestamp) == 0 ) @@ -229,7 +268,8 @@ char *basilisk_respond_geckoblock(struct supernet_info *myinfo,char *CMD,void *a int32_t basilisk_respond_geckogetblock(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2) { - int32_t datalen = 0; + int32_t datalen = 0; char str[65]; + printf("GOT request for block.(%s)\n",bits256_str(str,hash2)); // find block and set serialized return(datalen); } diff --git a/gecko/gecko_miner.c b/gecko/gecko_miner.c index 53730b4eb..1609ab47e 100755 --- a/gecko/gecko_miner.c +++ b/gecko/gecko_miner.c @@ -296,12 +296,12 @@ cJSON *gecko_paymentsobj(struct supernet_info *myinfo,cJSON *txjson,cJSON *valso return(txjson); } -void gecko_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr,bits256 hash2) +void gecko_blocksubmit(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,char *blockstr,bits256 hash2) { uint8_t *data,space[16384],*allocptr=0; int32_t i,len,numranked=0; struct iguana_peers *peers; struct iguana_peer *addr; if ( (peers= virt->peers) == 0 || (numranked= peers->numranked) == 0 ) - basilisk_blocksubmit(myinfo,virt,blockstr,hash2); - else + basilisk_blocksubmit(myinfo,btcd,virt,blockstr,hash2); + else // physical node for geckochain { if ( (data= get_dataptr(sizeof(struct iguana_msghdr),&allocptr,&len,space,sizeof(space),blockstr)) != 0 ) { @@ -335,7 +335,7 @@ void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct ig if ( (blockstr= gecko_createblock(myinfo,virt->chain->estblocktime,prevtimestamp,btcd,virt->chain->isPoS,(void *)&newblock,virt->symbol,txptrs,txn_count,maxmillis,minerpubkey33,reward)) != 0 ) { char str[65]; printf("%s.%x %s %u %d %.8f %d\n",virt->symbol,newblock.RO.bits,bits256_str(str,newblock.RO.hash2),newblock.RO.timestamp,newblock.height,dstr(reward),newblock.RO.txn_count); - gecko_blocksubmit(myinfo,virt,blockstr,newblock.RO.hash2); + gecko_blocksubmit(myinfo,btcd,virt,blockstr,newblock.RO.hash2); free(blockstr); } if ( txptrs != (void *)space ) diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index 32b376b46..4c8d4b56e 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -487,7 +487,7 @@ void iguana_blockzcopy(uint8_t zcash,struct iguana_block *dest,struct iguana_blo int32_t iguana_blocksizecheck(char *debugstr,uint8_t zcash,struct iguana_block *block); void basilisk_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,char *mineraddr); int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66]); -int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr,bits256 hash2); +int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,char *blockstr,bits256 hash2); struct supernet_info *SuperNET_MYINFO(char *passphrase); bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory); struct gecko_chain *category_find(bits256 categoryhash,bits256 subhash); diff --git a/includes/iguana_structs.h b/includes/iguana_structs.h index 1cd38fc28..2217b9cb6 100755 --- a/includes/iguana_structs.h +++ b/includes/iguana_structs.h @@ -185,7 +185,7 @@ struct iguana_zblockRO } __attribute__((packed)); #define iguana_blockfields double PoW; \ -int32_t height,fpos; uint32_t fpipbits,issued,lag:20,peerid:12; \ +int32_t height,fpos; uint32_t fpipbits,issued,lag:19,protected:1,peerid:12; \ uint16_t hdrsi:15,mainchain:1,bundlei:11,valid:1,queued:1,txvalid:1,newtx:1,processed:1; \ UT_hash_handle hh; struct iguana_bundlereq *req; \ struct iguana_blockRO RO @@ -375,7 +375,6 @@ struct hhbits256 { UT_hash_handle hh; bits256 txid; int32_t height; uint16_t fir struct iguana_monitorinfo { bits256 txid; int32_t numreported; uint8_t peerbits[IGUANA_MAXPEERS >> 3]; }; - struct iguana_info { UT_hash_handle hh;