char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 firsthash2) { bits256 hash2,prevhash2; struct iguana_block *block; int32_t height,firstheight,i,len=0,n,num; struct iguana_msgzblock zmsgB; char str[65],str2[65]; num = (int32_t)(datalen / 84); printf("headers.%s arrived.%d from %s\n",virt->symbol,num,bits256_str(str,firsthash2)); if ( (block= iguana_blockfind("geckohdrs",virt,firsthash2)) != 0 && (firstheight= block->height) >= 0 ) { gecko_blockhashupdate(virt,firsthash2,firstheight); prevhash2 = firsthash2; for (i=0; i<num; i++) { if ( (n= iguana_rwblock(myinfo,virt->symbol,virt->chain->zcash,virt->chain->auxpow,virt->chain->hashalgo,0,&hash2,&data[len],&zmsgB,datalen-len)) > 0 ) { if ( bits256_cmp(zmsgB.zH.prev_block,prevhash2) == 0 ) { height = (firstheight + i + 1); gecko_blockhashupdate(virt,hash2,height); printf("ht.%d %s\n",height,bits256_str(str,hash2)); } else printf("ht.%d non prevhash i.%d %s %s\n",height,i,bits256_str(str,prevhash2),bits256_str(str2,zmsgB.zH.prev_block)); len += n; prevhash2 = hash2; } } return(clonestr("{\"result\":\"gecko headers processed\"}")); } else return(clonestr("{\"error\":\"gecko headers couldnt find firsthash2\"}")); }
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 ( remoteonly == 0 && (block= iguana_blockfind(coin,blockhash)) != 0 ) { msg.H.version = block->RO.version; msg.H.merkle_root = block->RO.merkle_root; msg.H.timestamp = block->RO.timestamp; msg.H.bits = block->RO.bits; msg.H.nonce = block->RO.nonce; msg.txn_count = block->RO.txn_count; len = iguana_rwblock(1,&hash2,serialized,&msg); char str[65]; printf("timestamp.%u bits.%u nonce.%u v.%d (%s) len.%d (%ld %ld)\n",block->RO.timestamp,block->RO.bits,block->RO.nonce,block->RO.version,bits256_str(str,hash2),len,sizeof(serialized),sizeof(hexstr)); init_hexbytes_noT(hexstr,serialized,len); jaddstr(retjson,"result",hexstr); } else if ( coin->APIblockstr != 0 ) jaddstr(retjson,"error","already have pending request"); else { memset(txid.bytes,0,sizeof(txid)); if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,5)) != 0 ) { jaddstr(retjson,"result",blockstr); free(blockstr); } else jaddstr(retjson,"error","cant find blockhash"); } return(jprint(retjson,1)); }
HASH_AND_TWOINTS(bitcoinrpc,getblock,blockhash,verbose,remoteonly) { char *blockstr,*datastr; struct iguana_msgblock msg; struct iguana_block *block; cJSON *retjson; bits256 txid; int32_t len; retjson = cJSON_CreateObject(); memset(&msg,0,sizeof(msg)); if ( remoteonly == 0 && (block= iguana_blockfind("getblockRPC",coin,blockhash)) != 0 ) { if ( verbose != 0 ) return(jprint(iguana_blockjson(coin,block,1),1)); else { if ( (len= iguana_peerblockrequest(coin,coin->blockspace,coin->blockspacesize,0,blockhash,0)) > 0 ) { datastr = malloc(len*2 + 1); init_hexbytes_noT(datastr,coin->blockspace,len); jaddstr(retjson,"result",datastr); free(datastr); return(jprint(retjson,1)); } jaddstr(retjson,"error","error getting rawblock"); } } else if ( coin->APIblockstr != 0 ) jaddstr(retjson,"error","already have pending request"); else { memset(txid.bytes,0,sizeof(txid)); if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,5)) != 0 ) { jaddstr(retjson,"result",blockstr); free(blockstr); } else jaddstr(retjson,"error","cant find blockhash"); } return(jprint(retjson,1)); }
int32_t basilisk_respond_geckogetheaders(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2) { int32_t i,n,num,height,len=0; struct iguana_block *block; if ( (block= iguana_blockfind("geckohdr",virt,hash2)) != 0 ) { if ( (height= block->height) >= 0 ) { if ( (num= juint(valsobj,"num")) == 0 || num > virt->chain->bundlesize ) num = virt->chain->bundlesize; for (i=0; i<num; i++) { if ( block != 0 ) { if ( (n= iguana_headerget(myinfo,virt,&serialized[len],maxsize-len,block)) > 0 ) len += n; } hash2 = iguana_blockhash(virt,height+i+1); block = iguana_blockfind("geckohdri",virt,hash2); } return(len); } } return(-1); }
uint32_t gecko_nBits(struct iguana_info *virt,uint32_t *prevtimestampp,struct iguana_block *block,int32_t n) { uint32_t nBits = GECKO_DEFAULTDIFF,starttime,endtime,est; struct iguana_block *prev=0; int32_t i,diff; bits256 targetval; *prevtimestampp = 0; if ( virt->chain->estblocktime == 0 ) return(GECKO_EASIESTDIFF); for (i=0; i<n; i++) { if ( (prev= iguana_blockfind("geckotx",virt,block->RO.prev_block)) == 0 || prev->height == 0 ) { i++; break; } if ( i == 0 ) { *prevtimestampp = endtime = prev->RO.timestamp; nBits = prev->RO.bits; } starttime = prev->RO.timestamp; block = prev; } if ( starttime != 0 && endtime > starttime && i > 1 ) { diff = (endtime - starttime); est = virt->chain->estblocktime * i; targetval = bits256_from_compact(nBits); if ( diff > est ) { targetval = bits256_ave(targetval,bits256_ave(targetval,bits256_rshift(targetval))); } else if ( diff < est ) { if ( nBits == GECKO_EASIESTDIFF ) return(GECKO_EASIESTDIFF); targetval = bits256_ave(targetval,bits256_ave(targetval,bits256_lshift(targetval))); } //printf("diff.%d est.%d nBits.%08x <- %08x\n",diff,virt->chain->estblocktime * i,bits256_to_compact(targetval),nBits); nBits = bits256_to_compact(targetval); } if ( nBits > GECKO_EASIESTDIFF ) { //printf("nBits.%08x vs easiest %08x\n",nBits,GECKO_EASIESTDIFF); nBits = GECKO_EASIESTDIFF; } return(nBits); }